aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.arcconfig3
-rw-r--r--Makefile10
-rw-r--r--Makefile.inc117
-rw-r--r--ObsoleteFiles.inc79
-rw-r--r--UPDATING4
-rw-r--r--bin/chflags/chflags.115
-rw-r--r--bin/chflags/chflags.c51
-rw-r--r--bin/chmod/chmod.114
-rw-r--r--bin/chmod/chmod.c90
-rw-r--r--bin/ed/ed.12
-rw-r--r--bin/expr/expr.18
-rw-r--r--bin/sh/jobs.c2
-rw-r--r--cddl/contrib/opensolaris/lib/libnvpair/libnvpair.c11
-rw-r--r--cddl/lib/libdtrace/tcp.d75
-rw-r--r--contrib/gcclibs/libgomp/ChangeLog430
-rw-r--r--contrib/gcclibs/libgomp/ChangeLog.gcc448
-rw-r--r--contrib/gcclibs/libgomp/Makefile.am21
-rw-r--r--contrib/gcclibs/libgomp/Makefile.in237
-rw-r--r--contrib/gcclibs/libgomp/aclocal.m45
-rw-r--r--contrib/gcclibs/libgomp/config.h.in16
-rw-r--r--contrib/gcclibs/libgomp/config/bsd/proc.c117
-rw-r--r--contrib/gcclibs/libgomp/config/linux/affinity.c107
-rw-r--r--contrib/gcclibs/libgomp/config/linux/proc.c179
-rw-r--r--contrib/gcclibs/libgomp/config/mingw32/proc.c82
-rw-r--r--contrib/gcclibs/libgomp/config/posix/affinity.c41
-rwxr-xr-xcontrib/gcclibs/libgomp/configure11122
-rw-r--r--contrib/gcclibs/libgomp/configure.ac77
-rw-r--r--contrib/gcclibs/libgomp/configure.tgt20
-rw-r--r--contrib/gcclibs/libgomp/env.c97
-rw-r--r--contrib/gcclibs/libgomp/iter.c22
-rw-r--r--contrib/gcclibs/libgomp/libgomp.h12
-rw-r--r--contrib/gcclibs/libgomp/libgomp.texi27
-rw-r--r--contrib/gcclibs/libgomp/omp.h.in49
-rw-r--r--contrib/gcclibs/libgomp/omp_lib.h.in10
-rw-r--r--contrib/gcclibs/libgomp/team.c23
-rw-r--r--contrib/ldns/drill/config.h4
-rw-r--r--contrib/ldns/drill/drill.111
-rwxr-xr-xcontrib/ldns/freebsd-configure.sh19
-rw-r--r--contrib/ldns/packaging/fedora/ldns.spec212
-rw-r--r--contrib/ldns/packaging/ldns-config.143
-rwxr-xr-xcontrib/ldns/packaging/ldns-config.in31
-rw-r--r--contrib/ldns/packaging/libldns.pc.in13
-rw-r--r--contrib/libxo/Makefile.am2
-rw-r--r--contrib/libxo/configure.ac13
-rw-r--r--contrib/libxo/doc/libxo.txt97
-rw-r--r--contrib/libxo/libxo/Makefile.am5
-rw-r--r--contrib/libxo/libxo/libxo.c693
-rw-r--r--contrib/libxo/libxo/xo.h115
-rw-r--r--contrib/libxo/libxo/xo_error.37
-rw-r--r--contrib/libxo/libxo/xo_format.556
-rw-r--r--contrib/libxo/libxo/xo_open_container.38
-rw-r--r--contrib/libxo/libxo/xo_open_marker.3138
-rw-r--r--contrib/libxo/libxo/xo_set_version.359
-rw-r--r--contrib/libxo/libxo/xoconfig.h12
-rw-r--r--contrib/libxo/libxo/xoconfig.h.in6
-rw-r--r--contrib/libxo/libxo/xoversion.h6
-rw-r--r--contrib/libxo/m4/libtool.m42561
-rw-r--r--contrib/libxo/m4/ltoptions.m4127
-rw-r--r--contrib/libxo/m4/ltversion.m412
-rw-r--r--contrib/libxo/tests/core/Makefile.am4
-rw-r--r--contrib/libxo/tests/core/saved/test_01.JP.out6
-rw-r--r--contrib/libxo/tests/core/saved/test_02.JP.out4
-rw-r--r--contrib/libxo/tests/core/saved/test_05.H.out2
-rw-r--r--contrib/libxo/tests/core/saved/test_05.HIPx.out59
-rw-r--r--contrib/libxo/tests/core/saved/test_05.HP.out59
-rw-r--r--contrib/libxo/tests/core/saved/test_05.J.out2
-rw-r--r--contrib/libxo/tests/core/saved/test_05.JP.out16
-rw-r--r--contrib/libxo/tests/core/saved/test_05.T.out10
-rw-r--r--contrib/libxo/tests/core/saved/test_05.X.out2
-rw-r--r--contrib/libxo/tests/core/saved/test_05.XP.out16
-rw-r--r--contrib/libxo/tests/core/saved/test_09.JP.out20
-rw-r--r--contrib/libxo/tests/core/saved/test_10.H.err0
-rw-r--r--contrib/libxo/tests/core/saved/test_10.H.out1
-rw-r--r--contrib/libxo/tests/core/saved/test_10.HIPx.err0
-rw-r--r--contrib/libxo/tests/core/saved/test_10.HIPx.out316
-rw-r--r--contrib/libxo/tests/core/saved/test_10.HP.err0
-rw-r--r--contrib/libxo/tests/core/saved/test_10.HP.out316
-rw-r--r--contrib/libxo/tests/core/saved/test_10.J.err0
-rw-r--r--contrib/libxo/tests/core/saved/test_10.J.out2
-rw-r--r--contrib/libxo/tests/core/saved/test_10.JP.err0
-rw-r--r--contrib/libxo/tests/core/saved/test_10.JP.out113
-rw-r--r--contrib/libxo/tests/core/saved/test_10.T.err0
-rw-r--r--contrib/libxo/tests/core/saved/test_10.T.out48
-rw-r--r--contrib/libxo/tests/core/saved/test_10.X.err0
-rw-r--r--contrib/libxo/tests/core/saved/test_10.X.out1
-rw-r--r--contrib/libxo/tests/core/saved/test_10.XP.err0
-rw-r--r--contrib/libxo/tests/core/saved/test_10.XP.out100
-rw-r--r--contrib/libxo/tests/core/saved/test_10.err0
-rw-r--r--contrib/libxo/tests/core/saved/test_10.out38
-rw-r--r--contrib/libxo/tests/core/test_05.c17
-rw-r--r--contrib/libxo/tests/core/test_10.c212
-rw-r--r--contrib/libxo/xo/xo.12
-rw-r--r--contrib/libxo/xohtml/Makefile.am38
-rw-r--r--contrib/libxo/xohtml/xohtml.1125
-rw-r--r--contrib/libxo/xohtml/xohtml.css24
-rw-r--r--contrib/libxo/xohtml/xohtml.sh.in20
-rw-r--r--contrib/libxo/xolint/Makefile.am3
-rw-r--r--contrib/libxo/xolint/xolint.12
-rwxr-xr-xcontrib/libxo/xolint/xolint.pl63
-rw-r--r--contrib/netbsd-tests/lib/libm/t_fmod.c6
-rw-r--r--contrib/netbsd-tests/lib/libpthread/t_swapcontext.c3
-rw-r--r--contrib/tcpdump/interface.h2
-rw-r--r--contrib/tcpdump/netdissect.h2
-rw-r--r--contrib/tcpdump/print-ip.c2
-rw-r--r--contrib/tcpdump/print-pfsync.c210
-rw-r--r--contrib/unbound/Makefile.in184
-rw-r--r--contrib/unbound/compat/getentropy_linux.c21
-rw-r--r--contrib/unbound/config.h15
-rw-r--r--contrib/unbound/config.h.in9
-rwxr-xr-xcontrib/unbound/configure122
-rw-r--r--contrib/unbound/configure.ac18
-rw-r--r--contrib/unbound/daemon/remote.c9
-rw-r--r--contrib/unbound/daemon/unbound.c33
-rw-r--r--contrib/unbound/daemon/worker.c2
-rw-r--r--contrib/unbound/doc/Changelog106
-rw-r--r--contrib/unbound/doc/README2
-rw-r--r--contrib/unbound/doc/example.conf12
-rw-r--r--contrib/unbound/doc/example.conf.in12
-rw-r--r--contrib/unbound/doc/libunbound.34
-rw-r--r--contrib/unbound/doc/libunbound.3.in4
-rw-r--r--contrib/unbound/doc/unbound-anchor.82
-rw-r--r--contrib/unbound/doc/unbound-anchor.8.in2
-rw-r--r--contrib/unbound/doc/unbound-checkconf.86
-rw-r--r--contrib/unbound/doc/unbound-checkconf.8.in6
-rw-r--r--contrib/unbound/doc/unbound-control.82
-rw-r--r--contrib/unbound/doc/unbound-control.8.in2
-rw-r--r--contrib/unbound/doc/unbound-host.12
-rw-r--r--contrib/unbound/doc/unbound-host.1.in2
-rw-r--r--contrib/unbound/doc/unbound.84
-rw-r--r--contrib/unbound/doc/unbound.8.in4
-rw-r--r--contrib/unbound/doc/unbound.conf.516
-rw-r--r--contrib/unbound/doc/unbound.conf.5.in16
-rw-r--r--contrib/unbound/iterator/iter_scrub.c4
-rw-r--r--contrib/unbound/iterator/iter_utils.c36
-rw-r--r--contrib/unbound/iterator/iter_utils.h9
-rw-r--r--contrib/unbound/iterator/iterator.c15
-rw-r--r--contrib/unbound/libunbound/libworker.c6
-rw-r--r--contrib/unbound/libunbound/python/libunbound.i8
-rw-r--r--contrib/unbound/services/listen_dnsport.c64
-rw-r--r--contrib/unbound/services/localzone.c29
-rw-r--r--contrib/unbound/services/localzone.h9
-rw-r--r--contrib/unbound/smallapp/unbound-checkconf.c20
-rwxr-xr-xcontrib/unbound/smallapp/unbound-control-setup.sh3
-rwxr-xr-xcontrib/unbound/smallapp/unbound-control-setup.sh.in3
-rw-r--r--contrib/unbound/smallapp/unbound-control.c8
-rw-r--r--contrib/unbound/util/config_file.c25
-rw-r--r--contrib/unbound/util/config_file.h11
-rw-r--r--contrib/unbound/util/configlexer.lex1
-rw-r--r--contrib/unbound/util/configparser.y18
-rw-r--r--contrib/unbound/util/iana_ports.inc7
-rw-r--r--contrib/unbound/util/net_help.c7
-rw-r--r--contrib/unbound/util/rtt.c2
-rw-r--r--contrib/unbound/util/rtt.h2
-rw-r--r--contrib/unbound/validator/val_secalgo.c3
-rw-r--r--contrib/unbound/validator/val_utils.c12
-rw-r--r--contrib/unbound/validator/val_utils.h7
-rw-r--r--contrib/unbound/validator/validator.c57
-rw-r--r--etc/defaults/rc.conf2
-rw-r--r--etc/mtree/BSD.tests.dist14
-rw-r--r--etc/rc.d/Makefile4
-rwxr-xr-xetc/rc.d/devd2
-rwxr-xr-xetc/rc.d/hostid64
-rw-r--r--etc/rc.d/tests/Makefile (renamed from etc/tests/rc.d/Makefile)0
-rwxr-xr-xetc/rc.d/tests/routing_test.sh (renamed from etc/tests/rc.d/routing_test.sh)0
-rw-r--r--etc/tests/Makefile2
-rw-r--r--gnu/lib/libgomp/Makefile2
-rw-r--r--gnu/lib/libgomp/config.h6
-rw-r--r--gnu/usr.bin/cc/Makefile5
-rw-r--r--lib/libarchive/config_freebsd.h7
-rw-r--r--lib/libc/Makefile4
-rw-r--r--lib/libc/Makefile.amd646
-rw-r--r--lib/libc/Makefile.i3866
-rw-r--r--lib/libc/gen/_once_stub.c2
-rw-r--r--lib/libc/gen/getutxent.32
-rw-r--r--lib/libc/gen/nice.32
-rw-r--r--lib/libc/gen/posix_spawn.32
-rw-r--r--lib/libc/gen/posix_spawn_file_actions_addopen.32
-rw-r--r--lib/libc/gen/posix_spawn_file_actions_init.32
-rw-r--r--lib/libc/gen/posix_spawnattr_getflags.32
-rw-r--r--lib/libc/gen/posix_spawnattr_getpgroup.32
-rw-r--r--lib/libc/gen/posix_spawnattr_getschedparam.32
-rw-r--r--lib/libc/gen/posix_spawnattr_getschedpolicy.32
-rw-r--r--lib/libc/gen/posix_spawnattr_getsigdefault.32
-rw-r--r--lib/libc/gen/posix_spawnattr_getsigmask.32
-rw-r--r--lib/libc/gen/posix_spawnattr_init.32
-rw-r--r--lib/libc/include/compat.h2
-rw-r--r--lib/libc/locale/duplocale.32
-rw-r--r--lib/libc/locale/freelocale.32
-rw-r--r--lib/libc/locale/newlocale.32
-rw-r--r--lib/libc/locale/none.c2
-rw-r--r--lib/libc/locale/querylocale.32
-rw-r--r--lib/libc/locale/uselocale.32
-rw-r--r--lib/libc/net/sctp_recvmsg.36
-rw-r--r--lib/libc/nls/catopen.32
-rw-r--r--lib/libc/regex/re_format.76
-rw-r--r--lib/libc/regex/regcomp.c4
-rw-r--r--lib/libc/regex/regex.36
-rw-r--r--lib/libc/rpc/rpcbind.32
-rw-r--r--lib/libc/stdio/open_memstream.32
-rw-r--r--lib/libc/stdio/open_memstream.c2
-rw-r--r--lib/libc/stdio/open_wmemstream.c2
-rw-r--r--lib/libc/sys/closefrom.22
-rw-r--r--lib/libc/sys/posix_openpt.22
-rw-r--r--lib/libc/sys/procctl.22
-rw-r--r--lib/libc/tests/db/Makefile1
-rw-r--r--lib/libc/tests/sys/Makefile2
-rw-r--r--lib/libcapsicum/libcapsicum_dns.c36
-rw-r--r--lib/libcapsicum/libcapsicum_grp.c27
-rw-r--r--lib/libcapsicum/libcapsicum_pwd.c16
-rw-r--r--lib/libedit/el.c2
-rw-r--r--lib/libgeom/geom_xml2tree.c1
-rw-r--r--lib/libmd/mdXhl.c2
-rw-r--r--lib/libnv/Makefile175
-rw-r--r--lib/libnv/nv.311
-rw-r--r--lib/libnv/tests/dnv_tests.cc38
-rw-r--r--lib/libnv/tests/nv_tests.cc34
-rw-r--r--lib/librt/Makefile4
-rw-r--r--lib/librt/Makefile.amd646
-rw-r--r--lib/librt/Makefile.i3866
-rw-r--r--lib/libstand/Makefile33
-rw-r--r--lib/libthr/Makefile4
-rw-r--r--lib/libthr/Makefile.amd646
-rw-r--r--lib/libthr/Makefile.i3866
-rw-r--r--lib/libthr/tests/Makefile2
-rw-r--r--lib/libthr/thread/thr_clean.c2
-rw-r--r--lib/libxo/Makefile2
-rw-r--r--lib/msun/Makefile4
-rw-r--r--lib/msun/Makefile.amd646
-rw-r--r--lib/msun/Makefile.i3866
-rw-r--r--lib/msun/man/j0.36
-rw-r--r--lib/msun/man/lgamma.31
-rw-r--r--lib/msun/man/nextafter.34
-rw-r--r--lib/msun/tests/Makefile9
-rw-r--r--libexec/casper/dns/dns.c27
-rw-r--r--libexec/casper/grp/grp.c9
-rw-r--r--libexec/getty/subr.c14
-rw-r--r--libexec/rtld-elf/rtld.c81
-rw-r--r--release/Makefile.ec216
-rw-r--r--release/arm/BEAGLEBONE.conf2
-rw-r--r--release/arm/PANDABOARD.conf2
-rw-r--r--release/arm/RPI-B.conf2
-rw-r--r--release/arm/WANDBOARD-QUAD.conf2
-rw-r--r--release/arm/ZEDBOARD.conf2
-rwxr-xr-xrelease/arm64/make-memstick.sh2
-rw-r--r--release/doc/en_US.ISO8859-1/relnotes/article.xml139
-rw-r--r--release/doc/share/xml/release.ent1
-rw-r--r--release/doc/share/xml/sponsor.ent6
-rwxr-xr-xrelease/scripts/mk-vmimage.sh10
-rw-r--r--release/tools/vmimage.subr19
-rw-r--r--sbin/atm/atmconfig/atmconfig.84
-rw-r--r--sbin/camcontrol/camcontrol.87
-rw-r--r--sbin/growfs/Makefile6
-rw-r--r--sbin/growfs/growfs.c4
-rw-r--r--sbin/ipfw/ipfw2.c125
-rw-r--r--sbin/ipfw/ipfw2.h2
-rw-r--r--sbin/ipfw/tables.c67
-rw-r--r--share/doc/papers/Makefile1
-rw-r--r--share/doc/papers/bufbio/bio.ms20
-rw-r--r--share/doc/papers/hwpmc/Makefile8
-rw-r--r--share/doc/papers/hwpmc/hwpmc.ms34
-rw-r--r--share/doc/usd/06.bc/bc5
-rw-r--r--share/doc/usd/10.exref/Makefile6
-rw-r--r--share/doc/usd/10.exref/Makefile.inc4
-rw-r--r--share/doc/usd/10.exref/exref/Makefile5
-rw-r--r--share/doc/usd/10.exref/exref/ex.rm2215
-rw-r--r--share/doc/usd/10.exref/summary/Makefile7
-rw-r--r--share/doc/usd/10.exref/summary/ex.summary730
-rw-r--r--share/doc/usd/11.vitut/Makefile17
-rw-r--r--share/doc/usd/11.vitut/edittut.ms2280
-rw-r--r--share/doc/usd/12.vi/Makefile6
-rw-r--r--share/doc/usd/12.vi/Makefile.inc4
-rw-r--r--share/doc/usd/12.vi/summary/Makefile7
-rw-r--r--share/doc/usd/12.vi/summary/vi.summary468
-rw-r--r--share/doc/usd/12.vi/vi/Makefile6
-rw-r--r--share/doc/usd/12.vi/vi/vi.chars645
-rw-r--r--share/doc/usd/12.vi/vi/vi.in2074
-rw-r--r--share/doc/usd/12.vi/viapwh/Makefile6
-rw-r--r--share/doc/usd/12.vi/viapwh/vi.apwh.ms1081
-rw-r--r--share/doc/usd/13.viref/Makefile34
-rw-r--r--share/doc/usd/13.viref/ex.cmd.roff1924
-rw-r--r--share/doc/usd/13.viref/ref.so103
-rw-r--r--share/doc/usd/13.viref/set.opt.roff1303
-rw-r--r--share/doc/usd/13.viref/vi.cmd.roff3085
-rw-r--r--share/doc/usd/13.viref/vi.ref1840
-rw-r--r--share/doc/usd/18.msdiffs/ms.diffs1
-rw-r--r--share/doc/usd/22.trofftut/tt001
-rw-r--r--share/doc/usd/Makefile4
-rw-r--r--share/doc/usd/contents/contents.ms1
-rwxr-xr-xshare/dtrace/siftr68
-rw-r--r--share/man/man4/ada.41
-rw-r--r--share/man/man4/smb.4168
-rw-r--r--share/man/man4/urtwn.42
-rw-r--r--share/man/man4/xen.448
-rw-r--r--share/man/man9/BUS_BIND_INTR.92
-rw-r--r--share/man/man9/BUS_CHILD_DELETED.92
-rw-r--r--share/man/man9/BUS_CHILD_DETACHED.92
-rw-r--r--share/man/man9/BUS_DESCRIBE_INTR.92
-rw-r--r--share/man/man9/BUS_NEW_PASS.92
-rw-r--r--share/man/man9/Makefile1
-rw-r--r--share/man/man9/VOP_ADVISE.92
-rw-r--r--share/man/man9/VOP_ALLOCATE.92
-rw-r--r--share/man/man9/bus_adjust_resource.92
-rw-r--r--share/man/man9/bus_generic_new_pass.92
-rw-r--r--share/man/man9/bus_set_pass.92
-rw-r--r--share/man/man9/getenv.92
-rw-r--r--share/man/man9/panic.98
-rw-r--r--share/man/man9/refcount.92
-rw-r--r--share/man/man9/sglist.92
-rw-r--r--share/man/man9/shm_map.92
-rw-r--r--share/misc/committers-src.dot2
-rw-r--r--share/mk/src.opts.mk6
-rw-r--r--sys/amd64/amd64/apic_vector.S16
-rw-r--r--sys/amd64/amd64/mp_machdep.c1034
-rw-r--r--sys/amd64/conf/GENERIC4
-rw-r--r--sys/amd64/conf/NOTES2
-rw-r--r--sys/amd64/include/smp.h39
-rw-r--r--sys/amd64/include/vm.h2
-rw-r--r--sys/amd64/include/vmm.h6
-rw-r--r--sys/amd64/include/xen/xenfunc.h9
-rw-r--r--sys/amd64/include/xen/xenpmap.h227
-rw-r--r--sys/amd64/include/xen/xenvar.h61
-rw-r--r--sys/amd64/vmm/amd/amdv.c1
-rw-r--r--sys/amd64/vmm/amd/svm.c1
-rw-r--r--sys/amd64/vmm/amd/svm_msr.c24
-rw-r--r--sys/amd64/vmm/amd/vmcb.c1
-rw-r--r--sys/amd64/vmm/intel/vmx_msr.c16
-rw-r--r--sys/amd64/vmm/io/vatpic.c1
-rw-r--r--sys/amd64/vmm/io/vatpit.c1
-rw-r--r--sys/amd64/vmm/io/vhpet.c1
-rw-r--r--sys/amd64/vmm/io/vioapic.c1
-rw-r--r--sys/amd64/vmm/io/vlapic.c20
-rw-r--r--sys/amd64/vmm/io/vpmtmr.c1
-rw-r--r--sys/amd64/vmm/io/vrtc.c118
-rw-r--r--sys/amd64/vmm/vmm.c8
-rw-r--r--sys/amd64/vmm/vmm_instruction_emul.c129
-rw-r--r--sys/amd64/vmm/vmm_ioport.c6
-rw-r--r--sys/amd64/vmm/vmm_stat.c1
-rw-r--r--sys/amd64/vmm/x86.c4
-rw-r--r--sys/arm/allwinner/std.a102
-rw-r--r--sys/arm/amlogic/aml8726/aml8726_mmc.c318
-rw-r--r--sys/arm/amlogic/aml8726/aml8726_mmc.h14
-rw-r--r--sys/arm/amlogic/aml8726/files.aml87263
-rw-r--r--sys/arm/amlogic/aml8726/files.smp4
-rw-r--r--sys/arm/amlogic/aml8726/std.aml87269
-rw-r--r--sys/arm/amlogic/aml8726/std.odroidc117
-rw-r--r--sys/arm/amlogic/aml8726/std.vsatv102-m617
-rw-r--r--sys/arm/arm/busdma_machdep-v6.c4
-rw-r--r--sys/arm/arm/busdma_machdep.c4
-rw-r--r--sys/arm/arm/cpufunc.c3
-rw-r--r--sys/arm/arm/locore-v4.S74
-rw-r--r--sys/arm/arm/locore-v6.S125
-rw-r--r--sys/arm/arm/pmap-v6-new.c9
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_mbox.c3
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_sdhci.c13
-rw-r--r--sys/arm/broadcom/bcm2835/std.bcm28362
-rw-r--r--sys/arm/conf/AML8726143
-rw-r--r--sys/arm/conf/EFIKA_MX2
-rw-r--r--sys/arm/conf/IMX532
-rw-r--r--sys/arm/conf/IMX62
-rw-r--r--sys/arm/conf/ODROIDC1121
-rw-r--r--sys/arm/conf/RK31884
-rw-r--r--sys/arm/conf/RPI24
-rw-r--r--sys/arm/conf/VSATV102121
-rw-r--r--sys/arm/freescale/imx/files.imx5 (renamed from sys/arm/freescale/imx/files.imx53)5
-rw-r--r--sys/arm/freescale/imx/files.imx5149
-rw-r--r--sys/arm/freescale/imx/std.imx513
-rw-r--r--sys/arm/freescale/imx/std.imx533
-rw-r--r--sys/arm64/arm64/bus_machdep.c16
-rw-r--r--sys/arm64/arm64/bus_space_asm.S6
-rw-r--r--sys/arm64/arm64/db_disasm.c41
-rw-r--r--sys/arm64/arm64/db_interface.c168
-rw-r--r--sys/arm64/arm64/db_trace.c152
-rw-r--r--sys/arm64/arm64/debug_monitor.c487
-rw-r--r--sys/arm64/arm64/nexus.c6
-rw-r--r--sys/arm64/arm64/pmap.c12
-rw-r--r--sys/arm64/include/pmap.h2
-rw-r--r--sys/boot/common/md.c2
-rw-r--r--sys/boot/fdt/dts/arm/bcm2836.dtsi14
-rw-r--r--sys/boot/fdt/dts/arm/rpi2.dts20
-rw-r--r--sys/boot/forth/loader.conf10
-rw-r--r--sys/boot/i386/common/edd.h2
-rw-r--r--sys/boot/libstand32/Makefile36
-rw-r--r--sys/boot/userboot/libstand/Makefile39
-rw-r--r--sys/cddl/contrib/opensolaris/common/nvpair/nvpair.c1
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c4
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c13
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c32
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c3
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c5
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_onexit.c2
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c24
-rw-r--r--sys/cddl/dev/dtrace/amd64/dtrace_asm.S208
-rw-r--r--sys/cddl/dev/dtrace/arm/dtrace_asm.S18
-rw-r--r--sys/cddl/dev/dtrace/dtrace_hacks.c3
-rw-r--r--sys/cddl/dev/dtrace/i386/dtrace_asm.S164
-rw-r--r--sys/cddl/dev/dtrace/mips/dtrace_asm.S44
-rw-r--r--sys/cddl/dev/dtrace/powerpc/dtrace_asm.S40
-rw-r--r--sys/cddl/dev/profile/profile.c6
-rw-r--r--sys/compat/linux/linux_getcwd.c413
-rw-r--r--sys/conf/files58
-rw-r--r--sys/conf/files.amd6410
-rw-r--r--sys/conf/files.arm644
-rw-r--r--sys/conf/files.i38647
-rw-r--r--sys/conf/files.pc981
-rw-r--r--sys/conf/files.powerpc7
-rw-r--r--sys/conf/kern.mk2
-rw-r--r--sys/conf/kern.pre.mk2
-rw-r--r--sys/conf/options2
-rw-r--r--sys/conf/options.amd642
-rw-r--r--sys/conf/options.arm3
-rw-r--r--sys/conf/options.arm642
-rw-r--r--sys/conf/options.i3864
-rw-r--r--sys/dev/acpica/acpi.c2
-rw-r--r--sys/dev/atkbdc/atkbd.c82
-rw-r--r--sys/dev/bxe/bxe.h2
-rw-r--r--sys/dev/cxgbe/t4_main.c41
-rw-r--r--sys/dev/e1000/if_igb.c79
-rw-r--r--sys/dev/hyperv/include/hyperv.h167
-rw-r--r--sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c801
-rw-r--r--sys/dev/hyperv/storvsc/hv_vstorage.h16
-rw-r--r--sys/dev/hyperv/utilities/hv_kvp.c11
-rw-r--r--sys/dev/hyperv/utilities/hv_util.c9
-rw-r--r--sys/dev/hyperv/vmbus/hv_channel.c98
-rw-r--r--sys/dev/hyperv/vmbus/hv_channel_mgmt.c265
-rw-r--r--sys/dev/hyperv/vmbus/hv_connection.c286
-rw-r--r--sys/dev/hyperv/vmbus/hv_hv.c66
-rw-r--r--sys/dev/hyperv/vmbus/hv_ring_buffer.c76
-rw-r--r--sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c364
-rw-r--r--sys/dev/hyperv/vmbus/hv_vmbus_priv.h71
-rw-r--r--sys/dev/ichsmb/ichsmb_pci.c4
-rw-r--r--sys/dev/iicbus/pcf8563.c67
-rw-r--r--sys/dev/ipmi/ipmi.c23
-rw-r--r--sys/dev/ipmi/ipmi_kcs.c1
-rw-r--r--sys/dev/ipmi/ipmi_smic.c1
-rw-r--r--sys/dev/ipmi/ipmivars.h1
-rw-r--r--sys/dev/ixgbe/if_ix.c1073
-rw-r--r--sys/dev/ixgbe/if_ixv.c9
-rw-r--r--sys/dev/ixgbe/ix_txrx.c57
-rw-r--r--sys/dev/ixgbe/ixgbe.h39
-rw-r--r--sys/dev/ixgbe/ixgbe_82598.c7
-rw-r--r--sys/dev/ixgbe/ixgbe_82598.h2
-rw-r--r--sys/dev/ixgbe/ixgbe_82599.c6
-rw-r--r--sys/dev/ixgbe/ixgbe_82599.h2
-rw-r--r--sys/dev/ixgbe/ixgbe_api.c122
-rw-r--r--sys/dev/ixgbe/ixgbe_api.h11
-rw-r--r--sys/dev/ixgbe/ixgbe_common.c6
-rw-r--r--sys/dev/ixgbe/ixgbe_common.h2
-rw-r--r--sys/dev/ixgbe/ixgbe_dcb.c12
-rw-r--r--sys/dev/ixgbe/ixgbe_dcb.h2
-rw-r--r--sys/dev/ixgbe/ixgbe_dcb_82598.c2
-rw-r--r--sys/dev/ixgbe/ixgbe_dcb_82598.h2
-rw-r--r--sys/dev/ixgbe/ixgbe_dcb_82599.c2
-rw-r--r--sys/dev/ixgbe/ixgbe_dcb_82599.h2
-rw-r--r--sys/dev/ixgbe/ixgbe_mbx.c4
-rw-r--r--sys/dev/ixgbe/ixgbe_mbx.h2
-rw-r--r--sys/dev/ixgbe/ixgbe_osdep.h9
-rw-r--r--sys/dev/ixgbe/ixgbe_phy.c228
-rw-r--r--sys/dev/ixgbe/ixgbe_phy.h23
-rw-r--r--sys/dev/ixgbe/ixgbe_type.h265
-rw-r--r--sys/dev/ixgbe/ixgbe_vf.c3
-rw-r--r--sys/dev/ixgbe/ixgbe_vf.h2
-rw-r--r--sys/dev/ixgbe/ixgbe_x540.c12
-rw-r--r--sys/dev/ixgbe/ixgbe_x540.h2
-rw-r--r--sys/dev/ixgbe/ixgbe_x550.c3191
-rw-r--r--sys/dev/ixgbe/ixgbe_x550.h109
-rw-r--r--sys/dev/ixl/ixl.h2
-rw-r--r--sys/dev/mii/brgphy.c28
-rw-r--r--sys/dev/mxge/if_mxge.c2
-rw-r--r--sys/dev/pccbb/pccbb_pci.c52
-rw-r--r--sys/dev/pci/pci.c120
-rw-r--r--sys/dev/pci/pci_pci.c66
-rw-r--r--sys/dev/pci/pci_subr.c2
-rw-r--r--sys/dev/pci/pcib_private.h3
-rw-r--r--sys/dev/pci/pcivar.h10
-rw-r--r--sys/dev/smbus/smb.c148
-rw-r--r--sys/dev/smbus/smb.h37
-rw-r--r--sys/dev/smbus/smbconf.h33
-rw-r--r--sys/dev/smbus/smbus.c88
-rw-r--r--sys/dev/smbus/smbus.h4
-rw-r--r--sys/dev/smbus/smbus_if.m17
-rw-r--r--sys/dev/sound/pcm/dsp.c12
-rw-r--r--sys/dev/usb/controller/dwc_otg.c16
-rw-r--r--sys/dev/usb/usbdevs1
-rw-r--r--sys/dev/usb/wlan/if_urtwn.c61
-rw-r--r--sys/dev/virtio/network/if_vtnet.c5
-rw-r--r--sys/dev/vt/hw/fb/vt_fb.c54
-rw-r--r--sys/dev/vt/hw/vga/vt_vga.c16
-rw-r--r--sys/dev/vt/vt_core.c20
-rw-r--r--sys/dev/xen/balloon/balloon.c48
-rw-r--r--sys/dev/xen/blkback/blkback.c13
-rw-r--r--sys/dev/xen/control/control.c130
-rw-r--r--sys/dev/xen/grant_table/grant_table.c70
-rw-r--r--sys/dev/xen/netback/netback.c14
-rw-r--r--sys/dev/xen/netfront/netfront.c10
-rw-r--r--sys/fs/nfs/nfsport.h2
-rw-r--r--sys/fs/nfsclient/nfs_clvfsops.c8
-rw-r--r--sys/fs/nfsserver/nfs_nfsdkrpc.c3
-rw-r--r--sys/geom/uncompress/g_uncompress.c2
-rw-r--r--sys/geom/uzip/g_uzip.c2
-rw-r--r--sys/i386/conf/DEFAULTS1
-rw-r--r--sys/i386/conf/GENERIC4
-rw-r--r--sys/i386/conf/XEN96
-rw-r--r--sys/i386/i386/apic_vector.s24
-rw-r--r--sys/i386/i386/genassym.c5
-rw-r--r--sys/i386/i386/machdep.c318
-rw-r--r--sys/i386/i386/minidump_machdep.c28
-rw-r--r--sys/i386/i386/mp_machdep.c1002
-rw-r--r--sys/i386/i386/support.s2
-rw-r--r--sys/i386/i386/swtch.s22
-rw-r--r--sys/i386/i386/sys_machdep.c103
-rw-r--r--sys/i386/i386/vm_machdep.c27
-rw-r--r--sys/i386/include/asmacros.h31
-rw-r--r--sys/i386/include/cpufunc.h46
-rw-r--r--sys/i386/include/intr_machdep.h8
-rw-r--r--sys/i386/include/pcpu.h32
-rw-r--r--sys/i386/include/pmap.h81
-rw-r--r--sys/i386/include/segments.h6
-rw-r--r--sys/i386/include/smp.h44
-rw-r--r--sys/i386/include/vm.h2
-rw-r--r--sys/i386/include/vmparam.h8
-rw-r--r--sys/i386/include/xen/features.h22
-rw-r--r--sys/i386/include/xen/hypercall.h6
-rw-r--r--sys/i386/include/xen/xen-os.h99
-rw-r--r--sys/i386/include/xen/xenfunc.h1
-rw-r--r--sys/i386/include/xen/xenpmap.h237
-rw-r--r--sys/i386/include/xen/xenstored.h89
-rw-r--r--sys/i386/include/xen/xenvar.h85
-rw-r--r--sys/i386/isa/npx.c9
-rw-r--r--sys/i386/pci/pci_cfgreg.c10
-rw-r--r--sys/i386/pci/pci_pir.c9
-rw-r--r--sys/i386/xen/clock.c570
-rw-r--r--sys/i386/xen/exception.s494
-rw-r--r--sys/i386/xen/locore.s360
-rw-r--r--sys/i386/xen/mp_machdep.c1300
-rw-r--r--sys/i386/xen/mptable.c109
-rw-r--r--sys/i386/xen/pmap.c4420
-rw-r--r--sys/i386/xen/xen_machdep.c1236
-rw-r--r--sys/kern/imgact_elf.c14
-rw-r--r--sys/kern/kern_descrip.c38
-rw-r--r--sys/kern/kern_exec.c2
-rw-r--r--sys/kern/kern_exit.c8
-rw-r--r--sys/kern/kern_gzio.c3
-rw-r--r--sys/kern/kern_intr.c5
-rw-r--r--sys/kern/kern_jail.c22
-rw-r--r--sys/kern/kern_proc.c2
-rw-r--r--sys/kern/kern_racct.c98
-rw-r--r--sys/kern/kern_rctl.c69
-rw-r--r--sys/kern/kern_shutdown.c3
-rw-r--r--sys/kern/kern_synch.c9
-rw-r--r--sys/kern/kern_thr.c26
-rw-r--r--sys/kern/link_elf.c2
-rw-r--r--sys/kern/link_elf_obj.c2
-rw-r--r--sys/kern/sched_4bsd.c2
-rw-r--r--sys/kern/subr_dnvlist.c166
-rw-r--r--sys/kern/subr_nvlist.c807
-rw-r--r--sys/kern/subr_nvpair.c379
-rw-r--r--sys/kern/subr_param.c4
-rw-r--r--sys/kern/subr_trap.c22
-rw-r--r--sys/kern/sysv_msg.c42
-rw-r--r--sys/kern/sysv_sem.c25
-rw-r--r--sys/kern/sysv_shm.c80
-rw-r--r--sys/kern/uipc_shm.c2
-rw-r--r--sys/kern/vfs_aio.c206
-rw-r--r--sys/kern/vfs_bio.c107
-rw-r--r--sys/libkern/zlib.c (renamed from sys/net/zlib.c)2
-rw-r--r--sys/mips/mips/busdma_machdep.c4
-rw-r--r--sys/modules/ix/Makefile2
-rw-r--r--sys/modules/ixv/Makefile2
-rw-r--r--sys/modules/oce/Makefile2
-rw-r--r--sys/modules/zlib/Makefile2
-rw-r--r--sys/net/if_vlan.c21
-rw-r--r--sys/net/netisr.c15
-rw-r--r--sys/netgraph/ng_deflate.c3
-rw-r--r--sys/netinet/in_kdtrace.c3
-rw-r--r--sys/netinet/in_kdtrace.h3
-rw-r--r--sys/netinet/ip_fw.h5
-rw-r--r--sys/netinet/ip_ipsec.c11
-rw-r--r--sys/netinet/libalias/libalias.38
-rw-r--r--sys/netinet/sctp_indata.c11
-rw-r--r--sys/netinet/siftr.c4
-rw-r--r--sys/netinet/tcp_subr.c1
-rw-r--r--sys/netinet/tcp_timewait.c7
-rw-r--r--sys/netinet6/ip6_forward.c9
-rw-r--r--sys/netinet6/ip6_ipsec.c12
-rw-r--r--sys/netipsec/ipsec.c3
-rw-r--r--sys/netipsec/ipsec.h1
-rw-r--r--sys/netipsec/ipsec_input.c1
-rw-r--r--sys/netipsec/ipsec_output.c22
-rw-r--r--sys/netipsec/xform_ah.c7
-rw-r--r--sys/netipsec/xform_esp.c7
-rw-r--r--sys/netipsec/xform_ipcomp.c7
-rw-r--r--sys/netpfil/ipfw/ip_fw2.c6
-rw-r--r--sys/netpfil/ipfw/ip_fw_nat.c26
-rw-r--r--sys/netpfil/ipfw/ip_fw_private.h113
-rw-r--r--sys/netpfil/ipfw/ip_fw_sockopt.c564
-rw-r--r--sys/netpfil/ipfw/ip_fw_table.c573
-rw-r--r--sys/netpfil/ipfw/ip_fw_table.h13
-rw-r--r--sys/opencrypto/cryptodeflate.c4
-rw-r--r--sys/opencrypto/deflate.h2
-rw-r--r--sys/powerpc/aim/aim_machdep.c (renamed from sys/powerpc/aim/machdep.c)345
-rw-r--r--sys/powerpc/aim/mmu_oea64.c5
-rw-r--r--sys/powerpc/booke/booke_machdep.c (renamed from sys/powerpc/booke/machdep.c)369
-rw-r--r--sys/powerpc/booke/pmap.c7
-rw-r--r--sys/powerpc/conf/GENERIC1
-rw-r--r--sys/powerpc/ofw/ofw_machdep.c23
-rw-r--r--sys/powerpc/powerpc/busdma_machdep.c4
-rw-r--r--sys/powerpc/powerpc/machdep.c502
-rw-r--r--sys/powerpc/powerpc/uma_machdep.c (renamed from sys/powerpc/aim/uma_machdep.c)0
-rw-r--r--sys/sparc64/pci/apb.c10
-rw-r--r--sys/sys/cdefs.h24
-rw-r--r--sys/sys/nv.h124
-rw-r--r--sys/sys/nv_impl.h51
-rw-r--r--sys/sys/nvlist_impl.h4
-rw-r--r--sys/sys/param.h16
-rw-r--r--sys/sys/procctl.h2
-rw-r--r--sys/sys/racct.h4
-rw-r--r--sys/sys/seq.h8
-rw-r--r--sys/sys/systm.h1
-rw-r--r--sys/sys/zlib.h (renamed from sys/net/zlib.h)0
-rw-r--r--sys/sys/zutil.h (renamed from sys/net/zutil.h)2
-rw-r--r--sys/ufs/ffs/ffs_alloc.c78
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c1
-rw-r--r--sys/ufs/ufs/inode.h2
-rw-r--r--sys/vm/sg_pager.c2
-rw-r--r--sys/vm/swap_pager.c12
-rw-r--r--sys/vm/uma_int.h2
-rw-r--r--sys/vm/vm_fault.c4
-rw-r--r--sys/vm/vm_map.c55
-rw-r--r--sys/vm/vm_mmap.c32
-rw-r--r--sys/vm/vm_page.c186
-rw-r--r--sys/vm/vm_pageout.c59
-rw-r--r--sys/vm/vm_unix.c81
-rw-r--r--sys/x86/acpica/srat.c2
-rw-r--r--sys/x86/include/apicvar.h1
-rw-r--r--sys/x86/include/mca.h2
-rw-r--r--sys/x86/include/segments.h8
-rw-r--r--sys/x86/pci/qpi.c2
-rw-r--r--sys/x86/x86/busdma_bounce.c9
-rw-r--r--sys/x86/x86/cpu_machdep.c53
-rw-r--r--sys/x86/x86/identcpu.c4
-rw-r--r--sys/x86/x86/intr_machdep.c7
-rw-r--r--sys/x86/x86/local_apic.c6
-rw-r--r--sys/x86/x86/mca.c2
-rw-r--r--sys/x86/x86/mp_x86.c1120
-rw-r--r--sys/x86/xen/xen_intr.c4
-rw-r--r--sys/x86/xen/xen_nexus.c6
-rw-r--r--tests/freebsd_test_suite/macros.h56
-rw-r--r--tests/sys/Makefile6
-rw-r--r--tests/sys/aio/Makefile16
-rw-r--r--tests/sys/aio/aio_kqueue_test.c (renamed from tools/regression/aio/kqueue/aio_kqueue.c)36
-rw-r--r--tests/sys/aio/aio_test.c (renamed from tools/regression/aio/aiotest/aiotest.c)246
-rw-r--r--tests/sys/aio/lio_kqueue_test.c (renamed from tools/regression/aio/kqueue/lio/lio_kqueue.c)22
-rw-r--r--tests/sys/fifo/Makefile13
-rw-r--r--tests/sys/fifo/fifo_create.c (renamed from tools/regression/fifo/fifo_create/fifo_create.c)17
-rw-r--r--tests/sys/fifo/fifo_io.c (renamed from tools/regression/fifo/fifo_io/fifo_io.c)48
-rw-r--r--tests/sys/fifo/fifo_misc.c (renamed from tools/regression/fifo/fifo_misc/fifo_misc.c)15
-rw-r--r--tests/sys/fifo/fifo_open.c (renamed from tools/regression/fifo/fifo_open/fifo_open.c)6
-rw-r--r--tests/sys/file/Makefile25
-rw-r--r--tests/sys/file/closefrom_test.c275
-rw-r--r--tests/sys/file/dup_test.c (renamed from tools/regression/file/dup/dup.c)0
-rw-r--r--tests/sys/file/fcntlflags_test.c (renamed from tools/regression/file/fcntlflags/fcntlflags.c)0
-rw-r--r--tests/sys/file/flock_helper.c (renamed from tools/regression/file/flock/flock.c)0
-rwxr-xr-xtests/sys/file/flock_test.sh57
-rw-r--r--tests/sys/file/ftruncate_test.c (renamed from tools/regression/file/ftruncate/ftruncate.c)24
-rw-r--r--tests/sys/file/newfileops_on_fork_test.c (renamed from tools/regression/file/newfileops_on_fork/newfileops_on_fork.c)0
-rw-r--r--tests/sys/kern/Makefile2
-rw-r--r--tests/sys/kern/execve/Makefile39
-rw-r--r--tests/sys/kern/execve/bad_interp_len (renamed from tools/regression/execve/tests/badinterplen)0
-rw-r--r--tests/sys/kern/execve/dev_null_script (renamed from tools/regression/execve/tests/devnullscript)0
-rw-r--r--tests/sys/kern/execve/execve_helper.c (renamed from tools/regression/execve/doexec.c)14
-rw-r--r--tests/sys/kern/execve/execve_test.sh115
-rw-r--r--tests/sys/kern/execve/good_aout.c (renamed from tools/regression/execve/tests/goodaout.c)4
-rw-r--r--tests/sys/kern/execve/good_script (renamed from tools/regression/execve/tests/goodscript)2
-rw-r--r--tests/sys/kern/execve/non_exist_shell (renamed from tools/regression/execve/tests/nonexistshell)0
-rw-r--r--tests/sys/kern/execve/script_arg (renamed from tools/regression/execve/tests/scriptarg)0
-rw-r--r--tests/sys/kern/execve/script_arg_nospace (renamed from tools/regression/execve/tests/scriptarg-nospace)0
-rw-r--r--tests/sys/kqueue/Makefile (renamed from tools/regression/kqueue/Makefile)13
-rw-r--r--tests/sys/kqueue/common.h (renamed from tools/regression/kqueue/common.h)0
-rw-r--r--tests/sys/kqueue/config.h (renamed from tools/regression/kqueue/config.h)0
-rwxr-xr-xtests/sys/kqueue/kqueue_test.sh17
-rw-r--r--tests/sys/kqueue/main.c (renamed from tools/regression/kqueue/main.c)0
-rw-r--r--tests/sys/kqueue/proc.c (renamed from tools/regression/kqueue/proc.c)0
-rw-r--r--tests/sys/kqueue/read.c (renamed from tools/regression/kqueue/read.c)0
-rw-r--r--tests/sys/kqueue/signal.c (renamed from tools/regression/kqueue/signal.c)0
-rw-r--r--tests/sys/kqueue/timer.c (renamed from tools/regression/kqueue/timer.c)0
-rw-r--r--tests/sys/kqueue/user.c (renamed from tools/regression/kqueue/user.c)0
-rw-r--r--tests/sys/kqueue/vnode.c (renamed from tools/regression/kqueue/vnode.c)0
-rw-r--r--tests/sys/mqueue/Makefile22
-rw-r--r--tests/sys/mqueue/mqtest1.c (renamed from tools/regression/mqueue/mqtest1/mqtest1.c)7
-rw-r--r--tests/sys/mqueue/mqtest2.c (renamed from tools/regression/mqueue/mqtest2/mqtest2.c)18
-rw-r--r--tests/sys/mqueue/mqtest3.c (renamed from tools/regression/mqueue/mqtest3/mqtest3.c)23
-rw-r--r--tests/sys/mqueue/mqtest4.c (renamed from tools/regression/mqueue/mqtest4/mqtest4.c)25
-rw-r--r--tests/sys/mqueue/mqtest5.c (renamed from tools/regression/mqueue/mqtest5/mqtest5.c)18
-rwxr-xr-xtests/sys/mqueue/mqueue_test.sh81
-rw-r--r--tests/sys/vm/Makefile7
-rw-r--r--tests/sys/vm/mmap_test.c (renamed from tools/regression/mmap/mmap.c)39
-rwxr-xr-xtools/build/check-links.sh13
-rw-r--r--tools/build/mk/OptionalObsoleteFiles.inc4
-rw-r--r--tools/regression/aio/aiop/Makefile2
-rw-r--r--tools/regression/aio/aiop/aiop.c112
-rw-r--r--tools/regression/aio/aiotest/Makefile11
-rw-r--r--tools/regression/aio/kqueue/Makefile10
-rw-r--r--tools/regression/aio/kqueue/lio/Makefile8
-rw-r--r--tools/regression/execve/Makefile70
-rw-r--r--tools/regression/execve/execve.t27
-rw-r--r--tools/regression/fifo/fifo_create/Makefile7
-rw-r--r--tools/regression/fifo/fifo_io/Makefile7
-rw-r--r--tools/regression/fifo/fifo_misc/Makefile7
-rw-r--r--tools/regression/fifo/fifo_open/Makefile7
-rw-r--r--tools/regression/file/closefrom/closefrom.c2
-rw-r--r--tools/regression/file/dup/Makefile7
-rw-r--r--tools/regression/file/dup/dup.t10
-rw-r--r--tools/regression/file/fcntlflags/Makefile7
-rw-r--r--tools/regression/file/fcntlflags/fcntlflags.t10
-rw-r--r--tools/regression/file/flock/Makefile9
-rw-r--r--tools/regression/file/ftruncate/Makefile7
-rw-r--r--tools/regression/file/newfileops_on_fork/Makefile8
-rw-r--r--tools/regression/gaithrstress/gaithrstress.c10
-rw-r--r--tools/regression/lib/libc/stdio/test-open_memstream.c2
-rw-r--r--tools/regression/lib/libc/stdio/test-open_wmemstream.c2
-rw-r--r--tools/regression/mmap/Makefile6
-rw-r--r--tools/regression/mqueue/Makefile5
-rw-r--r--tools/regression/mqueue/mqtest1/Makefile9
-rw-r--r--tools/regression/mqueue/mqtest2/Makefile9
-rw-r--r--tools/regression/mqueue/mqtest3/Makefile9
-rw-r--r--tools/regression/mqueue/mqtest4/Makefile9
-rw-r--r--tools/regression/mqueue/mqtest5/Makefile9
-rw-r--r--tools/regression/netinet/arphold/arphold.c2
-rw-r--r--tools/regression/p1003_1b/Makefile1
-rw-r--r--tools/regression/p1003_1b/fifo.c14
-rw-r--r--tools/regression/p1003_1b/sched.c26
-rw-r--r--tools/regression/p1003_1b/yield.c2
-rw-r--r--tools/tools/tscdrift/tscdrift.c2
-rw-r--r--usr.bin/Makefile2
-rw-r--r--usr.bin/calendar/calendars/calendar.freebsd1
-rw-r--r--usr.bin/calendar/calendars/calendar.holiday2
-rw-r--r--usr.bin/col/col.c16
-rw-r--r--usr.bin/cxxfilt/Makefile17
-rw-r--r--usr.bin/hexdump/display.c2
-rw-r--r--usr.bin/kdump/kdump.c15
-rw-r--r--usr.bin/nfsstat/Makefile2
-rw-r--r--usr.bin/nfsstat/nfsstat.112
-rw-r--r--usr.bin/nfsstat/nfsstat.c548
-rw-r--r--usr.bin/perror/perror.12
-rw-r--r--usr.bin/perror/perror.c2
-rw-r--r--usr.bin/procstat/procstat_rusage.c2
-rw-r--r--usr.bin/protect/protect.12
-rw-r--r--usr.bin/protect/protect.c2
-rw-r--r--usr.bin/rctl/rctl.c47
-rw-r--r--usr.bin/whois/whois.c136
-rw-r--r--usr.sbin/bhyve/acpi.c2
-rw-r--r--usr.sbin/bhyve/ioapic.c2
-rw-r--r--usr.sbin/bhyve/ioapic.h2
-rw-r--r--usr.sbin/bhyve/pci_emul.c87
-rw-r--r--usr.sbin/bhyve/pci_irq.c2
-rw-r--r--usr.sbin/bhyve/pci_irq.h2
-rw-r--r--usr.sbin/bhyve/pm.c2
-rw-r--r--usr.sbin/bluetooth/Makefile13
-rw-r--r--usr.sbin/chown/chgrp.115
-rw-r--r--usr.sbin/chown/chown.811
-rw-r--r--usr.sbin/chown/chown.c106
-rw-r--r--usr.sbin/crunch/crunchide/exec_elf32.c22
-rw-r--r--usr.sbin/ctld/login.c3
-rw-r--r--usr.sbin/etcupdate/etcupdate.82
-rwxr-xr-xusr.sbin/etcupdate/etcupdate.sh2
-rw-r--r--usr.sbin/etcupdate/tests/always_test.sh2
-rw-r--r--usr.sbin/etcupdate/tests/conflicts_test.sh2
-rw-r--r--usr.sbin/etcupdate/tests/fbsdid_test.sh2
-rw-r--r--usr.sbin/etcupdate/tests/ignore_test.sh2
-rw-r--r--usr.sbin/etcupdate/tests/preworld_test.sh2
-rw-r--r--usr.sbin/etcupdate/tests/tests_test.sh2
-rw-r--r--usr.sbin/etcupdate/tests/tzsetup_test.sh2
-rw-r--r--usr.sbin/iovctl/iovctl.conf.56
-rw-r--r--usr.sbin/jail/jail.81
-rw-r--r--usr.sbin/mountd/mountd.88
-rw-r--r--usr.sbin/mountd/mountd.c37
-rw-r--r--usr.sbin/nfsd/nfsd.89
-rw-r--r--usr.sbin/nfsd/nfsd.c171
-rw-r--r--usr.sbin/ntp/doc/ntptime.84
-rw-r--r--usr.sbin/pciconf/err.c2
-rw-r--r--usr.sbin/smbmsg/smbmsg.c23
781 files changed, 50806 insertions, 23564 deletions
diff --git a/.arcconfig b/.arcconfig
index a759f47d119f..fa78c6db09ae 100644
--- a/.arcconfig
+++ b/.arcconfig
@@ -1,4 +1,5 @@
{
"project.name": "S",
- "phabricator.uri" : "https://reviews.freebsd.org/"
+ "phabricator.uri" : "https://reviews.freebsd.org/",
+ "history.immutable" : true
}
diff --git a/Makefile b/Makefile
index c82880ab7f5f..34ffe761b98b 100644
--- a/Makefile
+++ b/Makefile
@@ -373,19 +373,19 @@ kernel-toolchains:
# existing system is.
#
.if make(universe) || make(universe_kernels) || make(tinderbox) || make(targets)
-TARGETS?=amd64 arm i386 mips pc98 powerpc sparc64
# XXX Add arm64 to universe only if we have an external binutils installed.
-# It does not build with the in-tree linnker.
+# It does not build with the in-tree linker.
.if exists(/usr/local/aarch64-freebsd/bin/ld)
-TARGETS+=arm64
-TARGET_ARCHES_arm64?= aarch64
-.else
+UNIVERSE_arm64=arm64
+.elif empty(${TARGETS})
universe: universe_arm64_skip
universe_epilogue: universe_arm64_skip
universe_arm64_skip: universe_prologue
@echo ">> arm64 skipped - install aarch64-binutils port or package to build"
.endif
+TARGETS?=amd64 arm ${UNIVERSE_arm64} i386 mips pc98 powerpc sparc64
TARGET_ARCHES_arm?= arm armeb armv6 armv6hf
+TARGET_ARCHES_arm64?= aarch64
TARGET_ARCHES_mips?= mipsel mips mips64el mips64 mipsn32
TARGET_ARCHES_powerpc?= powerpc powerpc64
TARGET_ARCHES_pc98?= i386
diff --git a/Makefile.inc1 b/Makefile.inc1
index 039c7e2c583f..f21d779228af 100644
--- a/Makefile.inc1
+++ b/Makefile.inc1
@@ -1522,7 +1522,8 @@ cross-tools: .MAKE
NXBENV= MAKEOBJDIRPREFIX=${OBJTREE}/nxb \
INSTALL="sh ${.CURDIR}/tools/install.sh" \
- VERSION="${VERSION}"
+ VERSION="${VERSION}" \
+ PATH=${PATH}:${OBJTREE}/gperf_for_gcc/usr/bin
NXBMAKE= ${NXBENV} ${MAKE} \
TBLGEN=${OBJTREE}/nxb-bin/usr/bin/tblgen \
CLANG_TBLGEN=${OBJTREE}/nxb-bin/usr/bin/clang-tblgen \
@@ -1535,7 +1536,21 @@ NXBMAKE= ${NXBENV} ${MAKE} \
MK_CLANG_EXTRAS=no MK_CLANG_FULL=no \
MK_LLDB=no
+# native-xtools is the current target for qemu-user cross builds of ports
+# via poudriere and the imgact_binmisc kernel module.
+# For non-clang enabled targets that are still using the in tree gcc
+# we must build a gperf binary for one instance of its Makefiles. On
+# clang-enabled systems, the gperf binary is obsolete.
native-xtools: .MAKE
+.if ${MK_GCC_BOOTSTRAP} != "no"
+ mkdir -p ${OBJTREE}/gperf_for_gcc/usr/bin
+ ${_+_}@${ECHODIR} "===> ${_gperf} (obj,depend,all,install)"; \
+ cd ${.CURDIR}/${_gperf} && \
+ ${NXBMAKE} DIRPRFX=${_gperf}/ obj && \
+ ${NXBMAKE} DIRPRFX=${_gperf}/ depend && \
+ ${NXBMAKE} DIRPRFX=${_gperf}/ all && \
+ ${NXBMAKE} DIRPRFX=${_gperf}/ DESTDIR=${OBJTREE}/gperf_for_gcc install
+.endif
mkdir -p ${OBJTREE}/nxb-bin/bin
mkdir -p ${OBJTREE}/nxb-bin/sbin
mkdir -p ${OBJTREE}/nxb-bin/usr
diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc
index 12497e7bef6e..5a61f278809e 100644
--- a/ObsoleteFiles.inc
+++ b/ObsoleteFiles.inc
@@ -38,6 +38,69 @@
# xargs -n1 | sort | uniq -d;
# done
+# 20150501: Remove the nvlist_.*[vf] functions manpages.
+OLD_FILES+=usr/share/man/man3/nvlist_addf_binary.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_addf_bool.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_addf_descriptor.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_addf_null.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_addf_number.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_addf_nvlist.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_addf_string.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_addv_binary.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_addv_bool.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_addv_descriptor.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_addv_null.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_addv_number.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_addv_nvlist.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_addv_string.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_existsf_binary.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_existsf_bool.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_existsf_descriptor.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_existsf_null.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_existsf_number.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_existsf_nvlist.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_existsf_string.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_existsf_type.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_existsv_binary.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_existsv_bool.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_existsv_descriptor.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_existsv_null.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_existsv_number.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_existsv_nvlist.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_existsv_string.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_existsv_type.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_freef_binary.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_freef_bool.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_freef_descriptor.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_freef_null.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_freef_number.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_freef_nvlist.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_freef_string.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_freef_type.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_freev_binary.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_freev_bool.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_freev_descriptor.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_freev_null.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_freev_number.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_freev_nvlist.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_freev_string.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_freev_type.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_getf_binary.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_getf_bool.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_getf_descriptor.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_getf_number.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_getf_nvlist.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_getf_string.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_getv_binary.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_getv_bool.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_getv_descriptor.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_getv_number.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_getv_nvlist.3.gz
+OLD_FILES+=usr/share/man/man3/nvlist_getv_string.3.gz
+# 20150429:
+OLD_FILES+=usr/share/docs/papers/hwpmc.ascii.gz
+# 20150427: test/sys/kern/mmap_test moved to test/sys/vm/mmap_test
+OLD_FILES+=usr/tests/sys/kern/mmap_test
# 20150418
OLD_FILES+=sbin/mount_oldnfs
OLD_FILES+=usr/share/man/man8/mount_oldnfs.8.gz
@@ -56,18 +119,6 @@ OLD_FILES+=usr/include/altq/altq_rmclass.h
OLD_FILES+=usr/include/altq/altq_cbq.h
OLD_FILES+=usr/include/altq/altq_rio.h
OLD_DIRS+=usr/include/altq
-# 20150410
-OLD_FILES+=usr/share/doc/usd/10.exref/paper.ascii.gz
-OLD_FILES+=usr/share/doc/usd/10.exref/summary.ascii.gz
-OLD_DIRS+=usr/share/doc/usd/10.exref
-OLD_FILES+=usr/share/doc/usd/11.edit/paper.ascii.gz
-OLD_DIRS+=usr/share/doc/usd/11.edit
-OLD_FILES+=usr/share/doc/usd/12.vi/paper.ascii.gz
-OLD_FILES+=usr/share/doc/usd/12.vi/summary.ascii.gz
-OLD_FILES+=usr/share/doc/usd/12.vi/viapwh.ascii.gz
-OLD_DIRS+=usr/share/doc/usd/12.vi
-OLD_FILES+=usr/share/doc/usd/13.viref/paper.ascii.gz
-OLD_DIRS+=usr/share/doc/usd/13.viref
# 20150329
.if ${TARGET_ARCH} == "arm"
OLD_FILES+=usr/include/bootconfig.h
@@ -353,6 +404,10 @@ OLD_FILES+=usr/lib/debug/usr/lib32/i18n
OLD_FILES+=usr/lib/debug/usr/lib32/private
# 20141015: OpenSSL 1.0.1j import
OLD_FILES+=usr/share/openssl/man/man3/CMS_sign_add1_signer.3.gz
+.if ${MK_GCC} == "no"
+# 20141009: gperf disabled by default
+OLD_FILES+=usr/bin/gperf
+.endif
# 20140922: sleepq_calc_signal_retval.9 and sleepq_catch_signals.9 removed
OLD_FILES+=usr/share/man/man9/sleepq_calc_signal_retval.9.gz
OLD_FILES+=usr/share/man/man9/sleepq_catch_signals.9.gz
diff --git a/UPDATING b/UPDATING
index 886020b221ce..b7bf59b83458 100644
--- a/UPDATING
+++ b/UPDATING
@@ -31,6 +31,10 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW:
disable the most expensive debugging functionality run
"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
+20150423:
+ chmod, chflags, chown and chgrp now affect symlinks in -R mode as
+ defined in symlink(7); previously symlinks were silently ignored.
+
20150415:
The const qualifier has been removed from iconv(3) to comply with
POSIX. The ports tree is aware of this from r384038 onwards.
diff --git a/bin/chflags/chflags.1 b/bin/chflags/chflags.1
index 47d5b181b45d..755cbced269e 100644
--- a/bin/chflags/chflags.1
+++ b/bin/chflags/chflags.1
@@ -32,7 +32,7 @@
.\" @(#)chflags.1 8.4 (Berkeley) 5/2/95
.\" $FreeBSD$
.\"
-.Dd April 8, 2013
+.Dd April 20, 2015
.Dt CHFLAGS 1
.Os
.Sh NAME
@@ -66,8 +66,9 @@ nor modify the exit status to reflect such failures.
.It Fl H
If the
.Fl R
-option is specified, symbolic links on the command line are followed.
-(Symbolic links encountered in the tree traversal are not followed.)
+option is specified, symbolic links on the command line are followed
+and hence unaffected by the command.
+(Symbolic links encountered during traversal are not followed.)
.It Fl h
If the
.Ar file
@@ -83,8 +84,12 @@ If the
option is specified, no symbolic links are followed.
This is the default.
.It Fl R
-Change the file flags for the file hierarchies rooted
-in the files instead of just the files themselves.
+Change the file flags of the file hierarchies rooted in the files,
+instead of just the files themselves.
+Beware of unintentionally matching the
+.Dq Pa ".."
+hard link to the parent directory when using wildcards like
+.Dq Li ".*" .
.It Fl v
Cause
.Nm
diff --git a/bin/chflags/chflags.c b/bin/chflags/chflags.c
index e94c34df6eb1..2029ac5d7703 100644
--- a/bin/chflags/chflags.c
+++ b/bin/chflags/chflags.c
@@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include <err.h>
#include <errno.h>
+#include <fcntl.h>
#include <fts.h>
#include <stdio.h>
#include <stdlib.h>
@@ -65,7 +66,6 @@ main(int argc, char *argv[])
int Hflag, Lflag, Rflag, fflag, hflag, vflag;
int ch, fts_options, oct, rval;
char *flags, *ep;
- int (*change_flags)(const char *, unsigned long);
Hflag = Lflag = Rflag = fflag = hflag = vflag = 0;
while ((ch = getopt(argc, argv, "HLPRfhv")) != -1)
@@ -104,20 +104,23 @@ main(int argc, char *argv[])
usage();
if (Rflag) {
- fts_options = FTS_PHYSICAL;
if (hflag)
- errx(1, "the -R and -h options "
- "may not be specified together");
- if (Hflag)
- fts_options |= FTS_COMFOLLOW;
+ errx(1, "the -R and -h options may not be "
+ "specified together.");
if (Lflag) {
- fts_options &= ~FTS_PHYSICAL;
- fts_options |= FTS_LOGICAL;
- }
- } else
- fts_options = hflag ? FTS_PHYSICAL : FTS_LOGICAL;
+ fts_options = FTS_LOGICAL;
+ } else {
+ fts_options = FTS_PHYSICAL;
- change_flags = hflag ? lchflags : chflags;
+ if (Hflag) {
+ fts_options |= FTS_COMFOLLOW;
+ }
+ }
+ } else if (hflag) {
+ fts_options = FTS_PHYSICAL;
+ } else {
+ fts_options = FTS_LOGICAL;
+ }
flags = *argv;
if (*flags >= '0' && *flags <= '7') {
@@ -142,12 +145,21 @@ main(int argc, char *argv[])
err(1, NULL);
for (rval = 0; (p = fts_read(ftsp)) != NULL;) {
+ int atflag;
+
+ if ((fts_options & FTS_LOGICAL) ||
+ ((fts_options & FTS_COMFOLLOW) &&
+ p->fts_level == FTS_ROOTLEVEL))
+ atflag = 0;
+ else
+ atflag = AT_SYMLINK_NOFOLLOW;
+
switch (p->fts_info) {
case FTS_D: /* Change it at FTS_DP if we're recursive. */
if (!Rflag)
fts_set(ftsp, p, FTS_SKIP);
continue;
- case FTS_DNR: /* Warn, chflag, continue. */
+ case FTS_DNR: /* Warn, chflags. */
warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
rval = 1;
break;
@@ -156,16 +168,6 @@ main(int argc, char *argv[])
warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
rval = 1;
continue;
- case FTS_SL: /* Ignore. */
- case FTS_SLNONE:
- /*
- * The only symlinks that end up here are ones that
- * don't point to anything and ones that we found
- * doing a physical walk.
- */
- if (!hflag)
- continue;
- /* FALLTHROUGH */
default:
break;
}
@@ -175,7 +177,8 @@ main(int argc, char *argv[])
newflags = (p->fts_statp->st_flags | set) & clear;
if (newflags == p->fts_statp->st_flags)
continue;
- if ((*change_flags)(p->fts_accpath, newflags) && !fflag) {
+ if (chflagsat(AT_FDCWD, p->fts_accpath, newflags,
+ atflag) == -1 && !fflag) {
warn("%s", p->fts_path);
rval = 1;
} else if (vflag) {
diff --git a/bin/chmod/chmod.1 b/bin/chmod/chmod.1
index 34a1ff018d9f..7efaabcdefcf 100644
--- a/bin/chmod/chmod.1
+++ b/bin/chmod/chmod.1
@@ -32,7 +32,7 @@
.\" @(#)chmod.1 8.4 (Berkeley) 3/31/94
.\" $FreeBSD$
.\"
-.Dd January 26, 2009
+.Dd April 20, 2015
.Dt CHMOD 1
.Os
.Sh NAME
@@ -63,9 +63,9 @@ nor modify the exit status to reflect such failures.
.It Fl H
If the
.Fl R
-option is specified, symbolic links on the command line are followed.
-(Symbolic links encountered in the tree traversal are not followed by
-default.)
+option is specified, symbolic links on the command line are followed
+and hence unaffected by the command.
+(Symbolic links encountered during tree traversal are not followed.)
.It Fl h
If the file is a symbolic link, change the mode of the link itself
rather than the file that the link points to.
@@ -79,8 +79,12 @@ If the
option is specified, no symbolic links are followed.
This is the default.
.It Fl R
-Change the modes of the file hierarchies rooted in the files
+Change the modes of the file hierarchies rooted in the files,
instead of just the files themselves.
+Beware of unintentionally matching the
+.Dq Pa ".."
+hard link to the parent directory when using wildcards like
+.Dq Li ".*" .
.It Fl v
Cause
.Nm
diff --git a/bin/chmod/chmod.c b/bin/chmod/chmod.c
index dc51faa39b01..9b801576efa7 100644
--- a/bin/chmod/chmod.c
+++ b/bin/chmod/chmod.c
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
#include <err.h>
#include <errno.h>
+#include <fcntl.h>
#include <fts.h>
#include <limits.h>
#include <stdio.h>
@@ -62,7 +63,7 @@ main(int argc, char *argv[])
FTS *ftsp;
FTSENT *p;
mode_t *set;
- int Hflag, Lflag, Rflag, ch, error, fflag, fts_options, hflag, rval;
+ int Hflag, Lflag, Rflag, ch, fflag, fts_options, hflag, rval;
int vflag;
char *mode;
mode_t newmode;
@@ -126,18 +127,23 @@ done: argv += optind;
usage();
if (Rflag) {
- fts_options = FTS_PHYSICAL;
if (hflag)
- errx(1,
- "the -R and -h options may not be specified together.");
- if (Hflag)
- fts_options |= FTS_COMFOLLOW;
+ errx(1, "the -R and -h options may not be "
+ "specified together.");
if (Lflag) {
- fts_options &= ~FTS_PHYSICAL;
- fts_options |= FTS_LOGICAL;
+ fts_options = FTS_LOGICAL;
+ } else {
+ fts_options = FTS_PHYSICAL;
+
+ if (Hflag) {
+ fts_options |= FTS_COMFOLLOW;
+ }
}
- } else
- fts_options = hflag ? FTS_PHYSICAL : FTS_LOGICAL;
+ } else if (hflag) {
+ fts_options = FTS_PHYSICAL;
+ } else {
+ fts_options = FTS_LOGICAL;
+ }
mode = *argv;
if ((set = setmode(mode)) == NULL)
@@ -146,12 +152,21 @@ done: argv += optind;
if ((ftsp = fts_open(++argv, fts_options, 0)) == NULL)
err(1, "fts_open");
for (rval = 0; (p = fts_read(ftsp)) != NULL;) {
+ int atflag;
+
+ if ((fts_options & FTS_LOGICAL) ||
+ ((fts_options & FTS_COMFOLLOW) &&
+ p->fts_level == FTS_ROOTLEVEL))
+ atflag = 0;
+ else
+ atflag = AT_SYMLINK_NOFOLLOW;
+
switch (p->fts_info) {
case FTS_D: /* Change it at FTS_DP. */
if (!Rflag)
fts_set(ftsp, p, FTS_SKIP);
continue;
- case FTS_DNR: /* Warn, chmod, continue. */
+ case FTS_DNR: /* Warn, chmod. */
warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
rval = 1;
break;
@@ -160,16 +175,6 @@ done: argv += optind;
warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
rval = 1;
continue;
- case FTS_SL: /* Ignore. */
- case FTS_SLNONE:
- /*
- * The only symlinks that end up here are ones that
- * don't point to anything and ones that we found
- * doing a physical walk.
- */
- if (!hflag)
- continue;
- /* FALLTHROUGH */
default:
break;
}
@@ -182,32 +187,25 @@ done: argv += optind;
if (may_have_nfs4acl(p, hflag) == 0 &&
(newmode & ALLPERMS) == (p->fts_statp->st_mode & ALLPERMS))
continue;
- if (hflag)
- error = lchmod(p->fts_accpath, newmode);
- else
- error = chmod(p->fts_accpath, newmode);
- if (error) {
- if (!fflag) {
- warn("%s", p->fts_path);
- rval = 1;
- }
- } else {
- if (vflag) {
- (void)printf("%s", p->fts_path);
-
- if (vflag > 1) {
- char m1[12], m2[12];
-
- strmode(p->fts_statp->st_mode, m1);
- strmode((p->fts_statp->st_mode &
- S_IFMT) | newmode, m2);
- (void)printf(": 0%o [%s] -> 0%o [%s]",
- p->fts_statp->st_mode, m1,
- (p->fts_statp->st_mode & S_IFMT) |
- newmode, m2);
- }
- (void)printf("\n");
+ if (fchmodat(AT_FDCWD, p->fts_accpath, newmode, atflag) == -1
+ && !fflag) {
+ warn("%s", p->fts_path);
+ rval = 1;
+ } else if (vflag) {
+ (void)printf("%s", p->fts_path);
+
+ if (vflag > 1) {
+ char m1[12], m2[12];
+
+ strmode(p->fts_statp->st_mode, m1);
+ strmode((p->fts_statp->st_mode &
+ S_IFMT) | newmode, m2);
+ (void)printf(": 0%o [%s] -> 0%o [%s]",
+ p->fts_statp->st_mode, m1,
+ (p->fts_statp->st_mode & S_IFMT) |
+ newmode, m2);
}
+ (void)printf("\n");
}
}
if (errno)
diff --git a/bin/ed/ed.1 b/bin/ed/ed.1
index 8342645997c9..335dbd80ac7d 100644
--- a/bin/ed/ed.1
+++ b/bin/ed/ed.1
@@ -738,7 +738,7 @@ It is an error if no substitutions are performed on any of the addressed
lines.
The current address is set the last line affected.
.Pp
-.Ar Re
+.Ar \&Re
and
.Ar replacement
may be delimited by any character other than space and newline
diff --git a/bin/expr/expr.1 b/bin/expr/expr.1
index 34be0b8fa9de..d02105561fde 100644
--- a/bin/expr/expr.1
+++ b/bin/expr/expr.1
@@ -90,17 +90,17 @@ Return the evaluation of
.Ar expr1
if neither expression evaluates to an empty string or zero;
otherwise, returns zero.
-.It Ar expr1 Li "{=, >, >=, <, <=, !=}" Ar expr2
+.It Ar expr1 Bro =, >, >=, <, <=, != Brc Ar expr2
Return the results of integer comparison if both arguments are integers;
otherwise, returns the results of string comparison using the locale-specific
collation sequence.
The result of each comparison is 1 if the specified relation is true,
or 0 if the relation is false.
-.It Ar expr1 Li "{+, -}" Ar expr2
+.It Ar expr1 Bro +, - Brc Ar expr2
Return the results of addition or subtraction of integer-valued arguments.
-.It Ar expr1 Li "{*, /, %}" Ar expr2
+.It Ar expr1 Bro *, /, % Brc Ar expr2
Return the results of multiplication, integer division, or remainder of integer-valued arguments.
-.It Ar expr1 Li : Ar expr2
+.It Ar expr1 Li \&: Ar expr2
The
.Dq Li \&:
operator matches
diff --git a/bin/sh/jobs.c b/bin/sh/jobs.c
index 753cf7bd931f..b531231e4a59 100644
--- a/bin/sh/jobs.c
+++ b/bin/sh/jobs.c
@@ -1057,7 +1057,7 @@ waitforjob(struct job *jp, int *origstatus)
CLEAR_PENDING_INT;
}
#if JOBS
- else if (rootshell && iflag && propagate_int &&
+ else if (rootshell && propagate_int &&
WIFSIGNALED(status) && WTERMSIG(status) == SIGINT)
kill(getpid(), SIGINT);
#endif
diff --git a/cddl/contrib/opensolaris/lib/libnvpair/libnvpair.c b/cddl/contrib/opensolaris/lib/libnvpair/libnvpair.c
index 7a265bdc39d4..7ad5141a1a69 100644
--- a/cddl/contrib/opensolaris/lib/libnvpair/libnvpair.c
+++ b/cddl/contrib/opensolaris/lib/libnvpair/libnvpair.c
@@ -793,6 +793,7 @@ dump_nvlist(nvlist_t *list, int indent)
{
nvpair_t *elem = NULL;
boolean_t bool_value;
+ boolean_t *bool_array_value;
nvlist_t *nvlist_value;
nvlist_t **nvlist_array_value;
uint_t i, count;
@@ -853,6 +854,16 @@ dump_nvlist(nvlist_t *list, int indent)
NVP(elem, string, char *, char *, "'%s'");
break;
+ case DATA_TYPE_BOOLEAN_ARRAY:
+ (void) nvpair_value_boolean_array(elem,
+ &bool_array_value, &count);
+ for (i = 0; i < count; i++) {
+ (void) printf("%*s%s[%d]: %s\n", indent, "",
+ nvpair_name(elem), i,
+ bool_array_value[i] ? "true" : "false");
+ }
+ break;
+
case DATA_TYPE_BYTE_ARRAY:
NVPA(elem, byte_array, uchar_t, int, "%u");
break;
diff --git a/cddl/lib/libdtrace/tcp.d b/cddl/lib/libdtrace/tcp.d
index 4b826f175572..e642020d2d6b 100644
--- a/cddl/lib/libdtrace/tcp.d
+++ b/cddl/lib/libdtrace/tcp.d
@@ -241,3 +241,78 @@ translator tcpinfoh_t < struct tcphdr *p > {
translator tcplsinfo_t < int s > {
tcps_state = s;
};
+
+/*
+ * Convert a SIFTR direction value to a string
+ */
+#pragma D binding "1.12.1" SIFTR_IN
+inline int SIFTR_IN = 1;
+#pragma D binding "1.12.1" SIFTR_OUT
+inline int SIFTR_OUT = 2;
+
+/* SIFTR direction strings. */
+#pragma D binding "1.12.1" siftr_dir_string
+inline string siftr_dir_string[uint8_t direction] =
+ direction == SIFTR_IN ? "in" :
+ direction == SIFTR_OUT ? "out" :
+ "unknown" ;
+
+typedef struct siftrinfo {
+ struct timeval tval;
+ uint8_t direction;
+ uint8_t ipver;
+ uint32_t hash;
+ uint16_t tcp_localport;
+ uint16_t tcp_foreignport;
+ uint64_t snd_cwnd;
+ u_long snd_wnd;
+ u_long rcv_wnd;
+ u_long snd_bwnd;
+ u_long snd_ssthresh;
+ int conn_state;
+ u_int max_seg_size;
+ int smoothed_rtt;
+ u_char sack_enabled;
+ u_char snd_scale;
+ u_char rcv_scale;
+ u_int flags;
+ int rxt_length;
+ u_int snd_buf_hiwater;
+ u_int snd_buf_cc;
+ u_int rcv_buf_hiwater;
+ u_int rcv_buf_cc;
+ u_int sent_inflight_bytes;
+ int t_segqlen;
+ u_int flowid;
+ u_int flowtype;
+} siftrinfo_t;
+
+#pragma D binding "1.12.1" translator
+translator siftrinfo_t < struct pkt_node *p > {
+ direction = p == NULL ? 0 : p->direction;
+ ipver = p == NULL ? 0 : p->ipver;
+ hash = p == NULL ? 0 : p->hash;
+ tcp_localport = p == NULL ? 0 : ntohs(p->tcp_localport);
+ tcp_foreignport = p == NULL ? 0 : ntohs(p->tcp_foreignport);
+ snd_cwnd = p == NULL ? 0 : p->snd_cwnd;
+ snd_wnd = p == NULL ? 0 : p->snd_wnd;
+ rcv_wnd = p == NULL ? 0 : p->rcv_wnd;
+ snd_bwnd = p == NULL ? 0 : p->snd_bwnd;
+ snd_ssthresh = p == NULL ? 0 : p->snd_ssthresh;
+ conn_state = p == NULL ? 0 : p->conn_state;
+ max_seg_size = p == NULL ? 0 : p->max_seg_size;
+ smoothed_rtt = p == NULL ? 0 : p->smoothed_rtt;
+ sack_enabled = p == NULL ? 0 : p->sack_enabled;
+ snd_scale = p == NULL ? 0 : p->snd_scale;
+ rcv_scale = p == NULL ? 0 : p->rcv_scale;
+ flags = p == NULL ? 0 : p->flags;
+ rxt_length = p == NULL ? 0 : p->rxt_length;
+ snd_buf_hiwater = p == NULL ? 0 : p->snd_buf_hiwater;
+ snd_buf_cc = p == NULL ? 0 : p->snd_buf_cc;
+ rcv_buf_hiwater = p == NULL ? 0 : p->rcv_buf_hiwater;
+ rcv_buf_cc = p == NULL ? 0 : p->rcv_buf_cc;
+ sent_inflight_bytes = p == NULL ? 0 : p->sent_inflight_bytes;
+ t_segqlen = p == NULL ? 0 : p->t_segqlen;
+ flowid = p == NULL ? 0 : p->flowid;
+ flowtype = p == NULL ? 0 : p->flowtype;
+};
diff --git a/contrib/gcclibs/libgomp/ChangeLog b/contrib/gcclibs/libgomp/ChangeLog
index 56191ecee0cf..22378929a87c 100644
--- a/contrib/gcclibs/libgomp/ChangeLog
+++ b/contrib/gcclibs/libgomp/ChangeLog
@@ -1,6 +1,223 @@
-2007-07-19 Release Manager
+2010-05-22 Release Manager
- * GCC 4.2.1 released.
+ * GCC 4.3.5 released.
+
+2010-05-06 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ PR other/43620
+ * configure.ac (AM_INIT_AUTOMAKE): Add no-dist.
+ * configure: Regenerate.
+ * aclocal.m4: Regenerate.
+ * config.h.in: Regenerate.
+ * Makefile.in: Regenerate.
+ * testsuite/Makefile.in: Regenerate.
+
+2009-08-19 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/41102
+ omp_lib.h.in: Fix -std=f95 errors.
+
+2009-08-14 Uros Bizjak <ubizjak@gmail.com>
+
+ Backport from mainline:
+ 2008-12-26 Uros Bizjak <ubizjak@gmail.com>
+
+ * testsuite/libgomp.c/atomic-6.c: Add -mieee for alpha*-*-* targets.
+
+2009-08-04 Release Manager
+
+ * GCC 4.3.4 released.
+
+2009-01-24 Release Manager
+
+ * GCC 4.3.3 released.
+
+2008-12-05 Janis Johnson <janis187@us.ibm.com>
+
+ Backport from mainline:
+ 2008-05-15 Janis Johnson <janis187@us.ibm.com>
+
+ * testsuite/lib/libgomp.exp: Load new torture support.
+
+2008-12-02 Janis Johnson <janis187@us.ibm.com>
+
+ Backport from mainline:
+ 2008-11-26 Janis Johnson <janis187@us.ibm.com>
+
+ PR testsuite/28870
+ * testsuite/lib/libgomp.exp: Include new timeout library files.
+ (libgomp_target_compile): Set timeout value from new proc.
+
+2008-08-27 Release Manager
+
+ * GCC 4.3.2 released.
+
+2008-06-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/36506
+ * testsuite/libgomp.c/reduction-5.c: New test.
+
+2008-06-06 Release Manager
+
+ * GCC 4.3.1 released.
+
+2008-05-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/36308
+ * testsuite/libgomp.c++/ctor-11.C: New test.
+ * testsuite/libgomp.c++/ctor-12.C: New test.
+
+2008-05-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/36106
+ * testsuite/libgomp.c/atomic-5.c: New test.
+ * testsuite/libgomp.c/atomic-6.c: New test.
+ * testsuite/libgomp.c/autopar-1.c: New test.
+
+2008-03-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/35611
+ * testsuite/libgomp.c/atomic-4.c: New test.
+
+ PR libgomp/35625
+ * iter.c (gomp_iter_guided_next_locked): If q > n, set end to ws->end.
+ (gomp_iter_guided_next): Likewise.
+ * testsuite/libgomp.c/pr35625.c: New test.
+
+2008-03-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/35185
+ * testsuite/libgomp.c++/pr35185.C: New test.
+
+2008-03-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/35549
+ * testsuite/libgomp.c/pr35549.c: New test.
+
+2008-03-06 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.c/atomic-3.c: New test.
+
+2008-03-05 Release Manager
+
+ * GCC 4.3.0 released.
+
+2008-02-15 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/35196
+ * testsuite/libgomp.c/pr35196.c: New test.
+
+ PR middle-end/35130
+ * testsuite/libgomp.fortran/pr35130.f90: New test.
+ * testsuite/libgomp.c/pr35130.c: New test.
+
+2008-01-25 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/33880
+ * testsuite/libgomp.c/pr33880.c: New test.
+ * testsuite/libgomp.fortran/pr33880.f90: New test.
+
+2008-01-24 David Edelsohn <edelsohn@gnu.org>
+
+ * configure: Regenerate.
+
+2008-01-08 Jakub Jelinek <jakub@redhat.com>
+
+ * configure.ac: Move futex checking into ../config/futex.m4.
+ * configure: Rebuilt.
+ * aclocal.m4: Rebuilt.
+ * Makefile.in: Rebuilt.
+
+ * configure.tgt: Rename have_tls to gcc_cv_have_tls to match
+ 2007-10-15 ../config/tls.m4 change.
+
+2007-12-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/34513
+ * testsuite/libgomp.c/pr34513.c: New test.
+ * testsuite/libgomp.c++/pr34513.C: New test.
+
+2007-12-17 Jack Howarth <howarth@bromo.med.uc.edu>
+
+ PR target/32765
+ * testsuite/libgomp.fortran/crayptr2.f90: Move dg-options for darwin.
+
+2007-12-04 Jakub Jelinek <jakub@redhat.com>
+
+ * omp.h.in (__GOMP_NOTHROW): Define. Use it on omp_* prototypes.
+
+2007-12-03 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.c/private-1.c: New test.
+
+2007-11-29 Andris Pavenis <andris.pavenis@iki.fi>
+ Paolo Bonzini <bonzini@gnu.org>
+
+ * Makefile.am: Use space as vpath separator. Use 'vpath %'
+ instead of 'VPATH ='.
+ * Makefile.in: Regenerate.
+
+2007-11-23 Matthias Klose <doko@ubuntu.com>
+
+ * configure.ac: Adjust makeinfo version check.
+ * configure: Regenerate.
+
+2007-11-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR fortran/34020
+ * testsuite/libgomp.fortran/pr34020.f90: New test.
+
+2007-11-06 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/33894
+ * testsuite/libgomp.c++/atomic-1.C: New test.
+
+2007-10-25 Jakub Jelinek <jakub@redhat.com>
+
+ PR libgomp/33275
+ * testsuite/libgomp.fortran/omp_parse3.f90 (test_threadprivate):
+ Make x and y integers rather than (implicit) reals. Add private (j)
+ clause to the last omp parallel.
+
+2007-10-15 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * configure: Regenerate following changes to ../config/tls.m4.
+
+2007-09-28 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.fortran/stack.f90: New test.
+
+2007-09-10 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/mingw32/proc.c: New file.
+
+2007-09-05 Uros Bizjak <ubizjak@gmail.com>
+
+ * testsuite/libgomp.c/atomic-1.c: Include cpuid.h for i386 targets.
+ (main): Use __get_cpuid to get i386 target fetaures.
+ * testsuite/libgomp.c/atomic-2.c: Include cpuid.h for x86_64 targets.
+ (main): Use __get_cpuid to get x86_64 target fetaures.
+
+2007-08-15 Jack Howarth <howarth@bromo.med.uc.edu>
+
+ PR target/32765
+ * testsuite/libgomp.fortran/pr32550.f90: Use -static-libgcc on Darwin.
+ * testsuite/libgomp.fortran/crayptr2.f90: Likwise.
+
+2007-07-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR fortran/32550
+ * testsuite/libgomp.fortran/pr32550.f90: New test.
+ * testsuite/libgomp.fortran/crayptr2.f90: New test.
+
+2007-07-05 H.J. Lu <hongjiu.lu@intel.com>
+
+ * aclocal.m4: Regenerated.
+
+2007-07-05 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/32359
+ * testsuite/libgomp.fortran/pr32359.f90: New.
2007-07-02 Jakub Jelinek <jakub@redhat.com>
@@ -21,9 +238,117 @@
* testsuite/libgomp.c/pr32362-2.c: New test.
* testsuite/libgomp.c/pr32362-3.c: New test.
-2007-05-13 Release Manager
+2007-06-07 Jakub Jelinek <jakub@redhat.com>
+
+ * team.c (gomp_team_start): Fix setting up thread_attr
+ stack size.
+
+2007-06-02 Paolo Bonzini <bonzini@gnu.org>
+
+ * configure: Regenerate.
+
+2007-05-23 Steve Ellcey <sje@cup.hp.com>
+
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+ * aclocal.m4: Regenerate.
+ * testsuite/Makefile.in: Regenerate.
+
+2007-05-04 Jakub Jelinek <jakub@redhat.com>
+
+ * config/linux/proc.c: New file.
+
+ PR libgomp/28482
+ * configure.tgt: Don't link with -Wl,-z,nodlopen even on Linux.
+
+2007-04-19 Daniel Franke <franke.daniel@gmail.com>
- * GCC 4.2.0 released.
+ * libgomp.texi (GOMP_CPU_AFFINITY): Updated.
+
+2007-04-16 Matthias Klose <doko@debian.org>
+
+ * configure.tgt (i[456]86-*-linux*): Only add ia32 specific
+ flags if not building with -m64.
+ * testsuite/lib/libgomp-dg.exp (libgomp_init): Don't add -march
+ flag for i?86-*-* targets, if current target matches -m64.
+
+2007-04-14 Steve Ellcey <sje@cup.hp.com>
+
+ * Makefile.am: Add -I .. to ACLOCAL_AMFLAGS.
+ * Makefile.in: Regenerate.
+
+2007-04-07 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR testsuite/31369
+ * testsuite/libgomp.c++/c++.exp: Don't use concat when setting
+ ld_library_path.
+ * testsuite/libgomp.fortran/fortran.exp: Likewise.
+
+2007-04-04 Jakub Jelinek <jakub@redhat.com>
+
+ * libgomp.h (gomp_cpu_affinity, gomp_cpu_affinity_len): New extern
+ decls.
+ (gomp_init_affinity, gomp_init_thread_affinity): New prototypes.
+ * env.c (gomp_cpu_affinity, gomp_cpu_affinity_len): New variables.
+ (parse_affinity): New function.
+ (initialize_env): Call it and gomp_init_affinity.
+ * team.c (gomp_team_start): If gomp_cpu_affinity != NULL,
+ create new pthread_attr_t and call gomp_init_thread_affinity
+ on it for each thread before passing the attribute to pthread_create.
+ * config/linux/affinity.c: New file.
+ * config/posix/affinity.c: New file.
+ * configure.ac (HAVE_PTHREAD_AFFINITY_NP): New test.
+ * configure: Rebuilt.
+ * config.h.in: Rebuilt.
+ * Makefile.am (libgomp_la_SOURCES): Add affinity.c.
+ * Makefile.in: Rebuilt.
+
+2007-03-23 Andreas Tobler <a.tobler@schweiz.org>
+
+ * testsuite/lib/libgomp.exp (libgomp_init): Add -shared-libgcc for
+ *-*-darwin*.
+ * testsuite/libgomp.c++/c++.exp: Look for shared libstdc++ library
+ and use it if found.
+
+2007-03-18 Uros Bizjak <ubizjak@gmail.com>
+
+ * testsuite/config/default.exp: New file.
+ * testsuite/lib/libgomp.exp: New file.
+ * testsuite/lib/libgomp.dg (load_gcc_lib, libgomp_init,
+ libgomp_target_compile, libgomp_option_help, libgomp_option_proc,
+ load_lib *, load_gcc_lib *): Move to libgomp.exp.
+ (libgomp_load): Remove.
+ * testsuite/lib/libgomp.exp (libgomp_init): Compute
+ always_ld_library_path, not ld_library_path. Set additional_flags
+ to -march=i486 for ilp32 x86_64-*-* and i386-*-* targets.
+ (target_compile): Do not call libgomp_init. Append lang_library_path
+ and lang_link_flags to options.
+ * testsuite/libgomp.c/c.exp: Set DEFAULT_FLAGS to -O2. Set
+ ld_library_path from always_ld_library_path. Set LD_LIBRARY_PATH
+ here.
+ * testsuite/libgomp.c++/c++.exp: Set ld_library_path from
+ always_ld_library_path. Set LD_LIBRARY_PATH here.
+ * testsuite/libgomp.fortran/fortran.exp: Ditto.
+ * testsuite/libgomp.c/atomic-1.c: Set dg-options to
+ "-O2 -march=pentium" for ilp32 x86 targets. Simplify check for
+ CX8 flag.
+ * testsuite/libgomp.c/atomic-2.c: Set dg-options to "-O2 -mcx16" for
+ lp64 x86 targets. Do not check for SSE3 bit. Do not define bit_SSE3.
+ * testsuite/libgomp.c/pr29947-1.c: Remove default dg-options.
+ * testsuite/libgomp.c/pr29947-1.c: Ditto.
+ * testsuite/libgomp.c/atomic-10.c: Ditto.
+
+2007-03-21 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.fortran/appendix-a/a.22.8.f90: Add
+ dg-final cleanup-modules line.
+ * testsuite/libgomp.fortran/appendix-a/a.40.1.f90: Likewise.
+ * testsuite/libgomp.fortran/appendix-a/a.31.5.f90: Likewise.
+ * testsuite/libgomp.fortran/appendix-a/a.31.4.f90: Likewise.
+ * testsuite/libgomp.fortran/threadprivate2.f90: Likewise.
+ * testsuite/libgomp.fortran/reduction5.f90: Likewise.
+ * testsuite/libgomp.fortran/threadprivate3.f90: Likewise.
+ * testsuite/libgomp.fortran/threadprivate1.f90: Likewise.
2007-03-18 Andreas Schwab <schwab@suse.de>
@@ -31,15 +356,32 @@
extraction.
* configure: Regenerate.
+2007-03-01 Brooks Moses <brooks.moses@codesourcery.com>
+
+ * Makefile.am: Add install-pdf target as copied from
+ automake v1.10 rules.
+ * Makefile.in: Regenerate
+
2007-02-07 Jakub Jelinek <jakub@redhat.com>
+ PR libgomp/28486
+ * configure: Regenerate.
+
PR c++/30703
* testsuite/libgomp.c++/pr30703.C: New test.
-2007-02-07 Daniel Franke <franke.daniel@gmail.com>
+2007-02-02 Jakub Jelinek <jakub@redhat.com>
- Backport from mainline:
- 2007-01-31 Daniel Franke <franke.daniel@gmail.com>
+ Revert:
+ 2006-07-05 Eric Christopher <echristo@apple.com>
+ * configure.ac: Depend addition of -pthread on host OS.
+ * configure: Regenerate.
+
+2007-01-31 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * libgomp.texi: Fix spacing after abbreviations.
+
+2007-01-31 Daniel Franke <franke.daniel@gmail.com>
PR libgomp/30546
* configure.ac: Add check for makeinfo
@@ -50,74 +392,47 @@
* Makefile.in: Regenerated.
* testsuite/Makefile.in: Regenerated.
-2007-02-07 Daniel Franke <franke.daniel@gmail.com>
-
- Backport from mainline:
- 2007-01-31 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
-
- * libgomp.texi: Fix spacing after abbreviations.
-
- Backport from mainline:
- 2007-01-29 Daniel Franke <franke.daniel@gmail.com>
+2007-01-29 Daniel Franke <franke.daniel@gmail.com>
PR libgomp/30540
* libgomp.texi: More about implementation-dependent settings.
-2007-02-06 Roger Sayle <roger@eyesopen.com>
+2007-01-26 Tobias Burnus <burnus@net-b.de>
- PR libgomp/28296
- Backport from mainline.
- Revert:
- 2006-07-05 Eric Christopher <echristo@apple.com>
- * configure.ac: Depend addition of -pthread on host OS.
- * configure: Regenerate.
+ * testsuite/libgomp.fortran/fortran.exp: Support .f03 extension.
-2007-01-30 Tobias Burnus <burnus@net-b.de>
+2007-01-24 Jakub Jelinek <jakub@redhat.com>
- Backport from mainline.
- 2007-01-26 Tobias Burnus <burnus@net-b.de>
+ PR middle-end/30494
+ * testsuite/libgomp.c/pr30494.c: New test.
- * testsuite/libgomp.fortran/fortran.exp: Support .f03 extension.
+2007-01-15 Tom Tromey <tromey@redhat.com>
-2007-01-25 Daniel Franke <franke.daniel@gmail.com>
+ * configure: Rebuilt.
+ * configure.ac: Fixed comment.
- Backport from mainline:
- 2006-12-21 Daniel Franke <franke.daniel@gmail.com>
+2007-01-14 Daniel Franke <franke.daniel@gmail.com>
+
+ * libgomp.texi: Document implementation specific default values of
+ environment variables.
+
+2006-12-21 Daniel Franke <franke.daniel@gmail.com>
PR libgomp/28209
* libgomp.texi: New file.
* configure.ac: Add --enable-generated-files-in-srcdir option.
- * Makefile.am: Add info, dvi, pdf, html targets. On request,
- copy files to srcdir.
+ * Makefile.am: Add info, dvi, pdf, html targets. On request, copy
+ files to srcdir.
* Makefile.in: Regenerated.
+ * config.h.in: Regenerated.
* testsuite/Makefile.in: Regenerated.
* NOTES: Removed.
- Backport from mainline:
- 2007-01-14 Daniel Franke <franke.daniel@gmail.com>
- * libgomp.texi: Document implementation specific default values of
- environment variables.
-
-2007-01-24 Jakub Jelinek <jakub@redhat.com>
-
- PR middle-end/30494
- * testsuite/libgomp.c/pr30494.c: New test.
-
-2006-12-18 Daniel Franke <franke.daniel@gmail.com>
-
- Backport from mainline:
- 2006-12-04 Daniel Franke <franke.daniel@gmail.com>
+2006-12-04 Daniel Franke <franke.daniel@gmail.com>
PR libgomp/29949
* env.c (omp_set_num_threads): Set illegal thread count to 1.
- Backport from mainline:
- 2006-11-09 Uros Bizjak <ubizjak@gmail.com>
-
- * env.c (parse_schedule): Reject out of range values.
- (parse_unsigned_long): Reject out of range, negative
- or zero values.
-
2006-12-04 Eric Botcazou <ebotcazou@libertysurf.fr>
* configure: Regenerate.
@@ -135,6 +450,15 @@
* configure.tgt: Force initial-exec TLS model on Linux only.
+2006-11-13 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * configure: Regenerated.
+
+2006-11-09 Uros Bizjak <ubizjak@gmail.com>
+
+ * env.c (parse_schedule): Reject out of range values.
+ (parse_unsigned_long): Reject out of range, negative or zero values.
+
2006-10-29 Jakub Jelinek <jakub@redhat.com>
PR fortran/29629
diff --git a/contrib/gcclibs/libgomp/ChangeLog.gcc44 b/contrib/gcclibs/libgomp/ChangeLog.gcc44
new file mode 100644
index 000000000000..234d01026600
--- /dev/null
+++ b/contrib/gcclibs/libgomp/ChangeLog.gcc44
@@ -0,0 +1,8 @@
+2008-09-19 Jakub Jelinek <jakub@redhat.com> (r140497)
+ Andreas Tobler <a.tobler@schweiz.org>
+
+ * config/bsd/proc.c: New file.
+ * configure.tgt (*-*-darwin*): Use config_path "darwin posix".
+ * configure.ac: Check for header <sys/sysctl.h>
+ * configure: Regenerate.
+ * config.h.in: Likewise.
diff --git a/contrib/gcclibs/libgomp/Makefile.am b/contrib/gcclibs/libgomp/Makefile.am
index c2bfbeaad5fa..55e3bf3ee15c 100644
--- a/contrib/gcclibs/libgomp/Makefile.am
+++ b/contrib/gcclibs/libgomp/Makefile.am
@@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in
-ACLOCAL_AMFLAGS = -I ../config
+ACLOCAL_AMFLAGS = -I .. -I ../config
SUBDIRS = testsuite
## May be used by toolexeclibdir.
@@ -12,9 +12,7 @@ search_path = $(addprefix $(top_srcdir)/config/, $(config_path)) $(top_srcdir)
fincludedir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/finclude
libsubincludedir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/include
-empty =
-space = $(empty) $(empty)
-VPATH = $(subst $(space),:,$(strip $(search_path)))
+vpath % $(strip $(search_path))
AM_CPPFLAGS = $(addprefix -I, $(search_path))
AM_CFLAGS = $(XCFLAGS)
@@ -33,7 +31,7 @@ libgomp_la_LDFLAGS = $(libgomp_version_info) $(libgomp_version_script)
libgomp_la_SOURCES = alloc.c barrier.c critical.c env.c error.c iter.c \
loop.c ordered.c parallel.c sections.c single.c team.c work.c \
- lock.c mutex.c proc.c sem.c bar.c time.c fortran.c
+ lock.c mutex.c proc.c sem.c bar.c time.c fortran.c affinity.c
nodist_noinst_HEADERS = libgomp_f.h
nodist_libsubinclude_HEADERS = omp.h
@@ -51,10 +49,19 @@ env.lo: libgomp_f.h
env.o: libgomp_f.h
-# No install-html target
-.PHONY: install-html
+# No install-html or install-pdf support in automake yet
+.PHONY: install-html install-pdf
install-html:
+install-pdf: $(PDFS)
+ @$(NORMAL_INSTALL)
+ test -z "$(pdfdir)" || $(mkinstalldirs) "$(DESTDIR)$(pdfdir)"
+ @list='$(PDFS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(INSTALL_DATA) '$$d$$p' '$(DESTDIR)$(pdfdir)/$$f'"; \
+ $(INSTALL_DATA) "$$d$$p" "$(DESTDIR)$(pdfdir)/$$f"; \
+ done
# Automake Documentation:
# If your package has Texinfo files in many directories, you can use the
diff --git a/contrib/gcclibs/libgomp/Makefile.in b/contrib/gcclibs/libgomp/Makefile.in
index 7fee1ccb3cb7..57daccc6e720 100644
--- a/contrib/gcclibs/libgomp/Makefile.in
+++ b/contrib/gcclibs/libgomp/Makefile.in
@@ -17,6 +17,7 @@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
+VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
@@ -37,24 +38,27 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
-DIST_COMMON = $(am__configure_deps) $(srcdir)/../config.guess \
- $(srcdir)/../config.sub $(srcdir)/../depcomp \
- $(srcdir)/../install-sh $(srcdir)/../ltmain.sh \
- $(srcdir)/../missing $(srcdir)/../mkinstalldirs \
- $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
- $(srcdir)/config.h.in $(srcdir)/libgomp.spec.in \
- $(srcdir)/libgomp_f.h.in $(srcdir)/omp.h.in \
- $(srcdir)/omp_lib.f90.in $(srcdir)/omp_lib.h.in \
- $(top_srcdir)/configure ChangeLog
+DIST_COMMON = $(srcdir)/../config.guess $(srcdir)/../config.sub \
+ ChangeLog $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/configure $(am__configure_deps) \
+ $(srcdir)/config.h.in $(srcdir)/../mkinstalldirs \
+ $(srcdir)/omp.h.in $(srcdir)/omp_lib.h.in \
+ $(srcdir)/omp_lib.f90.in $(srcdir)/libgomp_f.h.in \
+ $(srcdir)/libgomp.spec.in $(srcdir)/../depcomp \
+ $(srcdir)/../ltmain.sh $(srcdir)/../config.guess \
+ $(srcdir)/../config.sub
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
$(top_srcdir)/../config/depstand.m4 \
$(top_srcdir)/../config/enable.m4 \
+ $(top_srcdir)/../config/futex.m4 \
$(top_srcdir)/../config/lead-dot.m4 \
$(top_srcdir)/../config/multi.m4 \
$(top_srcdir)/../config/stdint.m4 \
- $(top_srcdir)/../config/tls.m4 $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/../config/tls.m4 $(top_srcdir)/../ltoptions.m4 \
+ $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
+ $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/../libtool.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -79,21 +83,20 @@ libgomp_la_LIBADD =
am_libgomp_la_OBJECTS = alloc.lo barrier.lo critical.lo env.lo \
error.lo iter.lo loop.lo ordered.lo parallel.lo sections.lo \
single.lo team.lo work.lo lock.lo mutex.lo proc.lo sem.lo \
- bar.lo time.lo fortran.lo
+ bar.lo time.lo fortran.lo affinity.lo
libgomp_la_OBJECTS = $(am_libgomp_la_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
depcomp = $(SHELL) $(top_srcdir)/../depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) \
+LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
-LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(libgomp_la_SOURCES)
-DIST_SOURCES = $(libgomp_la_SOURCES)
MULTISRCTOP =
MULTIBUILDTOP =
MULTIDIRS =
@@ -126,18 +129,6 @@ HEADERS = $(nodist_finclude_HEADERS) $(nodist_libsubinclude_HEADERS) \
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-distdir = $(PACKAGE)-$(VERSION)
-top_distdir = $(distdir)
-am__remove_distdir = \
- { test ! -d $(distdir) \
- || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
- && rm -fr $(distdir); }; }
-DIST_ARCHIVES = $(distdir).tar.gz
-GZIP_ENV = --best
-distuninstallcheck_listfiles = find . -type f -print
-distcleancheck_listfiles = find . -type f -print
-VPATH = $(subst $(space),:,$(strip $(search_path)))
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
@@ -157,6 +148,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
+DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -164,12 +156,15 @@ EGREP = @EGREP@
EXEEXT = @EXEEXT@
FC = @FC@
FCFLAGS = @FCFLAGS@
+FGREP = @FGREP@
GENINSRC_FALSE = @GENINSRC_FALSE@
GENINSRC_TRUE = @GENINSRC_TRUE@
+GREP = @GREP@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
LDFLAGS = @LDFLAGS@
LIBGOMP_BUILD_VERSIONED_SHLIB_FALSE = @LIBGOMP_BUILD_VERSIONED_SHLIB_FALSE@
LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE = @LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@
@@ -182,6 +177,7 @@ MAINT = @MAINT@
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
MAKEINFO = @MAKEINFO@
+NM = @NM@
OBJEXT = @OBJEXT@
OMP_LOCK_ALIGN = @OMP_LOCK_ALIGN@
OMP_LOCK_KIND = @OMP_LOCK_KIND@
@@ -200,6 +196,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
RANLIB = @RANLIB@
SECTION_LDFLAGS = @SECTION_LDFLAGS@
+SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
@@ -210,6 +207,7 @@ XCFLAGS = @XCFLAGS@
XLDFLAGS = @XLDFLAGS@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
ac_ct_FC = @ac_ct_FC@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
@@ -244,6 +242,7 @@ libexecdir = @libexecdir@
libtool_VERSION = @libtool_VERSION@
link_gomp = @link_gomp@
localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
multi_basedir = @multi_basedir@
@@ -260,14 +259,12 @@ target_os = @target_os@
target_vendor = @target_vendor@
toolexecdir = @toolexecdir@
toolexeclibdir = @toolexeclibdir@
-ACLOCAL_AMFLAGS = -I ../config
+ACLOCAL_AMFLAGS = -I .. -I ../config
SUBDIRS = testsuite
gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
search_path = $(addprefix $(top_srcdir)/config/, $(config_path)) $(top_srcdir)
fincludedir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/finclude
libsubincludedir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/include
-empty =
-space = $(empty) $(empty)
AM_CPPFLAGS = $(addprefix -I, $(search_path))
AM_CFLAGS = $(XCFLAGS)
AM_LDFLAGS = $(XLDFLAGS) $(SECTION_LDFLAGS) $(OPT_LDFLAGS)
@@ -279,7 +276,7 @@ libgomp_version_info = -version-info $(libtool_VERSION)
libgomp_la_LDFLAGS = $(libgomp_version_info) $(libgomp_version_script)
libgomp_la_SOURCES = alloc.c barrier.c critical.c env.c error.c iter.c \
loop.c ordered.c parallel.c sections.c single.c team.c work.c \
- lock.c mutex.c proc.c sem.c bar.c time.c fortran.c
+ lock.c mutex.c proc.c sem.c bar.c time.c fortran.c affinity.c
nodist_noinst_HEADERS = libgomp_f.h
nodist_libsubinclude_HEADERS = omp.h
@@ -406,6 +403,7 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/affinity.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alloc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bar.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/barrier.Plo@am__quote@
@@ -733,152 +731,6 @@ GTAGS:
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
- $(am__remove_distdir)
- mkdir $(distdir)
- $(mkdir_p) $(distdir)/. $(distdir)/.. $(distdir)/../config
- @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
- list='$(DISTFILES)'; for file in $$list; do \
- case $$file in \
- $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
- $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
- esac; \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test "$$dir" != "$$file" && test "$$dir" != "."; then \
- dir="/$$dir"; \
- $(mkdir_p) "$(distdir)$$dir"; \
- else \
- dir=''; \
- fi; \
- if test -d $$d/$$file; then \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
- fi; \
- cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
- else \
- test -f $(distdir)/$$file \
- || cp -p $$d/$$file $(distdir)/$$file \
- || exit 1; \
- fi; \
- done
- list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
- if test "$$subdir" = .; then :; else \
- test -d "$(distdir)/$$subdir" \
- || $(mkdir_p) "$(distdir)/$$subdir" \
- || exit 1; \
- distdir=`$(am__cd) $(distdir) && pwd`; \
- top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
- (cd $$subdir && \
- $(MAKE) $(AM_MAKEFLAGS) \
- top_distdir="$$top_distdir" \
- distdir="$$distdir/$$subdir" \
- distdir) \
- || exit 1; \
- fi; \
- done
- $(MAKE) $(AM_MAKEFLAGS) \
- top_distdir="$(top_distdir)" distdir="$(distdir)" \
- dist-info
- -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
- ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
- ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
- ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
- || chmod -R a+r $(distdir)
-dist-gzip: distdir
- tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
- $(am__remove_distdir)
-
-dist-bzip2: distdir
- tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
- $(am__remove_distdir)
-
-dist-tarZ: distdir
- tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
- $(am__remove_distdir)
-
-dist-shar: distdir
- shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
- $(am__remove_distdir)
-
-dist-zip: distdir
- -rm -f $(distdir).zip
- zip -rq $(distdir).zip $(distdir)
- $(am__remove_distdir)
-
-dist dist-all: distdir
- tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
- $(am__remove_distdir)
-
-# This target untars the dist file and tries a VPATH configuration. Then
-# it guarantees that the distribution is self-contained by making another
-# tarfile.
-distcheck: dist
- case '$(DIST_ARCHIVES)' in \
- *.tar.gz*) \
- GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
- *.tar.bz2*) \
- bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
- *.tar.Z*) \
- uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
- *.shar.gz*) \
- GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
- *.zip*) \
- unzip $(distdir).zip ;;\
- esac
- chmod -R a-w $(distdir); chmod a+w $(distdir)
- mkdir $(distdir)/_build
- mkdir $(distdir)/_inst
- chmod a-w $(distdir)
- dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
- && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
- && cd $(distdir)/_build \
- && ../configure --srcdir=.. --prefix="$$dc_install_base" \
- $(DISTCHECK_CONFIGURE_FLAGS) \
- && $(MAKE) $(AM_MAKEFLAGS) \
- && $(MAKE) $(AM_MAKEFLAGS) dvi \
- && $(MAKE) $(AM_MAKEFLAGS) check \
- && $(MAKE) $(AM_MAKEFLAGS) install \
- && $(MAKE) $(AM_MAKEFLAGS) installcheck \
- && $(MAKE) $(AM_MAKEFLAGS) uninstall \
- && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
- distuninstallcheck \
- && chmod -R a-w "$$dc_install_base" \
- && ({ \
- (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
- && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
- && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
- && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
- distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
- } || { rm -rf "$$dc_destdir"; exit 1; }) \
- && rm -rf "$$dc_destdir" \
- && $(MAKE) $(AM_MAKEFLAGS) dist \
- && rm -rf $(DIST_ARCHIVES) \
- && $(MAKE) $(AM_MAKEFLAGS) distcleancheck
- $(am__remove_distdir)
- @(echo "$(distdir) archives ready for distribution: "; \
- list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
- sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}'
-distuninstallcheck:
- @cd $(distuninstallcheck_dir) \
- && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
- || { echo "ERROR: files left after uninstall:" ; \
- if test -n "$(DESTDIR)"; then \
- echo " (check DESTDIR support)"; \
- fi ; \
- $(distuninstallcheck_listfiles) ; \
- exit 1; } >&2
-distcleancheck: distclean
- @if test '$(srcdir)' = . ; then \
- echo "ERROR: distcleancheck can only run from a VPATH build" ; \
- exit 1 ; \
- fi
- @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
- || { echo "ERROR: files left in build directory after distclean:" ; \
- $(distcleancheck_listfiles) ; \
- exit 1; } >&2
check-am: all-am
check: check-recursive
all-am: Makefile $(INFO_DEPS) $(LTLIBRARIES) all-multi $(HEADERS) \
@@ -1011,16 +863,13 @@ uninstall-info: uninstall-info-recursive
.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am all-local \
all-multi am--refresh check check-am clean clean-generic \
clean-libtool clean-multi clean-recursive \
- clean-toolexeclibLTLIBRARIES ctags ctags-recursive dist \
- dist-all dist-bzip2 dist-gzip dist-info dist-shar dist-tarZ \
- dist-zip distcheck distclean distclean-compile \
- distclean-generic distclean-hdr distclean-libtool \
- distclean-multi distclean-recursive distclean-tags \
- distcleancheck distdir distuninstallcheck dvi dvi-am html \
- html-am info info-am install install-am install-data \
- install-data-am install-exec install-exec-am install-info \
- install-info-am install-man install-multi \
- install-nodist_fincludeHEADERS \
+ clean-toolexeclibLTLIBRARIES ctags ctags-recursive dist-info \
+ distclean distclean-compile distclean-generic distclean-hdr \
+ distclean-libtool distclean-multi distclean-recursive \
+ distclean-tags dvi dvi-am html html-am info info-am install \
+ install-am install-data install-data-am install-exec \
+ install-exec-am install-info install-info-am install-man \
+ install-multi install-nodist_fincludeHEADERS \
install-nodist_libsubincludeHEADERS \
install-nodist_toolexeclibHEADERS install-strip \
install-toolexeclibLTLIBRARIES installcheck installcheck-am \
@@ -1036,6 +885,8 @@ uninstall-info: uninstall-info-recursive
uninstall-toolexeclibLTLIBRARIES
+vpath % $(strip $(search_path))
+
omp_lib_kinds.mod: omp_lib.mod
:
omp_lib.mod: omp_lib.f90
@@ -1045,10 +896,20 @@ fortran.o: libgomp_f.h
env.lo: libgomp_f.h
env.o: libgomp_f.h
-# No install-html target
-.PHONY: install-html
+# No install-html or install-pdf support in automake yet
+.PHONY: install-html install-pdf
install-html:
+install-pdf: $(PDFS)
+ @$(NORMAL_INSTALL)
+ test -z "$(pdfdir)" || $(mkinstalldirs) "$(DESTDIR)$(pdfdir)"
+ @list='$(PDFS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(INSTALL_DATA) '$$d$$p' '$(DESTDIR)$(pdfdir)/$$f'"; \
+ $(INSTALL_DATA) "$$d$$p" "$(DESTDIR)$(pdfdir)/$$f"; \
+ done
+
all-local: $(STAMP_GENINSRC)
stamp-geninsrc: libgomp.info
diff --git a/contrib/gcclibs/libgomp/aclocal.m4 b/contrib/gcclibs/libgomp/aclocal.m4
index 31c2eec2d9a6..eee6ec06b284 100644
--- a/contrib/gcclibs/libgomp/aclocal.m4
+++ b/contrib/gcclibs/libgomp/aclocal.m4
@@ -859,8 +859,13 @@ AC_SUBST([am__untar])
m4_include([../config/acx.m4])
m4_include([../config/depstand.m4])
m4_include([../config/enable.m4])
+m4_include([../config/futex.m4])
m4_include([../config/lead-dot.m4])
m4_include([../config/multi.m4])
m4_include([../config/stdint.m4])
m4_include([../config/tls.m4])
+m4_include([../ltoptions.m4])
+m4_include([../ltsugar.m4])
+m4_include([../ltversion.m4])
+m4_include([../lt~obsolete.m4])
m4_include([acinclude.m4])
diff --git a/contrib/gcclibs/libgomp/config.h.in b/contrib/gcclibs/libgomp/config.h.in
index 0c1599388b2d..fa4206b7d771 100644
--- a/contrib/gcclibs/libgomp/config.h.in
+++ b/contrib/gcclibs/libgomp/config.h.in
@@ -12,9 +12,15 @@
/* Define if the POSIX Semaphores do not work on your system. */
#undef HAVE_BROKEN_POSIX_SEMAPHORES
+/* Define to 1 if the target assembler supports thread-local storage. */
+#undef HAVE_CC_TLS
+
/* Define to 1 if you have the `clock_gettime' function. */
#undef HAVE_CLOCK_GETTIME
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
/* Define to 1 if you have the `getloadavg' function. */
#undef HAVE_GETLOADAVG
@@ -24,6 +30,9 @@
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
+/* Define if pthread_{,attr_}{g,s}etaffinity_np is supported. */
+#undef HAVE_PTHREAD_AFFINITY_NP
+
/* Define to 1 if you have the <semaphore.h> header file. */
#undef HAVE_SEMAPHORE_H
@@ -48,6 +57,9 @@
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
+/* Define to 1 if you have the <sys/sysctl.h> header file. */
+#undef HAVE_SYS_SYSCTL_H
+
/* Define to 1 if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
@@ -60,6 +72,10 @@
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#undef LT_OBJDIR
+
/* Name of package */
#undef PACKAGE
diff --git a/contrib/gcclibs/libgomp/config/bsd/proc.c b/contrib/gcclibs/libgomp/config/bsd/proc.c
new file mode 100644
index 000000000000..513d8df39108
--- /dev/null
+++ b/contrib/gcclibs/libgomp/config/bsd/proc.c
@@ -0,0 +1,117 @@
+/* Copyright (C) 2005, 2006, 2008 Free Software Foundation, Inc.
+ Contributed by Richard Henderson <rth@redhat.com>.
+
+ This file is part of the GNU OpenMP Library (libgomp).
+
+ Libgomp is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+ more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with libgomp; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* As a special exception, if you link this library with other files, some
+ of which are compiled with GCC, to produce an executable, this library
+ does not by itself cause the resulting executable to be covered by the
+ GNU General Public License. This exception does not however invalidate
+ any other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+/* This file contains system specific routines related to counting
+ online processors and dynamic load balancing. It is expected that
+ a system may well want to write special versions of each of these.
+
+ The following implementation uses a mix of POSIX and BSD routines. */
+
+#include "libgomp.h"
+#include <unistd.h>
+#include <stdlib.h>
+#ifdef HAVE_GETLOADAVG
+# ifdef HAVE_SYS_LOADAVG_H
+# include <sys/loadavg.h>
+# endif
+#endif
+#ifdef HAVE_SYS_SYSCTL_H
+# include <sys/sysctl.h>
+#endif
+
+static int
+get_num_procs (void)
+{
+#ifdef _SC_NPROCESSORS_ONLN
+ return sysconf (_SC_NPROCESSORS_ONLN);
+#elif defined HW_NCPU
+ int ncpus = 1;
+ size_t len = sizeof(ncpus);
+ sysctl((int[2]) {CTL_HW, HW_NCPU}, 2, &ncpus, &len, NULL, 0);
+ return ncpus;
+#else
+ return 0;
+#endif
+}
+
+/* At startup, determine the default number of threads. It would seem
+ this should be related to the number of cpus online. */
+
+void
+gomp_init_num_threads (void)
+{
+ int ncpus = get_num_procs ();
+
+ if (ncpus > 0)
+ gomp_global_icv.nthreads_var = ncpus;
+}
+
+/* When OMP_DYNAMIC is set, at thread launch determine the number of
+ threads we should spawn for this team. */
+/* ??? I have no idea what best practice for this is. Surely some
+ function of the number of processors that are *still* online and
+ the load average. Here I use the number of processors online
+ minus the 15 minute load average. */
+
+unsigned
+gomp_dynamic_max_threads (void)
+{
+ unsigned n_onln, loadavg;
+ unsigned nthreads_var = gomp_icv (false)->nthreads_var;
+
+ n_onln = get_num_procs ();
+ if (!n_onln || n_onln > nthreads_var)
+ n_onln = nthreads_var;
+
+ loadavg = 0;
+#ifdef HAVE_GETLOADAVG
+ {
+ double dloadavg[3];
+ if (getloadavg (dloadavg, 3) == 3)
+ {
+ /* Add 0.1 to get a kind of biased rounding. */
+ loadavg = dloadavg[2] + 0.1;
+ }
+ }
+#endif
+
+ if (loadavg >= n_onln)
+ return 1;
+ else
+ return n_onln - loadavg;
+}
+
+int
+omp_get_num_procs (void)
+{
+ int ncpus = get_num_procs ();
+ if (ncpus <= 0)
+ ncpus = gomp_icv (false)->nthreads_var;
+ return ncpus;
+}
+
+ialias (omp_get_num_procs)
diff --git a/contrib/gcclibs/libgomp/config/linux/affinity.c b/contrib/gcclibs/libgomp/config/linux/affinity.c
new file mode 100644
index 000000000000..8fcce5f3a5b4
--- /dev/null
+++ b/contrib/gcclibs/libgomp/config/linux/affinity.c
@@ -0,0 +1,107 @@
+/* Copyright (C) 2006, 2007 Free Software Foundation, Inc.
+ Contributed by Jakub Jelinek <jakub@redhat.com>.
+
+ This file is part of the GNU OpenMP Library (libgomp).
+
+ Libgomp is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+ more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with libgomp; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* As a special exception, if you link this library with other files, some
+ of which are compiled with GCC, to produce an executable, this library
+ does not by itself cause the resulting executable to be covered by the
+ GNU General Public License. This exception does not however invalidate
+ any other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+/* This is a Linux specific implementation of a CPU affinity setting. */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE 1
+#endif
+#include "libgomp.h"
+#include <sched.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#ifdef HAVE_PTHREAD_AFFINITY_NP
+
+static unsigned int affinity_counter;
+#ifndef HAVE_SYNC_BUILTINS
+static gomp_mutex_t affinity_lock;
+#endif
+
+void
+gomp_init_affinity (void)
+{
+ cpu_set_t cpuset;
+ size_t idx, widx;
+
+ if (pthread_getaffinity_np (pthread_self (), sizeof (cpuset), &cpuset))
+ {
+ gomp_error ("could not get CPU affinity set");
+ free (gomp_cpu_affinity);
+ gomp_cpu_affinity = NULL;
+ gomp_cpu_affinity_len = 0;
+ return;
+ }
+
+ for (widx = idx = 0; idx < gomp_cpu_affinity_len; idx++)
+ if (gomp_cpu_affinity[idx] < CPU_SETSIZE
+ && CPU_ISSET (gomp_cpu_affinity[idx], &cpuset))
+ gomp_cpu_affinity[widx++] = gomp_cpu_affinity[idx];
+
+ if (widx == 0)
+ {
+ gomp_error ("no CPUs left for affinity setting");
+ free (gomp_cpu_affinity);
+ gomp_cpu_affinity = NULL;
+ gomp_cpu_affinity_len = 0;
+ return;
+ }
+
+ gomp_cpu_affinity_len = widx;
+ CPU_ZERO (&cpuset);
+ CPU_SET (gomp_cpu_affinity[0], &cpuset);
+ pthread_setaffinity_np (pthread_self (), sizeof (cpuset), &cpuset);
+ affinity_counter = 1;
+#ifndef HAVE_SYNC_BUILTINS
+ gomp_mutex_init (&affinity_lock);
+#endif
+}
+
+void
+gomp_init_thread_affinity (pthread_attr_t *attr)
+{
+ unsigned int cpu;
+ cpu_set_t cpuset;
+
+#ifdef HAVE_SYNC_BUILTINS
+ cpu = __sync_fetch_and_add (&affinity_counter, 1);
+#else
+ gomp_mutex_lock (&affinity_lock);
+ cpu = affinity_counter++;
+ gomp_mutex_unlock (&affinity_lock);
+#endif
+ cpu %= gomp_cpu_affinity_len;
+ CPU_ZERO (&cpuset);
+ CPU_SET (gomp_cpu_affinity[cpu], &cpuset);
+ pthread_attr_setaffinity_np (attr, sizeof (cpu_set_t), &cpuset);
+}
+
+#else
+
+#include "../posix/affinity.c"
+
+#endif
diff --git a/contrib/gcclibs/libgomp/config/linux/proc.c b/contrib/gcclibs/libgomp/config/linux/proc.c
new file mode 100644
index 000000000000..2267cfbd2d1b
--- /dev/null
+++ b/contrib/gcclibs/libgomp/config/linux/proc.c
@@ -0,0 +1,179 @@
+/* Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
+ Contributed by Jakub Jelinek <jakub@redhat.com>.
+
+ This file is part of the GNU OpenMP Library (libgomp).
+
+ Libgomp is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+ more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with libgomp; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* As a special exception, if you link this library with other files, some
+ of which are compiled with GCC, to produce an executable, this library
+ does not by itself cause the resulting executable to be covered by the
+ GNU General Public License. This exception does not however invalidate
+ any other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+/* This file contains system specific routines related to counting
+ online processors and dynamic load balancing. */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE 1
+#endif
+#include "libgomp.h"
+#include <sched.h>
+#include <stdlib.h>
+#include <unistd.h>
+#ifdef HAVE_GETLOADAVG
+# ifdef HAVE_SYS_LOADAVG_H
+# include <sys/loadavg.h>
+# endif
+#endif
+
+#ifdef HAVE_PTHREAD_AFFINITY_NP
+static unsigned long
+cpuset_popcount (cpu_set_t *cpusetp)
+{
+#ifdef CPU_COUNT
+ /* glibc 2.6 and above provide a macro for this. */
+ return CPU_COUNT (cpusetp);
+#else
+ size_t i;
+ unsigned long ret = 0;
+ extern int check[sizeof (cpusetp->__bits[0]) == sizeof (unsigned long int)];
+
+ (void) check;
+ for (i = 0; i < sizeof (*cpusetp) / sizeof (cpusetp->__bits[0]); i++)
+ {
+ unsigned long int mask = cpusetp->__bits[i];
+ if (mask == 0)
+ continue;
+ ret += __builtin_popcountl (mask);
+ }
+ return ret;
+#endif
+}
+#endif
+
+/* At startup, determine the default number of threads. It would seem
+ this should be related to the number of cpus online. */
+
+void
+gomp_init_num_threads (void)
+{
+#ifdef HAVE_PTHREAD_AFFINITY_NP
+ cpu_set_t cpuset;
+
+ if (pthread_getaffinity_np (pthread_self (), sizeof (cpuset), &cpuset) == 0)
+ {
+ /* Count only the CPUs this process can use. */
+ gomp_nthreads_var = cpuset_popcount (&cpuset);
+ if (gomp_nthreads_var == 0)
+ gomp_nthreads_var = 1;
+ return;
+ }
+#endif
+#ifdef _SC_NPROCESSORS_ONLN
+ gomp_nthreads_var = sysconf (_SC_NPROCESSORS_ONLN);
+#endif
+}
+
+static int
+get_num_procs (void)
+{
+#ifdef HAVE_PTHREAD_AFFINITY_NP
+ cpu_set_t cpuset;
+
+ if (gomp_cpu_affinity == NULL)
+ {
+ /* Count only the CPUs this process can use. */
+ if (pthread_getaffinity_np (pthread_self (), sizeof (cpuset),
+ &cpuset) == 0)
+ {
+ int ret = cpuset_popcount (&cpuset);
+ return ret != 0 ? ret : 1;
+ }
+ }
+ else
+ {
+ size_t idx;
+ static int affinity_cpus;
+
+ /* We can't use pthread_getaffinity_np in this case
+ (we have changed it ourselves, it binds to just one CPU).
+ Count instead the number of different CPUs we are
+ using. */
+ CPU_ZERO (&cpuset);
+ if (affinity_cpus == 0)
+ {
+ int cpus = 0;
+ for (idx = 0; idx < gomp_cpu_affinity_len; idx++)
+ if (! CPU_ISSET (gomp_cpu_affinity[idx], &cpuset))
+ {
+ cpus++;
+ CPU_SET (gomp_cpu_affinity[idx], &cpuset);
+ }
+ affinity_cpus = cpus;
+ }
+ return affinity_cpus;
+ }
+#endif
+#ifdef _SC_NPROCESSORS_ONLN
+ return sysconf (_SC_NPROCESSORS_ONLN);
+#else
+ return gomp_nthreads_var;
+#endif
+}
+
+/* When OMP_DYNAMIC is set, at thread launch determine the number of
+ threads we should spawn for this team. */
+/* ??? I have no idea what best practice for this is. Surely some
+ function of the number of processors that are *still* online and
+ the load average. Here I use the number of processors online
+ minus the 15 minute load average. */
+
+unsigned
+gomp_dynamic_max_threads (void)
+{
+ unsigned n_onln, loadavg;
+
+ n_onln = get_num_procs ();
+ if (n_onln > gomp_nthreads_var)
+ n_onln = gomp_nthreads_var;
+
+ loadavg = 0;
+#ifdef HAVE_GETLOADAVG
+ {
+ double dloadavg[3];
+ if (getloadavg (dloadavg, 3) == 3)
+ {
+ /* Add 0.1 to get a kind of biased rounding. */
+ loadavg = dloadavg[2] + 0.1;
+ }
+ }
+#endif
+
+ if (loadavg >= n_onln)
+ return 1;
+ else
+ return n_onln - loadavg;
+}
+
+int
+omp_get_num_procs (void)
+{
+ return get_num_procs ();
+}
+
+ialias (omp_get_num_procs)
diff --git a/contrib/gcclibs/libgomp/config/mingw32/proc.c b/contrib/gcclibs/libgomp/config/mingw32/proc.c
new file mode 100644
index 000000000000..def7bb5e8f48
--- /dev/null
+++ b/contrib/gcclibs/libgomp/config/mingw32/proc.c
@@ -0,0 +1,82 @@
+/* Copyright (C) 2007 Free Software Foundation, Inc.
+ Contributed by Danny Smith <dannysmith@users.sourceforge.net>
+
+ This file is part of the GNU OpenMP Library (libgomp).
+
+ Libgomp is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+ more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with libgomp; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* As a special exception, if you link this library with other files, some
+ of which are compiled with GCC, to produce an executable, this library
+ does not by itself cause the resulting executable to be covered by the
+ GNU General Public License. This exception does not however invalidate
+ any other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+/* This file contains system specific routines related to counting
+ online processors and dynamic load balancing. It is expected that
+ a system may well want to write special versions of each of these.
+
+ The following implementation uses win32 API routines. */
+
+#include "libgomp.h"
+#include <windows.h>
+
+/* Count the CPU's currently available to this process. */
+static int
+count_avail_process_cpus ()
+{
+ DWORD_PTR process_cpus;
+ DWORD_PTR system_cpus;
+
+ if (GetProcessAffinityMask (GetCurrentProcess (),
+ &process_cpus, &system_cpus))
+ {
+ unsigned int count;
+ for (count = 0; process_cpus != 0; process_cpus >>= 1)
+ if (process_cpus & 1)
+ count++;
+ return count;
+ }
+ return 1;
+}
+
+/* At startup, determine the default number of threads. It would seem
+ this should be related to the number of cpus available to the process. */
+
+void
+gomp_init_num_threads (void)
+{
+ gomp_nthreads_var = count_avail_process_cpus ();
+}
+
+/* When OMP_DYNAMIC is set, at thread launch determine the number of
+ threads we should spawn for this team. FIXME: How do we adjust for
+ load average on MS Windows? */
+
+unsigned
+gomp_dynamic_max_threads (void)
+{
+ int n_onln = count_avail_process_cpus ();
+ return n_onln > gomp_nthreads_var ? gomp_nthreads_var : n_onln;
+}
+
+int
+omp_get_num_procs (void)
+{
+ return count_avail_process_cpus ();
+}
+
+ialias (omp_get_num_procs)
diff --git a/contrib/gcclibs/libgomp/config/posix/affinity.c b/contrib/gcclibs/libgomp/config/posix/affinity.c
new file mode 100644
index 000000000000..67cb37ad924b
--- /dev/null
+++ b/contrib/gcclibs/libgomp/config/posix/affinity.c
@@ -0,0 +1,41 @@
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+ Contributed by Jakub Jelinek <jakub@redhat.com>.
+
+ This file is part of the GNU OpenMP Library (libgomp).
+
+ Libgomp is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+ more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with libgomp; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* As a special exception, if you link this library with other files, some
+ of which are compiled with GCC, to produce an executable, this library
+ does not by itself cause the resulting executable to be covered by the
+ GNU General Public License. This exception does not however invalidate
+ any other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+/* This is a generic stub implementation of a CPU affinity setting. */
+
+#include "libgomp.h"
+
+void
+gomp_init_affinity (void)
+{
+}
+
+void
+gomp_init_thread_affinity (pthread_attr_t *attr)
+{
+ (void) attr;
+}
diff --git a/contrib/gcclibs/libgomp/configure b/contrib/gcclibs/libgomp/configure
index af4254c1fda0..a5cee6ac4dbb 100755
--- a/contrib/gcclibs/libgomp/configure
+++ b/contrib/gcclibs/libgomp/configure
@@ -241,6 +241,155 @@ IFS=" $as_nl"
$as_unset CDPATH
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$lt_ECHO in
+X*--fallback-echo)
+ # Remove one level of quotation (which was required for Make).
+ ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','`
+ ;;
+esac
+
+ECHO=${lt_ECHO-echo}
+if test "X$1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X$1" = X--fallback-echo; then
+ # Avoid inline document here, it may be left over
+ :
+elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then
+ # Yippee, $ECHO works!
+ :
+else
+ # Restart under the correct shell.
+ exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<_LT_EOF
+$*
+_LT_EOF
+ exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test -z "$lt_ECHO"; then
+ if test "X${echo_test_string+set}" != Xset; then
+ # find a string as large as possible, as long as the shell can cope with it
+ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
+ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+ if { echo_test_string=`eval $cmd`; } 2>/dev/null &&
+ { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null
+ then
+ break
+ fi
+ done
+ fi
+
+ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ :
+ else
+ # The Solaris, AIX, and Digital Unix default echo programs unquote
+ # backslashes. This makes it impossible to quote backslashes using
+ # echo "$something" | sed 's/\\/\\\\/g'
+ #
+ # So, first we look for a working echo in the user's PATH.
+
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for dir in $PATH /usr/ucb; do
+ IFS="$lt_save_ifs"
+ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ ECHO="$dir/echo"
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+
+ if test "X$ECHO" = Xecho; then
+ # We didn't find a better echo, so look for alternatives.
+ if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ # This shell has a builtin print -r that does the trick.
+ ECHO='print -r'
+ elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } &&
+ test "X$CONFIG_SHELL" != X/bin/ksh; then
+ # If we have ksh, try running configure again with it.
+ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+ export ORIGINAL_CONFIG_SHELL
+ CONFIG_SHELL=/bin/ksh
+ export CONFIG_SHELL
+ exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"}
+ else
+ # Try using printf.
+ ECHO='printf %s\n'
+ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ # Cool, printf works
+ :
+ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+ test "X$echo_testing_string" = 'X\t' &&
+ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+ export CONFIG_SHELL
+ SHELL="$CONFIG_SHELL"
+ export SHELL
+ ECHO="$CONFIG_SHELL $0 --fallback-echo"
+ elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+ test "X$echo_testing_string" = 'X\t' &&
+ echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ ECHO="$CONFIG_SHELL $0 --fallback-echo"
+ else
+ # maybe with a smaller string...
+ prev=:
+
+ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
+ if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null
+ then
+ break
+ fi
+ prev="$cmd"
+ done
+
+ if test "$prev" != 'sed 50q "$0"'; then
+ echo_test_string=`eval $prev`
+ export echo_test_string
+ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"}
+ else
+ # Oops. We lost completely, so just stick with echo.
+ ECHO=echo
+ fi
+ fi
+ fi
+ fi
+ fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+lt_ECHO=$ECHO
+if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then
+ lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo"
+fi
+
+
+
+
# Name of the host.
# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
# so uname gets run too.
@@ -308,7 +457,7 @@ ac_includes_default="\
# include <unistd.h>
#endif"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS GENINSRC_TRUE GENINSRC_FALSE build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar multi_basedir toolexecdir toolexeclibdir CC ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CFLAGS AR ac_ct_AR RANLIB ac_ct_RANLIB PERL BUILD_INFO_TRUE BUILD_INFO_FALSE LN_S LIBTOOL enable_shared enable_static MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT FC FCFLAGS LDFLAGS ac_ct_FC libtool_VERSION CPP CPPFLAGS EGREP SECTION_LDFLAGS OPT_LDFLAGS LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE LIBGOMP_BUILD_VERSIONED_SHLIB_FALSE config_path XCFLAGS XLDFLAGS link_gomp USE_FORTRAN_TRUE USE_FORTRAN_FALSE OMP_LOCK_SIZE OMP_LOCK_ALIGN OMP_NEST_LOCK_SIZE OMP_NEST_LOCK_ALIGN OMP_LOCK_KIND OMP_NEST_LOCK_KIND LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS GENINSRC_TRUE GENINSRC_FALSE build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar multi_basedir toolexecdir toolexeclibdir CC ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CFLAGS AR ac_ct_AR RANLIB ac_ct_RANLIB PERL BUILD_INFO_TRUE BUILD_INFO_FALSE LIBTOOL SED EGREP FGREP GREP LD DUMPBIN ac_ct_DUMPBIN NM LN_S lt_ECHO CPP CPPFLAGS enable_shared enable_static MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT FC FCFLAGS LDFLAGS ac_ct_FC libtool_VERSION SECTION_LDFLAGS OPT_LDFLAGS LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE LIBGOMP_BUILD_VERSIONED_SHLIB_FALSE config_path XCFLAGS XLDFLAGS link_gomp USE_FORTRAN_TRUE USE_FORTRAN_FALSE OMP_LOCK_SIZE OMP_LOCK_ALIGN OMP_NEST_LOCK_SIZE OMP_NEST_LOCK_ALIGN OMP_LOCK_KIND OMP_NEST_LOCK_KIND LIBOBJS LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
@@ -718,13 +867,13 @@ echo X"$0" |
/^X\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
srcdir=$ac_confdir
- if test ! -r "$srcdir/$ac_unique_file"; then
+ if test ! -r $srcdir/$ac_unique_file; then
srcdir=..
fi
else
ac_srcdir_defaulted=no
fi
-if test ! -r "$srcdir/$ac_unique_file"; then
+if test ! -r $srcdir/$ac_unique_file; then
if test "$ac_srcdir_defaulted" = yes; then
{ echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
{ (exit 1); exit 1; }; }
@@ -733,7 +882,7 @@ if test ! -r "$srcdir/$ac_unique_file"; then
{ (exit 1); exit 1; }; }
fi
fi
-(cd $srcdir && test -r "./$ac_unique_file") 2>/dev/null ||
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
{ echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
{ (exit 1); exit 1; }; }
srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
@@ -749,6 +898,14 @@ ac_env_target_alias_set=${target_alias+set}
ac_env_target_alias_value=$target_alias
ac_cv_env_target_alias_set=${target_alias+set}
ac_cv_env_target_alias_value=$target_alias
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
ac_env_FC_set=${FC+set}
ac_env_FC_value=$FC
ac_cv_env_FC_set=${FC+set}
@@ -761,14 +918,6 @@ ac_env_LDFLAGS_set=${LDFLAGS+set}
ac_env_LDFLAGS_value=$LDFLAGS
ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
ac_cv_env_LDFLAGS_value=$LDFLAGS
-ac_env_CPP_set=${CPP+set}
-ac_env_CPP_value=$CPP
-ac_cv_env_CPP_set=${CPP+set}
-ac_cv_env_CPP_value=$CPP
-ac_env_CPPFLAGS_set=${CPPFLAGS+set}
-ac_env_CPPFLAGS_value=$CPPFLAGS
-ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
-ac_cv_env_CPPFLAGS_value=$CPPFLAGS
#
# Report the --help message.
@@ -854,8 +1003,6 @@ Optional Features:
--enable-version-specific-runtime-libs
Specify that runtime libraries should be installed
in a compiler-specific directory [default=no]
- --enable-linux-futex Use the Linux futex system call
- [default=default]
--enable-generated-files-in-srcdir
put copies of generated files in source dir intended
for creating source tarballs for users without
@@ -863,12 +1010,17 @@ Optional Features:
--enable-multilib build many library versions (default)
--disable-dependency-tracking speeds up one-time build
--enable-dependency-tracking do not reject slow dependency extractors
- --enable-shared=PKGS build shared libraries default=yes
- --enable-static=PKGS build static libraries default=yes
- --enable-fast-install=PKGS optimize for fast installation default=yes
+ --enable-shared[=PKGS]
+ build shared libraries [default=yes]
+ --enable-static[=PKGS]
+ build static libraries [default=yes]
+ --enable-fast-install[=PKGS]
+ optimize for fast installation [default=yes]
--disable-libtool-lock avoid locking (might break parallel builds)
--enable-maintainer-mode enable make rules and dependencies not useful
(and sometimes confusing) to the casual installer
+ --enable-linux-futex use the Linux futex system call
+ [default=default]
--enable-tls Use thread-local storage [default=yes]
--enable-symvers=STYLE enables symbol versioning of the shared library
[default=yes]
@@ -876,8 +1028,9 @@ Optional Features:
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
- --with-gnu-ld assume the C compiler uses GNU ld default=no
- --with-pic try to use only PIC/non-PIC objects default=use both
+ --with-pic try to use only PIC/non-PIC objects [default=use
+ both]
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]
Some influential environment variables:
CC C compiler command
@@ -886,9 +1039,9 @@ Some influential environment variables:
nonstandard directory <lib dir>
CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have
headers in a nonstandard directory <include dir>
+ CPP C preprocessor
FC Fortran compiler command
FCFLAGS Fortran compiler flags
- CPP C preprocessor
Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.
@@ -1365,26 +1518,6 @@ fi;
echo "$as_me:$LINENO: result: $enable_version_specific_runtime_libs" >&5
echo "${ECHO_T}$enable_version_specific_runtime_libs" >&6
-echo "$as_me:$LINENO: checking for --enable-linux-futex" >&5
-echo $ECHO_N "checking for --enable-linux-futex... $ECHO_C" >&6
- # Check whether --enable-linux-futex or --disable-linux-futex was given.
-if test "${enable_linux_futex+set}" = set; then
- enableval="$enable_linux_futex"
-
- case "$enableval" in
- yes|no|default) ;;
- *) { { echo "$as_me:$LINENO: error: Unknown argument to enable/disable linux-futex" >&5
-echo "$as_me: error: Unknown argument to enable/disable linux-futex" >&2;}
- { (exit 1); exit 1; }; } ;;
- esac
-
-else
- enable_linux_futex=default
-fi;
-
-echo "$as_me:$LINENO: result: $enable_linux_futex" >&5
-echo "${ECHO_T}$enable_linux_futex" >&6
-
# We would like our source tree to be readonly. However when releases or
# pre-releases are generated, the flex/bison generated files as well as the
# various formats of manuals need to be included along with the rest of the
@@ -1556,7 +1689,7 @@ target_alias=${target_alias-$host_alias}
# we can do about that; they come from AC_INIT).
# foreign: we don't follow the normal rules for GNU packages (no COPYING
# file in the top srcdir, etc, etc), so stop complaining.
-# no-dependencies: turns off auto dependency generation (just for now)
+# no-dist: we don't want 'dist' and related rules.
# -Wall: turns on all automake warnings...
# -Wno-portability: ...except this one, since GNU make is required.
# -Wno-override: ... and this one, since we do want this in testsuite.
@@ -3526,13 +3659,10 @@ else
sed -n 's/^.*GNU texinfo.* \([0-9][0-9.]*\).*$/\1/p'`
case $ac_prog_version in
- '') gcc_cv_prog_makeinfo_modern=no;;
- 4.[4-9]*) gcc_cv_prog_makeinfo_modern=yes;;
- *) gcc_cv_prog_makeinfo_modern=no;;
- esac
- if test $gcc_cv_prog_makeinfo_modern = no; then
- MAKEINFO="${CONFIG_SHELL-/bin/sh} $ac_aux_dir/missing makeinfo"
- fi
+ '') gcc_cv_prog_makeinfo_modern=no;;
+ 4.[4-9]*|4.[1-9][0-9]*|[5-9]*|[1-9][0-9]*) gcc_cv_prog_makeinfo_modern=yes;;
+ *) gcc_cv_prog_makeinfo_modern=no;;
+ esac
fi
echo "$as_me:$LINENO: result: $gcc_cv_prog_makeinfo_modern" >&5
@@ -3540,6 +3670,9 @@ echo "${ECHO_T}$gcc_cv_prog_makeinfo_modern" >&6
else
gcc_cv_prog_makeinfo_modern=no
fi
+ if test $gcc_cv_prog_makeinfo_modern = no; then
+ MAKEINFO="${CONFIG_SHELL-/bin/sh} $ac_aux_dir/missing makeinfo"
+ fi
@@ -3554,73 +3687,264 @@ fi
# Configure libtool
+
+
+macro_version='2.1a'
+macro_revision='1.2435'
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+# Set options
+
+enable_dlopen=no
+
+
+enable_win32_dll=no
+
+
# Check whether --enable-shared or --disable-shared was given.
if test "${enable_shared+set}" = set; then
enableval="$enable_shared"
p=${PACKAGE-default}
-case $enableval in
-yes) enable_shared=yes ;;
-no) enable_shared=no ;;
-*)
- enable_shared=no
- # Look at the argument we got. We use all the common list separators.
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
- for pkg in $enableval; do
- if test "X$pkg" = "X$p"; then
- enable_shared=yes
- fi
- done
- IFS="$ac_save_ifs"
- ;;
-esac
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
else
enable_shared=yes
fi;
+
+
+
+
+
+
+
+
# Check whether --enable-static or --disable-static was given.
if test "${enable_static+set}" = set; then
enableval="$enable_static"
p=${PACKAGE-default}
-case $enableval in
-yes) enable_static=yes ;;
-no) enable_static=no ;;
-*)
- enable_static=no
- # Look at the argument we got. We use all the common list separators.
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
- for pkg in $enableval; do
- if test "X$pkg" = "X$p"; then
- enable_static=yes
- fi
- done
- IFS="$ac_save_ifs"
- ;;
-esac
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
else
enable_static=yes
fi;
+
+
+
+
+
+
+
+
+
+# Check whether --with-pic or --without-pic was given.
+if test "${with_pic+set}" = set; then
+ withval="$with_pic"
+ pic_mode="$withval"
+else
+ pic_mode=default
+fi;
+
+test -z "$pic_mode" && pic_mode=default
+
+
+
+
+
+
+
# Check whether --enable-fast-install or --disable-fast-install was given.
if test "${enable_fast_install+set}" = set; then
enableval="$enable_fast_install"
p=${PACKAGE-default}
-case $enableval in
-yes) enable_fast_install=yes ;;
-no) enable_fast_install=no ;;
-*)
- enable_fast_install=no
- # Look at the argument we got. We use all the common list separators.
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
- for pkg in $enableval; do
- if test "X$pkg" = "X$p"; then
- enable_fast_install=yes
- fi
- done
- IFS="$ac_save_ifs"
- ;;
-esac
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
else
enable_fast_install=yes
fi;
+
+
+
+
+
+
+
+echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5
+echo $ECHO_N "checking for a sed that does not truncate output... $ECHO_C" >&6
+if test "${lt_cv_path_SED+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for lt_ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+ lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+ fi
+ done
+ done
+done
+IFS=$as_save_IFS
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+ test ! -f $lt_ac_sed && continue
+ cat /dev/null > conftest.in
+ lt_ac_count=0
+ echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+ # Check for GNU sed and select it if it is found.
+ if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+ lt_cv_path_SED=$lt_ac_sed
+ break
+ fi
+ while true; do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo >>conftest.nl
+ $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+ cmp -s conftest.out conftest.nl || break
+ # 10000 chars as input seems more than enough
+ test $lt_ac_count -gt 10 && break
+ lt_ac_count=`expr $lt_ac_count + 1`
+ if test $lt_ac_count -gt $lt_ac_max; then
+ lt_ac_max=$lt_ac_count
+ lt_cv_path_SED=$lt_ac_sed
+ fi
+ done
+done
+
+fi
+
+SED=$lt_cv_path_SED
+
+echo "$as_me:$LINENO: result: $SED" >&5
+echo "${ECHO_T}$SED" >&6
+
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+
+
+
+
+
+
+
+
+
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+ then ac_cv_prog_egrep='grep -E'
+ else ac_cv_prog_egrep='egrep'
+ fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+echo "$as_me:$LINENO: checking for fgrep" >&5
+echo $ECHO_N "checking for fgrep... $ECHO_C" >&6
+if test "${ac_cv_prog_fgrep+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if echo 'ab*c' | (grep -F 'ab*c') >/dev/null 2>&1
+ then ac_cv_prog_fgrep='grep -F'
+ else ac_cv_prog_fgrep='fgrep'
+ fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_fgrep" >&5
+echo "${ECHO_T}$ac_cv_prog_fgrep" >&6
+ FGREP=$ac_cv_prog_fgrep
+
+
+test -z "$GREP" && GREP=grep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# Check whether --with-gnu-ld or --without-gnu-ld was given.
if test "${with_gnu_ld+set}" = set; then
withval="$with_gnu_ld"
@@ -3631,8 +3955,8 @@ fi;
ac_prog=ld
if test "$GCC" = yes; then
# Check if gcc -print-prog-name=ld gives a path.
- echo "$as_me:$LINENO: checking for ld used by GCC" >&5
-echo $ECHO_N "checking for ld used by GCC... $ECHO_C" >&6
+ echo "$as_me:$LINENO: checking for ld used by $CC" >&5
+echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6
case $host in
*-*-mingw*)
# gcc leaves a trailing carriage return which upsets mingw
@@ -3642,12 +3966,12 @@ echo $ECHO_N "checking for ld used by GCC... $ECHO_C" >&6
esac
case $ac_prog in
# Accept absolute paths.
- [\\/]* | [A-Za-z]:[\\/]*)
+ [\\/]* | ?:[\\/]*)
re_direlt='/[^/][^/]*/\.\./'
- # Canonicalize the path of ld
- ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
- while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
- ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
done
test -z "$LD" && LD="$ac_prog"
;;
@@ -3671,22 +3995,26 @@ if test "${lt_cv_path_LD+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test -z "$LD"; then
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
for ac_dir in $PATH; do
+ IFS="$lt_save_ifs"
test -z "$ac_dir" && ac_dir=.
if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
lt_cv_path_LD="$ac_dir/$ac_prog"
# Check to see if the program is GNU ld. I'd rather use --version,
- # but apparently some GNU ld's only accept -v.
+ # but apparently some variants of GNU ld only accept -v.
# Break only if it was the GNU/non-GNU ld that we prefer.
- if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
test "$with_gnu_ld" != no && break
- else
+ ;;
+ *)
test "$with_gnu_ld" != yes && break
- fi
+ ;;
+ esac
fi
done
- IFS="$ac_save_ifs"
+ IFS="$lt_save_ifs"
else
lt_cv_path_LD="$LD" # Let the user override the test with a path.
fi
@@ -3708,32 +4036,31 @@ echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6
if test "${lt_cv_prog_gnu_ld+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- # I'd rather use --version here, but apparently some GNU ld's only accept -v.
-if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
lt_cv_prog_gnu_ld=yes
-else
+ ;;
+*)
lt_cv_prog_gnu_ld=no
-fi
+ ;;
+esac
fi
echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5
echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6
with_gnu_ld=$lt_cv_prog_gnu_ld
-echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5
-echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6
-if test "${lt_cv_ld_reload_flag+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_cv_ld_reload_flag='-r'
-fi
-echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5
-echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6
-reload_flag=$lt_cv_ld_reload_flag
-test -n "$reload_flag" && reload_flag=" $reload_flag"
-echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5
-echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6
+
+
+
+
+
+
+
+echo "$as_me:$LINENO: checking for BSD- or MS-compatible name lister (nm)" >&5
+echo $ECHO_N "checking for BSD- or MS-compatible name lister (nm)... $ECHO_C" >&6
if test "${lt_cv_path_NM+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
@@ -3741,35 +4068,173 @@ else
# Let the user override the test.
lt_cv_path_NM="$NM"
else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
- for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
- test -z "$ac_dir" && ac_dir=.
- tmp_nm=$ac_dir/${ac_tool_prefix}nm
- if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then
- # Check to see if the nm accepts a BSD-compat flag.
- # Adding the `sed 1q' prevents false positives on HP-UX, which says:
- # nm: unknown option "B" ignored
- # Tru64's nm complains that /dev/null is an invalid object file
- if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then
- lt_cv_path_NM="$tmp_nm -B"
- break
- elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
- lt_cv_path_NM="$tmp_nm -p"
- break
- else
- lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
- continue # so that we can try to find one that supports BSD flags
+ lt_nm_to_check="${ac_tool_prefix}nm"
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm="$ac_dir/$lt_tmp_nm"
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+ */dev/null* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
fi
- fi
+ done
+ IFS="$lt_save_ifs"
done
- IFS="$ac_save_ifs"
- test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
+ : ${lt_cv_path_NM=no}
+fi
+fi
+echo "$as_me:$LINENO: result: $lt_cv_path_NM" >&5
+echo "${ECHO_T}$lt_cv_path_NM" >&6
+if test "$lt_cv_path_NM" != "no"; then
+ NM="$lt_cv_path_NM"
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in "dumpbin -symbols" "link -dump -symbols"
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_DUMPBIN+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$DUMPBIN"; then
+ ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+ echo "$as_me:$LINENO: result: $DUMPBIN" >&5
+echo "${ECHO_T}$DUMPBIN" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$DUMPBIN" && break
+ done
+fi
+if test -z "$DUMPBIN"; then
+ ac_ct_DUMPBIN=$DUMPBIN
+ for ac_prog in "dumpbin -symbols" "link -dump -symbols"
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_DUMPBIN+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_DUMPBIN"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
fi
fi
+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+ echo "$as_me:$LINENO: result: $ac_ct_DUMPBIN" >&5
+echo "${ECHO_T}$ac_ct_DUMPBIN" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$ac_ct_DUMPBIN" && break
+done
+test -n "$ac_ct_DUMPBIN" || ac_ct_DUMPBIN=":"
-NM="$lt_cv_path_NM"
-echo "$as_me:$LINENO: result: $NM" >&5
-echo "${ECHO_T}$NM" >&6
+ DUMPBIN=$ac_ct_DUMPBIN
+fi
+
+
+ if test "$DUMPBIN" != ":"; then
+ NM="$DUMPBIN"
+ fi
+fi
+test -z "$NM" && NM=nm
+
+
+
+
+
+
+echo "$as_me:$LINENO: checking the name lister ($NM) interface" >&5
+echo $ECHO_N "checking the name lister ($NM) interface... $ECHO_C" >&6
+if test "${lt_cv_nm_interface+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:4223: $ac_compile\"" >&5)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:4226: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:4229: output\"" >&5)
+ cat conftest.out >&5
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*
+fi
+echo "$as_me:$LINENO: result: $lt_cv_nm_interface" >&5
+echo "${ECHO_T}$lt_cv_nm_interface" >&6
echo "$as_me:$LINENO: checking whether ln -s works" >&5
echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6
@@ -3782,8 +4247,234 @@ else
echo "${ECHO_T}no, using $LN_S" >&6
fi
-echo "$as_me:$LINENO: checking how to recognise dependant libraries" >&5
-echo $ECHO_N "checking how to recognise dependant libraries... $ECHO_C" >&6
+# find the maximum length of command line arguments
+echo "$as_me:$LINENO: checking the maximum length of command line arguments" >&5
+echo $ECHO_N "checking the maximum length of command line arguments... $ECHO_C" >&6
+if test "${lt_cv_sys_max_cmd_len+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ i=0
+ teststring="ABCD"
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`getconf ARG_MAX 2> /dev/null`
+ if test -n $lt_cv_sys_max_cmd_len; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8 ; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test "X"`$SHELL $0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \
+ = "XX$teststring$teststring"; } >/dev/null 2>&1 &&
+ test $i != 17 # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+
+fi
+
+if test -n $lt_cv_sys_max_cmd_len ; then
+ echo "$as_me:$LINENO: result: $lt_cv_sys_max_cmd_len" >&5
+echo "${ECHO_T}$lt_cv_sys_max_cmd_len" >&6
+else
+ echo "$as_me:$LINENO: result: none" >&5
+echo "${ECHO_T}none" >&6
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+
+
+
+
+
+
+: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+
+echo "$as_me:$LINENO: checking whether the shell understands some XSI constructs" >&5
+echo $ECHO_N "checking whether the shell understands some XSI constructs... $ECHO_C" >&6
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+ test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
+ = c,a/b,, ) >/dev/null 2>&1 \
+ && xsi_shell=yes
+echo "$as_me:$LINENO: result: $xsi_shell" >&5
+echo "${ECHO_T}$xsi_shell" >&6
+
+
+echo "$as_me:$LINENO: checking whether the shell understands \"+=\"" >&5
+echo $ECHO_N "checking whether the shell understands \"+=\"... $ECHO_C" >&6
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \
+ >/dev/null 2>&1 \
+ && lt_shell_append=yes
+echo "$as_me:$LINENO: result: $lt_shell_append" >&5
+echo "${ECHO_T}$lt_shell_append" >&6
+
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+
+
+
+
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5
+echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6
+if test "${lt_cv_ld_reload_flag+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ lt_cv_ld_reload_flag='-r'
+fi
+echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5
+echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ darwin*)
+ if test "$GCC" = yes; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+echo "$as_me:$LINENO: checking how to recognize dependent libraries" >&5
+echo $ECHO_N "checking how to recognize dependent libraries... $ECHO_C" >&6
if test "${lt_cv_deplibs_check_method+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
@@ -3796,13 +4487,13 @@ lt_cv_deplibs_check_method='unknown'
# `unknown' -- same as none, but documents that we really don't know.
# 'pass_all' -- all dependencies passed with no checks.
# 'test_compile' -- check by making test program.
-# 'file_magic [regex]' -- check by looking for files in library path
-# which responds to the $file_magic_cmd with a given egrep regex.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
# If you have `file' or equivalent on your system and you're not sure
# whether `pass_all' will *always* work, you probably want this one.
case $host_os in
-aix*)
+aix[4-9]*)
lt_cv_deplibs_check_method=pass_all
;;
@@ -3810,39 +4501,42 @@ beos*)
lt_cv_deplibs_check_method=pass_all
;;
-bsdi4*)
+bsdi[45]*)
lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
lt_cv_file_magic_cmd='/usr/bin/file -L'
lt_cv_file_magic_test_file=/shlib/libc.so
;;
-cygwin* | mingw* |pw32*)
- lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
- lt_cv_file_magic_cmd='$OBJDUMP -f'
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ if ( file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
;;
darwin* | rhapsody*)
- # this will be overwritten by pass_all, but leave it in just in case
- lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library'
- lt_cv_file_magic_cmd='/usr/bin/file -L'
- case "$host_os" in
- rhapsody* | darwin1.012)
- lt_cv_file_magic_test_file='/System/Library/Frameworks/System.framework/System'
- ;;
- *) # Darwin 1.3 on
- lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib'
- ;;
- esac
lt_cv_deplibs_check_method=pass_all
;;
-freebsd* | kfreebsd*-gnu)
- if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
case $host_cpu in
i*86 )
# Not sure whether the presence of OpenBSD here was a mistake.
# Let's accept both of them until this is cleared up.
- lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library'
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
lt_cv_file_magic_cmd=/usr/bin/file
lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
;;
@@ -3856,92 +4550,116 @@ gnu*)
lt_cv_deplibs_check_method=pass_all
;;
-hpux10.20*|hpux11*)
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
case $host_cpu in
- hppa*)
- lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
- lt_cv_file_magic_cmd=/usr/bin/file
- lt_cv_file_magic_test_file=/usr/lib/libc.sl
- ;;
ia64*)
lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
- lt_cv_file_magic_cmd=/usr/bin/file
lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
;;
- esac
- ;;
-
-irix5* | irix6*)
- case $host_os in
- irix5*)
- # this will be overridden with pass_all, but let us keep it just in case
- lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
+ hppa*64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
;;
*)
- case $LD in
- *-32|*"-32 ") libmagic=32-bit;;
- *-n32|*"-n32 ") libmagic=N32;;
- *-64|*"-64 ") libmagic=64-bit;;
- *) libmagic=never-match;;
- esac
- # this will be overridden with pass_all, but let us keep it just in case
- lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1"
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
;;
esac
- lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*`
+ ;;
+
+interix[3-9]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
lt_cv_deplibs_check_method=pass_all
;;
# This must be Linux ELF.
-linux-gnu*)
+linux* | k*bsd*-gnu)
lt_cv_deplibs_check_method=pass_all
;;
-netbsd* | knetbsd*-gnu)
- if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
- lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$'
+netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
else
- lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so$'
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
fi
;;
-newsos6)
+newos6*)
lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
lt_cv_file_magic_cmd=/usr/bin/file
lt_cv_file_magic_test_file=/usr/lib/libnls.so
;;
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ fi
+ ;;
+
osf3* | osf4* | osf5*)
- # this will be overridden with pass_all, but let us keep it just in case
- lt_cv_deplibs_check_method='file_magic COFF format alpha shared library'
- lt_cv_file_magic_test_file=/shlib/libc.so
lt_cv_deplibs_check_method=pass_all
;;
-sco3.2v5*)
+rdos*)
lt_cv_deplibs_check_method=pass_all
;;
solaris*)
lt_cv_deplibs_check_method=pass_all
- lt_cv_file_magic_test_file=/lib/libc.so
;;
-sysv5uw[78]* | sysv4*uw2*)
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
lt_cv_deplibs_check_method=pass_all
;;
-sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+sysv4 | sysv4.3*)
case $host_vendor in
- ncr)
- lt_cv_deplibs_check_method=pass_all
- ;;
motorola)
lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
esac
;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
esac
fi
@@ -3949,223 +4667,29 @@ echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5
echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6
file_magic_cmd=$lt_cv_file_magic_cmd
deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
-# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers!
-
-# find the maximum length of command line arguments
-echo "$as_me:$LINENO: checking the maximum length of command line arguments" >&5
-echo $ECHO_N "checking the maximum length of command line arguments... $ECHO_C" >&6
-if test "${lt_cv_sys_max_cmd_len+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- i=0
- teststring="ABCD"
-
- case $build_os in
- msdosdjgpp*)
- # On DJGPP, this test can blow up pretty badly due to problems in libc
- # (any single argument exceeding 2000 bytes causes a buffer overrun
- # during glob expansion). Even if it were fixed, the result of this
- # check would be larger than it should be.
- lt_cv_sys_max_cmd_len=12288; # 12K is about right
- ;;
-
- cygwin* | mingw*)
- # On Win9x/ME, this test blows up -- it succeeds, but takes
- # about 5 minutes as the teststring grows exponentially.
- # Worse, since 9x/ME are not pre-emptively multitasking,
- # you end up with a "frozen" computer, even though with patience
- # the test eventually succeeds (with a max line length of 256k).
- # Instead, let's just punt: use the minimum linelength reported by
- # all of the supported platforms: 8192 (on NT/2K/XP).
- lt_cv_sys_max_cmd_len=8192;
- ;;
-
- amigaos*)
- # On AmigaOS with pdksh, this test takes hours, literally.
- # So we just punt and use a minimum line length of 8192.
- lt_cv_sys_max_cmd_len=8192;
- ;;
-
- netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
- # This has been around since 386BSD, at least. Likely further.
- if test -x /sbin/sysctl; then
- lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
- elif test -x /usr/sbin/sysctl; then
- lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
- else
- lt_cv_sys_max_cmd_len=65536 # usable default for *BSD
- fi
- # And add a safety zone
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
- lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
- ;;
- esac
-
-fi
-
-if test -n "$lt_cv_sys_max_cmd_len" ; then
- echo "$as_me:$LINENO: result: $lt_cv_sys_max_cmd_len" >&5
-echo "${ECHO_T}$lt_cv_sys_max_cmd_len" >&6
-else
- echo "$as_me:$LINENO: result: none" >&5
-echo "${ECHO_T}none" >&6
-fi
-
-
-# Only perform the check for file, if the check method requires it
-case $deplibs_check_method in
-file_magic*)
- if test "$file_magic_cmd" = '$MAGIC_CMD'; then
- echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5
-echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6
-if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $MAGIC_CMD in
- /*)
- lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
- ;;
- ?:/*)
- lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path.
- ;;
- *)
- ac_save_MAGIC_CMD="$MAGIC_CMD"
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="/usr/bin:$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/${ac_tool_prefix}file; then
- lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
- if test -n "$file_magic_test_file"; then
- case $deplibs_check_method in
- "file_magic "*)
- file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
- MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
- if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
- egrep "$file_magic_regex" > /dev/null; then
- :
- else
- cat <<EOF 1>&2
-
-*** Warning: the command libtool uses to detect shared libraries,
-*** $file_magic_cmd, produces output that libtool cannot recognize.
-*** The result is that libtool may fail to recognize shared libraries
-*** as such. This will affect the creation of libtool libraries that
-*** depend on shared libraries, but programs linked with such libtool
-*** libraries will work regardless of this problem. Nevertheless, you
-*** may want to report the problem to your system manager and/or to
-*** bug-libtool@gnu.org
-EOF
- fi ;;
- esac
- fi
- break
- fi
- done
- IFS="$ac_save_ifs"
- MAGIC_CMD="$ac_save_MAGIC_CMD"
- ;;
-esac
-fi
-
-MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
-if test -n "$MAGIC_CMD"; then
- echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
-echo "${ECHO_T}$MAGIC_CMD" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-if test -z "$lt_cv_path_MAGIC_CMD"; then
- if test -n "$ac_tool_prefix"; then
- echo "$as_me:$LINENO: checking for file" >&5
-echo $ECHO_N "checking for file... $ECHO_C" >&6
-if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- case $MAGIC_CMD in
- /*)
- lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
- ;;
- ?:/*)
- lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path.
- ;;
- *)
- ac_save_MAGIC_CMD="$MAGIC_CMD"
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="/usr/bin:$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/file; then
- lt_cv_path_MAGIC_CMD="$ac_dir/file"
- if test -n "$file_magic_test_file"; then
- case $deplibs_check_method in
- "file_magic "*)
- file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
- MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
- if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
- egrep "$file_magic_regex" > /dev/null; then
- :
- else
- cat <<EOF 1>&2
-*** Warning: the command libtool uses to detect shared libraries,
-*** $file_magic_cmd, produces output that libtool cannot recognize.
-*** The result is that libtool may fail to recognize shared libraries
-*** as such. This will affect the creation of libtool libraries that
-*** depend on shared libraries, but programs linked with such libtool
-*** libraries will work regardless of this problem. Nevertheless, you
-*** may want to report the problem to your system manager and/or to
-*** bug-libtool@gnu.org
-EOF
- fi ;;
- esac
- fi
- break
- fi
- done
- IFS="$ac_save_ifs"
- MAGIC_CMD="$ac_save_MAGIC_CMD"
- ;;
-esac
-fi
-MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
-if test -n "$MAGIC_CMD"; then
- echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
-echo "${ECHO_T}$MAGIC_CMD" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
- else
- MAGIC_CMD=:
- fi
-fi
- fi
- ;;
-esac
if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
-set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+ # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_RANLIB+set}" = set; then
+if test "${ac_cv_prog_AR+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- if test -n "$RANLIB"; then
- ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
@@ -4174,7 +4698,7 @@ do
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ ac_cv_prog_AR="${ac_tool_prefix}ar"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
@@ -4183,27 +4707,27 @@ done
fi
fi
-RANLIB=$ac_cv_prog_RANLIB
-if test -n "$RANLIB"; then
- echo "$as_me:$LINENO: result: $RANLIB" >&5
-echo "${ECHO_T}$RANLIB" >&6
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ echo "$as_me:$LINENO: result: $AR" >&5
+echo "${ECHO_T}$AR" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
fi
-if test -z "$ac_cv_prog_RANLIB"; then
- ac_ct_RANLIB=$RANLIB
- # Extract the first word of "ranlib", so it can be a program name with args.
-set dummy ranlib; ac_word=$2
+if test -z "$ac_cv_prog_AR"; then
+ ac_ct_AR=$AR
+ # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+if test "${ac_cv_prog_ac_ct_AR+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- if test -n "$ac_ct_RANLIB"; then
- ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
@@ -4212,30 +4736,43 @@ do
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_ac_ct_RANLIB="ranlib"
+ ac_cv_prog_ac_ct_AR="ar"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
- test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+ test -z "$ac_cv_prog_ac_ct_AR" && ac_cv_prog_ac_ct_AR="false"
fi
fi
-ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
-if test -n "$ac_ct_RANLIB"; then
- echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
-echo "${ECHO_T}$ac_ct_RANLIB" >&6
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ echo "$as_me:$LINENO: result: $ac_ct_AR" >&5
+echo "${ECHO_T}$ac_ct_AR" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
- RANLIB=$ac_ct_RANLIB
+ AR=$ac_ct_AR
else
- RANLIB="$ac_cv_prog_RANLIB"
+ AR="$ac_cv_prog_AR"
fi
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+
+
+
+
+
+
+
+
+
+
+
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
set dummy ${ac_tool_prefix}strip; ac_word=$2
@@ -4316,96 +4853,472 @@ else
STRIP="$ac_cv_prog_STRIP"
fi
+test -z "$STRIP" && STRIP=:
-# Check for any special flags to pass to ltconfig.
-libtool_flags="--cache-file=$cache_file"
-test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
-test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
-test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
-test "$GCC" = yes && libtool_flags="$libtool_flags --with-gcc"
-test "$lt_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
-# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
-if test "${enable_libtool_lock+set}" = set; then
- enableval="$enable_libtool_lock"
-fi;
-test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
-test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
-# Check whether --with-pic or --without-pic was given.
-if test "${with_pic+set}" = set; then
- withval="$with_pic"
- pic_mode="$withval"
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- pic_mode=default
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ RANLIB=$ac_ct_RANLIB
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+test -z "$RANLIB" && RANLIB=:
+
+
+
+
+
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+echo "$as_me:$LINENO: checking command to parse $NM output from $compiler object" >&5
+echo $ECHO_N "checking command to parse $NM output from $compiler object... $ECHO_C" >&6
+if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[BCDT]'
+ ;;
+cygwin* | mingw* | pw32*)
+ symcode='[ABCDGISTW]'
+ ;;
+hpux*)
+ if test "$host_cpu" = ia64; then
+ symcode='[ABCDEGRST]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[BCDEGRST]'
+ ;;
+osf*)
+ symcode='[BCDEGQRST]'
+ ;;
+solaris*)
+ symcode='[BDRT]'
+ ;;
+sco3.2v5*)
+ symcode='[DT]'
+ ;;
+sysv4.2uw2*)
+ symcode='[DT]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[ABDT]'
+ ;;
+sysv4)
+ symcode='[DFNSTU]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[ABCDGIRSTW]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function
+ # and D for any global variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK '"\
+" {last_section=section; section=\$ 3};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+" s[1]~/^[@?]/{print s[1], s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if { (eval echo "$as_me:$LINENO: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\"") >&5
+ (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_save_LIBS="$LIBS"
+ lt_save_CFLAGS="$CFLAGS"
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && test -s conftest${ac_exeext}; then
+ pipe_works=yes
+ fi
+ LIBS="$lt_save_LIBS"
+ CFLAGS="$lt_save_CFLAGS"
+ else
+ echo "cannot find nm_test_func in $nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&5
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ fi
+ rm -f conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ echo "$as_me:$LINENO: result: failed" >&5
+echo "${ECHO_T}failed" >&6
+else
+ echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+ enableval="$enable_libtool_lock"
+
fi;
-test x"$pic_mode" = xyes && libtool_flags="$libtool_flags --prefer-pic"
-test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic"
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
# Some flags need to be propagated to the compiler or linker for good
# libtool support.
case $host in
-*-*-irix6*)
+ia64-*-hpux*)
# Find out which ABI we are using.
- echo '#line 4353 "configure"' > conftest.$ac_ext
+ echo 'int i;' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; then
- if test "$lt_cv_prog_gnu_ld" = yes; then
case `/usr/bin/file conftest.$ac_objext` in
- *32-bit*)
- LD="${LD-ld} -melf32bsmip"
- ;;
- *N32*)
- LD="${LD-ld} -melf32bmipn32"
- ;;
- *64-bit*)
- LD="${LD-ld} -melf64bmip"
- ;;
- esac
- else
- case `/usr/bin/file conftest.$ac_objext` in
- *32-bit*)
- LD="${LD-ld} -32"
- ;;
- *N32*)
- LD="${LD-ld} -n32"
- ;;
- *64-bit*)
- LD="${LD-ld} -64"
- ;;
+ *ELF-32*)
+ HPUX_IA64_MODE="32"
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE="64"
+ ;;
esac
- fi
fi
rm -rf conftest*
;;
-
-ia64-*-hpux*)
+*-*-irix6*)
# Find out which ABI we are using.
- echo 'int i;' > conftest.$ac_ext
+ echo '#line 5285 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; then
- case "`/usr/bin/file conftest.o`" in
- *ELF-32*)
- HPUX_IA64_MODE="32"
- ;;
- *ELF-64*)
- HPUX_IA64_MODE="64"
- ;;
- esac
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
fi
rm -rf conftest*
;;
-x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
# Find out which ABI we are using.
echo 'int i;' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
@@ -4413,39 +5326,45 @@ x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; then
- case "`/usr/bin/file conftest.o`" in
- *32-bit*)
- case $host in
- x86_64-*linux*)
- LD="${LD-ld} -m elf_i386"
- ;;
- ppc64-*linux*|powerpc64-*linux*)
- LD="${LD-ld} -m elf32ppclinux"
- ;;
- s390x-*linux*)
- LD="${LD-ld} -m elf_s390"
- ;;
- sparc64-*linux*)
- LD="${LD-ld} -m elf32_sparc"
- ;;
- esac
- ;;
- *64-bit*)
- case $host in
- x86_64-*linux*)
- LD="${LD-ld} -m elf_x86_64"
- ;;
- ppc*-*linux*|powerpc*-*linux*)
- LD="${LD-ld} -m elf64ppc"
- ;;
- s390*-*linux*)
- LD="${LD-ld} -m elf64_s390"
- ;;
- sparc*-*linux*)
- LD="${LD-ld} -m elf64_sparc"
- ;;
- esac
- ;;
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ ppc64-*linux*|powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ ppc*-*linux*|powerpc*-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
esac
fi
rm -rf conftest*
@@ -4460,9 +5379,7 @@ echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6
if test "${lt_cv_cc_needs_belf+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
-
-
- ac_ext=c
+ ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
@@ -4528,114 +5445,4553 @@ echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6
CFLAGS="$SAVE_CFLAGS"
fi
;;
+sparc*-*solaris*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*) LD="${LD-ld} -m elf64_sparc" ;;
+ *) LD="${LD-ld} -64" ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks="$enable_libtool_lock"
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if test "${ac_cv_prog_CPP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether non-existent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether non-existent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ :
+else
+ { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_header_stdc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then
+ :
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ exit(2);
+ exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_Header=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+for ac_header in dlfcn.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_Header=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test -z "$LN_S" && LN_S="ln -s"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+echo "$as_me:$LINENO: checking for objdir" >&5
+echo $ECHO_N "checking for objdir... $ECHO_C" >&6
+if test "${lt_cv_objdir+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+echo "$as_me:$LINENO: result: $lt_cv_objdir" >&5
+echo "${ECHO_T}$lt_cv_objdir" >&6
+objdir=$lt_cv_objdir
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LT_OBJDIR "$lt_cv_objdir/"
+_ACEOF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+for cc_temp in $compiler""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5
+echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/${ac_tool_prefix}file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
+echo "${ECHO_T}$MAGIC_CMD" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ echo "$as_me:$LINENO: checking for file" >&5
+echo $ECHO_N "checking for file... $ECHO_C" >&6
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
+echo "${ECHO_T}$MAGIC_CMD" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+
+ else
+ MAGIC_CMD=:
+ fi
+fi
+
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+
+lt_save_CC="$CC"
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM conftest*
+
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+ lt_prog_compiler_no_builtin_flag=' -fno-builtin'
+
+ echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6
+if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ lt_cv_prog_compiler_rtti_exceptions=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="-fno-rtti -fno-exceptions"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:6385: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:6389: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_rtti_exceptions=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6
+
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
+ lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+ :
+fi
+
+fi
+
+
+
+
+
+
+ lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
+echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
+
+ if test "$GCC" = yes; then
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_static='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ if test "$host_cpu" = m68k; then
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+ fi
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic='-fno-common'
+ ;;
+
+ hpux*)
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[3-9]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ lt_prog_compiler_can_build_shared=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ lt_prog_compiler_wl='-Wl,'
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ else
+ lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+ darwin*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ case $cc_basename in
+ xlc*)
+ lt_prog_compiler_pic='-qnocommon'
+ lt_prog_compiler_wl='-Wl,'
+ ;;
+ esac
+ ;;
+
+ mingw* | cygwin* | pw32* | os2*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ lt_prog_compiler_static='${wl}-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC (with -KPIC) is the default.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu)
+ case $cc_basename in
+ icc* | ecc*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ ccc*)
+ lt_prog_compiler_wl='-Wl,'
+ # All Alpha code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C 5.9
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Wl,'
+ ;;
+ *Sun\ F*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl=''
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ lt_prog_compiler_wl='-Wl,'
+ # All OSF/1 code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ rdos*)
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ solaris*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95*)
+ lt_prog_compiler_wl='-Qoption ld ';;
+ *)
+ lt_prog_compiler_wl='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ lt_prog_compiler_wl='-Qoption ld '
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ lt_prog_compiler_pic='-Kconform_pic'
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ unicos*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_can_build_shared=no
+ ;;
+
+ uts4*)
+ lt_prog_compiler_pic='-pic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *)
+ lt_prog_compiler_can_build_shared=no
+ ;;
+ esac
+ fi
+
+case $host_os in
+ # For platforms which do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ lt_prog_compiler_pic=
+ ;;
+ *)
+ lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+ ;;
+esac
+echo "$as_me:$LINENO: result: $lt_prog_compiler_pic" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic" >&6
+
+
+
+
-# Save cache, so that ltconfig can load it
-cat >confcache <<\_ACEOF
-# This file is a shell script that caches the results of configure
-# tests run on this system so they can be shared between configure
-# scripts and configure runs, see configure's option --config-cache.
-# It is not useful on other systems. If it contains results you don't
-# want to keep, you may remove or edit it.
#
-# config.status only pays attention to the cache file if you give it
-# the --recheck option to rerun configure.
+# Check to make sure the PIC flag actually works.
#
-# `ac_cv_env_foo' variables (set or unset) will be overridden when
-# loading this file, other *unset* `ac_cv_foo' will be assigned the
-# following values.
+if test -n "$lt_prog_compiler_pic"; then
+ echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic works... $ECHO_C" >&6
+if test "${lt_prog_compiler_pic_works+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ lt_prog_compiler_pic_works=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:6707: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:6711: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_prog_compiler_pic_works=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_works" >&6
+
+if test x"$lt_prog_compiler_pic_works" = xyes; then
+ case $lt_prog_compiler_pic in
+ "" | " "*) ;;
+ *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+ esac
+else
+ lt_prog_compiler_pic=
+ lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6
+if test "${lt_prog_compiler_static_works+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ lt_prog_compiler_static_works=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_prog_compiler_static_works=yes
+ fi
+ else
+ lt_prog_compiler_static_works=yes
+ fi
+ fi
+ $RM conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works" >&5
+echo "${ECHO_T}$lt_prog_compiler_static_works" >&6
+
+if test x"$lt_prog_compiler_static_works" = xyes; then
+ :
+else
+ lt_prog_compiler_static=
+fi
+
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
+echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6
+if test "${lt_cv_prog_compiler_c_o+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:6812: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:6816: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_c_o" >&6
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
+echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6
+if test "${lt_cv_prog_compiler_c_o+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:6867: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:6871: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_c_o" >&6
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
+echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ echo "$as_me:$LINENO: result: $hard_links" >&5
+echo "${ECHO_T}$hard_links" >&6
+ if test "$hard_links" = no; then
+ { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6
+
+ runpath_var=
+ allow_undefined_flag=
+ always_export_symbols=no
+ archive_cmds=
+ archive_expsym_cmds=
+ compiler_needs_object=no
+ enable_shared_with_static_runtimes=no
+ export_dynamic_flag_spec=
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ hardcode_automatic=no
+ hardcode_direct=no
+ hardcode_direct_absolute=no
+ hardcode_libdir_flag_spec=
+ hardcode_libdir_flag_spec_ld=
+ hardcode_libdir_separator=
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=unsupported
+ inherit_rpath=no
+ link_all_deplibs=unknown
+ module_cmds=
+ module_expsym_cmds=
+ old_archive_from_new_cmds=
+ old_archive_from_expsyms_cmds=
+ thread_safe_flag_spec=
+ whole_archive_flag_spec=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ include_expsyms=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ` (' and `)$', so one must not match beginning or
+ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+ # as well as any symbol that contains `d'.
+ exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+ esac
+
+ ld_shlibs=yes
+ if test "$with_gnu_ld" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ export_dynamic_flag_spec='${wl}--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ whole_archive_flag_spec=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[3-9]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ if test "$host_cpu" = m68k; then
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ fi
+
+ # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+ # that the semantics of dynamic libraries on AmigaOS, at least up
+ # to version 4, is to share data among multiple programs linked
+ # with the same dynamic library. Since this doesn't match the
+ # behavior of shared libraries on other platforms, we can't use
+ # them.
+ ld_shlibs=no
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+ # as there is no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ allow_undefined_flag=unsupported
+ always_export_symbols=no
+ enable_shared_with_static_runtimes=yes
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ interix[3-9]*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu)
+ tmp_diet=no
+ if test "$host_os" = linux-dietlibc; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test "$tmp_diet" = no
+ then
+ tmp_addflag=
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ compiler_needs_object=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ *)
+ tmp_sharedflag='-shared' ;;
+ esac
+ archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+
+ if test "$ld_shlibs" = no; then
+ runpath_var=
+ hardcode_libdir_flag_spec=
+ export_dynamic_flag_spec=
+ whole_archive_flag_spec=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ archive_cmds=''
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ file_list_spec='${wl}-f,'
+
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ always_export_symbols=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
-# The following way of writing the cache mishandles newlines in values,
-# but we know of no workaround that is simple, portable, and efficient.
-# So, don't put newlines in cache variables' values.
-# Ultrix sh set writes to stderr and can't be redirected directly,
-# and sets the high bit in the cache file unless we assign to the vars.
+int
+main ()
{
- (set) 2>&1 |
- case `(ac_space=' '; set | grep ac_space) 2>&1` in
- *ac_space=\ *)
- # `set' does not quote correctly, so add quotes (double-quote
- # substitution turns \\\\ into \\, and sed turns \\ into \).
- sed -n \
- "s/'/'\\\\''/g;
- s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+
+lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\(.*\)$/\1/
+ p
+ }
+ }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag="-z nodefs"
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+
+lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\(.*\)$/\1/
+ p
+ }
+ }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ no_undefined_flag=' ${wl}-bernotok'
+ allow_undefined_flag=' ${wl}-berok'
+ # Exported symbols can be pulled into shared objects from archives
+ whole_archive_flag_spec='$convenience'
+ archive_cmds_need_lc=yes
+ # This is similar to how AIX traditionally builds its shared libraries.
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ if test "$host_cpu" = m68k; then
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ fi
+ # see comment about different semantics on the GNU ld section
+ ld_shlibs=no
+ ;;
+
+ bsdi[45]*)
+ export_dynamic_flag_spec=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ fix_srcfile_path='`cygpath -w "$srcfile"`'
+ enable_shared_with_static_runtimes=yes
+ ;;
+
+ darwin* | rhapsody*)
+ case $host_os in
+ rhapsody* | darwin1.[012])
+ allow_undefined_flag='${wl}-undefined ${wl}suppress'
+ ;;
+ *) # Darwin 1.3 on
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
+ 10.[012])
+ allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+ ;;
+ 10.*)
+ allow_undefined_flag='${wl}-undefined ${wl}dynamic_lookup'
+ ;;
+ esac
+ ;;
+ esac
+ archive_cmds_need_lc=no
+ hardcode_direct=no
+ hardcode_automatic=yes
+ hardcode_shlibpath_var=unsupported
+ whole_archive_flag_spec=''
+ link_all_deplibs=yes
+ if test "$GCC" = yes ; then
+ if test "${lt_cv_apple_cc_single_mod+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ lt_cv_apple_cc_single_mod=no
+ if test -z "${LT_MULTI_MODULE}"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi-module to the
+ # link flags.
+ echo "int foo(void){return 1;}" > conftest.c
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib ${wl}-single_module conftest.c
+ if test -f libconftest.dylib; then
+ lt_cv_apple_cc_single_mod=yes
+ rm libconftest.dylib
+ fi
+ rm conftest.$ac_ext
+ fi
+fi
+
+ output_verbose_link_cmd=echo
+ if test "X$lt_cv_apple_cc_single_mod" = Xyes ; then
+ archive_cmds='$CC -dynamiclib $single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+ archive_expsym_cmds='sed "s,^,_," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $single_module -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ else
+ archive_cmds='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+ archive_expsym_cmds='sed "s,^,_," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ fi
+ module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+ module_expsym_cmds='sed -e "s,^,_," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ else
+ case $cc_basename in
+ xlc*)
+ output_verbose_link_cmd=echo
+ archive_cmds='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`$ECHO $rpath/$soname` $verstring'
+ module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+ archive_expsym_cmds='sed "s,^,_," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ module_expsym_cmds='sed "s,^,_," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ ;;
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+ fi
+ ;;
+
+ dgux*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ freebsd1*)
+ ld_shlibs=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ hpux9*)
+ if test "$GCC" = yes; then
+ archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ export_dynamic_flag_spec='${wl}-E'
+ ;;
+
+ hpux10*)
+ if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+ archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_flag_spec_ld='+b $libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='${wl}-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ ;;
+ *)
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='${wl}-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+ cat >conftest.$ac_ext <<_ACEOF
+int foo(void) {}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$save_LDFLAGS"
+ else
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ inherit_rpath=yes
+ link_all_deplibs=yes
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ newsos6)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_shlibpath_var=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd*)
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ hardcode_direct_absolute=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
+ else
+ case $host_os in
+ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_separator=:
+ ;;
+
+ solaris*)
+ no_undefined_flag=' -z defs'
+ if test "$GCC" = yes; then
+ wlarc='${wl}'
+ archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='${wl}'
+ archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_shlibpath_var=no
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'. GCC discards it without `$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test "$GCC" = yes; then
+ whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ else
+ whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ link_all_deplibs=yes
+ ;;
+
+ sunos4*)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ reload_cmds='$CC -r -o $output$reload_objs'
+ hardcode_direct=no
+ ;;
+ motorola)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
;;
+
+ sysv4.3*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ export_dynamic_flag_spec='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ld_shlibs=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ no_undefined_flag='${wl}-z,text'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ no_undefined_flag='${wl}-z,text'
+ allow_undefined_flag='${wl}-z,nodefs'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='${wl}-R,$libdir'
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ export_dynamic_flag_spec='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
*)
- # `set' quotes correctly as required by POSIX, so do not add quotes.
- sed -n \
- "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ld_shlibs=no
;;
- esac;
-} |
- sed '
- t clear
- : clear
- s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
- t end
- /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
- : end' >>confcache
-if diff $cache_file confcache >/dev/null 2>&1; then :; else
- if test -w $cache_file; then
- test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
- cat confcache >$cache_file
+ esac
+
+ if test x$host_vendor = xsni; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ export_dynamic_flag_spec='${wl}-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+
+echo "$as_me:$LINENO: result: $ld_shlibs" >&5
+echo "${ECHO_T}$ld_shlibs" >&6
+test "$ld_shlibs" = no && can_build_shared=no
+
+with_gnu_ld=$with_gnu_ld
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+ # Assume -lc should be added
+ archive_cmds_need_lc=yes
+
+ if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $archive_cmds in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
+echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_prog_compiler_wl
+ pic_flag=$lt_prog_compiler_pic
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$allow_undefined_flag
+ allow_undefined_flag=
+ if { (eval echo "$as_me:$LINENO: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\"") >&5
+ (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+ then
+ archive_cmds_need_lc=no
+ else
+ archive_cmds_need_lc=yes
+ fi
+ allow_undefined_flag=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+ echo "$as_me:$LINENO: result: $archive_cmds_need_lc" >&5
+echo "${ECHO_T}$archive_cmds_need_lc" >&6
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
+echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6
+withGCC=$GCC
+if test "$withGCC" = yes; then
+ case $host_os in
+ darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+ *) lt_awk_arg="/^libraries:/" ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+ if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'`
else
- echo "not updating unwritable cache $cache_file"
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary.
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+ else
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+ lt_foo="";
+ lt_count=0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo="/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[lt_foo]++; }
+ if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+ sys_lib_search_path_spec=`$ECHO $lt_search_path_spec`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+
+aix[4-9]*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[01] | aix4.[01].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ if test "$host_cpu" = m68k; then
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ else
+ dynamic_linker=no
+ fi
+ ;;
+
+beos*)
+ library_names_spec='${libname}${shared_ext}'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[45]*)
+ version_type=linux
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32*)
+ version_type=windows
+ shrext_cmds=".dll"
+ need_version=no
+ need_lib_prefix=no
+
+ case $withGCC,$host_os in
+ yes,cygwin* | yes,mingw* | yes,pw32*)
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+ ;;
+ mingw*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+ # It is most probably a Windows format PATH printed by
+ # mingw gcc, but we are running on Cygwin. Gcc prints its search
+ # path with ; separators, and with drive letters. We can handle the
+ # drive letters (cygwin fileutils understands them), so leave them,
+ # especially as we might pass files found there to a mingw objdump,
+ # which wouldn't understand a cygwinified path. Ahh.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ esac
+ ;;
+
+ *)
+ library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+ soname_spec='${libname}${release}${major}$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd1*)
+ dynamic_linker=no
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[123]*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[01]* | freebsdelf3.[01]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ if test "X$HPUX_IA64_MODE" = X32; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555.
+ postinstall_cmds='chmod 555 $lib'
+ ;;
+
+interix[3-9]*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ version_type=linux
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ # Some binutils ld are patched to set DT_RUNPATH
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir"; then
+ shlibpath_overrides_runpath=yes
+fi
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
+ need_lib_prefix=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case $host_os in
+ openbsd2.[89] | openbsd2.[89].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ ;;
+
+os2*)
+ libname_spec='$name'
+ shrext_cmds=".dll"
+ need_lib_prefix=no
+ library_names_spec='$libname${shared_ext} $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux
+ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+ soname_spec='$libname${shared_ext}.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_name_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+echo "$as_me:$LINENO: result: $dynamic_linker" >&5
+echo "${ECHO_T}$dynamic_linker" >&6
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
fi
-rm -f confcache
-# Actually configure libtool. ac_aux_dir is where install-sh is found.
-AR="$AR" LTCC="$CC" CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
-MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
-LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \
-AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \
-objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \
-deplibs_check_method="$deplibs_check_method" file_magic_cmd="$file_magic_cmd" \
-${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
-$libtool_flags --no-verify --build="$build" $ac_aux_dir/ltmain.sh $host \
-|| { { echo "$as_me:$LINENO: error: libtool configure failed" >&5
-echo "$as_me: error: libtool configure failed" >&2;}
- { (exit 1); exit 1; }; }
-# Reload cache, that may have been modified by ltconfig
-if test -r "$cache_file"; then
- # Some versions of bash will fail to source /dev/null (special
- # files actually), so we avoid doing that.
- if test -f "$cache_file"; then
- { echo "$as_me:$LINENO: loading cache $cache_file" >&5
-echo "$as_me: loading cache $cache_file" >&6;}
- case $cache_file in
- [\\/]* | ?:[\\/]* ) . $cache_file;;
- *) . ./$cache_file;;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
+echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" ||
+ test -n "$runpath_var" ||
+ test "X$hardcode_automatic" = "Xyes" ; then
+
+ # We can hardcode non-existent directories.
+ if test "$hardcode_direct" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no &&
+ test "$hardcode_minus_L" != no; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action=unsupported
+fi
+echo "$as_me:$LINENO: result: $hardcode_action" >&5
+echo "${ECHO_T}$hardcode_action" >&6
+
+if test "$hardcode_action" = relink ||
+ test "$inherit_rpath" = yes; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+
+
+
+
+
+ if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32*)
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen="dlopen"
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlopen ();
+int
+main ()
+{
+dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_dl_dlopen=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dl_dlopen=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
+if test $ac_cv_lib_dl_dlopen = yes; then
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+
+ lt_cv_dlopen="dyld"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+
+fi
+
+ ;;
+
+ *)
+ echo "$as_me:$LINENO: checking for shl_load" >&5
+echo $ECHO_N "checking for shl_load... $ECHO_C" >&6
+if test "${ac_cv_func_shl_load+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define shl_load to an innocuous variant, in case <limits.h> declares shl_load.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define shl_load innocuous_shl_load
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char shl_load (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef shl_load
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char shl_load ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_shl_load) || defined (__stub___shl_load)
+choke me
+#else
+char (*f) () = shl_load;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != shl_load;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_func_shl_load=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_shl_load=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5
+echo "${ECHO_T}$ac_cv_func_shl_load" >&6
+if test $ac_cv_func_shl_load = yes; then
+ lt_cv_dlopen="shl_load"
+else
+ echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
+echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char shl_load ();
+int
+main ()
+{
+shl_load ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_dld_shl_load=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dld_shl_load=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6
+if test $ac_cv_lib_dld_shl_load = yes; then
+ lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"
+else
+ echo "$as_me:$LINENO: checking for dlopen" >&5
+echo $ECHO_N "checking for dlopen... $ECHO_C" >&6
+if test "${ac_cv_func_dlopen+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define dlopen to an innocuous variant, in case <limits.h> declares dlopen.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define dlopen innocuous_dlopen
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char dlopen (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef dlopen
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlopen ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_dlopen) || defined (__stub___dlopen)
+choke me
+#else
+char (*f) () = dlopen;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != dlopen;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_func_dlopen=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_dlopen=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5
+echo "${ECHO_T}$ac_cv_func_dlopen" >&6
+if test $ac_cv_func_dlopen = yes; then
+ lt_cv_dlopen="dlopen"
+else
+ echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlopen ();
+int
+main ()
+{
+dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_dl_dlopen=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dl_dlopen=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
+if test $ac_cv_lib_dl_dlopen = yes; then
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+ echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5
+echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6
+if test "${ac_cv_lib_svld_dlopen+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlopen ();
+int
+main ()
+{
+dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_svld_dlopen=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_svld_dlopen=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6
+if test $ac_cv_lib_svld_dlopen = yes; then
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+ echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5
+echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6
+if test "${ac_cv_lib_dld_dld_link+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dld_link ();
+int
+main ()
+{
+dld_link ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_dld_dld_link=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dld_dld_link=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6
+if test $ac_cv_lib_dld_dld_link = yes; then
+ lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+ ;;
+ esac
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ else
+ enable_dlopen=no
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS="$CPPFLAGS"
+ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS="$LDFLAGS"
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS="$LIBS"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5
+echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6
+if test "${lt_cv_dlopen_self+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test "$cross_compiling" = yes; then :
+ lt_cv_dlopen_self=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line 9664 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ exit (status);
+}
+_LT_EOF
+ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self=no
fi
+fi
+rm -fr conftest*
+
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5
+echo "${ECHO_T}$lt_cv_dlopen_self" >&6
+
+ if test "x$lt_cv_dlopen_self" = xyes; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5
+echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6
+if test "${lt_cv_dlopen_self_static+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- { echo "$as_me:$LINENO: creating cache $cache_file" >&5
-echo "$as_me: creating cache $cache_file" >&6;}
- >$cache_file
+ if test "$cross_compiling" = yes; then :
+ lt_cv_dlopen_self_static=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line 9764 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ exit (status);
+}
+_LT_EOF
+ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self_static=no
+ fi
fi
+rm -fr conftest*
+
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5
+echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6
+ fi
+
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+striplib=
+old_striplib=
+echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5
+echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP" ; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+ else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ fi
+ ;;
+ *)
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+ # Report which library types will actually be built
+ echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5
+echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6
+ echo "$as_me:$LINENO: result: $can_build_shared" >&5
+echo "${ECHO_T}$can_build_shared" >&6
+
+ echo "$as_me:$LINENO: checking whether to build shared libraries" >&5
+echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ echo "$as_me:$LINENO: result: $enable_shared" >&5
+echo "${ECHO_T}$enable_shared" >&6
+
+ echo "$as_me:$LINENO: checking whether to build static libraries" >&5
+echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ echo "$as_me:$LINENO: result: $enable_static" >&5
+echo "${ECHO_T}$enable_static" >&6
+
+
+
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC="$lt_save_CC"
+
+
+
-# This can be used to rebuild libtool when needed
-LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh $ac_aux_dir/ltcf-c.sh"
-# Always use our own libtool.
-LIBTOOL='$(SHELL) $(top_builddir)/libtool'
-# Redirect the config.log output again, so that the ltconfig log is not
-# clobbered by the next message.
-exec 5>>./config.log
+ ac_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
@@ -4760,7 +10116,7 @@ fi
# Provide some information about the compiler.
-echo "$as_me:4763:" \
+echo "$as_me:10119:" \
"checking for Fortran compiler version" >&5
ac_compiler=`set X $ac_compile; echo $2`
{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
@@ -4903,241 +10259,2926 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
-FCFLAGS="$FCFLAGS -Wall"
-# For libtool versioning info, format is CURRENT:REVISION:AGE
-libtool_VERSION=1:0:0
+ac_ext=${FC_SRCEXT-f}
+ac_compile='$FC -c $FCFLAGS $FCFLAGS_SRCEXT conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $FCFLAGS_SRCEXT conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ for ac_prog in f95 fort xlf95 ifc efc pgf95 lf95 gfortran f90 xlf90 pgf90 epcf90 g77 f77 xlf frt pgf77 fort77 fl32 af77
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_FC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$FC"; then
+ ac_cv_prog_FC="$FC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_FC="$ac_tool_prefix$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+fi
+fi
+FC=$ac_cv_prog_FC
+if test -n "$FC"; then
+ echo "$as_me:$LINENO: result: $FC" >&5
+echo "${ECHO_T}$FC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
-# Check header files.
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
-echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
- CPP=
+ test -n "$FC" && break
+ done
fi
-if test -z "$CPP"; then
- if test "${ac_cv_prog_CPP+set}" = set; then
+if test -z "$FC"; then
+ ac_ct_FC=$FC
+ for ac_prog in f95 fort xlf95 ifc efc pgf95 lf95 gfortran f90 xlf90 pgf90 epcf90 g77 f77 xlf frt pgf77 fort77 fl32 af77
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_FC+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- # Double quotes because CPP needs to be expanded
- for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
- do
- ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
+ if test -n "$ac_ct_FC"; then
+ ac_cv_prog_ac_ct_FC="$ac_ct_FC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_FC="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_FC=$ac_cv_prog_ac_ct_FC
+if test -n "$ac_ct_FC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_FC" >&5
+echo "${ECHO_T}$ac_ct_FC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$ac_ct_FC" && break
+done
+
+ FC=$ac_ct_FC
+fi
+
+
+# Provide some information about the compiler.
+echo "$as_me:10355:" \
+ "checking for Fortran compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+ (eval $ac_compiler --version </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+ (eval $ac_compiler -v </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+ (eval $ac_compiler -V </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+rm -f a.out
+
+# If we don't use `.F' as extension, the preprocessor is not run on the
+# input file. (Note that this only needs to work for GNU compilers.)
+ac_save_ext=$ac_ext
+ac_ext=F
+echo "$as_me:$LINENO: checking whether we are using the GNU Fortran compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU Fortran compiler... $ECHO_C" >&6
+if test "${ac_cv_fc_compiler_gnu+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
+ program main
+#ifndef __GNUC__
+ choke me
#endif
- Syntax error
+
+ end
_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- :
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_fc_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_compiler_gnu=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
- # Broken: fails on valid input.
-continue
+ac_compiler_gnu=no
fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_fc_compiler_gnu=$ac_compiler_gnu
- # OK, works on sane cases. Now check whether non-existent headers
- # can be detected and how.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
+fi
+echo "$as_me:$LINENO: result: $ac_cv_fc_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_fc_compiler_gnu" >&6
+ac_ext=$ac_save_ext
+ac_test_FFLAGS=${FCFLAGS+set}
+ac_save_FFLAGS=$FCFLAGS
+FCFLAGS=
+echo "$as_me:$LINENO: checking whether $FC accepts -g" >&5
+echo $ECHO_N "checking whether $FC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_fc_g+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ FCFLAGS=-g
+cat >conftest.$ac_ext <<_ACEOF
+ program main
+
+ end
_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_fc_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_prog_fc_g=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_fc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_fc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_fc_g" >&6
+if test "$ac_test_FFLAGS" = set; then
+ FCFLAGS=$ac_save_FFLAGS
+elif test $ac_cv_prog_fc_g = yes; then
+ if test "x$ac_cv_fc_compiler_gnu" = xyes; then
+ FCFLAGS="-g -O2"
else
- ac_cpp_err=
+ FCFLAGS="-g"
fi
else
- ac_cpp_err=yes
+ if test "x$ac_cv_fc_compiler_gnu" = xyes; then
+ FCFLAGS="-O2"
+ else
+ FCFLAGS=
+ fi
fi
-if test -z "$ac_cpp_err"; then
- # Broken: success on invalid input.
-continue
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
- # Passes both tests.
-ac_preproc_ok=:
-break
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+if test -z "$FC" || test "X$FC" = "Xno"; then
+ _lt_disable_FC=yes
fi
-rm -f conftest.err conftest.$ac_ext
+
+
+ ac_ext=${FC_SRCEXT-f}
+ac_compile='$FC -c $FCFLAGS $FCFLAGS_SRCEXT conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $FCFLAGS_SRCEXT conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+
+
+archive_cmds_need_lc_FC=no
+allow_undefined_flag_FC=
+always_export_symbols_FC=no
+archive_expsym_cmds_FC=
+export_dynamic_flag_spec_FC=
+hardcode_direct_FC=no
+hardcode_direct_absolute_FC=no
+hardcode_libdir_flag_spec_FC=
+hardcode_libdir_flag_spec_ld_FC=
+hardcode_libdir_separator_FC=
+hardcode_minus_L_FC=no
+hardcode_automatic_FC=no
+inherit_rpath_FC=no
+module_cmds_FC=
+module_expsym_cmds_FC=
+link_all_deplibs_FC=unknown
+old_archive_cmds_FC=$old_archive_cmds
+no_undefined_flag_FC=
+whole_archive_flag_spec_FC=
+enable_shared_with_static_runtimes_FC=no
+
+# Source file extension for fc test sources.
+ac_ext=${ac_fc_srcext-f}
+
+# Object file extension for compiled fc test sources.
+objext=o
+objext_FC=$objext
+
+# No sense in running all these tests if we already determined that
+# the FC compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_FC" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+ # save warnings/boilerplate of simple test code
+ ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM conftest*
+
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC="$CC"
+ CC=${FC-"f95"}
+ compiler=$CC
+ compiler_FC=$CC
+ for cc_temp in $compiler""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
- break
+cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
+
+ if test -n "$compiler"; then
+ echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5
+echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6
+ echo "$as_me:$LINENO: result: $can_build_shared" >&5
+echo "${ECHO_T}$can_build_shared" >&6
+
+ echo "$as_me:$LINENO: checking whether to build shared libraries" >&5
+echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[4-9]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ echo "$as_me:$LINENO: result: $enable_shared" >&5
+echo "${ECHO_T}$enable_shared" >&6
+
+ echo "$as_me:$LINENO: checking whether to build static libraries" >&5
+echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ echo "$as_me:$LINENO: result: $enable_static" >&5
+echo "${ECHO_T}$enable_static" >&6
+
+ GCC_FC="$ac_cv_fc_compiler_gnu"
+ LD_FC="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ # Dependencies to place before and after the object being linked:
+predep_objects_FC=
+postdep_objects_FC=
+predeps_FC=
+postdeps_FC=
+compiler_lib_search_path_FC=
+
+cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer a
+ a=0
+ return
+ end
+_LT_EOF
+
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # Parse the compiler output and extract the necessary
+ # objects, libraries and library flags.
+
+ # Sentinel used to keep track of whether or not we are before
+ # the conftest object file.
+ pre_test_object_deps_done=no
+
+ # The `*' in the case matches for architectures that use `case' in
+ # $output_verbose_cmd can trigger glob expansion during the loop
+ # eval without this substitution.
+ output_verbose_link_cmd=`$ECHO "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"`
+
+ for p in `eval $output_verbose_link_cmd`; do
+ case $p in
+
+ -L* | -R* | -l*)
+ # Some compilers place space between "-{L,R}" and the path.
+ # Remove the space.
+ if test $p = "-L" ||
+ test $p = "-R"; then
+ prev=$p
+ continue
+ else
+ prev=
+ fi
+
+ if test "$pre_test_object_deps_done" = no; then
+ case $p in
+ -L* | -R*)
+ # Internal compiler library paths should come after those
+ # provided the user. The postdeps already come after the
+ # user supplied libs so there is no need to process them.
+ if test -z "$compiler_lib_search_path_FC"; then
+ compiler_lib_search_path_FC="${prev}${p}"
+ else
+ compiler_lib_search_path_FC="${compiler_lib_search_path_FC} ${prev}${p}"
+ fi
+ ;;
+ # The "-l" case would never come before the object being
+ # linked, so don't bother handling this case.
+ esac
+ else
+ if test -z "$postdeps_FC"; then
+ postdeps_FC="${prev}${p}"
+ else
+ postdeps_FC="${postdeps_FC} ${prev}${p}"
+ fi
+ fi
+ ;;
+
+ *.$objext)
+ # This assumes that the test object file only shows up
+ # once in the compiler output.
+ if test "$p" = "conftest.$objext"; then
+ pre_test_object_deps_done=yes
+ continue
+ fi
+
+ if test "$pre_test_object_deps_done" = no; then
+ if test -z "$predep_objects_FC"; then
+ predep_objects_FC="$p"
+ else
+ predep_objects_FC="$predep_objects_FC $p"
+ fi
+ else
+ if test -z "$postdep_objects_FC"; then
+ postdep_objects_FC="$p"
+ else
+ postdep_objects_FC="$postdep_objects_FC $p"
+ fi
+ fi
+ ;;
+
+ *) ;; # Ignore the rest.
+
+ esac
+ done
+
+ # Clean up.
+ rm -f a.out a.exe
+else
+ echo "libtool.m4: error: problem compiling FC test program"
fi
- done
- ac_cv_prog_CPP=$CPP
+$RM -f confest.$objext
+
+# PORTME: override above test on systems where it is broken
+
+
+case " $postdeps_FC " in
+*" -lc "*) archive_cmds_need_lc_FC=no ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ lt_prog_compiler_wl_FC=
+lt_prog_compiler_pic_FC=
+lt_prog_compiler_static_FC=
+
+echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
+echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
+
+ if test "$GCC" = yes; then
+ lt_prog_compiler_wl_FC='-Wl,'
+ lt_prog_compiler_static_FC='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static_FC='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ if test "$host_cpu" = m68k; then
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ lt_prog_compiler_pic_FC='-m68020 -resident32 -malways-restore-a4'
+ fi
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ lt_prog_compiler_pic_FC='-DDLL_EXPORT'
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic_FC='-fno-common'
+ ;;
+
+ hpux*)
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic_FC='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[3-9]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ lt_prog_compiler_can_build_shared_FC=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic_FC='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic_FC=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ lt_prog_compiler_pic_FC='-fPIC'
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ lt_prog_compiler_wl_FC='-Wl,'
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static_FC='-Bstatic'
+ else
+ lt_prog_compiler_static_FC='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+ darwin*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ case $cc_basename in
+ xlc*)
+ lt_prog_compiler_pic_FC='-qnocommon'
+ lt_prog_compiler_wl_FC='-Wl,'
+ ;;
+ esac
+ ;;
+
+ mingw* | cygwin* | pw32* | os2*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_prog_compiler_pic_FC='-DDLL_EXPORT'
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ lt_prog_compiler_wl_FC='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic_FC='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ lt_prog_compiler_static_FC='${wl}-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ lt_prog_compiler_wl_FC='-Wl,'
+ # PIC (with -KPIC) is the default.
+ lt_prog_compiler_static_FC='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu)
+ case $cc_basename in
+ icc* | ecc*)
+ lt_prog_compiler_wl_FC='-Wl,'
+ lt_prog_compiler_pic_FC='-KPIC'
+ lt_prog_compiler_static_FC='-static'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ lt_prog_compiler_wl_FC='-Wl,'
+ lt_prog_compiler_pic_FC='-fpic'
+ lt_prog_compiler_static_FC='-Bstatic'
+ ;;
+ ccc*)
+ lt_prog_compiler_wl_FC='-Wl,'
+ # All Alpha code is PIC.
+ lt_prog_compiler_static_FC='-non_shared'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C 5.9
+ lt_prog_compiler_pic_FC='-KPIC'
+ lt_prog_compiler_static_FC='-Bstatic'
+ lt_prog_compiler_wl_FC='-Wl,'
+ ;;
+ *Sun\ F*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ lt_prog_compiler_pic_FC='-KPIC'
+ lt_prog_compiler_static_FC='-Bstatic'
+ lt_prog_compiler_wl_FC=''
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ lt_prog_compiler_pic_FC='-KPIC'
+ lt_prog_compiler_static_FC='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic_FC='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ lt_prog_compiler_wl_FC='-Wl,'
+ # All OSF/1 code is PIC.
+ lt_prog_compiler_static_FC='-non_shared'
+ ;;
+
+ rdos*)
+ lt_prog_compiler_static_FC='-non_shared'
+ ;;
+
+ solaris*)
+ lt_prog_compiler_pic_FC='-KPIC'
+ lt_prog_compiler_static_FC='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95*)
+ lt_prog_compiler_wl_FC='-Qoption ld ';;
+ *)
+ lt_prog_compiler_wl_FC='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ lt_prog_compiler_wl_FC='-Qoption ld '
+ lt_prog_compiler_pic_FC='-PIC'
+ lt_prog_compiler_static_FC='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ lt_prog_compiler_wl_FC='-Wl,'
+ lt_prog_compiler_pic_FC='-KPIC'
+ lt_prog_compiler_static_FC='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ lt_prog_compiler_pic_FC='-Kconform_pic'
+ lt_prog_compiler_static_FC='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ lt_prog_compiler_wl_FC='-Wl,'
+ lt_prog_compiler_pic_FC='-KPIC'
+ lt_prog_compiler_static_FC='-Bstatic'
+ ;;
+
+ unicos*)
+ lt_prog_compiler_wl_FC='-Wl,'
+ lt_prog_compiler_can_build_shared_FC=no
+ ;;
+
+ uts4*)
+ lt_prog_compiler_pic_FC='-pic'
+ lt_prog_compiler_static_FC='-Bstatic'
+ ;;
+
+ *)
+ lt_prog_compiler_can_build_shared_FC=no
+ ;;
+ esac
+ fi
+
+case $host_os in
+ # For platforms which do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ lt_prog_compiler_pic_FC=
+ ;;
+ *)
+ lt_prog_compiler_pic_FC="$lt_prog_compiler_pic_FC"
+ ;;
+esac
+echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_FC" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_FC" >&6
+
+
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic_FC"; then
+ echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_FC works" >&5
+echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_FC works... $ECHO_C" >&6
+if test "${lt_prog_compiler_pic_works_FC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ lt_prog_compiler_pic_works_FC=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$lt_prog_compiler_pic_FC"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:11071: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:11075: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_prog_compiler_pic_works_FC=yes
+ fi
+ fi
+ $RM conftest*
fi
- CPP=$ac_cv_prog_CPP
+echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_FC" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_works_FC" >&6
+
+if test x"$lt_prog_compiler_pic_works_FC" = xyes; then
+ case $lt_prog_compiler_pic_FC in
+ "" | " "*) ;;
+ *) lt_prog_compiler_pic_FC=" $lt_prog_compiler_pic_FC" ;;
+ esac
else
- ac_cv_prog_CPP=$CPP
+ lt_prog_compiler_pic_FC=
+ lt_prog_compiler_can_build_shared_FC=no
fi
-echo "$as_me:$LINENO: result: $CPP" >&5
-echo "${ECHO_T}$CPP" >&6
-ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
+
+fi
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl_FC eval lt_tmp_static_flag=\"$lt_prog_compiler_static_FC\"
+echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6
+if test "${lt_prog_compiler_static_works_FC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ lt_prog_compiler_static_works_FC=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_prog_compiler_static_works_FC=yes
+ fi
+ else
+ lt_prog_compiler_static_works_FC=yes
+ fi
+ fi
+ $RM conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_FC" >&5
+echo "${ECHO_T}$lt_prog_compiler_static_works_FC" >&6
+
+if test x"$lt_prog_compiler_static_works_FC" = xyes; then
+ :
+else
+ lt_prog_compiler_static_FC=
+fi
+
+
+
+
+ echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
+echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6
+if test "${lt_cv_prog_compiler_c_o_FC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ lt_cv_prog_compiler_c_o_FC=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:11170: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:11174: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o_FC=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_FC" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_c_o_FC" >&6
+
+
+
+ echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
+echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6
+if test "${lt_cv_prog_compiler_c_o_FC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ lt_cv_prog_compiler_c_o_FC=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:11222: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:11226: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o_FC=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_FC" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_c_o_FC" >&6
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_FC" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
+echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ echo "$as_me:$LINENO: result: $hard_links" >&5
+echo "${ECHO_T}$hard_links" >&6
+ if test "$hard_links" = no; then
+ { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+
+
+ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6
+
+ runpath_var=
+ allow_undefined_flag_FC=
+ always_export_symbols_FC=no
+ archive_cmds_FC=
+ archive_expsym_cmds_FC=
+ compiler_needs_object_FC=no
+ enable_shared_with_static_runtimes_FC=no
+ export_dynamic_flag_spec_FC=
+ export_symbols_cmds_FC='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ hardcode_automatic_FC=no
+ hardcode_direct_FC=no
+ hardcode_direct_absolute_FC=no
+ hardcode_libdir_flag_spec_FC=
+ hardcode_libdir_flag_spec_ld_FC=
+ hardcode_libdir_separator_FC=
+ hardcode_minus_L_FC=no
+ hardcode_shlibpath_var_FC=unsupported
+ inherit_rpath_FC=no
+ link_all_deplibs_FC=unknown
+ module_cmds_FC=
+ module_expsym_cmds_FC=
+ old_archive_from_new_cmds_FC=
+ old_archive_from_expsyms_cmds_FC=
+ thread_safe_flag_spec_FC=
+ whole_archive_flag_spec_FC=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ include_expsyms_FC=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ` (' and `)$', so one must not match beginning or
+ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+ # as well as any symbol that contains `d'.
+ exclude_expsyms_FC="_GLOBAL_OFFSET_TABLE_"
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+ esac
+
+ ld_shlibs_FC=yes
+ if test "$with_gnu_ld" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec_FC='${wl}-rpath ${wl}$libdir'
+ export_dynamic_flag_spec_FC='${wl}--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec_FC="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ whole_archive_flag_spec_FC=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[3-9]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ ld_shlibs_FC=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ if test "$host_cpu" = m68k; then
+ archive_cmds_FC='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec_FC='-L$libdir'
+ hardcode_minus_L_FC=yes
+ fi
+
+ # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+ # that the semantics of dynamic libraries on AmigaOS, at least up
+ # to version 4, is to share data among multiple programs linked
+ # with the same dynamic library. Since this doesn't match the
+ # behavior of shared libraries on other platforms, we can't use
+ # them.
+ ld_shlibs_FC=no
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag_FC=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds_FC='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ ld_shlibs_FC=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, FC) is actually meaningless,
+ # as there is no search path for DLLs.
+ hardcode_libdir_flag_spec_FC='-L$libdir'
+ allow_undefined_flag_FC=unsupported
+ always_export_symbols_FC=no
+ enable_shared_with_static_runtimes_FC=yes
+ export_symbols_cmds_FC='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ archive_cmds_FC='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ archive_expsym_cmds_FC='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ ld_shlibs_FC=no
+ fi
+ ;;
+
+ interix[3-9]*)
+ hardcode_direct_FC=no
+ hardcode_shlibpath_var_FC=no
+ hardcode_libdir_flag_spec_FC='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec_FC='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ archive_cmds_FC='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds_FC='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu)
+ tmp_diet=no
+ if test "$host_os" = linux-dietlibc; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test "$tmp_diet" = no
+ then
+ tmp_addflag=
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ whole_archive_flag_spec_FC='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers
+ whole_archive_flag_spec_FC='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ whole_archive_flag_spec_FC='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ compiler_needs_object_FC=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ *)
+ tmp_sharedflag='-shared' ;;
+ esac
+ archive_cmds_FC='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds_FC='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+ else
+ ld_shlibs_FC=no
+ fi
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds_FC='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ archive_cmds_FC='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds_FC='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ ld_shlibs_FC=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds_FC='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds_FC='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs_FC=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs_FC=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec_FC='${wl}-rpath ${wl}$libdir'
+ archive_cmds_FC='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds_FC='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs_FC=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ archive_cmds_FC='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ hardcode_direct_FC=yes
+ hardcode_shlibpath_var_FC=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds_FC='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds_FC='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs_FC=no
+ fi
+ ;;
+ esac
+
+ if test "$ld_shlibs_FC" = no; then
+ runpath_var=
+ hardcode_libdir_flag_spec_FC=
+ export_dynamic_flag_spec_FC=
+ whole_archive_flag_spec_FC=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ allow_undefined_flag_FC=unsupported
+ always_export_symbols_FC=yes
+ archive_expsym_cmds_FC='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L_FC=yes
+ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct_FC=unsupported
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ export_symbols_cmds_FC='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ export_symbols_cmds_FC='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ archive_cmds_FC=''
+ hardcode_direct_FC=yes
+ hardcode_direct_absolute_FC=yes
+ hardcode_libdir_separator_FC=':'
+ link_all_deplibs_FC=yes
+ file_list_spec_FC='${wl}-f,'
+
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct_FC=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L_FC=yes
+ hardcode_libdir_flag_spec_FC='-L$libdir'
+ hardcode_libdir_separator_FC=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ always_export_symbols_FC=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag_FC='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ cat >conftest.$ac_ext <<_ACEOF
+ program main
+
+ end
_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_fc_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+
+lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\(.*\)$/\1/
+ p
+ }
+ }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
fi
-if test -z "$ac_cpp_err"; then
- :
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
- # Broken: fails on valid input.
-continue
fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
- # OK, works on sane cases. Now check whether non-existent headers
- # can be detected and how.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
+ hardcode_libdir_flag_spec_FC='${wl}-blibpath:$libdir:'"$aix_libpath"
+ archive_expsym_cmds_FC='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec_FC='${wl}-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag_FC="-z nodefs"
+ archive_expsym_cmds_FC="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ cat >conftest.$ac_ext <<_ACEOF
+ program main
+
+ end
_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_fc_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+
+lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\(.*\)$/\1/
+ p
+ }
+ }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+ hardcode_libdir_flag_spec_FC='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ no_undefined_flag_FC=' ${wl}-bernotok'
+ allow_undefined_flag_FC=' ${wl}-berok'
+ # Exported symbols can be pulled into shared objects from archives
+ whole_archive_flag_spec_FC='$convenience'
+ archive_cmds_need_lc_FC=yes
+ # This is similar to how AIX traditionally builds its shared libraries.
+ archive_expsym_cmds_FC="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ if test "$host_cpu" = m68k; then
+ archive_cmds_FC='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec_FC='-L$libdir'
+ hardcode_minus_L_FC=yes
+ fi
+ # see comment about different semantics on the GNU ld section
+ ld_shlibs_FC=no
+ ;;
+
+ bsdi[45]*)
+ export_dynamic_flag_spec_FC=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec_FC=' '
+ allow_undefined_flag_FC=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds_FC='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds_FC='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds_FC='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ fix_srcfile_path_FC='`cygpath -w "$srcfile"`'
+ enable_shared_with_static_runtimes_FC=yes
+ ;;
+
+ darwin* | rhapsody*)
+ case $host_os in
+ rhapsody* | darwin1.[012])
+ allow_undefined_flag_FC='${wl}-undefined ${wl}suppress'
+ ;;
+ *) # Darwin 1.3 on
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
+ 10.[012])
+ allow_undefined_flag_FC='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+ ;;
+ 10.*)
+ allow_undefined_flag_FC='${wl}-undefined ${wl}dynamic_lookup'
+ ;;
+ esac
+ ;;
+ esac
+ archive_cmds_need_lc_FC=no
+ hardcode_direct_FC=no
+ hardcode_automatic_FC=yes
+ hardcode_shlibpath_var_FC=unsupported
+ whole_archive_flag_spec_FC=''
+ link_all_deplibs_FC=yes
+ if test "$GCC" = yes ; then
+ if test "${lt_cv_apple_cc_single_mod+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ lt_cv_apple_cc_single_mod=no
+ if test -z "${LT_MULTI_MODULE}"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi-module to the
+ # link flags.
+ echo "int foo(void){return 1;}" > conftest.c
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib ${wl}-single_module conftest.c
+ if test -f libconftest.dylib; then
+ lt_cv_apple_cc_single_mod=yes
+ rm libconftest.dylib
+ fi
+ rm conftest.$ac_ext
+ fi
+fi
+
+ output_verbose_link_cmd=echo
+ if test "X$lt_cv_apple_cc_single_mod" = Xyes ; then
+ archive_cmds_FC='$CC -dynamiclib $single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+ archive_expsym_cmds_FC='sed "s,^,_," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $single_module -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ else
+ archive_cmds_FC='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+ archive_expsym_cmds_FC='sed "s,^,_," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ fi
+ module_cmds_FC='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+ module_expsym_cmds_FC='sed -e "s,^,_," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ else
+ case $cc_basename in
+ xlc*)
+ output_verbose_link_cmd=echo
+ archive_cmds_FC='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`$ECHO $rpath/$soname` $verstring'
+ module_cmds_FC='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+ archive_expsym_cmds_FC='sed "s,^,_," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ module_expsym_cmds_FC='sed "s,^,_," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ ;;
+ *)
+ ld_shlibs_FC=no
+ ;;
+ esac
+ fi
+ ;;
+
+ dgux*)
+ archive_cmds_FC='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec_FC='-L$libdir'
+ hardcode_shlibpath_var_FC=no
+ ;;
+
+ freebsd1*)
+ ld_shlibs_FC=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds_FC='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec_FC='-R$libdir'
+ hardcode_direct_FC=yes
+ hardcode_shlibpath_var_FC=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2*)
+ archive_cmds_FC='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct_FC=yes
+ hardcode_minus_L_FC=yes
+ hardcode_shlibpath_var_FC=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ archive_cmds_FC='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec_FC='-R$libdir'
+ hardcode_direct_FC=yes
+ hardcode_shlibpath_var_FC=no
+ ;;
+
+ hpux9*)
+ if test "$GCC" = yes; then
+ archive_cmds_FC='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ archive_cmds_FC='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ fi
+ hardcode_libdir_flag_spec_FC='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator_FC=:
+ hardcode_direct_FC=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L_FC=yes
+ export_dynamic_flag_spec_FC='${wl}-E'
+ ;;
+
+ hpux10*)
+ if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+ archive_cmds_FC='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds_FC='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec_FC='${wl}+b ${wl}$libdir'
+ hardcode_libdir_flag_spec_ld_FC='+b $libdir'
+ hardcode_libdir_separator_FC=:
+ hardcode_direct_FC=yes
+ hardcode_direct_absolute_FC=yes
+ export_dynamic_flag_spec_FC='${wl}-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L_FC=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds_FC='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds_FC='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds_FC='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds_FC='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds_FC='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds_FC='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec_FC='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator_FC=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct_FC=no
+ hardcode_shlibpath_var_FC=no
+ ;;
+ *)
+ hardcode_direct_FC=yes
+ hardcode_direct_absolute_FC=yes
+ export_dynamic_flag_spec_FC='${wl}-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L_FC=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test "$GCC" = yes; then
+ archive_cmds_FC='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+ cat >conftest.$ac_ext <<_ACEOF
+int foo(void) {}
_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_fc_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ archive_expsym_cmds_FC='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$save_LDFLAGS"
+ else
+ archive_cmds_FC='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds_FC='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ archive_cmds_need_lc_FC='no'
+ hardcode_libdir_flag_spec_FC='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator_FC=:
+ inherit_rpath_FC=yes
+ link_all_deplibs_FC=yes
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds_FC='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ archive_cmds_FC='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ hardcode_libdir_flag_spec_FC='-R$libdir'
+ hardcode_direct_FC=yes
+ hardcode_shlibpath_var_FC=no
+ ;;
+
+ newsos6)
+ archive_cmds_FC='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct_FC=yes
+ hardcode_libdir_flag_spec_FC='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator_FC=:
+ hardcode_shlibpath_var_FC=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd*)
+ hardcode_direct_FC=yes
+ hardcode_shlibpath_var_FC=no
+ hardcode_direct_absolute_FC=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ archive_cmds_FC='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_FC='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+ hardcode_libdir_flag_spec_FC='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec_FC='${wl}-E'
+ else
+ case $host_os in
+ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+ archive_cmds_FC='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec_FC='-R$libdir'
+ ;;
+ *)
+ archive_cmds_FC='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec_FC='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec_FC='-L$libdir'
+ hardcode_minus_L_FC=yes
+ allow_undefined_flag_FC=unsupported
+ archive_cmds_FC='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ old_archive_from_new_cmds_FC='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$GCC" = yes; then
+ allow_undefined_flag_FC=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds_FC='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ allow_undefined_flag_FC=' -expect_unresolved \*'
+ archive_cmds_FC='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ archive_cmds_need_lc_FC='no'
+ hardcode_libdir_flag_spec_FC='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator_FC=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test "$GCC" = yes; then
+ allow_undefined_flag_FC=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds_FC='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ hardcode_libdir_flag_spec_FC='${wl}-rpath ${wl}$libdir'
+ else
+ allow_undefined_flag_FC=' -expect_unresolved \*'
+ archive_cmds_FC='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds_FC='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec_FC='-rpath $libdir'
+ fi
+ archive_cmds_need_lc_FC='no'
+ hardcode_libdir_separator_FC=:
+ ;;
+
+ solaris*)
+ no_undefined_flag_FC=' -z defs'
+ if test "$GCC" = yes; then
+ wlarc='${wl}'
+ archive_cmds_FC='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_FC='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ archive_cmds_FC='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_expsym_cmds_FC='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='${wl}'
+ archive_cmds_FC='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_FC='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ hardcode_libdir_flag_spec_FC='-R$libdir'
+ hardcode_shlibpath_var_FC=no
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'. GCC discards it without `$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test "$GCC" = yes; then
+ whole_archive_flag_spec_FC='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ else
+ whole_archive_flag_spec_FC='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ link_all_deplibs_FC=yes
+ ;;
+
+ sunos4*)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ archive_cmds_FC='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds_FC='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ hardcode_libdir_flag_spec_FC='-L$libdir'
+ hardcode_direct_FC=yes
+ hardcode_minus_L_FC=yes
+ hardcode_shlibpath_var_FC=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ archive_cmds_FC='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct_FC=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ archive_cmds_FC='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ reload_cmds_FC='$CC -r -o $output$reload_objs'
+ hardcode_direct_FC=no
+ ;;
+ motorola)
+ archive_cmds_FC='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct_FC=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var_FC=no
+ ;;
+
+ sysv4.3*)
+ archive_cmds_FC='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var_FC=no
+ export_dynamic_flag_spec_FC='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ archive_cmds_FC='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var_FC=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ld_shlibs_FC=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ no_undefined_flag_FC='${wl}-z,text'
+ archive_cmds_need_lc_FC=no
+ hardcode_shlibpath_var_FC=no
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds_FC='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_FC='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds_FC='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_FC='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ no_undefined_flag_FC='${wl}-z,text'
+ allow_undefined_flag_FC='${wl}-z,nodefs'
+ archive_cmds_need_lc_FC=no
+ hardcode_shlibpath_var_FC=no
+ hardcode_libdir_flag_spec_FC='${wl}-R,$libdir'
+ hardcode_libdir_separator_FC=':'
+ link_all_deplibs_FC=yes
+ export_dynamic_flag_spec_FC='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds_FC='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_FC='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds_FC='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_FC='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ archive_cmds_FC='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec_FC='-L$libdir'
+ hardcode_shlibpath_var_FC=no
+ ;;
+
+ *)
+ ld_shlibs_FC=no
+ ;;
+ esac
+
+ if test x$host_vendor = xsni; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ export_dynamic_flag_spec_FC='${wl}-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+
+echo "$as_me:$LINENO: result: $ld_shlibs_FC" >&5
+echo "${ECHO_T}$ld_shlibs_FC" >&6
+test "$ld_shlibs_FC" = no && can_build_shared=no
+
+with_gnu_ld_FC=$with_gnu_ld
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc_FC" in
+x|xyes)
+ # Assume -lc should be added
+ archive_cmds_need_lc_FC=yes
+
+ if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $archive_cmds_FC in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
+echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_prog_compiler_wl_FC
+ pic_flag=$lt_prog_compiler_pic_FC
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$allow_undefined_flag_FC
+ allow_undefined_flag_FC=
+ if { (eval echo "$as_me:$LINENO: \"$archive_cmds_FC 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\"") >&5
+ (eval $archive_cmds_FC 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+ then
+ archive_cmds_need_lc_FC=no
+ else
+ archive_cmds_need_lc_FC=yes
+ fi
+ allow_undefined_flag_FC=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+ echo "$as_me:$LINENO: result: $archive_cmds_need_lc_FC" >&5
+echo "${ECHO_T}$archive_cmds_need_lc_FC" >&6
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
+echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6
+withGCC=$ac_cv_fc_compiler_gnu
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+
+aix[4-9]*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
else
- ac_cpp_err=
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[01] | aix4.[01].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ fi
+ shlibpath_var=LIBPATH
fi
-else
- ac_cpp_err=yes
+ ;;
+
+amigaos*)
+ if test "$host_cpu" = m68k; then
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ else
+ dynamic_linker=no
+ fi
+ ;;
+
+beos*)
+ library_names_spec='${libname}${shared_ext}'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[45]*)
+ version_type=linux
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32*)
+ version_type=windows
+ shrext_cmds=".dll"
+ need_version=no
+ need_lib_prefix=no
+
+ case $withGCC,$host_os in
+ yes,cygwin* | yes,mingw* | yes,pw32*)
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+ ;;
+ mingw*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+ # It is most probably a Windows format PATH printed by
+ # mingw gcc, but we are running on Cygwin. Gcc prints its search
+ # path with ; separators, and with drive letters. We can handle the
+ # drive letters (cygwin fileutils understands them), so leave them,
+ # especially as we might pass files found there to a mingw objdump,
+ # which wouldn't understand a cygwinified path. Ahh.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ esac
+ ;;
+
+ *)
+ library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+ soname_spec='${libname}${release}${major}$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd1*)
+ dynamic_linker=no
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[123]*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[01]* | freebsdelf3.[01]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ if test "X$HPUX_IA64_MODE" = X32; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555.
+ postinstall_cmds='chmod 555 $lib'
+ ;;
+
+interix[3-9]*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ version_type=linux
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ # Some binutils ld are patched to set DT_RUNPATH
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_FC\"; \
+ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_FC\""
+ cat >conftest.$ac_ext <<_ACEOF
+ program main
+
+ end
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_fc_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir"; then
+ shlibpath_overrides_runpath=yes
fi
-if test -z "$ac_cpp_err"; then
- # Broken: success on invalid input.
-continue
+
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
- # Passes both tests.
-ac_preproc_ok=:
-break
fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
- :
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
+ need_lib_prefix=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case $host_os in
+ openbsd2.[89] | openbsd2.[89].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ ;;
+
+os2*)
+ libname_spec='$name'
+ shrext_cmds=".dll"
+ need_lib_prefix=no
+ library_names_spec='$libname${shared_ext} $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux
+ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+ soname_spec='$libname${shared_ext}.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_name_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+echo "$as_me:$LINENO: result: $dynamic_linker" >&5
+echo "${ECHO_T}$dynamic_linker" >&6
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
+echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6
+hardcode_action_FC=
+if test -n "$hardcode_libdir_flag_spec_FC" ||
+ test -n "$runpath_var_FC" ||
+ test "X$hardcode_automatic_FC" = "Xyes" ; then
+
+ # We can hardcode non-existent directories.
+ if test "$hardcode_direct_FC" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, FC)" != no &&
+ test "$hardcode_minus_L_FC" != no; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action_FC=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action_FC=immediate
+ fi
else
- { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." >&5
-echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action_FC=unsupported
+fi
+echo "$as_me:$LINENO: result: $hardcode_action_FC" >&5
+echo "${ECHO_T}$hardcode_action_FC" >&6
+
+if test "$hardcode_action_FC" = relink ||
+ test "$inherit_rpath_FC" = yes; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
fi
+
+
+
+
+
+
+ fi # test -n "$compiler"
+
+ CC="$lt_save_CC"
+fi # test "$_lt_disable_FC" != yes
+
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -5145,21 +13186,13 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
ac_compiler_gnu=$ac_cv_c_compiler_gnu
-echo "$as_me:$LINENO: checking for egrep" >&5
-echo $ECHO_N "checking for egrep... $ECHO_C" >&6
-if test "${ac_cv_prog_egrep+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if echo a | (grep -E '(a|b)') >/dev/null 2>&1
- then ac_cv_prog_egrep='grep -E'
- else ac_cv_prog_egrep='egrep'
- fi
-fi
-echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
-echo "${ECHO_T}$ac_cv_prog_egrep" >&6
- EGREP=$ac_cv_prog_egrep
+FCFLAGS="$FCFLAGS -Wall"
+
+# For libtool versioning info, format is CURRENT:REVISION:AGE
+libtool_VERSION=1:0:0
+# Check header files.
echo "$as_me:$LINENO: checking for ANSI C header files" >&5
echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
if test "${ac_cv_header_stdc+set}" = set; then
@@ -5391,83 +13424,11 @@ _ACEOF
fi
-# On IRIX 5.3, sys/types and inttypes.h are conflicting.
-
-
-
-
-
-
-
-
-
-for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
- inttypes.h stdint.h unistd.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- eval "$as_ac_Header=yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-eval "$as_ac_Header=no"
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
-for ac_header in unistd.h semaphore.h sys/loadavg.h sys/time.h
+for ac_header in unistd.h semaphore.h sys/loadavg.h sys/sysctl.h sys/time.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if eval "test \"\${$as_ac_Header+set}\" = set"; then
@@ -8681,6 +16642,24 @@ cat >>confdefs.h <<\_ACEOF
_ACEOF
;;
+esac
+
+ # Check whether --enable-linux-futex or --disable-linux-futex was given.
+if test "${enable_linux_futex+set}" = set; then
+ enableval="$enable_linux_futex"
+
+ case "$enableval" in
+ yes|no|default) ;;
+ *) { { echo "$as_me:$LINENO: error: Unknown argument to enable/disable linux-futex" >&5
+echo "$as_me: error: Unknown argument to enable/disable linux-futex" >&2;}
+ { (exit 1); exit 1; }; } ;;
+ esac
+
+else
+ enable_linux_futex=default
+fi;
+
+case "$target" in
*-linux*)
case "$enable_linux_futex" in
default)
@@ -8729,7 +16708,9 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- cat >conftest.$ac_ext <<_ACEOF
+ save_LIBS="$LIBS"
+ LIBS="-lpthread $LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -8777,7 +16758,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
if test x$cross_compiling = xno; then
if getconf GNU_LIBPTHREAD_VERSION 2>/dev/null \
- | LC_ALL=C grep -i NPTL > /dev/null 2>/dev/null; then
+ | LC_ALL=C grep -i NPTL > /dev/null 2>/dev/null; then :; else
{ echo "$as_me:$LINENO: WARNING: The kernel might not support futex or gettid syscalls.
If so, please configure with --disable-linux-futex" >&5
echo "$as_me: WARNING: The kernel might not support futex or gettid syscalls.
@@ -8788,6 +16769,7 @@ If so, please configure with --disable-linux-futex" >&2;}
fi
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
+ LIBS="$save_LIBS"
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
@@ -8849,7 +16831,76 @@ rm -f conftest.err conftest.$ac_objext \
;;
esac
;;
+ *)
+ enable_linux_futex=no
+ ;;
esac
+if test x$enable_linux_futex = xyes; then
+ :
+fi
+
+
+# Check for pthread_{,attr_}[sg]etaffinity_np.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#define _GNU_SOURCE
+ #include <pthread.h>
+int
+main ()
+{
+cpu_set_t cpuset;
+ pthread_attr_t attr;
+ pthread_getaffinity_np (pthread_self (), sizeof (cpu_set_t), &cpuset);
+ if (CPU_ISSET (0, &cpuset))
+ CPU_SET (1, &cpuset);
+ else
+ CPU_ZERO (&cpuset);
+ pthread_setaffinity_np (pthread_self (), sizeof (cpu_set_t), &cpuset);
+ pthread_attr_init (&attr);
+ pthread_attr_getaffinity_np (&attr, sizeof (cpu_set_t), &cpuset);
+ pthread_attr_setaffinity_np (&attr, sizeof (cpu_set_t), &cpuset);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_PTHREAD_AFFINITY_NP 1
+_ACEOF
+
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
# At least for glibc, clock_gettime is in librt. But don't pull that
# in if it still doesn't give us the function we want.
@@ -8948,17 +16999,17 @@ fi;
echo "$as_me:$LINENO: checking whether the target supports thread-local storage" >&5
echo $ECHO_N "checking whether the target supports thread-local storage... $ECHO_C" >&6
-if test "${have_tls+set}" = set; then
+if test "${gcc_cv_have_tls+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test "$cross_compiling" = yes; then
- cat >conftest.$ac_ext <<_ACEOF
-__thread int foo;
+ cat >conftest.$ac_ext <<_ACEOF
+__thread int a; int b; int main() { return a = b; }
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
@@ -8972,20 +17023,22 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- have_tls=yes
+ gcc_cv_have_tls=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-have_tls=no
+gcc_cv_have_tls=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
else
cat >conftest.$ac_ext <<_ACEOF
@@ -9002,7 +17055,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- save_LDFLAGS="$LDFLAGS"
+ chktls_save_LDFLAGS="$LDFLAGS"
LDFLAGS="-static $LDFLAGS"
cat >conftest.$ac_ext <<_ACEOF
int main() { return 0; }
@@ -9050,14 +17103,14 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- have_tls=yes
+ gcc_cv_have_tls=yes
else
echo "$as_me: program exited with status $ac_status" >&5
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
( exit $ac_status )
-have_tls=no
+gcc_cv_have_tls=no
fi
rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
fi
@@ -9065,25 +17118,147 @@ else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-have_tls=yes
+gcc_cv_have_tls=yes
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$chktls_save_LDFLAGS"
+ if test $gcc_cv_have_tls = yes; then
+ chktls_save_CFLAGS="$CFLAGS"
+ thread_CFLAGS=failed
+ for flag in '' '-pthread' '-lpthread'; do
+ CFLAGS="$flag $chktls_save_CFLAGS"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <pthread.h>
+ void *g(void *d) { return NULL; }
+int
+main ()
+{
+pthread_t t; pthread_create(&t,NULL,g,NULL);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ thread_CFLAGS="$flag"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
fi
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
- LDFLAGS="$save_LDFLAGS"
+ if test "X$thread_CFLAGS" != Xfailed; then
+ break
+ fi
+ done
+ CFLAGS="$chktls_save_CFLAGS"
+ if test "X$thread_CFLAGS" != Xfailed; then
+ CFLAGS="$thread_CFLAGS $chktls_save_CFLAGS"
+ if test "$cross_compiling" = yes; then
+ { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <pthread.h>
+ __thread int a;
+ static int *a_in_other_thread;
+ static void *
+ thread_func (void *arg)
+ {
+ a_in_other_thread = &a;
+ return (void *)0;
+ }
+int
+main ()
+{
+pthread_t thread;
+ void *thread_retval;
+ int *a_in_main_thread;
+ if (pthread_create (&thread, (pthread_attr_t *)0,
+ thread_func, (void *)0))
+ return 0;
+ a_in_main_thread = &a;
+ if (pthread_join (thread, &thread_retval))
+ return 0;
+ return (a_in_other_thread == a_in_main_thread);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ gcc_cv_have_tls=yes
else
echo "$as_me: program exited with status $ac_status" >&5
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
( exit $ac_status )
-have_tls=no
+gcc_cv_have_tls=no
fi
rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
fi
+ CFLAGS="$chktls_save_CFLAGS"
+ fi
+ fi
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+gcc_cv_have_tls=no
fi
-echo "$as_me:$LINENO: result: $have_tls" >&5
-echo "${ECHO_T}$have_tls" >&6
- if test "$enable_tls $have_tls" = "yes yes"; then
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_have_tls" >&5
+echo "${ECHO_T}$gcc_cv_have_tls" >&6
+ if test "$enable_tls $gcc_cv_have_tls" = "yes yes"; then
cat >>confdefs.h <<\_ACEOF
#define HAVE_TLS 1
@@ -9288,6 +17463,118 @@ _ACEOF
fi
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+ withval="$with_gnu_ld"
+ test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi;
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ echo "$as_me:$LINENO: checking for ld used by $CC" >&5
+echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [\\/]* | ?:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ echo "$as_me:$LINENO: checking for GNU ld" >&5
+echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6
+else
+ echo "$as_me:$LINENO: checking for non-GNU ld" >&5
+echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6
+fi
+if test "${lt_cv_path_LD+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -z "$LD"; then
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break
+ ;;
+ *)
+ test "$with_gnu_ld" != yes && break
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ echo "$as_me:$LINENO: result: $LD" >&5
+echo "${ECHO_T}$LD" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5
+echo "$as_me: error: no acceptable ld found in \$PATH" >&2;}
+ { (exit 1); exit 1; }; }
+echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
+echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6
+if test "${lt_cv_prog_gnu_ld+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5
+echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
# If we're not using GNU ld, then there's no point in even trying these
# tests. Check for that first. We should have already tested for gld
# by now (in libtool), but require it now just to be safe...
@@ -11703,6 +19990,339 @@ CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
CC="$CC"
AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+macro_version='`$ECHO "X$macro_version" | $Xsed -e "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "X$macro_revision" | $Xsed -e "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "X$enable_shared" | $Xsed -e "$delay_single_quote_subst"`'
+enable_static='`$ECHO "X$enable_static" | $Xsed -e "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "X$pic_mode" | $Xsed -e "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "X$enable_fast_install" | $Xsed -e "$delay_single_quote_subst"`'
+host_alias='`$ECHO "X$host_alias" | $Xsed -e "$delay_single_quote_subst"`'
+host='`$ECHO "X$host" | $Xsed -e "$delay_single_quote_subst"`'
+host_os='`$ECHO "X$host_os" | $Xsed -e "$delay_single_quote_subst"`'
+build_alias='`$ECHO "X$build_alias" | $Xsed -e "$delay_single_quote_subst"`'
+build='`$ECHO "X$build" | $Xsed -e "$delay_single_quote_subst"`'
+build_os='`$ECHO "X$build_os" | $Xsed -e "$delay_single_quote_subst"`'
+SED='`$ECHO "X$SED" | $Xsed -e "$delay_single_quote_subst"`'
+Xsed='`$ECHO "X$Xsed" | $Xsed -e "$delay_single_quote_subst"`'
+GREP='`$ECHO "X$GREP" | $Xsed -e "$delay_single_quote_subst"`'
+EGREP='`$ECHO "X$EGREP" | $Xsed -e "$delay_single_quote_subst"`'
+FGREP='`$ECHO "X$FGREP" | $Xsed -e "$delay_single_quote_subst"`'
+LD='`$ECHO "X$LD" | $Xsed -e "$delay_single_quote_subst"`'
+NM='`$ECHO "X$NM" | $Xsed -e "$delay_single_quote_subst"`'
+LN_S='`$ECHO "X$LN_S" | $Xsed -e "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "X$max_cmd_len" | $Xsed -e "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "X$ac_objext" | $Xsed -e "$delay_single_quote_subst"`'
+exeext='`$ECHO "X$exeext" | $Xsed -e "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "X$lt_unset" | $Xsed -e "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "X$lt_SP2NL" | $Xsed -e "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`'
+AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "X$AR_FLAGS" | $Xsed -e "$delay_single_quote_subst"`'
+STRIP='`$ECHO "X$STRIP" | $Xsed -e "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "X$RANLIB" | $Xsed -e "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "X$old_postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "X$old_postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "X$old_archive_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+CC='`$ECHO "X$CC" | $Xsed -e "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "X$CFLAGS" | $Xsed -e "$delay_single_quote_subst"`'
+compiler='`$ECHO "X$compiler" | $Xsed -e "$delay_single_quote_subst"`'
+GCC='`$ECHO "X$GCC" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "X$lt_cv_sys_global_symbol_pipe" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "X$lt_cv_sys_global_symbol_to_cdecl" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address" | $Xsed -e "$delay_single_quote_subst"`'
+objdir='`$ECHO "X$objdir" | $Xsed -e "$delay_single_quote_subst"`'
+SHELL='`$ECHO "X$SHELL" | $Xsed -e "$delay_single_quote_subst"`'
+ECHO='`$ECHO "X$ECHO" | $Xsed -e "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "X$MAGIC_CMD" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "X$lt_prog_compiler_no_builtin_flag" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "X$lt_prog_compiler_wl" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "X$lt_prog_compiler_pic" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "X$lt_prog_compiler_static" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "X$lt_cv_prog_compiler_c_o" | $Xsed -e "$delay_single_quote_subst"`'
+need_locks='`$ECHO "X$need_locks" | $Xsed -e "$delay_single_quote_subst"`'
+libext='`$ECHO "X$libext" | $Xsed -e "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "X$shrext_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "X$extract_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "X$archive_cmds_need_lc" | $Xsed -e "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "X$enable_shared_with_static_runtimes" | $Xsed -e "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "X$export_dynamic_flag_spec" | $Xsed -e "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "X$whole_archive_flag_spec" | $Xsed -e "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "X$compiler_needs_object" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "X$old_archive_from_new_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "X$old_archive_from_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "X$archive_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "X$archive_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "X$module_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "X$module_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "X$with_gnu_ld" | $Xsed -e "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "X$allow_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "X$no_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "X$hardcode_libdir_flag_spec" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_ld='`$ECHO "X$hardcode_libdir_flag_spec_ld" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "X$hardcode_libdir_separator" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "X$hardcode_direct" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "X$hardcode_direct_absolute" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "X$hardcode_minus_L" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "X$hardcode_shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "X$hardcode_automatic" | $Xsed -e "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "X$inherit_rpath" | $Xsed -e "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "X$link_all_deplibs" | $Xsed -e "$delay_single_quote_subst"`'
+fix_srcfile_path='`$ECHO "X$fix_srcfile_path" | $Xsed -e "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "X$always_export_symbols" | $Xsed -e "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "X$export_symbols_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "X$exclude_expsyms" | $Xsed -e "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "X$include_expsyms" | $Xsed -e "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "X$prelink_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "X$file_list_spec" | $Xsed -e "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "X$variables_saved_for_relink" | $Xsed -e "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "X$need_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`'
+need_version='`$ECHO "X$need_version" | $Xsed -e "$delay_single_quote_subst"`'
+version_type='`$ECHO "X$version_type" | $Xsed -e "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "X$runpath_var" | $Xsed -e "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "X$shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "X$shlibpath_overrides_runpath" | $Xsed -e "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "X$libname_spec" | $Xsed -e "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "X$library_names_spec" | $Xsed -e "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "X$soname_spec" | $Xsed -e "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "X$postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "X$postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "X$finish_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "X$finish_eval" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "X$hardcode_into_libs" | $Xsed -e "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "X$sys_lib_search_path_spec" | $Xsed -e "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "X$sys_lib_dlsearch_path_spec" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "X$hardcode_action" | $Xsed -e "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "X$enable_dlopen" | $Xsed -e "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "X$enable_dlopen_self" | $Xsed -e "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "X$enable_dlopen_self_static" | $Xsed -e "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "X$old_striplib" | $Xsed -e "$delay_single_quote_subst"`'
+striplib='`$ECHO "X$striplib" | $Xsed -e "$delay_single_quote_subst"`'
+predep_objects='`$ECHO "X$predep_objects" | $Xsed -e "$delay_single_quote_subst"`'
+postdep_objects='`$ECHO "X$postdep_objects" | $Xsed -e "$delay_single_quote_subst"`'
+predeps='`$ECHO "X$predeps" | $Xsed -e "$delay_single_quote_subst"`'
+postdeps='`$ECHO "X$postdeps" | $Xsed -e "$delay_single_quote_subst"`'
+compiler_lib_search_path='`$ECHO "X$compiler_lib_search_path" | $Xsed -e "$delay_single_quote_subst"`'
+LD_FC='`$ECHO "X$LD_FC" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_cmds_FC='`$ECHO "X$old_archive_cmds_FC" | $Xsed -e "$delay_single_quote_subst"`'
+compiler_FC='`$ECHO "X$compiler_FC" | $Xsed -e "$delay_single_quote_subst"`'
+GCC_FC='`$ECHO "X$GCC_FC" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag_FC='`$ECHO "X$lt_prog_compiler_no_builtin_flag_FC" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_wl_FC='`$ECHO "X$lt_prog_compiler_wl_FC" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_pic_FC='`$ECHO "X$lt_prog_compiler_pic_FC" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_static_FC='`$ECHO "X$lt_prog_compiler_static_FC" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o_FC='`$ECHO "X$lt_cv_prog_compiler_c_o_FC" | $Xsed -e "$delay_single_quote_subst"`'
+archive_cmds_need_lc_FC='`$ECHO "X$archive_cmds_need_lc_FC" | $Xsed -e "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes_FC='`$ECHO "X$enable_shared_with_static_runtimes_FC" | $Xsed -e "$delay_single_quote_subst"`'
+export_dynamic_flag_spec_FC='`$ECHO "X$export_dynamic_flag_spec_FC" | $Xsed -e "$delay_single_quote_subst"`'
+whole_archive_flag_spec_FC='`$ECHO "X$whole_archive_flag_spec_FC" | $Xsed -e "$delay_single_quote_subst"`'
+compiler_needs_object_FC='`$ECHO "X$compiler_needs_object_FC" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_from_new_cmds_FC='`$ECHO "X$old_archive_from_new_cmds_FC" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds_FC='`$ECHO "X$old_archive_from_expsyms_cmds_FC" | $Xsed -e "$delay_single_quote_subst"`'
+archive_cmds_FC='`$ECHO "X$archive_cmds_FC" | $Xsed -e "$delay_single_quote_subst"`'
+archive_expsym_cmds_FC='`$ECHO "X$archive_expsym_cmds_FC" | $Xsed -e "$delay_single_quote_subst"`'
+module_cmds_FC='`$ECHO "X$module_cmds_FC" | $Xsed -e "$delay_single_quote_subst"`'
+module_expsym_cmds_FC='`$ECHO "X$module_expsym_cmds_FC" | $Xsed -e "$delay_single_quote_subst"`'
+with_gnu_ld_FC='`$ECHO "X$with_gnu_ld_FC" | $Xsed -e "$delay_single_quote_subst"`'
+allow_undefined_flag_FC='`$ECHO "X$allow_undefined_flag_FC" | $Xsed -e "$delay_single_quote_subst"`'
+no_undefined_flag_FC='`$ECHO "X$no_undefined_flag_FC" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_FC='`$ECHO "X$hardcode_libdir_flag_spec_FC" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_ld_FC='`$ECHO "X$hardcode_libdir_flag_spec_ld_FC" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_separator_FC='`$ECHO "X$hardcode_libdir_separator_FC" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_direct_FC='`$ECHO "X$hardcode_direct_FC" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_direct_absolute_FC='`$ECHO "X$hardcode_direct_absolute_FC" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_minus_L_FC='`$ECHO "X$hardcode_minus_L_FC" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_shlibpath_var_FC='`$ECHO "X$hardcode_shlibpath_var_FC" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_automatic_FC='`$ECHO "X$hardcode_automatic_FC" | $Xsed -e "$delay_single_quote_subst"`'
+inherit_rpath_FC='`$ECHO "X$inherit_rpath_FC" | $Xsed -e "$delay_single_quote_subst"`'
+link_all_deplibs_FC='`$ECHO "X$link_all_deplibs_FC" | $Xsed -e "$delay_single_quote_subst"`'
+fix_srcfile_path_FC='`$ECHO "X$fix_srcfile_path_FC" | $Xsed -e "$delay_single_quote_subst"`'
+always_export_symbols_FC='`$ECHO "X$always_export_symbols_FC" | $Xsed -e "$delay_single_quote_subst"`'
+export_symbols_cmds_FC='`$ECHO "X$export_symbols_cmds_FC" | $Xsed -e "$delay_single_quote_subst"`'
+exclude_expsyms_FC='`$ECHO "X$exclude_expsyms_FC" | $Xsed -e "$delay_single_quote_subst"`'
+include_expsyms_FC='`$ECHO "X$include_expsyms_FC" | $Xsed -e "$delay_single_quote_subst"`'
+prelink_cmds_FC='`$ECHO "X$prelink_cmds_FC" | $Xsed -e "$delay_single_quote_subst"`'
+file_list_spec_FC='`$ECHO "X$file_list_spec_FC" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_action_FC='`$ECHO "X$hardcode_action_FC" | $Xsed -e "$delay_single_quote_subst"`'
+predep_objects_FC='`$ECHO "X$predep_objects_FC" | $Xsed -e "$delay_single_quote_subst"`'
+postdep_objects_FC='`$ECHO "X$postdep_objects_FC" | $Xsed -e "$delay_single_quote_subst"`'
+predeps_FC='`$ECHO "X$predeps_FC" | $Xsed -e "$delay_single_quote_subst"`'
+postdeps_FC='`$ECHO "X$postdeps_FC" | $Xsed -e "$delay_single_quote_subst"`'
+compiler_lib_search_path_FC='`$ECHO "X$compiler_lib_search_path_FC" | $Xsed -e "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# Quote evaled strings.
+for var in SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+deplibs_check_method \
+file_magic_cmd \
+AR \
+AR_FLAGS \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_c_name_address \
+SHELL \
+ECHO \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_wl \
+lt_prog_compiler_pic \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_flag_spec_ld \
+hardcode_libdir_separator \
+fix_srcfile_path \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+finish_eval \
+old_striplib \
+striplib \
+predep_objects \
+postdep_objects \
+predeps \
+postdeps \
+compiler_lib_search_path \
+LD_FC \
+compiler_FC \
+lt_prog_compiler_no_builtin_flag_FC \
+lt_prog_compiler_wl_FC \
+lt_prog_compiler_pic_FC \
+lt_prog_compiler_static_FC \
+lt_cv_prog_compiler_c_o_FC \
+export_dynamic_flag_spec_FC \
+whole_archive_flag_spec_FC \
+compiler_needs_object_FC \
+with_gnu_ld_FC \
+allow_undefined_flag_FC \
+no_undefined_flag_FC \
+hardcode_libdir_flag_spec_FC \
+hardcode_libdir_flag_spec_ld_FC \
+hardcode_libdir_separator_FC \
+fix_srcfile_path_FC \
+exclude_expsyms_FC \
+include_expsyms_FC \
+file_list_spec_FC \
+predep_objects_FC \
+postdep_objects_FC \
+predeps_FC \
+postdeps_FC \
+compiler_lib_search_path_FC; do
+ case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+sys_lib_dlsearch_path_spec \
+old_archive_cmds_FC \
+old_archive_from_new_cmds_FC \
+old_archive_from_expsyms_cmds_FC \
+archive_cmds_FC \
+archive_expsym_cmds_FC \
+module_cmds_FC \
+module_expsym_cmds_FC \
+export_symbols_cmds_FC \
+prelink_cmds_FC; do
+ case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Fix-up fallback echo if it was mangled by the above quoting rules.
+case \$lt_ECHO in
+*'\\\$0 --fallback-echo"') lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\$0 --fallback-echo"\$/\$0 --fallback-echo"/'\`
+ ;;
+esac
+
+ac_aux_dir='$ac_aux_dir'
+xsi_shell='$xsi_shell'
+lt_shell_append='$lt_shell_append'
+
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ TIMESTAMP='$TIMESTAMP'
+ RM='$RM'
+ ofile='$ofile'
+
+
+
+
+
+
GCC="$GCC"
CC="$CC"
acx_cv_header_stdint="$acx_cv_header_stdint"
@@ -11739,6 +20359,7 @@ do
"libgomp.spec" ) CONFIG_FILES="$CONFIG_FILES libgomp.spec" ;;
"default-1" ) CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;;
"depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+ "libtool" ) CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
"gstdint.h" ) CONFIG_COMMANDS="$CONFIG_COMMANDS gstdint.h" ;;
"config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
*) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
@@ -11886,8 +20507,19 @@ s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
s,@PERL@,$PERL,;t t
s,@BUILD_INFO_TRUE@,$BUILD_INFO_TRUE,;t t
s,@BUILD_INFO_FALSE@,$BUILD_INFO_FALSE,;t t
-s,@LN_S@,$LN_S,;t t
s,@LIBTOOL@,$LIBTOOL,;t t
+s,@SED@,$SED,;t t
+s,@EGREP@,$EGREP,;t t
+s,@FGREP@,$FGREP,;t t
+s,@GREP@,$GREP,;t t
+s,@LD@,$LD,;t t
+s,@DUMPBIN@,$DUMPBIN,;t t
+s,@ac_ct_DUMPBIN@,$ac_ct_DUMPBIN,;t t
+s,@NM@,$NM,;t t
+s,@LN_S@,$LN_S,;t t
+s,@lt_ECHO@,$lt_ECHO,;t t
+s,@CPP@,$CPP,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
s,@enable_shared@,$enable_shared,;t t
s,@enable_static@,$enable_static,;t t
s,@MAINTAINER_MODE_TRUE@,$MAINTAINER_MODE_TRUE,;t t
@@ -11898,9 +20530,6 @@ s,@FCFLAGS@,$FCFLAGS,;t t
s,@LDFLAGS@,$LDFLAGS,;t t
s,@ac_ct_FC@,$ac_ct_FC,;t t
s,@libtool_VERSION@,$libtool_VERSION,;t t
-s,@CPP@,$CPP,;t t
-s,@CPPFLAGS@,$CPPFLAGS,;t t
-s,@EGREP@,$EGREP,;t t
s,@SECTION_LDFLAGS@,$SECTION_LDFLAGS,;t t
s,@OPT_LDFLAGS@,$OPT_LDFLAGS,;t t
s,@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@,$LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE,;t t
@@ -12609,6 +21238,716 @@ echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;}
done
done
;;
+ libtool )
+
+ # See if we are running on zsh, and set the options which allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile="${ofile}T"
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me (GNU $PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007 Free Software Foundation, Inc.
+#
+# This file is part of GNU Libtool:
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, a copy can be downloaded from
+# http://www.gnu.org/copyleft/gpl.html, or by writing to the Free
+# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags="FC "
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that does not interpret backslashes.
+ECHO=$lt_ECHO
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# If ld is used when linking, flag to hardcode \$libdir into a binary
+# during linking. This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path=$lt_fix_srcfile_path
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects
+postdep_objects=$lt_postdep_objects
+predeps=$lt_predeps
+postdeps=$lt_postdeps
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ case $xsi_shell in
+ yes)
+ cat << \_LT_EOF >> "$cfgfile"
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac
+}
+
+# func_basename file
+func_basename ()
+{
+ func_basename_result="${1##*/}"
+}
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+func_stripname ()
+{
+ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+ # positional parameters, so assign one to ordinary parameter first.
+ func_stripname_result=${3}
+ func_stripname_result=${func_stripname_result#"${1}"}
+ func_stripname_result=${func_stripname_result%"${2}"}
+}
+
+# func_opt_split
+func_opt_split ()
+{
+ func_opt_split_opt=${1%%=*}
+ func_opt_split_arg=${1#*=}
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+ case ${1} in
+ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+ *) func_lo2o_result=${1} ;;
+ esac
+}
+_LT_EOF
+ ;;
+ *) # Bourne compatible functions.
+ cat << \_LT_EOF >> "$cfgfile"
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+ # Extract subdirectory from the argument.
+ func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+}
+
+# func_basename file
+func_basename ()
+{
+ func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
+}
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+ case ${2} in
+ .*) func_stripname_result=`$ECHO "X${3}" \
+ | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;;
+ *) func_stripname_result=`$ECHO "X${3}" \
+ | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;;
+ esac
+}
+
+# sed scripts:
+my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q'
+my_sed_long_arg='1s/^-[^=]*=//'
+
+# func_opt_split
+func_opt_split ()
+{
+ func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"`
+ func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"`
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+ func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"`
+}
+_LT_EOF
+esac
+
+case $lt_shell_append in
+ yes)
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+ eval "$1+=\$2"
+}
+_LT_EOF
+ ;;
+ *)
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+ eval "$1=\$$1\$2"
+}
+_LT_EOF
+ ;;
+ esac
+
+
+ sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+
+
+ cat <<_LT_EOF >> "$ofile"
+
+# ### BEGIN LIBTOOL TAG CONFIG: FC
+
+# The linker used to build libraries.
+LD=$lt_LD_FC
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds_FC
+
+# A language specific compiler.
+CC=$lt_compiler_FC
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC_FC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_FC
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_FC
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_FC
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_FC
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_FC
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_FC
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_FC
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_FC
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_FC
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object_FC
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_FC
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_FC
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds_FC
+archive_expsym_cmds=$lt_archive_expsym_cmds_FC
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds_FC
+module_expsym_cmds=$lt_module_expsym_cmds_FC
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld_FC
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_FC
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_FC
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_FC
+
+# If ld is used when linking, flag to hardcode \$libdir into a binary
+# during linking. This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_FC
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_FC
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct_FC
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute_FC
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L_FC
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_FC
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic_FC
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath_FC
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_FC
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path=$lt_fix_srcfile_path_FC
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols_FC
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_FC
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_FC
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_FC
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds_FC
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec_FC
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_FC
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects_FC
+postdep_objects=$lt_postdep_objects_FC
+predeps=$lt_predeps_FC
+postdeps=$lt_postdeps_FC
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_FC
+
+# ### END LIBTOOL TAG CONFIG: FC
+_LT_EOF
+
+ ;;
gstdint.h )
if test "$GCC" = yes; then
echo "/* generated for " `$CC --version | sed 1q` "*/" > tmp-stdint.h
@@ -12650,33 +21989,51 @@ if test "$acx_cv_header_stdint" = stddef.h; then
#ifndef _UINT8_T
#define _UINT8_T
+ #ifndef __uint8_t_defined
+ #define __uint8_t_defined
typedef unsigned $acx_cv_type_int8_t uint8_t;
#endif
+ #endif
#ifndef _UINT16_T
#define _UINT16_T
+ #ifndef __uint16_t_defined
+ #define __uint16_t_defined
typedef unsigned $acx_cv_type_int16_t uint16_t;
#endif
+ #endif
#ifndef _UINT32_T
#define _UINT32_T
+ #ifndef __uint32_t_defined
+ #define __uint32_t_defined
typedef unsigned $acx_cv_type_int32_t uint32_t;
#endif
+ #endif
#ifndef _INT8_T
#define _INT8_T
+ #ifndef __int8_t_defined
+ #define __int8_t_defined
typedef $acx_cv_type_int8_t int8_t;
#endif
+ #endif
#ifndef _INT16_T
#define _INT16_T
+ #ifndef __int16_t_defined
+ #define __int16_t_defined
typedef $acx_cv_type_int16_t int16_t;
#endif
+ #endif
#ifndef _INT32_T
#define _INT32_T
+ #ifndef __int32_t_defined
+ #define __int32_t_defined
typedef $acx_cv_type_int32_t int32_t;
#endif
+ #endif
EOF
elif test "$ac_cv_type_u_int32_t" = yes; then
sed 's/^ *//' >> tmp-stdint.h <<EOF
@@ -12694,18 +22051,27 @@ elif test "$ac_cv_type_u_int32_t" = yes; then
#ifndef _UINT8_T
#define _UINT8_T
+ #ifndef __uint8_t_defined
+ #define __uint8_t_defined
typedef u_int8_t uint8_t;
#endif
+ #endif
#ifndef _UINT16_T
#define _UINT16_T
+ #ifndef __uint16_t_defined
+ #define __uint16_t_defined
typedef u_int16_t uint16_t;
#endif
+ #endif
#ifndef _UINT32_T
#define _UINT32_T
+ #ifndef __uint32_t_defined
+ #define __uint32_t_defined
typedef u_int32_t uint32_t;
#endif
+ #endif
EOF
else
sed 's/^ *//' >> tmp-stdint.h <<EOF
@@ -12753,8 +22119,11 @@ elif test "$ac_cv_type_u_int64_t" = yes; then
#endif
#ifndef _UINT64_T
#define _UINT64_T
+ #ifndef __uint64_t_defined
+ #define __uint64_t_defined
typedef u_int64_t uint64_t;
#endif
+ #endif
EOF
elif test -n "$acx_cv_type_int64_t"; then
sed 's/^ *//' >> tmp-stdint.h <<EOF
@@ -12766,8 +22135,11 @@ elif test -n "$acx_cv_type_int64_t"; then
#endif
#ifndef _UINT64_T
#define _UINT64_T
+ #ifndef __uint64_t_defined
+ #define __uint64_t_defined
typedef unsigned $acx_cv_type_int64_t uint64_t;
#endif
+ #endif
EOF
else
sed 's/^ *//' >> tmp-stdint.h <<EOF
@@ -12776,8 +22148,10 @@ else
#if defined __STDC_VERSION__ && (__STDC_VERSION__-0) >= 199901L
#ifndef _INT64_T
#define _INT64_T
+ #ifndef __int64_t_defined
typedef long long int64_t;
#endif
+ #endif
#ifndef _UINT64_T
#define _UINT64_T
typedef unsigned long long uint64_t;
@@ -12822,8 +22196,12 @@ if test "$ac_cv_type_uintptr_t" != yes; then
sed 's/^ *//' >> tmp-stdint.h <<EOF
/* Define intptr_t based on sizeof(void*) = $ac_cv_sizeof_void_p */
+ #ifndef __uintptr_t_defined
typedef u$acx_cv_type_intptr_t uintptr_t;
+ #endif
+ #ifndef __intptr_t_defined
typedef $acx_cv_type_intptr_t intptr_t;
+ #endif
EOF
fi
diff --git a/contrib/gcclibs/libgomp/configure.ac b/contrib/gcclibs/libgomp/configure.ac
index fc0f0030d4e6..c43858dcac0b 100644
--- a/contrib/gcclibs/libgomp/configure.ac
+++ b/contrib/gcclibs/libgomp/configure.ac
@@ -15,12 +15,6 @@ LIBGOMP_ENABLE(version-specific-runtime-libs, no, ,
permit yes|no)
AC_MSG_RESULT($enable_version_specific_runtime_libs)
-AC_MSG_CHECKING([for --enable-linux-futex])
-LIBGOMP_ENABLE(linux-futex, default, ,
- [Use the Linux futex system call],
- permit yes|no|default)
-AC_MSG_RESULT($enable_linux_futex)
-
# We would like our source tree to be readonly. However when releases or
# pre-releases are generated, the flex/bison generated files as well as the
# various formats of manuals need to be included along with the rest of the
@@ -64,11 +58,11 @@ target_alias=${target_alias-$host_alias}
# we can do about that; they come from AC_INIT).
# foreign: we don't follow the normal rules for GNU packages (no COPYING
# file in the top srcdir, etc, etc), so stop complaining.
-# no-dependencies: turns off auto dependency generation (just for now)
+# no-dist: we don't want 'dist' and related rules.
# -Wall: turns on all automake warnings...
# -Wno-portability: ...except this one, since GNU make is required.
# -Wno-override: ... and this one, since we do want this in testsuite.
-AM_INIT_AUTOMAKE([1.9.0 foreign -Wall -Wno-portability -Wno-override])
+AM_INIT_AUTOMAKE([1.9.0 foreign no-dist -Wall -Wno-portability -Wno-override])
AM_ENABLE_MULTILIB(, ..)
# Calculate toolexeclibdir
@@ -135,7 +129,7 @@ AC_PROG_INSTALL
# that we can use it.
ACX_CHECK_PROG_VER([MAKEINFO], [makeinfo], [--version],
[GNU texinfo.* \([0-9][0-9.]*\)],
- [4.[4-9]*])
+ [4.[4-9]*|4.[1-9][0-9]*|[5-9]*|[1-9][0-9]*])
AM_CONDITIONAL(BUILD_INFO, test $gcc_cv_prog_makeinfo_modern = "yes")
@@ -160,7 +154,7 @@ AC_SUBST(libtool_VERSION)
# Check header files.
AC_STDC_HEADERS
AC_HEADER_TIME
-AC_CHECK_HEADERS(unistd.h semaphore.h sys/loadavg.h sys/time.h)
+AC_CHECK_HEADERS(unistd.h semaphore.h sys/loadavg.h sys/sysctl.h sys/time.h)
GCC_HEADER_STDINT(gstdint.h)
@@ -193,50 +187,29 @@ case "$host" in
AC_DEFINE(HAVE_BROKEN_POSIX_SEMAPHORES, 1,
Define if the POSIX Semaphores do not work on your system.)
;;
- *-linux*)
- case "$enable_linux_futex" in
- default)
- # If headers don't have gettid/futex syscalls definition, then
- # default to no, otherwise there will be compile time failures.
- # Otherwise, default to yes. If we don't detect we are
- # compiled/linked against NPTL and not cross-compiling, check
- # if programs are run by default against NPTL and if not, issue
- # a warning.
- enable_linux_futex=no
- AC_LINK_IFELSE(
- [AC_LANG_PROGRAM(
- [#include <sys/syscall.h>
- int lk;],
- [syscall (SYS_gettid); syscall (SYS_futex, &lk, 0, 0, 0);])],
- [AC_LINK_IFELSE(
- [AC_LANG_PROGRAM(
- [#ifndef _GNU_SOURCE
- #define _GNU_SOURCE 1
- #endif
- #include <pthread.h>
- pthread_t th; void *status;],
- [pthread_tryjoin_np (th, &status);])],[enable_linux_futex=yes],
- [if test x$cross_compiling = xno; then
- if getconf GNU_LIBPTHREAD_VERSION 2>/dev/null \
- | LC_ALL=C grep -i NPTL > /dev/null 2>/dev/null; then
- AC_MSG_WARN([The kernel might not support futex or gettid syscalls.
-If so, please configure with --disable-linux-futex])
- fi
- fi
- enable_linux_futex=yes])])
- ;;
- yes)
- AC_LINK_IFELSE(
- [AC_LANG_PROGRAM(
- [#include <sys/syscall.h>
- int lk;],
- [syscall (SYS_gettid); syscall (SYS_futex, &lk, 0, 0, 0);])],[],
- [AC_MSG_ERROR([SYS_gettid and SYS_futex required for --enable-linux-futex])])
- ;;
- esac
- ;;
esac
+GCC_LINUX_FUTEX(:)
+
+# Check for pthread_{,attr_}[sg]etaffinity_np.
+AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM(
+ [#define _GNU_SOURCE
+ #include <pthread.h>],
+ [cpu_set_t cpuset;
+ pthread_attr_t attr;
+ pthread_getaffinity_np (pthread_self (), sizeof (cpu_set_t), &cpuset);
+ if (CPU_ISSET (0, &cpuset))
+ CPU_SET (1, &cpuset);
+ else
+ CPU_ZERO (&cpuset);
+ pthread_setaffinity_np (pthread_self (), sizeof (cpu_set_t), &cpuset);
+ pthread_attr_init (&attr);
+ pthread_attr_getaffinity_np (&attr, sizeof (cpu_set_t), &cpuset);
+ pthread_attr_setaffinity_np (&attr, sizeof (cpu_set_t), &cpuset);])],
+ AC_DEFINE(HAVE_PTHREAD_AFFINITY_NP, 1,
+[ Define if pthread_{,attr_}{g,s}etaffinity_np is supported.]))
+
# At least for glibc, clock_gettime is in librt. But don't pull that
# in if it still doesn't give us the function we want.
if test $ac_cv_func_clock_gettime = no; then
diff --git a/contrib/gcclibs/libgomp/configure.tgt b/contrib/gcclibs/libgomp/configure.tgt
index 89bae02e80a7..a666943edb97 100644
--- a/contrib/gcclibs/libgomp/configure.tgt
+++ b/contrib/gcclibs/libgomp/configure.tgt
@@ -11,14 +11,11 @@
# XLDFLAGS Add extra link flags to use.
# Optimize TLS usage by avoiding the overhead of dynamic allocation.
-# This does require that the library be present during process
-# startup, so mark the library as not to be dlopened.
-if test $have_tls = yes ; then
+if test $gcc_cv_have_tls = yes ; then
case "${target}" in
*-*-linux*)
XCFLAGS="${XCFLAGS} -ftls-model=initial-exec"
- XLDFLAGS="${XLDFLAGS} -Wl,-z,nodlopen"
;;
esac
fi
@@ -49,9 +46,14 @@ if test $enable_linux_futex = yes; then
# Note that bare i386 is not included here. We need cmpxchg.
i[456]86-*-linux*)
config_path="linux/x86 linux posix"
- if test -z "$with_arch"; then
- XCFLAGS="${XCFLAGS} -march=i486 -mtune=${target_cpu}"
- fi
+ case " ${CC} ${CFLAGS} " in
+ *" -m64 "*)
+ ;;
+ *)
+ if test -z "$with_arch"; then
+ XCFLAGS="${XCFLAGS} -march=i486 -mtune=${target_cpu}"
+ fi
+ esac
;;
# Similar jiggery-pokery for x86_64 multilibs, except here we
@@ -105,6 +107,10 @@ case "${target}" in
XLDFLAGS="${XLDFLAGS} -lposix4"
;;
+ *-*-darwin*)
+ config_path="bsd posix"
+ ;;
+
*)
;;
diff --git a/contrib/gcclibs/libgomp/env.c b/contrib/gcclibs/libgomp/env.c
index f07b31b914b3..4a07bfa4975a 100644
--- a/contrib/gcclibs/libgomp/env.c
+++ b/contrib/gcclibs/libgomp/env.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp).
@@ -42,6 +42,8 @@ bool gomp_dyn_var = false;
bool gomp_nest_var = false;
enum gomp_schedule_type gomp_run_sched_var = GFS_DYNAMIC;
unsigned long gomp_run_sched_chunk = 1;
+unsigned short *gomp_cpu_affinity;
+size_t gomp_cpu_affinity_len;
/* Parse the OMP_SCHEDULE environment variable. */
@@ -177,6 +179,97 @@ parse_boolean (const char *name, bool *value)
gomp_error ("Invalid value for environment variable %s", name);
}
+/* Parse the GOMP_CPU_AFFINITY environment varible. Return true if one was
+ present and it was successfully parsed. */
+
+static bool
+parse_affinity (void)
+{
+ char *env, *end;
+ unsigned long cpu_beg, cpu_end, cpu_stride;
+ unsigned short *cpus = NULL;
+ size_t allocated = 0, used = 0, needed;
+
+ env = getenv ("GOMP_CPU_AFFINITY");
+ if (env == NULL)
+ return false;
+
+ do
+ {
+ while (*env == ' ' || *env == '\t')
+ env++;
+
+ cpu_beg = strtoul (env, &end, 0);
+ cpu_end = cpu_beg;
+ cpu_stride = 1;
+ if (env == end || cpu_beg >= 65536)
+ goto invalid;
+
+ env = end;
+ if (*env == '-')
+ {
+ cpu_end = strtoul (++env, &end, 0);
+ if (env == end || cpu_end >= 65536 || cpu_end < cpu_beg)
+ goto invalid;
+
+ env = end;
+ if (*env == ':')
+ {
+ cpu_stride = strtoul (++env, &end, 0);
+ if (env == end || cpu_stride == 0 || cpu_stride >= 65536)
+ goto invalid;
+
+ env = end;
+ }
+ }
+
+ needed = (cpu_end - cpu_beg) / cpu_stride + 1;
+ if (used + needed >= allocated)
+ {
+ unsigned short *new_cpus;
+
+ if (allocated < 64)
+ allocated = 64;
+ if (allocated > needed)
+ allocated <<= 1;
+ else
+ allocated += 2 * needed;
+ new_cpus = realloc (cpus, allocated * sizeof (unsigned short));
+ if (new_cpus == NULL)
+ {
+ free (cpus);
+ gomp_error ("not enough memory to store GOMP_CPU_AFFINITY list");
+ return false;
+ }
+
+ cpus = new_cpus;
+ }
+
+ while (needed--)
+ {
+ cpus[used++] = cpu_beg;
+ cpu_beg += cpu_stride;
+ }
+
+ while (*env == ' ' || *env == '\t')
+ env++;
+
+ if (*env == ',')
+ env++;
+ else if (*env == '\0')
+ break;
+ }
+ while (1);
+
+ gomp_cpu_affinity = cpus;
+ gomp_cpu_affinity_len = used;
+ return true;
+
+ invalid:
+ gomp_error ("Invalid value for enviroment variable GOMP_CPU_AFFINITY");
+ return false;
+}
+
static void __attribute__((constructor))
initialize_env (void)
{
@@ -190,6 +283,8 @@ initialize_env (void)
parse_boolean ("OMP_NESTED", &gomp_nest_var);
if (!parse_unsigned_long ("OMP_NUM_THREADS", &gomp_nthreads_var))
gomp_init_num_threads ();
+ if (parse_affinity ())
+ gomp_init_affinity ();
/* Not strictly environment related, but ordering constructors is tricky. */
pthread_attr_init (&gomp_thread_attr);
diff --git a/contrib/gcclibs/libgomp/iter.c b/contrib/gcclibs/libgomp/iter.c
index 1a8a2a7d04fd..2d5dd2edd5a7 100644
--- a/contrib/gcclibs/libgomp/iter.c
+++ b/contrib/gcclibs/libgomp/iter.c
@@ -242,16 +242,16 @@ gomp_iter_guided_next_locked (long *pstart, long *pend)
if (ws->next == ws->end)
return false;
- n = (ws->end - ws->next) / ws->incr;
+ start = ws->next;
+ n = (ws->end - start) / ws->incr;
q = (n + nthreads - 1) / nthreads;
if (q < ws->chunk_size)
q = ws->chunk_size;
- if (q > n)
- q = n;
-
- start = ws->next;
- end = start + q * ws->incr;
+ if (q <= n)
+ end = start + q * ws->incr;
+ else
+ end = ws->end;
ws->next = end;
*pstart = start;
@@ -286,15 +286,15 @@ gomp_iter_guided_next (long *pstart, long *pend)
if (start == end)
return false;
- n = (end - start) / ws->incr;
+ n = (end - start) / incr;
q = (n + nthreads - 1) / nthreads;
if (q < chunk_size)
q = chunk_size;
- if (q > n)
- q = n;
-
- nend = start + q * incr;
+ if (__builtin_expect (q <= n, 1))
+ nend = start + q * incr;
+ else
+ nend = end;
tmp = __sync_val_compare_and_swap (&ws->next, start, nend);
if (__builtin_expect (tmp == start, 1))
diff --git a/contrib/gcclibs/libgomp/libgomp.h b/contrib/gcclibs/libgomp/libgomp.h
index 47e68e69cfec..7075250a87fc 100644
--- a/contrib/gcclibs/libgomp/libgomp.h
+++ b/contrib/gcclibs/libgomp/libgomp.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2007 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp).
@@ -246,8 +246,18 @@ extern unsigned long gomp_run_sched_chunk;
/* The attributes to be used during thread creation. */
extern pthread_attr_t gomp_thread_attr;
+/* Other variables. */
+
+extern unsigned short *gomp_cpu_affinity;
+extern size_t gomp_cpu_affinity_len;
+
/* Function prototypes. */
+/* affinity.c */
+
+extern void gomp_init_affinity (void);
+extern void gomp_init_thread_affinity (pthread_attr_t *);
+
/* alloc.c */
extern void *gomp_malloc (size_t) __attribute__((malloc));
diff --git a/contrib/gcclibs/libgomp/libgomp.texi b/contrib/gcclibs/libgomp/libgomp.texi
index c48cf93e089f..f92a5da77fd8 100644
--- a/contrib/gcclibs/libgomp/libgomp.texi
+++ b/contrib/gcclibs/libgomp/libgomp.texi
@@ -895,14 +895,25 @@ dynamic scheduling and a chunk size of 1 is used.
@cindex Environment Variable
@table @asis
@item @emph{Description}:
-A patch for this extension has been submitted, but was not yet applied at the
-time of writing.
-
-@item @emph{Reference}:
-@uref{http://gcc.gnu.org/ml/gcc-patches/2006-05/msg00982.html,
-GCC Patches Mailinglist}
-@uref{http://gcc.gnu.org/ml/gcc-patches/2006-05/msg01133.html,
-GCC Patches Mailinglist}
+Binds threads to specific CPUs. The variable should contain a space- or
+comma-separated list of CPUs. This list may contain different kind of
+entries: either single CPU numbers in any order, a range of CPUs (M-N)
+or a range with some stride (M-N:S). CPU numbers are zero based. For example,
+@code{GOMP_CPU_AFFINITY="0 3 1-2 4-15:2"} will bind the initial thread
+to CPU 0, the second to CPU 3, the third to CPU 1, the fourth to
+CPU 2, the fifth to CPU 4, the sixth through tenth to CPUs 6, 8, 10, 12,
+and 14 respectively and then start assigning back from the beginning of
+the list. @code{GOMP_CPU_AFFINITY=0} binds all threads to CPU 0.
+
+There is no GNU OpenMP library routine to determine whether a CPU affinity
+specification is in effect. As a workaround, language-specific library
+functions, e.g., @code{getenv} in C or @code{GET_ENVIRONMENT_VARIABLE} in
+Fortran, may be used to query the setting of the @code{GOMP_CPU_AFFINITY}
+environment variable. A defined CPU affinity on startup cannot be changed
+or disabled during the runtime of the application.
+
+If this environment variable is omitted, the host system will handle the
+assignment of threads to CPUs.
@end table
diff --git a/contrib/gcclibs/libgomp/omp.h.in b/contrib/gcclibs/libgomp/omp.h.in
index 44fda9088c33..5ebcdbb27351 100644
--- a/contrib/gcclibs/libgomp/omp.h.in
+++ b/contrib/gcclibs/libgomp/omp.h.in
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2007 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp).
@@ -49,36 +49,39 @@ typedef struct
#ifdef __cplusplus
extern "C" {
+# define __GOMP_NOTHROW throw ()
+#else
+# define __GOMP_NOTHROW __attribute__((__nothrow__))
#endif
-extern void omp_set_num_threads (int);
-extern int omp_get_num_threads (void);
-extern int omp_get_max_threads (void);
-extern int omp_get_thread_num (void);
-extern int omp_get_num_procs (void);
+extern void omp_set_num_threads (int) __GOMP_NOTHROW;
+extern int omp_get_num_threads (void) __GOMP_NOTHROW;
+extern int omp_get_max_threads (void) __GOMP_NOTHROW;
+extern int omp_get_thread_num (void) __GOMP_NOTHROW;
+extern int omp_get_num_procs (void) __GOMP_NOTHROW;
-extern int omp_in_parallel (void);
+extern int omp_in_parallel (void) __GOMP_NOTHROW;
-extern void omp_set_dynamic (int);
-extern int omp_get_dynamic (void);
+extern void omp_set_dynamic (int) __GOMP_NOTHROW;
+extern int omp_get_dynamic (void) __GOMP_NOTHROW;
-extern void omp_set_nested (int);
-extern int omp_get_nested (void);
+extern void omp_set_nested (int) __GOMP_NOTHROW;
+extern int omp_get_nested (void) __GOMP_NOTHROW;
-extern void omp_init_lock (omp_lock_t *);
-extern void omp_destroy_lock (omp_lock_t *);
-extern void omp_set_lock (omp_lock_t *);
-extern void omp_unset_lock (omp_lock_t *);
-extern int omp_test_lock (omp_lock_t *);
+extern void omp_init_lock (omp_lock_t *) __GOMP_NOTHROW;
+extern void omp_destroy_lock (omp_lock_t *) __GOMP_NOTHROW;
+extern void omp_set_lock (omp_lock_t *) __GOMP_NOTHROW;
+extern void omp_unset_lock (omp_lock_t *) __GOMP_NOTHROW;
+extern int omp_test_lock (omp_lock_t *) __GOMP_NOTHROW;
-extern void omp_init_nest_lock (omp_nest_lock_t *);
-extern void omp_destroy_nest_lock (omp_nest_lock_t *);
-extern void omp_set_nest_lock (omp_nest_lock_t *);
-extern void omp_unset_nest_lock (omp_nest_lock_t *);
-extern int omp_test_nest_lock (omp_nest_lock_t *);
+extern void omp_init_nest_lock (omp_nest_lock_t *) __GOMP_NOTHROW;
+extern void omp_destroy_nest_lock (omp_nest_lock_t *) __GOMP_NOTHROW;
+extern void omp_set_nest_lock (omp_nest_lock_t *) __GOMP_NOTHROW;
+extern void omp_unset_nest_lock (omp_nest_lock_t *) __GOMP_NOTHROW;
+extern int omp_test_nest_lock (omp_nest_lock_t *) __GOMP_NOTHROW;
-extern double omp_get_wtime (void);
-extern double omp_get_wtick (void);
+extern double omp_get_wtime (void) __GOMP_NOTHROW;
+extern double omp_get_wtick (void) __GOMP_NOTHROW;
#ifdef __cplusplus
}
diff --git a/contrib/gcclibs/libgomp/omp_lib.h.in b/contrib/gcclibs/libgomp/omp_lib.h.in
index 734f2f781fc3..2376b23bd301 100644
--- a/contrib/gcclibs/libgomp/omp_lib.h.in
+++ b/contrib/gcclibs/libgomp/omp_lib.h.in
@@ -38,16 +38,16 @@
external omp_set_num_threads
external omp_get_dynamic, omp_get_nested
- logical*4 omp_get_dynamic, omp_get_nested
+ logical(4) omp_get_dynamic, omp_get_nested
external omp_test_lock, omp_in_parallel
- logical*4 omp_test_lock, omp_in_parallel
+ logical(4) omp_test_lock, omp_in_parallel
external omp_get_max_threads, omp_get_num_procs
- integer*4 omp_get_max_threads, omp_get_num_procs
+ integer(4) omp_get_max_threads, omp_get_num_procs
external omp_get_num_threads, omp_get_thread_num
- integer*4 omp_get_num_threads, omp_get_thread_num
+ integer(4) omp_get_num_threads, omp_get_thread_num
external omp_test_nest_lock
- integer*4 omp_test_nest_lock
+ integer(4) omp_test_nest_lock
external omp_get_wtick, omp_get_wtime
double precision omp_get_wtick, omp_get_wtime
diff --git a/contrib/gcclibs/libgomp/team.c b/contrib/gcclibs/libgomp/team.c
index 060f4ea2c6b7..7d50bfc29af8 100644
--- a/contrib/gcclibs/libgomp/team.c
+++ b/contrib/gcclibs/libgomp/team.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp).
@@ -183,6 +183,7 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
struct gomp_team *team;
bool nested;
unsigned i, n, old_threads_used = 0;
+ pthread_attr_t thread_attr, *attr;
thr = gomp_thread ();
nested = thr->ts.team != NULL;
@@ -265,6 +266,17 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
}
}
+ attr = &gomp_thread_attr;
+ if (gomp_cpu_affinity != NULL)
+ {
+ size_t stacksize;
+ pthread_attr_init (&thread_attr);
+ pthread_attr_setdetachstate (&thread_attr, PTHREAD_CREATE_DETACHED);
+ if (! pthread_attr_getstacksize (&gomp_thread_attr, &stacksize))
+ pthread_attr_setstacksize (&thread_attr, stacksize);
+ attr = &thread_attr;
+ }
+
start_data = gomp_alloca (sizeof (struct gomp_thread_start_data)
* (nthreads-i));
@@ -283,12 +295,17 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
start_data->fn_data = data;
start_data->nested = nested;
- err = pthread_create (&pt, &gomp_thread_attr,
- gomp_thread_start, start_data);
+ if (gomp_cpu_affinity != NULL)
+ gomp_init_thread_affinity (attr);
+
+ err = pthread_create (&pt, attr, gomp_thread_start, start_data);
if (err != 0)
gomp_fatal ("Thread creation failed: %s", strerror (err));
}
+ if (gomp_cpu_affinity != NULL)
+ pthread_attr_destroy (&thread_attr);
+
do_release:
gomp_barrier_wait (nested ? &team->barrier : &gomp_threads_dock);
diff --git a/contrib/ldns/drill/config.h b/contrib/ldns/drill/config.h
index 74b1e40a4112..f012625feb74 100644
--- a/contrib/ldns/drill/config.h
+++ b/contrib/ldns/drill/config.h
@@ -122,7 +122,7 @@
#define PACKAGE_NAME "ldns"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "ldns 1.6.16"
+#define PACKAGE_STRING "ldns 1.6.17"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libdns"
@@ -131,7 +131,7 @@
#define PACKAGE_URL ""
/* Define to the version of this package. */
-#define PACKAGE_VERSION "1.6.16"
+#define PACKAGE_VERSION "1.6.17"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
diff --git a/contrib/ldns/drill/drill.1 b/contrib/ldns/drill/drill.1
index 971b73ab7035..cfbde05f53f4 100644
--- a/contrib/ldns/drill/drill.1
+++ b/contrib/ldns/drill/drill.1
@@ -83,6 +83,11 @@ Chase the signature(s) of 'name' to a known key or as high up in
the tree as possible.
.TP
+\fB\-I \fIIPv4 or IPv6 address\fR
+Source address to query from. The source address has to be present
+on an interface of the host running drill.
+
+.TP
\fB\-V \fIlevel\fR
Be more verbose. Set level to 5 to see the actual query that is sent.
@@ -217,6 +222,12 @@ specify named base64 tsig key, and optional an algorithm (defaults to hmac-md5.s
\fB\-z \fR
don't randomize the nameserver list before sending queries.
+.SH "EXIT STATUS"
+The exit status is 0 if the looked up answer is secure and trusted,
+or insecure.
+The exit status is not 0 if the looked up answer is untrusted or bogus,
+or an error occurred while performing the lookup.
+
.SH "FILES"
.TP
/etc/unbound/root.key
diff --git a/contrib/ldns/freebsd-configure.sh b/contrib/ldns/freebsd-configure.sh
new file mode 100755
index 000000000000..3ad644664196
--- /dev/null
+++ b/contrib/ldns/freebsd-configure.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+#
+# $FreeBSD$
+#
+
+set -e
+
+ldns=$(dirname $(realpath $0))
+cd $ldns
+
+libtoolize --copy
+autoheader
+autoconf
+./configure --prefix= --exec-prefix=/usr
+
+cd $ldns/drill
+autoheader
+autoconf
+./configure --prefix= --exec-prefix=/usr
diff --git a/contrib/ldns/packaging/fedora/ldns.spec b/contrib/ldns/packaging/fedora/ldns.spec
new file mode 100644
index 000000000000..6658d011a000
--- /dev/null
+++ b/contrib/ldns/packaging/fedora/ldns.spec
@@ -0,0 +1,212 @@
+%{?!with_python: %global with_python 1}
+
+%if %{with_python}
+%{!?python_sitelib: %global python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")}
+%{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")}
+%endif
+
+Summary: Lowlevel DNS(SEC) library with API
+Name: ldns
+Version: 1.6.13
+Release: 1%{?dist}
+License: BSD
+Url: http://www.nlnetlabs.nl/%{name}/
+Source: http://www.nlnetlabs.nl/downloads/%{%name}/%{name}-%{version}.tar.gz
+Group: System Environment/Libraries
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+BuildRequires: perl, libpcap-devel, openssl-devel , gcc-c++, doxygen,
+# Only needed for builds from svn snapshot
+# BuildRequires: libtool, autoconf, automake
+
+%if %{with_python}
+BuildRequires: python-devel, swig
+%endif
+
+%description
+ldns is a library with the aim to simplify DNS programing in C. All
+lowlevel DNS/DNSSEC operations are supported. We also define a higher
+level API which allows a programmer to (for instance) create or sign
+packets.
+
+%package devel
+Summary: Development package that includes the ldns header files
+Group: Development/Libraries
+Requires: %{name} = %{version}-%{release}
+
+%description devel
+The devel package contains the ldns library and the include files
+
+%if %{with_python}
+%package python
+Summary: Python extensions for ldns
+Group: Applications/System
+Requires: %{name} = %{version}-%{release}
+
+%description python
+Python extensions for ldns
+%endif
+
+%prep
+%setup -q
+# To built svn snapshots
+# rm config.guess config.sub ltmain.sh
+# aclocal
+# libtoolize -c
+# autoreconf
+
+%build
+%configure --disable-rpath --disable-static --with-sha2 --disable-gost \
+%if %{with_python}
+ --with-pyldns
+%endif
+
+(cd drill ; %configure --disable-rpath --disable-static --with-sha2 --disable-gost --with-ldns=%{buildroot}/lib/ )
+(cd examples ; %configure --disable-rpath --disable-static --with-sha2 --disable-gost --with-ldns=%{buildroot}/lib/ )
+
+make %{?_smp_mflags}
+( cd drill ; make %{?_smp_mflags} )
+( cd examples ; make %{?_smp_mflags} )
+make %{?_smp_mflags} doc
+
+%install
+rm -rf %{buildroot}
+
+make DESTDIR=%{buildroot} INSTALL="%{__install} -p" install
+make DESTDIR=%{buildroot} INSTALL="%{__install} -p" install-doc
+
+# don't install another set of man pages from doc/
+rm -rf doc/man/
+
+# don't package building script for install-doc in doc section
+rm doc/doxyparse.pl
+
+# remove .la files
+rm -rf %{buildroot}%{_libdir}/*.la %{buildroot}%{python_sitearch}/*.la
+(cd drill ; make DESTDIR=%{buildroot} install)
+(cd examples; make DESTDIR=%{buildroot} install)
+
+%clean
+rm -rf %{buildroot}
+
+%files
+%defattr(-,root,root)
+%{_libdir}/libldns*so.*
+%{_bindir}/drill
+%{_bindir}/ldnsd
+%{_bindir}/ldns-chaos
+%{_bindir}/ldns-compare-zones
+%{_bindir}/ldns-[d-z]*
+%doc README LICENSE
+%{_mandir}/*/*
+
+%files devel
+%defattr(-,root,root,-)
+%{_libdir}/libldns*so
+%{_bindir}/ldns-config
+%dir %{_includedir}/ldns
+%{_includedir}/ldns/*.h
+%doc doc Changelog README
+
+%if %{with_python}
+%files python
+%defattr(-,root,root)
+%{python_sitearch}/*
+%endif
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+%changelog
+* Thu Sep 22 2011 Paul Wouters <paul@xelerance.com> - 1.6.11-1
+- Updated to 1.6.11
+- Cleanup spec for
+- Python goes into sitearch, not sitelib
+
+* Wed Jun 08 2011 Paul Wouters <paul@xelerance.com> - 1.6.10-1
+- Updated to 1.6.10
+- commented out build dependancies for svn snapshots
+
+* Sun Mar 27 2011 Paul Wouters <paul@xelerance.com> - 1.6.9-1
+- Updated to 1.6.9
+
+* Mon Jan 24 2011 Paul Wouters <paul@xelerance.com> - 1.6.8-1
+- Updated to 1.6.8
+
+* Thu Aug 26 2010 Paul Wouters <paul@xelerance.com> - 1.6.6-1
+- Upgraded to 1.6.6
+
+* Mon Apr 26 2010 Paul Wouters <paul@xelerance.com> - 1.6.4-4
+- Disable a debug line that was added to find the LOC issue that causes
+ unexpected output for automated tools using ldns-read-zone
+
+* Thu Feb 11 2010 Paul Wouters <paul@xelerance.com> - 1.6.4-3
+- Applied fix svn 3186 for LOC record parsing
+
+* Fri Jan 22 2010 Paul Wouters <paul@xelerance.com> - 1.6.4-2
+- libtool on EL-5 does not take --install as argument
+
+* Fri Jan 22 2010 Paul Wouters <paul@xelerance.com> - 1.6.4-1
+- Upgraded to 1.6.4
+- Added ldns-python sub package
+- Patch for installing ldns-python files
+- Patch for rpath in ldns-python
+
+* Sun Aug 16 2009 Paul Wouters <paul@xelerance.com> - 1.6.1-2
+- Bump version, sources file was not updated.
+
+* Sun Aug 16 2009 Paul Wouters <paul@xelerance.com> - 1.6.1-1
+-Updated to 1.6.1
+
+* Sat Jul 11 2009 Paul Wouters <paul@xelerance.com> - 1.6.0-1
+- Updated to 1.6.0
+
+* Thu Apr 16 2009 Paul Wouters <paul@xelerance.com> - 1.5.1-2
+- Memory management bug when generating a sha256 key, see:
+ https://bugzilla.redhat.com/show_bug.cgi?id=493953
+
+* Fri Feb 13 2009 Paul Wouters <paul@xelerance.com> - 1.5.1-1
+- Upgrade to 1.5.1 (1.5.0 was a dud release)
+
+* Sun Nov 9 2008 Paul Wouters <paul@xelerance.com> - 1.4.0-2
+- libldns.so was missing in files section.
+
+* Sun Nov 9 2008 Paul Wouters <paul@xelerance.com> - 1.4.0-1
+- Updated to 1.4.0
+- enable SHA2 functionality
+
+* Mon Jun 30 2008 Paul Wouters <paul@xelerance.com> - 1.3.0-1
+- Updated to latest release
+
+* Thu Nov 29 2007 Paul Wouters <paul@xelerance.com> - 1.2.2-1
+- Upgraded to 1.2.2.
+
+* Mon Sep 11 2006 Paul Wouters <paul@xelerance.com> 1.0.1-4
+- Commented out 1.1.0 make targets, put make 1.0.1 targets.
+
+* Mon Sep 11 2006 Paul Wouters <paul@xelerance.com> 1.0.1-3
+- Fixed changelog typo in date
+- Rebuild requested for PT_GNU_HASH support from gcc
+- Did not upgrade to 1.1.0 due to compile issues on x86_64
+
+* Fri Jan 6 2006 Paul Wouters <paul@xelerance.com> 1.0.1-1
+- Upgraded to 1.0.1. Removed temporary clean hack from spec file.
+
+* Sun Dec 18 2005 Paul Wouters <paul@xelerance.com> 1.0.0-8
+- Cannot use make clean because there are no Makefiles. Use hardcoded rm.
+
+* Sun Dec 18 2005 Paul Wouters <paul@xelerance.com> 1.0.0-7
+- Patched 'make clean' target to get rid of object files shipped with 1.0.0
+
+* Sun Dec 13 2005 Paul Wouters <paul@xelerance.com> 1.0.0-6
+- added a make clean for 2.3.3 since .o files were left behind upstream,
+ causing failure on ppc platform
+
+* Sun Dec 11 2005 Tom "spot" Callaway <tcallawa@redhat.com> 1.0.0-5
+- minor cleanups
+
+* Wed Oct 5 2005 Paul Wouters <paul@xelerance.com> 0.70_1205
+- reworked for svn version
+
+* Sun Sep 25 2005 Paul Wouters <paul@xelerance.com> - 0.70
+- Initial version
diff --git a/contrib/ldns/packaging/ldns-config.1 b/contrib/ldns/packaging/ldns-config.1
new file mode 100644
index 000000000000..c5a00a1eb384
--- /dev/null
+++ b/contrib/ldns/packaging/ldns-config.1
@@ -0,0 +1,43 @@
+.TH ldns-config 1 "22 Sep 2011"
+.SH NAME
+ldns-config \- show compiler and linker flags for ldns usage.
+.SH SYNOPSIS
+.B ldns-config
+[
+.IR OPTIONS
+]
+
+.SH DESCRIPTION
+When writing programs using ldns, you have to tell the compiler
+where to look for include files and what libraries from which location
+to link to. \fBldns-config\fR can be used to find out what flags to use
+with the C compiler and the linker.
+
+.SH OPTIONS
+.TP
+\fB--cflags\fR
+Show the C compiler flags needed to compile with ldns
+
+.TP
+\fB--libs\fR
+Show the flags to be used to link with ldns
+
+.TP
+\fB--version\fR
+Shows the version of the installed ldns library
+
+.TP
+\fB--help\fR
+Show \fBldns-config\fR usage description
+
+.SH AUTHOR
+Written by the ldns team.
+
+.SH REPORTING BUGS
+Report bugs to <ldns-team@nlnetlabs.nl>.
+
+.SH COPYRIGHT
+Copyright (C) 2011 NLnet Labs. This is free software. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE.
+
diff --git a/contrib/ldns/packaging/ldns-config.in b/contrib/ldns/packaging/ldns-config.in
new file mode 100755
index 000000000000..b728ba544e12
--- /dev/null
+++ b/contrib/ldns/packaging/ldns-config.in
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+prefix="@prefix@"
+exec_prefix="@exec_prefix@"
+VERSION="@PACKAGE_VERSION@"
+CFLAGS="@CFLAGS@"
+CPPFLAGS="@CPPFLAGS@ @LIBSSL_CPPFLAGS@ @PYTHON_CPPFLAGS@"
+LDFLAGS="@LDFLAGS@ @LIBSSL_LDFLAGS@ @PYTHON_LDFLAGS@"
+LIBS="@LIBS@ @LIBSSL_LIBS@"
+LIBDIR="@libdir@"
+INCLUDEDIR="@includedir@"
+
+for arg in $@
+do
+ if [ $arg = "--cflags" ]
+ then
+ echo "-I${INCLUDEDIR}"
+ fi
+ if [ $arg = "--libs" ]
+ then
+ echo "${LDFLAGS} -L${LIBDIR} ${LIBS} -lldns"
+ fi
+ if [ $arg = "-h" ] || [ $arg = "--help" ]
+ then
+ echo "Usage: $0 [--cflags] [--libs] [--version]"
+ fi
+ if [ $arg = "--version" ]
+ then
+ echo "${VERSION}"
+ fi
+done
diff --git a/contrib/ldns/packaging/libldns.pc.in b/contrib/ldns/packaging/libldns.pc.in
new file mode 100644
index 000000000000..923b688379d7
--- /dev/null
+++ b/contrib/ldns/packaging/libldns.pc.in
@@ -0,0 +1,13 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: ldns
+Description: Library for DNS programming
+URL: http://www.nlnetlabs.nl/projects/ldns
+Version: @PACKAGE_VERSION@
+Requires:
+Libs: -L${libdir} -lldns
+Libs.private: @LDFLAGS@
+Cflags: -I${includedir}
diff --git a/contrib/libxo/Makefile.am b/contrib/libxo/Makefile.am
index 4ff2aad892d6..1abfd5e7cf25 100644
--- a/contrib/libxo/Makefile.am
+++ b/contrib/libxo/Makefile.am
@@ -10,7 +10,7 @@
ACLOCAL_AMFLAGS = -I m4
-SUBDIRS = libxo xo xolint tests doc
+SUBDIRS = libxo xo xolint xohtml tests doc
bin_SCRIPTS=libxo-config
dist_doc_DATA = Copyright
diff --git a/contrib/libxo/configure.ac b/contrib/libxo/configure.ac
index b2553b89ac5b..5491d573b18c 100644
--- a/contrib/libxo/configure.ac
+++ b/contrib/libxo/configure.ac
@@ -12,7 +12,7 @@
#
AC_PREREQ(2.2)
-AC_INIT([libxo], [0.2.0], [phil@juniper.net])
+AC_INIT([libxo], [0.3.2], [phil@juniper.net])
AM_INIT_AUTOMAKE([-Wall -Werror foreign -Wno-portability])
# Support silent build rules. Requires at least automake-1.11.
@@ -133,6 +133,14 @@ AC_ARG_ENABLE([debug],
AC_MSG_RESULT([$LIBXO_DEBUG])
AM_CONDITIONAL([LIBXO_DEBUG], [test "$LIBXO_DEBUG" != "no"])
+AC_MSG_CHECKING([whether to build with text-only rendering])
+AC_ARG_ENABLE([text-only],
+ [ --enable-text-only Turn on text-only rendering],
+ [LIBXO_TEXT_ONLY=yes; AC_DEFINE([LIBXO_TEXT_ONLY], [1], [Enable text-only rendering])],
+ [LIBXO_TEXT_ONLY=no])
+AC_MSG_RESULT([$LIBXO_TEXT_ONLY])
+AM_CONDITIONAL([LIBXO_TEXT_ONLY], [test "$LIBXO_TEXT_ONLY" != "no"])
+
AC_CHECK_LIB([m], [lrint])
AM_CONDITIONAL([HAVE_LIBM], [test "$HAVE_LIBM" != "no"])
@@ -233,6 +241,7 @@ AC_CONFIG_FILES([
libxo/xoversion.h
xo/Makefile
xolint/Makefile
+ xohtml/Makefile
packaging/libxo.pc
doc/Makefile
tests/Makefile
@@ -253,6 +262,7 @@ AC_MSG_NOTICE([summary of build options:
bindir: ${XO_BINDIR}
includedir: ${XO_INCLUDEDIR}
share dir: ${XO_SHAREDIR}
+ oxtradoc dir: ${SLAX_OXTRADOCDIR}
compiler: ${CC} (${HAVE_GCC:-no})
compiler flags: ${CFLAGS}
@@ -262,4 +272,5 @@ AC_MSG_NOTICE([summary of build options:
debug: ${LIBXO_DEBUG:-no}
printf-like: ${HAVE_PRINTFLIKE:-no}
libxo-options: ${LIBXO_OPTS:-no}
+ text-only: ${LIBXO_TEXT_ONLY:-no}
])
diff --git a/contrib/libxo/doc/libxo.txt b/contrib/libxo/doc/libxo.txt
index 31aec5333b51..81a40b61f06d 100644
--- a/contrib/libxo/doc/libxo.txt
+++ b/contrib/libxo/doc/libxo.txt
@@ -134,7 +134,7 @@ A single libxo function call in source code is all that's required:
<host>my-box</host>
<domain>example.com</domain>
JSON:
- "host": my-box",
+ "host": "my-box",
"domain": "example.com"
For brevity, the HTML output is emitted.
@@ -228,17 +228,17 @@ data, including data type, description, and an XPath location.
<div class="line">
<div class="data" data-tag="blocks">36</div>
<div class="padding"> </div>
- <div class="data data-tag="path">./src</div>
+ <div class="data" data-tag="path">./src</div>
</div>
<div class="line">
<div class="data" data-tag="blocks">40</div>
<div class="padding"> </div>
- <div class="data data-tag="path">./bin</div>
+ <div class="data" data-tag="path">./bin</div>
</div>
<div class="line">
<div class="data" data-tag="blocks">90</div>
<div class="padding"> </div>
- <div class="data data-tag="path">./</div>
+ <div class="data" data-tag="path">./</div>
</div>
** Format Strings @format-strings@
@@ -285,6 +285,7 @@ content. The roles are listed below; only one role is permitted:
|---+--------------+-------------------------------------------------|
| M | Name | Description |
|---+--------------+-------------------------------------------------|
+| C | color/effect | Field has color and effect controls |
| D | decoration | Field is non-text (e.g., colon, comma) |
| E | error | Field is an error message |
| L | label | Field is text that prefixes a value |
@@ -298,6 +299,56 @@ content. The roles are listed below; only one role is permitted:
| ] | stop anchor | End a section of anchored variable-width text |
|---+--------------+-------------------------------------------------|
+**** The Color Role ({C:})
+
+Colors and effects control how text values are displayed; they are
+used for display styles (TEXT and HTML). The color content can be
+either static, when placed directly within the field descriptor, or a
+printf-style format descriptor can be used, if preceded by a slash ("/"):
+
+ xo_emit("{C:bold}{Lwc:Cost}{:cost/%u}{C:reset}\n", cost);
+ xo_emit("{C:/fg-%s,bg-%s}{Lwc:Cost}{:cost/%u}{C:reset}\n",
+ fg_color, bg_color, cost);
+
+The content should be a comma-separated list of zero or more colors or
+display effects. Colors and effects remain in effect until
+modified by other "C" roles. If the content is empty, the "reset"
+action is performed.
+
+|---------------+-------------------------------------------------|
+| Name | Description |
+|---------------+-------------------------------------------------|
+| bg-XXXXX | Change background color |
+| bold | Start bold text effect |
+| fg-XXXXX | Change foreground color |
+| inverse | Start inverse (aka reverse) text effect |
+| no-bold | Stop bold text effect |
+| no-inverse | Stop inverse (aka reverse) text effect |
+| no-underline | Stop underline text effect |
+| normal | Reset effects (only) |
+| reset | Reset colors and effects (restore defaults) |
+| underline | Start underline text effect |
+|---------------+-------------------------------------------------|
+
+The following color names are supported:
+
+|---------------|
+| Name |
+|---------------|
+| black |
+| blue |
+| cyan |
+| default |
+| green |
+| magenta |
+| red |
+| white |
+| yellow |
+|---------------|
+
+Color names are prefixed with either "fg-" or "bg-" to change the
+foreground and background colors, respectively.
+
**** The Decoration Role ({D:})
Decorations are typically punctuation marks such as colons,
@@ -1404,9 +1455,21 @@ functions like xo_failure, xo_warn, xo_err, etc. The program name is
initialized by xo_parse_args, but subsequent calls to xo_set_program
can override this value.
+ xo_set_program(argv[0]);
+
Note that the value is not copied, so the memory passed to
xo_set_program (and xo_parse_args) must be maintained by the caller.
+*** xo_set_version
+
+The xo_set_version function records a version number to be emitted as
+part of the data for encoding styles (XML and JSON). This version
+number is suitable for tracking changes in the content, allowing a
+user of the data to discern which version of the data model is in use.
+
+ void xo_set_version (const char *version);
+ void xo_set_version_h (xo_handle_t *xop, const char *version);
+
*** Field Information (xo_info_t) @info@
HTML data can include additional information in attributes that
@@ -1705,6 +1768,32 @@ The "-V" option does not report errors, but prints a complete list of
all field names, sorted alphabetically. The output can help spot
inconsistencies and spelling errors.
+* xohtml
+
+xohtml is a tool for turning the output of libxo-enabled commands into
+html files suitable for display in modern HTML web browsers. It can
+be used to test and debug HTML output, as well as to make the user
+ache to escape the world of 70s terminal devices.
+
+xohtml is given a command, either on the command line or via the "-c"
+option. If not command is given, standard input is used. The
+command's output is wrapped in HTML tags, with references to
+supporting CSS and Javascript files, and written to standard output or
+the file given in the "-f" option. The "-b" option can be used to
+provide an alternative base path for the support files.
+
+|--------------+---------------------------------------------------|
+| Option | Meaning |
+|--------------+---------------------------------------------------|
+| -b <base> | Base path for finding css/javascript files |
+| -c <command> | Command to execute |
+| -f <file> | Output file name |
+|--------------+---------------------------------------------------|
+
+The "-c" option takes a full command with arguments, including
+any libxo options needed to generate html ("--libxo=html"). This
+value must be quoted if it consists of multiple tokens.
+
* FAQs
This section contains the set of questions that users typically ask,
diff --git a/contrib/libxo/libxo/Makefile.am b/contrib/libxo/libxo/Makefile.am
index 3303e94e4372..0047b6322586 100644
--- a/contrib/libxo/libxo/Makefile.am
+++ b/contrib/libxo/libxo/Makefile.am
@@ -38,12 +38,15 @@ man_MANS = \
xo_no_setlocale.3 \
xo_open_container.3 \
xo_open_list.3 \
+ xo_open_marker.3 \
xo_parse_args.3 \
xo_set_allocator.3 \
xo_set_flags.3 \
xo_set_info.3 \
xo_set_options.3 \
xo_set_style.3 \
+ xo_set_version.3 \
xo_set_writer.3
-EXTRA_DIST =
+EXTRA_DIST = ${man_MANS}
+
diff --git a/contrib/libxo/libxo/libxo.c b/contrib/libxo/libxo/libxo.c
index e9d05ce0ceb3..4fd18fd01bb4 100644
--- a/contrib/libxo/libxo/libxo.c
+++ b/contrib/libxo/libxo/libxo.c
@@ -121,6 +121,50 @@ typedef struct xo_stack_s {
char *xs_keys; /* XPath predicate for any key fields */
} xo_stack_t;
+/* "colors" refers to fancy ansi codes */
+#define XO_COL_DEFAULT 0
+#define XO_COL_BLACK 1
+#define XO_COL_RED 2
+#define XO_COL_GREEN 3
+#define XO_COL_YELLOW 4
+#define XO_COL_BLUE 5
+#define XO_COL_MAGENTA 6
+#define XO_COL_CYAN 7
+#define XO_COL_WHITE 8
+
+#define XO_NUM_COLORS 9
+
+/* "effects" refers to fancy ansi codes */
+/*
+ * Yes, there's no blink. We're civilized. We like users. Blink
+ * isn't something one does to someone you like. Friends don't let
+ * friends use blink. On friends. You know what I mean. Blink is
+ * like, well, it's like bursting into show tunes at a funeral. It's
+ * just not done. Not something anyone wants. And on those rare
+ * instances where it might actually be appropriate, it's still wrong.
+ * It's likely done my the wrong person for the wrong reason. Just
+ * like blink. And if I implemented blink, I'd be like a funeral
+ * director who adds "Would you like us to burst into show tunes?" on
+ * the list of questions asking while making funeral arrangements.
+ * It's formalizing wrongness in the wrong way. And we're just too
+ * civilized to do that. Hhhmph!
+ */
+#define XO_EFF_RESET (1<<0)
+#define XO_EFF_NORMAL (1<<1)
+#define XO_EFF_BOLD (1<<2)
+#define XO_EFF_UNDERLINE (1<<3)
+#define XO_EFF_INVERSE (1<<4)
+
+#define XO_EFF_CLEAR_BITS XO_EFF_RESET
+
+typedef uint8_t xo_effect_t;
+typedef uint8_t xo_color_t;
+typedef struct xo_colors_s {
+ xo_effect_t xoc_effects; /* Current effect set */
+ xo_color_t xoc_col_fg; /* Foreground color */
+ xo_color_t xoc_col_bg; /* Background color */
+} xo_colors_t;
+
/*
* xo_handle_t: this is the principle data structure for libxo.
* It's used as a store for state, options, and content.
@@ -136,7 +180,6 @@ struct xo_handle_s {
xo_formatter_t xo_formatter; /* Custom formating function */
xo_checkpointer_t xo_checkpointer; /* Custom formating support function */
void *xo_opaque; /* Opaque data for write function */
- FILE *xo_fp; /* XXX File pointer */
xo_buffer_t xo_data; /* Output data */
xo_buffer_t xo_fmt; /* Work area for building format strings */
xo_buffer_t xo_attrs; /* Work area for building XML attributes */
@@ -154,6 +197,11 @@ struct xo_handle_s {
int xo_anchor_min_width; /* Desired width of anchored text */
unsigned xo_units_offset; /* Start of units insertion point */
unsigned xo_columns; /* Columns emitted during this xo_emit call */
+ uint8_t xo_color_map_fg[XO_NUM_COLORS]; /* Foreground color mappings */
+ uint8_t xo_color_map_bg[XO_NUM_COLORS]; /* Background color mappings */
+ xo_colors_t xo_colors; /* Current color and effect values */
+ xo_buffer_t xo_color_buf; /* HTML: buffer of colors and effects */
+ char *xo_version; /* Version string */
};
/* Flags for formatting functions */
@@ -161,7 +209,7 @@ typedef unsigned long xo_xff_flags_t;
#define XFF_COLON (1<<0) /* Append a ":" */
#define XFF_COMMA (1<<1) /* Append a "," iff there's more output */
#define XFF_WS (1<<2) /* Append a blank */
-#define XFF_ENCODE_ONLY (1<<3) /* Only emit for encoding formats (xml and json) */
+#define XFF_ENCODE_ONLY (1<<3) /* Only emit for encoding formats (xml, json) */
#define XFF_QUOTE (1<<4) /* Force quotes */
#define XFF_NOQUOTE (1<<5) /* Force no quotes */
@@ -277,6 +325,24 @@ static void
xo_anchor_clear (xo_handle_t *xop);
/*
+ * xo_style is used to retrieve the current style. When we're built
+ * for "text only" mode, we use this function to drive the removal
+ * of most of the code in libxo. We return a constant and the compiler
+ * happily removes the non-text code that is not longer executed. This
+ * trims our code nicely without needing to trampel perfectly readable
+ * code with ifdefs.
+ */
+static inline unsigned short
+xo_style (xo_handle_t *xop UNUSED)
+{
+#ifdef LIBXO_TEXT_ONLY
+ return XO_STYLE_TEXT;
+#else /* LIBXO_TEXT_ONLY */
+ return xop->xo_style;
+#endif /* LIBXO_TEXT_ONLY */
+}
+
+/*
* Callback to write data to a FILE pointer
*/
static int
@@ -321,6 +387,24 @@ xo_buf_init (xo_buffer_t *xbp)
}
/*
+ * Reset the buffer to empty
+ */
+static void
+xo_buf_reset (xo_buffer_t *xbp)
+{
+ xbp->xb_curp = xbp->xb_bufp;
+}
+
+/*
+ * Reset the buffer to empty
+ */
+static int
+xo_buf_is_empty (xo_buffer_t *xbp)
+{
+ return (xbp->xb_curp == xbp->xb_bufp);
+}
+
+/*
* Initialize the contents of an xo_buffer_t.
*/
static void
@@ -363,8 +447,8 @@ xo_no_setlocale (void)
/*
* We need to decide if stdout is line buffered (_IOLBF). Lacking a
* standard way to decide this (e.g. getlinebuf()), we have configure
- * look to find __flbf, which glibc supported. If not, we'll rely
- * on isatty, with the assumption that terminals are the only thing
+ * look to find __flbf, which glibc supported. If not, we'll rely on
+ * isatty, with the assumption that terminals are the only thing
* that's line buffered. We _could_ test for "steam._flags & _IOLBF",
* which is all __flbf does, but that's even tackier. Like a
* bedazzled Elvis outfit on an ugly lap dog sort of tacky. Not
@@ -399,6 +483,13 @@ xo_init_handle (xo_handle_t *xop)
xop->xo_flags |= XOF_FLUSH_LINE;
/*
+ * We only want to do color output on terminals, but we only want
+ * to do this if the user has asked for color.
+ */
+ if ((xop->xo_flags & XOF_COLOR_ALLOWED) && isatty(1))
+ xop->xo_flags |= XOF_COLOR;
+
+ /*
* We need to initialize the locale, which isn't really pretty.
* Libraries should depend on their caller to set up the
* environment. But we really can't count on the caller to do
@@ -497,7 +588,7 @@ xo_default (xo_handle_t *xop)
/*
* Return the number of spaces we should be indenting. If
- * we are pretty-printing, theis is indent * indent_by.
+ * we are pretty-printing, this is indent * indent_by.
*/
static int
xo_indent (xo_handle_t *xop)
@@ -647,6 +738,21 @@ xo_buf_append (xo_buffer_t *xbp, const char *str, int len)
xbp->xb_curp += len;
}
+/*
+ * Append the given NUL-terminated string to the given buffer
+ */
+static void
+xo_buf_append_str (xo_buffer_t *xbp, const char *str)
+{
+ int len = strlen(str);
+
+ if (!xo_buf_has_room(xbp, len))
+ return;
+
+ memcpy(xbp->xb_curp, str, len);
+ xbp->xb_curp += len;
+}
+
static void
xo_buf_escape (xo_handle_t *xop, xo_buffer_t *xbp,
const char *str, int len, xo_xff_flags_t flags)
@@ -656,7 +762,7 @@ xo_buf_escape (xo_handle_t *xop, xo_buffer_t *xbp,
memcpy(xbp->xb_curp, str, len);
- switch (xop->xo_style) {
+ switch (xo_style(xop)) {
case XO_STYLE_XML:
case XO_STYLE_HTML:
len = xo_escape_xml(xbp, len, (flags & XFF_ATTR));
@@ -711,7 +817,7 @@ xo_vsnprintf (xo_handle_t *xop, xo_buffer_t *xbp, const char *fmt, va_list vap)
else
rc = vsnprintf(xbp->xb_curp, left, fmt, va_local);
- if (rc > xbp->xb_size) {
+ if (rc >= left) {
if (!xo_buf_has_room(xbp, rc)) {
va_end(va_local);
return -1;
@@ -721,7 +827,7 @@ xo_vsnprintf (xo_handle_t *xop, xo_buffer_t *xbp, const char *fmt, va_list vap)
* After we call vsnprintf(), the stage of vap is not defined.
* We need to copy it before we pass. Then we have to do our
* own logic below to move it along. This is because the
- * implementation can have va_list be a point (bsd) or a
+ * implementation can have va_list be a pointer (bsd) or a
* structure (macosx) or anything in between.
*/
@@ -730,7 +836,7 @@ xo_vsnprintf (xo_handle_t *xop, xo_buffer_t *xbp, const char *fmt, va_list vap)
left = xbp->xb_size - (xbp->xb_curp - xbp->xb_bufp);
if (xop->xo_formatter)
- xop->xo_formatter(xop, xbp->xb_curp, left, fmt, va_local);
+ rc = xop->xo_formatter(xop, xbp->xb_curp, left, fmt, va_local);
else
rc = vsnprintf(xbp->xb_curp, left, fmt, va_local);
}
@@ -1219,7 +1325,7 @@ xo_message_hcv (xo_handle_t *xop, int code, const char *fmt, va_list vap)
int need_nl = (fmt[strlen(fmt) - 1] != '\n');
- switch (xop->xo_style) {
+ switch (xo_style(xop)) {
case XO_STYLE_XML:
xbp = &xop->xo_data;
if (xop->xo_flags & XOF_PRETTY)
@@ -1431,6 +1537,10 @@ xo_destroy (xo_handle_t *xop_arg)
xo_buf_cleanup(&xop->xo_fmt);
xo_buf_cleanup(&xop->xo_predicate);
xo_buf_cleanup(&xop->xo_attrs);
+ xo_buf_cleanup(&xop->xo_color_buf);
+
+ if (xop->xo_version)
+ xo_free(xop->xo_version);
if (xop_arg == NULL) {
bzero(&xo_default_handle, sizeof(xo_default_handle));
@@ -1457,7 +1567,7 @@ xo_style_t
xo_get_style (xo_handle_t *xop)
{
xop = xo_default(xop);
- return xop->xo_style;
+ return xo_style(xop);
}
static int
@@ -1492,6 +1602,8 @@ xo_name_to_flag (const char *name)
return XOF_INFO;
if (strcmp(name, "warn-xml") == 0)
return XOF_WARN_XML;
+ if (strcmp(name, "color") == 0)
+ return XOF_COLOR_ALLOWED;
if (strcmp(name, "columns") == 0)
return XOF_COLUMNS;
if (strcmp(name, "dtrt") == 0)
@@ -1547,6 +1659,11 @@ xo_set_options (xo_handle_t *xop, const char *input)
xop = xo_default(xop);
+#ifdef LIBXO_COLOR_ON_BY_DEFAULT
+ /* If the installer used --enable-color-on-by-default, then we allow it */
+ xop->xo_flags |= XOF_COLOR_ALLOWED;
+#endif /* LIBXO_COLOR_ON_BY_DEFAULT */
+
/*
* We support a simpler, old-school style of giving option
* also, using a single character for each option. It's
@@ -1557,6 +1674,10 @@ xo_set_options (xo_handle_t *xop, const char *input)
for (input++ ; *input; input++) {
switch (*input) {
+ case 'c':
+ xop->xo_flags |= XOF_COLOR_ALLOWED;
+ break;
+
case 'f':
xop->xo_flags |= XOF_FLUSH;
break;
@@ -1634,6 +1755,11 @@ xo_set_options (xo_handle_t *xop, const char *input)
if (vp)
*vp++ = '\0';
+ if (strcmp("colors", cp) == 0) {
+ /* XXX Look for colors=red-blue+green-yellow */
+ continue;
+ }
+
new_style = xo_name_to_style(cp);
if (new_style >= 0) {
if (style >= 0)
@@ -1645,7 +1771,9 @@ xo_set_options (xo_handle_t *xop, const char *input)
if (new_flag != 0)
xop->xo_flags |= new_flag;
else {
- if (strcmp(cp, "indent") == 0) {
+ if (strcmp(cp, "no-color") == 0) {
+ xop->xo_flags &= ~XOF_COLOR_ALLOWED;
+ } else if (strcmp(cp, "indent") == 0) {
xop->xo_indent_by = atoi(vp);
} else {
xo_warnx("unknown option: '%s'", cp);
@@ -1801,7 +1929,7 @@ xo_line_ensure_open (xo_handle_t *xop, xo_xff_flags_t flags UNUSED)
if (xop->xo_flags & XOF_DIV_OPEN)
return;
- if (xop->xo_style != XO_STYLE_HTML)
+ if (xo_style(xop) != XO_STYLE_HTML)
return;
xop->xo_flags |= XOF_DIV_OPEN;
@@ -1819,7 +1947,7 @@ xo_line_close (xo_handle_t *xop)
{
static char div_close[] = "</div>";
- switch (xop->xo_style) {
+ switch (xo_style(xop)) {
case XO_STYLE_HTML:
if (!(xop->xo_flags & XOF_DIV_OPEN))
xo_line_ensure_open(xop, 0);
@@ -1976,7 +2104,7 @@ xo_format_string_direct (xo_handle_t *xop, xo_buffer_t *xbp,
if (width < 0)
width = iswcntrl(wc) ? 0 : 1;
- if (xop->xo_style == XO_STYLE_TEXT || xop->xo_style == XO_STYLE_HTML) {
+ if (xo_style(xop) == XO_STYLE_TEXT || xo_style(xop) == XO_STYLE_HTML) {
if (max > 0 && cols + width > max)
break;
}
@@ -1985,7 +2113,7 @@ xo_format_string_direct (xo_handle_t *xop, xo_buffer_t *xbp,
case XF_ENC_UTF8:
/* Output in UTF-8 needs to be escaped, based on the style */
- switch (xop->xo_style) {
+ switch (xo_style(xop)) {
case XO_STYLE_XML:
case XO_STYLE_HTML:
if (wc == '<')
@@ -2071,7 +2199,7 @@ xo_format_string (xo_handle_t *xop, xo_buffer_t *xbp, xo_xff_flags_t flags,
wchar_t *wcp = NULL;
int len, cols = 0, rc = 0;
int off = xbp->xb_curp - xbp->xb_bufp, off2;
- int need_enc = (xop->xo_style == XO_STYLE_TEXT)
+ int need_enc = (xo_style(xop) == XO_STYLE_TEXT)
? XF_ENC_LOCALE : XF_ENC_UTF8;
if (xo_check_conversion(xop, xfp->xf_enc, need_enc))
@@ -2185,7 +2313,7 @@ static void
xo_data_append_content (xo_handle_t *xop, const char *str, int len)
{
int cols;
- int need_enc = (xop->xo_style == XO_STYLE_TEXT)
+ int need_enc = (xo_style(xop) == XO_STYLE_TEXT)
? XF_ENC_LOCALE : XF_ENC_UTF8;
cols = xo_format_string_direct(xop, &xop->xo_data, XFF_UNESCAPE,
@@ -2246,9 +2374,9 @@ xo_format_data (xo_handle_t *xop, xo_buffer_t *xbp,
xo_format_t xf;
const char *cp, *ep, *sp, *xp = NULL;
int rc, cols;
- int style = (flags & XFF_XML) ? XO_STYLE_XML : xop->xo_style;
+ int style = (flags & XFF_XML) ? XO_STYLE_XML : xo_style(xop);
unsigned make_output = !(flags & XFF_NO_OUTPUT);
- int need_enc = (xop->xo_style == XO_STYLE_TEXT)
+ int need_enc = (xo_style(xop) == XO_STYLE_TEXT)
? XF_ENC_LOCALE : XF_ENC_UTF8;
if (xbp == NULL)
@@ -2310,11 +2438,11 @@ xo_format_data (xo_handle_t *xop, xo_buffer_t *xbp,
/* Hidden fields are only visible to JSON and XML */
if (xop->xo_flags & XFF_ENCODE_ONLY) {
if (style != XO_STYLE_XML
- && xop->xo_style != XO_STYLE_JSON)
+ && xo_style(xop) != XO_STYLE_JSON)
xf.xf_skip = 1;
} else if (xop->xo_flags & XFF_DISPLAY_ONLY) {
if (style != XO_STYLE_TEXT
- && xop->xo_style != XO_STYLE_HTML)
+ && xo_style(xop) != XO_STYLE_HTML)
xf.xf_skip = 1;
}
@@ -2420,8 +2548,8 @@ xo_format_data (xo_handle_t *xop, xo_buffer_t *xbp,
rc = xo_format_string(xop, xbp, flags, &xf);
if ((flags & XFF_TRIM_WS)
- && (xop->xo_style == XO_STYLE_XML
- || xop->xo_style == XO_STYLE_JSON))
+ && (xo_style(xop) == XO_STYLE_XML
+ || xo_style(xop) == XO_STYLE_JSON))
rc = xo_trim_ws(xbp, rc);
} else {
@@ -2567,6 +2695,20 @@ xo_fix_encoding (xo_handle_t *xop UNUSED, char *encoding)
}
static void
+xo_color_append_html (xo_handle_t *xop)
+{
+ /*
+ * If the color buffer has content, we add it now. It's already
+ * prebuilt and ready, since we want to add it to every <div>.
+ */
+ if (!xo_buf_is_empty(&xop->xo_color_buf)) {
+ xo_buffer_t *xbp = &xop->xo_color_buf;
+
+ xo_data_append(xop, xbp->xb_bufp, xbp->xb_curp - xbp->xb_bufp);
+ }
+}
+
+static void
xo_buf_append_div (xo_handle_t *xop, const char *class, xo_xff_flags_t flags,
const char *name, int nlen,
const char *value, int vlen,
@@ -2663,6 +2805,16 @@ xo_buf_append_div (xo_handle_t *xop, const char *class, xo_xff_flags_t flags,
xo_data_append(xop, div_start, sizeof(div_start) - 1);
xo_data_append(xop, class, strlen(class));
+ /*
+ * If the color buffer has content, we add it now. It's already
+ * prebuilt and ready, since we want to add it to every <div>.
+ */
+ if (!xo_buf_is_empty(&xop->xo_color_buf)) {
+ xo_buffer_t *xbp = &xop->xo_color_buf;
+
+ xo_data_append(xop, xbp->xb_bufp, xbp->xb_curp - xbp->xb_bufp);
+ }
+
if (name) {
xo_data_append(xop, div_tag, sizeof(div_tag) - 1);
xo_data_escape(xop, name, nlen);
@@ -2753,7 +2905,7 @@ xo_buf_append_div (xo_handle_t *xop, const char *class, xo_xff_flags_t flags,
static void
xo_format_text (xo_handle_t *xop, const char *str, int len)
{
- switch (xop->xo_style) {
+ switch (xo_style(xop)) {
case XO_STYLE_TEXT:
xo_buf_append_locale(xop, &xop->xo_data, str, len);
break;
@@ -2768,7 +2920,8 @@ static void
xo_format_title (xo_handle_t *xop, const char *str, int len,
const char *fmt, int flen)
{
- static char div_open[] = "<div class=\"title\">";
+ static char div_open[] = "<div class=\"title";
+ static char div_middle[] = "\">";
static char div_close[] = "</div>";
if (flen == 0) {
@@ -2776,7 +2929,7 @@ xo_format_title (xo_handle_t *xop, const char *str, int len,
flen = 2;
}
- switch (xop->xo_style) {
+ switch (xo_style(xop)) {
case XO_STYLE_XML:
case XO_STYLE_JSON:
/*
@@ -2794,12 +2947,14 @@ xo_format_title (xo_handle_t *xop, const char *str, int len,
int rc;
int need_enc = XF_ENC_LOCALE;
- if (xop->xo_style == XO_STYLE_HTML) {
+ if (xo_style(xop) == XO_STYLE_HTML) {
need_enc = XF_ENC_UTF8;
xo_line_ensure_open(xop, 0);
if (xop->xo_flags & XOF_PRETTY)
xo_buf_indent(xop, xop->xo_indent_by);
xo_buf_append(&xop->xo_data, div_open, sizeof(div_open) - 1);
+ xo_color_append_html(xop);
+ xo_buf_append(&xop->xo_data, div_middle, sizeof(div_middle) - 1);
}
start = xbp->xb_curp - xbp->xb_bufp; /* Reset start */
@@ -2862,7 +3017,7 @@ xo_format_title (xo_handle_t *xop, const char *str, int len,
}
/* If we're styling HTML, then we need to escape it */
- if (xop->xo_style == XO_STYLE_HTML) {
+ if (xo_style(xop) == XO_STYLE_HTML) {
rc = xo_escape_xml(xbp, rc, 0);
}
@@ -2870,7 +3025,7 @@ xo_format_title (xo_handle_t *xop, const char *str, int len,
xbp->xb_curp += rc;
move_along:
- if (xop->xo_style == XO_STYLE_HTML) {
+ if (xo_style(xop) == XO_STYLE_HTML) {
xo_data_append(xop, div_close, sizeof(div_close) - 1);
if (xop->xo_flags & XOF_PRETTY)
xo_data_append(xop, "\n", 1);
@@ -2978,7 +3133,7 @@ xo_format_value (xo_handle_t *xop, const char *name, int nlen,
}
}
- switch (xop->xo_style) {
+ switch (xo_style(xop)) {
case XO_STYLE_TEXT:
if (flags & XFF_ENCODE_ONLY)
flags |= XFF_NO_OUTPUT;
@@ -3103,7 +3258,9 @@ xo_format_value (xo_handle_t *xop, const char *name, int nlen,
}
if (flags & XFF_LEAF_LIST) {
- if (first && pretty)
+ if (!first && pretty)
+ xo_data_append(xop, "\n", 1);
+ if (pretty)
xo_buf_indent(xop, -1);
} else {
if (pretty)
@@ -3122,10 +3279,10 @@ xo_format_value (xo_handle_t *xop, const char *name, int nlen,
xbp->xb_bufp[off] = '_';
}
xo_data_append(xop, "\":", 2);
+ if (pretty)
+ xo_data_append(xop, " ", 1);
}
- if (pretty)
- xo_data_append(xop, " ", 1);
if (quote)
xo_data_append(xop, "\"", 1);
@@ -3142,7 +3299,7 @@ xo_format_content (xo_handle_t *xop, const char *class_name,
const char *xml_tag, int display_only,
const char *str, int len, const char *fmt, int flen)
{
- switch (xop->xo_style) {
+ switch (xo_style(xop)) {
case XO_STYLE_TEXT:
if (len) {
xo_data_append_content(xop, str, len);
@@ -3195,6 +3352,362 @@ xo_format_content (xo_handle_t *xop, const char *class_name,
}
}
+static const char *xo_color_names[] = {
+ "default", /* XO_COL_DEFAULT */
+ "black", /* XO_COL_BLACK */
+ "red", /* XO_CLOR_RED */
+ "green", /* XO_COL_GREEN */
+ "yellow", /* XO_COL_YELLOW */
+ "blue", /* XO_COL_BLUE */
+ "magenta", /* XO_COL_MAGENTA */
+ "cyan", /* XO_COL_CYAN */
+ "white", /* XO_COL_WHITE */
+ NULL
+};
+
+static int
+xo_color_find (const char *str)
+{
+ int i;
+
+ for (i = 0; xo_color_names[i]; i++) {
+ if (strcmp(xo_color_names[i], str) == 0)
+ return i;
+ }
+
+ return -1;
+}
+
+static const char *xo_effect_names[] = {
+ "reset", /* XO_EFF_RESET */
+ "normal", /* XO_EFF_NORMAL */
+ "bold", /* XO_EFF_BOLD */
+ "underline", /* XO_EFF_UNDERLINE */
+ "inverse", /* XO_EFF_INVERSE */
+ NULL
+};
+
+static const char *xo_effect_on_codes[] = {
+ "0", /* XO_EFF_RESET */
+ "0", /* XO_EFF_NORMAL */
+ "1", /* XO_EFF_BOLD */
+ "4", /* XO_EFF_UNDERLINE */
+ "7", /* XO_EFF_INVERSE */
+ NULL
+};
+
+#if 0
+/*
+ * See comment below re: joy of terminal standards. These can
+ * be use by just adding:
+ * if (newp->xoc_effects & bit)
+ * code = xo_effect_on_codes[i];
+ * + else
+ * + code = xo_effect_off_codes[i];
+ * in xo_color_handle_text.
+ */
+static const char *xo_effect_off_codes[] = {
+ "0", /* XO_EFF_RESET */
+ "0", /* XO_EFF_NORMAL */
+ "21", /* XO_EFF_BOLD */
+ "24", /* XO_EFF_UNDERLINE */
+ "27", /* XO_EFF_INVERSE */
+ NULL
+};
+#endif /* 0 */
+
+static int
+xo_effect_find (const char *str)
+{
+ int i;
+
+ for (i = 0; xo_effect_names[i]; i++) {
+ if (strcmp(xo_effect_names[i], str) == 0)
+ return i;
+ }
+
+ return -1;
+}
+
+static void
+xo_colors_parse (xo_handle_t *xop, xo_colors_t *xocp, char *str)
+{
+#ifdef LIBXO_TEXT_ONLY
+ return;
+#endif /* LIBXO_TEXT_ONLY */
+
+ char *cp, *ep, *np, *xp;
+ int len = strlen(str);
+ int rc;
+
+ /*
+ * Possible tokens: colors, bg-colors, effects, no-effects, "reset".
+ */
+ for (cp = str, ep = cp + len - 1; cp && cp < ep; cp = np) {
+ /* Trim leading whitespace */
+ while (isspace((int) *cp))
+ cp += 1;
+
+ np = strchr(cp, ',');
+ if (np)
+ *np++ = '\0';
+
+ /* Trim trailing whitespace */
+ xp = cp + strlen(cp) - 1;
+ while (isspace(*xp) && xp > cp)
+ *xp-- = '\0';
+
+ if (cp[0] == 'f' && cp[1] == 'g' && cp[2] == '-') {
+ rc = xo_color_find(cp + 3);
+ if (rc < 0)
+ goto unknown;
+
+ xocp->xoc_col_fg = rc;
+
+ } else if (cp[0] == 'b' && cp[1] == 'g' && cp[2] == '-') {
+ rc = xo_color_find(cp + 3);
+ if (rc < 0)
+ goto unknown;
+ xocp->xoc_col_bg = rc;
+
+ } else if (cp[0] == 'n' && cp[1] == 'o' && cp[2] == '-') {
+ rc = xo_effect_find(cp + 3);
+ if (rc < 0)
+ goto unknown;
+ xocp->xoc_effects &= ~(1 << rc);
+
+ } else {
+ rc = xo_effect_find(cp);
+ if (rc < 0)
+ goto unknown;
+ xocp->xoc_effects |= 1 << rc;
+
+ switch (1 << rc) {
+ case XO_EFF_RESET:
+ xocp->xoc_col_fg = xocp->xoc_col_bg = 0;
+ /* Note: not "|=" since we want to wipe out the old value */
+ xocp->xoc_effects = XO_EFF_RESET;
+ break;
+
+ case XO_EFF_NORMAL:
+ xocp->xoc_effects &= ~(XO_EFF_BOLD | XO_EFF_UNDERLINE
+ | XO_EFF_INVERSE | XO_EFF_NORMAL);
+ break;
+ }
+ }
+ continue;
+
+ unknown:
+ if (xop->xo_flags & XOF_WARN)
+ xo_failure(xop, "unknown color/effect string detected: '%s'", cp);
+ }
+}
+
+static inline int
+xo_colors_enabled (xo_handle_t *xop UNUSED)
+{
+#ifdef LIBXO_TEXT_ONLY
+ return 0;
+#else /* LIBXO_TEXT_ONLY */
+ return ((xop->xo_flags & XOF_COLOR) ? 1 : 0);
+#endif /* LIBXO_TEXT_ONLY */
+}
+
+static void
+xo_colors_handle_text (xo_handle_t *xop UNUSED, xo_colors_t *newp)
+{
+ char buf[BUFSIZ];
+ char *cp = buf, *ep = buf + sizeof(buf);
+ unsigned i, bit;
+ xo_colors_t *oldp = &xop->xo_colors;
+ const char *code = NULL;
+
+ /*
+ * Start the buffer with an escape. We don't want to add the '['
+ * now, since we let xo_effect_text_add unconditionally add the ';'.
+ * We'll replace the first ';' with a '[' when we're done.
+ */
+ *cp++ = 0x1b; /* Escape */
+
+ /*
+ * Terminals were designed back in the age before "certainty" was
+ * invented, when standards were more what you'd call "guidelines"
+ * than actual rules. Anyway we can't depend on them to operate
+ * correctly. So when display attributes are changed, we punt,
+ * reseting them all and turning back on the ones we want to keep.
+ * Longer, but should be completely reliable. Savvy?
+ */
+ if (oldp->xoc_effects != (newp->xoc_effects & oldp->xoc_effects)) {
+ newp->xoc_effects |= XO_EFF_RESET;
+ oldp->xoc_effects = 0;
+ }
+
+ for (i = 0, bit = 1; xo_effect_names[i]; i++, bit <<= 1) {
+ if ((newp->xoc_effects & bit) == (oldp->xoc_effects & bit))
+ continue;
+
+ if (newp->xoc_effects & bit)
+ code = xo_effect_on_codes[i];
+
+ cp += snprintf(cp, ep - cp, ";%s", code);
+ if (cp >= ep)
+ return; /* Should not occur */
+
+ if (bit == XO_EFF_RESET) {
+ /* Mark up the old value so we can detect current values as new */
+ oldp->xoc_effects = 0;
+ oldp->xoc_col_fg = oldp->xoc_col_bg = XO_COL_DEFAULT;
+ }
+ }
+
+ if (newp->xoc_col_fg != oldp->xoc_col_fg) {
+ cp += snprintf(cp, ep - cp, ";3%u",
+ (newp->xoc_col_fg != XO_COL_DEFAULT)
+ ? newp->xoc_col_fg - 1 : 9);
+ }
+
+ if (newp->xoc_col_bg != oldp->xoc_col_bg) {
+ cp += snprintf(cp, ep - cp, ";4%u",
+ (newp->xoc_col_bg != XO_COL_DEFAULT)
+ ? newp->xoc_col_bg - 1 : 9);
+ }
+
+ if (cp - buf != 1 && cp < ep - 3) {
+ buf[1] = '['; /* Overwrite leading ';' */
+ *cp++ = 'm';
+ *cp = '\0';
+ xo_buf_append(&xop->xo_data, buf, cp - buf);
+ }
+}
+
+static void
+xo_colors_handle_html (xo_handle_t *xop, xo_colors_t *newp)
+{
+ xo_colors_t *oldp = &xop->xo_colors;
+
+ /*
+ * HTML colors are mostly trivial: fill in xo_color_buf with
+ * a set of class tags representing the colors and effects.
+ */
+
+ /* If nothing changed, then do nothing */
+ if (oldp->xoc_effects == newp->xoc_effects
+ && oldp->xoc_col_fg == newp->xoc_col_fg
+ && oldp->xoc_col_bg == newp->xoc_col_bg)
+ return;
+
+ unsigned i, bit;
+ xo_buffer_t *xbp = &xop->xo_color_buf;
+
+ xo_buf_reset(xbp); /* We rebuild content after each change */
+
+ for (i = 0, bit = 1; xo_effect_names[i]; i++, bit <<= 1) {
+ if (!(newp->xoc_effects & bit))
+ continue;
+
+ xo_buf_append_str(xbp, " effect-");
+ xo_buf_append_str(xbp, xo_effect_names[i]);
+ }
+
+ const char *fg = NULL;
+ const char *bg = NULL;
+
+ if (newp->xoc_col_fg != XO_COL_DEFAULT)
+ fg = xo_color_names[newp->xoc_col_fg];
+ if (newp->xoc_col_bg != XO_COL_DEFAULT)
+ bg = xo_color_names[newp->xoc_col_bg];
+
+ if (newp->xoc_effects & XO_EFF_INVERSE) {
+ const char *tmp = fg;
+ fg = bg;
+ bg = tmp;
+ if (fg == NULL)
+ fg = "inverse";
+ if (bg == NULL)
+ bg = "inverse";
+
+ }
+
+ if (fg) {
+ xo_buf_append_str(xbp, " color-fg-");
+ xo_buf_append_str(xbp, fg);
+ }
+
+ if (bg) {
+ xo_buf_append_str(xbp, " color-bg-");
+ xo_buf_append_str(xbp, bg);
+ }
+}
+
+static void
+xo_format_colors (xo_handle_t *xop, const char *str, int len,
+ const char *fmt, int flen)
+{
+ xo_buffer_t xb;
+
+ /* If the string is static and we've in an encoding style, bail */
+ if (len != 0
+ && (xo_style(xop) == XO_STYLE_XML || xo_style(xop) == XO_STYLE_JSON))
+ return;
+
+ xo_buf_init(&xb);
+
+ if (len)
+ xo_buf_append(&xb, str, len);
+ else if (flen)
+ xo_format_data(xop, &xb, fmt, flen, 0);
+ else
+ xo_buf_append(&xb, "reset", 6); /* Default if empty */
+
+ if (xo_colors_enabled(xop)) {
+ switch (xo_style(xop)) {
+ case XO_STYLE_TEXT:
+ case XO_STYLE_HTML:
+ xo_buf_append(&xb, "", 1);
+
+ xo_colors_t xoc = xop->xo_colors;
+ xo_colors_parse(xop, &xoc, xb.xb_bufp);
+
+ if (xo_style(xop) == XO_STYLE_TEXT) {
+ /*
+ * Text mode means emitting the colors as ANSI character
+ * codes. This will allow people who like colors to have
+ * colors. The issue is, of course conflicting with the
+ * user's perfectly reasonable color scheme. Which leads
+ * to the hell of LSCOLORS, where even app need to have
+ * customization hooks for adjusting colors. Instead we
+ * provide a simpler-but-still-annoying answer where one
+ * can map colors to other colors.
+ */
+ xo_colors_handle_text(xop, &xoc);
+ xoc.xoc_effects &= ~XO_EFF_RESET; /* After handling it */
+
+ } else {
+ /*
+ * HTML output is wrapped in divs, so the color information
+ * must appear in every div until cleared. Most pathetic.
+ * Most unavoidable.
+ */
+ xoc.xoc_effects &= ~XO_EFF_RESET; /* Before handling effects */
+ xo_colors_handle_html(xop, &xoc);
+ }
+
+ xop->xo_colors = xoc;
+ break;
+
+ case XO_STYLE_XML:
+ case XO_STYLE_JSON:
+ /*
+ * Nothing to do; we did all that work just to clear the stack of
+ * formatting arguments.
+ */
+ break;
+ }
+ }
+
+ xo_buf_cleanup(&xb);
+}
+
static void
xo_format_units (xo_handle_t *xop, const char *str, int len,
const char *fmt, int flen)
@@ -3211,9 +3724,9 @@ xo_format_units (xo_handle_t *xop, const char *str, int len,
int start = xop->xo_units_offset;
int stop = xbp->xb_curp - xbp->xb_bufp;
- if (xop->xo_style == XO_STYLE_XML)
+ if (xo_style(xop) == XO_STYLE_XML)
xo_buf_append(xbp, units_start_xml, sizeof(units_start_xml) - 1);
- else if (xop->xo_style == XO_STYLE_HTML)
+ else if (xo_style(xop) == XO_STYLE_HTML)
xo_buf_append(xbp, units_start_html, sizeof(units_start_html) - 1);
else
return;
@@ -3295,7 +3808,7 @@ static void
xo_anchor_start (xo_handle_t *xop, const char *str, int len,
const char *fmt, int flen)
{
- if (xop->xo_style != XO_STYLE_TEXT && xop->xo_style != XO_STYLE_HTML)
+ if (xo_style(xop) != XO_STYLE_TEXT && xo_style(xop) != XO_STYLE_HTML)
return;
if (xop->xo_flags & XOF_ANCHOR)
@@ -3317,7 +3830,7 @@ static void
xo_anchor_stop (xo_handle_t *xop, const char *str, int len,
const char *fmt, int flen)
{
- if (xop->xo_style != XO_STYLE_TEXT && xop->xo_style != XO_STYLE_HTML)
+ if (xo_style(xop) != XO_STYLE_TEXT && xo_style(xop) != XO_STYLE_HTML)
return;
if (!(xop->xo_flags & XOF_ANCHOR)) {
@@ -3484,6 +3997,7 @@ xo_do_emit (xo_handle_t *xop, const char *fmt)
}
switch (*sp) {
+ case 'C':
case 'D':
case 'E':
case 'L':
@@ -3621,6 +4135,8 @@ xo_do_emit (xo_handle_t *xop, const char *fmt)
xo_anchor_start(xop, content, clen, format, flen);
else if (ftype == ']')
xo_anchor_stop(xop, content, clen, format, flen);
+ else if (ftype == 'C')
+ xo_format_colors(xop, content, clen, format, flen);
else if (clen || format) { /* Need either content or format */
if (format == NULL) {
@@ -3726,7 +4242,7 @@ xo_attr_hv (xo_handle_t *xop, const char *name, const char *fmt, va_list vap)
const int extra = 5; /* space, equals, quote, quote, and nul */
xop = xo_default(xop);
- if (xop->xo_style != XO_STYLE_XML)
+ if (xo_style(xop) != XO_STYLE_XML)
return 0;
int nlen = strlen(name);
@@ -3798,7 +4314,7 @@ static void
xo_depth_change (xo_handle_t *xop, const char *name,
int delta, int indent, xo_state_t state, xo_xsf_flags_t flags)
{
- if (xop->xo_style == XO_STYLE_HTML || xop->xo_style == XO_STYLE_TEXT)
+ if (xo_style(xop) == XO_STYLE_HTML || xo_style(xop) == XO_STYLE_TEXT)
indent = 0;
if (xop->xo_flags & XOF_DTRT)
@@ -3884,6 +4400,20 @@ xo_stack_flags (unsigned xflags)
return 0;
}
+static void
+xo_emit_top (xo_handle_t *xop, const char *ppn)
+{
+ xo_printf(xop, "%*s{%s", xo_indent(xop), "", ppn);
+ xop->xo_flags |= XOF_TOP_EMITTED;
+
+ if (xop->xo_version) {
+ xo_printf(xop, "%*s\"__version\": \"%s\", %s",
+ xo_indent(xop), "", xop->xo_version, ppn);
+ xo_free(xop->xo_version);
+ xop->xo_version = NULL;
+ }
+}
+
static int
xo_do_open_container (xo_handle_t *xop, xo_xof_flags_t flags, const char *name)
{
@@ -3898,7 +4428,7 @@ xo_do_open_container (xo_handle_t *xop, xo_xof_flags_t flags, const char *name)
flags |= xop->xo_flags; /* Pick up handle flags */
- switch (xop->xo_style) {
+ switch (xo_style(xop)) {
case XO_STYLE_XML:
rc = xo_printf(xop, "%*s<%s", xo_indent(xop), "", name);
@@ -3915,12 +4445,9 @@ xo_do_open_container (xo_handle_t *xop, xo_xof_flags_t flags, const char *name)
case XO_STYLE_JSON:
xo_stack_set_flags(xop);
- if (!(xop->xo_flags & XOF_NO_TOP)) {
- if (!(xop->xo_flags & XOF_TOP_EMITTED)) {
- xo_printf(xop, "%*s{%s", xo_indent(xop), "", ppn);
- xop->xo_flags |= XOF_TOP_EMITTED;
- }
- }
+ if (!(xop->xo_flags & XOF_NO_TOP)
+ && !(xop->xo_flags & XOF_TOP_EMITTED))
+ xo_emit_top(xop, ppn);
if (xop->xo_stack[xop->xo_depth].xs_flags & XSF_NOT_FIRST)
pre_nl = (xop->xo_flags & XOF_PRETTY) ? ",\n" : ", ";
@@ -3992,7 +4519,7 @@ xo_do_close_container (xo_handle_t *xop, const char *name)
}
}
- switch (xop->xo_style) {
+ switch (xo_style(xop)) {
case XO_STYLE_XML:
xo_depth_change(xop, name, -1, -1, XSS_CLOSE_CONTAINER, 0);
rc = xo_printf(xop, "%*s</%s>%s", xo_indent(xop), "", name, ppn);
@@ -4048,17 +4575,14 @@ xo_do_open_list (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name)
xop = xo_default(xop);
- if (xop->xo_style == XO_STYLE_JSON) {
+ if (xo_style(xop) == XO_STYLE_JSON) {
const char *ppn = (xop->xo_flags & XOF_PRETTY) ? "\n" : "";
const char *pre_nl = "";
indent = 1;
- if (!(xop->xo_flags & XOF_NO_TOP)) {
- if (!(xop->xo_flags & XOF_TOP_EMITTED)) {
- xo_printf(xop, "%*s{%s", xo_indent(xop), "", ppn);
- xop->xo_flags |= XOF_TOP_EMITTED;
- }
- }
+ if (!(xop->xo_flags & XOF_NO_TOP)
+ && !(xop->xo_flags & XOF_TOP_EMITTED))
+ xo_emit_top(xop, ppn);
if (name == NULL) {
xo_failure(xop, "NULL passed for list name");
@@ -4133,7 +4657,7 @@ xo_do_close_list (xo_handle_t *xop, const char *name)
}
}
- if (xop->xo_style == XO_STYLE_JSON) {
+ if (xo_style(xop) == XO_STYLE_JSON) {
if (xop->xo_stack[xop->xo_depth].xs_flags & XSF_NOT_FIRST)
pre_nl = (xop->xo_flags & XOF_PRETTY) ? "\n" : "";
xop->xo_stack[xop->xo_depth].xs_flags |= XSF_NOT_FIRST;
@@ -4182,7 +4706,7 @@ xo_do_open_leaf_list (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name)
xop = xo_default(xop);
- if (xop->xo_style == XO_STYLE_JSON) {
+ if (xo_style(xop) == XO_STYLE_JSON) {
const char *ppn = (xop->xo_flags & XOF_PRETTY) ? "\n" : "";
const char *pre_nl = "";
@@ -4238,7 +4762,7 @@ xo_do_close_leaf_list (xo_handle_t *xop, const char *name)
}
}
- if (xop->xo_style == XO_STYLE_JSON) {
+ if (xo_style(xop) == XO_STYLE_JSON) {
if (xop->xo_stack[xop->xo_depth].xs_flags & XSF_NOT_FIRST)
pre_nl = (xop->xo_flags & XOF_PRETTY) ? "\n" : "";
xop->xo_stack[xop->xo_depth].xs_flags |= XSF_NOT_FIRST;
@@ -4271,7 +4795,7 @@ xo_do_open_instance (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name)
name = XO_FAILURE_NAME;
}
- switch (xop->xo_style) {
+ switch (xo_style(xop)) {
case XO_STYLE_XML:
rc = xo_printf(xop, "%*s<%s", xo_indent(xop), "", name);
@@ -4357,7 +4881,7 @@ xo_do_close_instance (xo_handle_t *xop, const char *name)
}
}
- switch (xop->xo_style) {
+ switch (xo_style(xop)) {
case XO_STYLE_XML:
xo_depth_change(xop, name, -1, -1, XSS_CLOSE_INSTANCE, 0);
rc = xo_printf(xop, "%*s</%s>%s", xo_indent(xop), "", name, ppn);
@@ -4639,8 +5163,8 @@ xo_transition (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name,
rc = xo_do_open_instance(xop, flags, name);
break;
- case XSS_TRANSITION(XSS_OPEN_CONTAINER, XSS_OPEN_INSTANCE):
case XSS_TRANSITION(XSS_INIT, XSS_OPEN_INSTANCE):
+ case XSS_TRANSITION(XSS_OPEN_CONTAINER, XSS_OPEN_INSTANCE):
rc = xo_do_open_list(xop, flags, name);
if (rc >= 0)
goto open_instance;
@@ -4673,6 +5197,8 @@ xo_transition (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name,
case XSS_TRANSITION(XSS_INIT, XSS_CLOSE_INSTANCE):
/* This one makes no sense; ignore it */
+ xo_failure(xop, "xo_close_instance ignored when called from "
+ "initial state ('%s')", name ?: "(unknown)");
break;
case XSS_TRANSITION(XSS_OPEN_CONTAINER, XSS_CLOSE_INSTANCE):
@@ -4715,6 +5241,8 @@ xo_transition (xo_handle_t *xop, xo_xsf_flags_t flags, const char *name,
case XSS_TRANSITION(XSS_INIT, XSS_CLOSE_LEAF_LIST):
/* Makes no sense; ignore */
+ xo_failure(xop, "xo_close_leaf_list ignored when called from "
+ "initial state ('%s')", name ?: "(unknown)");
break;
case XSS_TRANSITION(XSS_OPEN_CONTAINER, XSS_CLOSE_LEAF_LIST):
@@ -4836,7 +5364,7 @@ xo_flush_h (xo_handle_t *xop)
xop = xo_default(xop);
- switch (xop->xo_style) {
+ switch (xo_style(xop)) {
case XO_STYLE_HTML:
if (xop->xo_flags & XOF_DIV_OPEN) {
xop->xo_flags &= ~XOF_DIV_OPEN;
@@ -4871,7 +5399,7 @@ xo_finish_h (xo_handle_t *xop)
if (!(xop->xo_flags & XOF_NO_CLOSE))
xo_do_close_all(xop, xop->xo_stack);
- switch (xop->xo_style) {
+ switch (xo_style(xop)) {
case XO_STYLE_JSON:
if (!(xop->xo_flags & XOF_NO_TOP)) {
if (xop->xo_flags & XOF_TOP_EMITTED)
@@ -4913,7 +5441,7 @@ xo_error_hv (xo_handle_t *xop, const char *fmt, va_list vap)
fmt = newfmt;
}
- switch (xop->xo_style) {
+ switch (xo_style(xop)) {
case XO_STYLE_TEXT:
vfprintf(stderr, fmt, vap);
break;
@@ -5052,6 +5580,41 @@ xo_set_program (const char *name)
xo_program = name;
}
+void
+xo_set_version_h (xo_handle_t *xop, const char *version UNUSED)
+{
+ xop = xo_default(xop);
+
+ if (version == NULL || strchr(version, '"') != NULL)
+ return;
+
+ switch (xo_style(xop)) {
+ case XO_STYLE_XML:
+ /* For XML, we record this as an attribute for the first tag */
+ xo_attr_h(xop, "__version", "%s", version);
+ break;
+
+ case XO_STYLE_JSON:
+ {
+ /*
+ * For XML, we record the version string in our handle, and emit
+ * it in xo_emit_top.
+ */
+ int len = strlen(version) + 1;
+ xop->xo_version = xo_realloc(NULL, len);
+ if (xop->xo_version)
+ memcpy(xop->xo_version, version, len);
+ }
+ break;
+ }
+}
+
+void
+xo_set_version (const char *version)
+{
+ xo_set_version_h(NULL, version);
+}
+
#ifdef UNIT_TEST
int
main (int argc, char **argv)
diff --git a/contrib/libxo/libxo/xo.h b/contrib/libxo/libxo/xo.h
index ea289f088b65..c06574032e89 100644
--- a/contrib/libxo/libxo/xo.h
+++ b/contrib/libxo/libxo/xo.h
@@ -9,7 +9,7 @@
*/
/**
- * libxo provides a means of generating text, XML, and JSON output
+ * libxo provides a means of generating text, XML, JSON, and HTML output
* using a single set of function calls, maximizing the value of output
* while minimizing the cost/impact on the code.
*/
@@ -17,6 +17,27 @@
#ifndef INCLUDE_XO_H
#define INCLUDE_XO_H
+#include <sys/types.h>
+
+#ifdef __dead2
+#define NORETURN __dead2
+#else
+#define NORETURN
+#endif /* __dead2 */
+
+/*
+ * Normally we'd use the HAVE_PRINTFLIKE define triggered by the
+ * --enable-printflike option to configure, but we don't install
+ * our internal "xoconfig.h", and I'd rather not. Taking the
+ * coward's path, we'll turn it on inside a #if that allows
+ * others to turn it off where needed. Not ideal, but functional.
+ */
+#if !defined(NO_PRINTFLIKE) && !defined(__linux__)
+#define PRINTFLIKE(_x, _y) __printflike(_x, _y)
+#else
+#define PRINTFLIKE(_x, _y)
+#endif /* NO_PRINTFLIKE */
+
/** Formatting types */
typedef unsigned xo_style_t;
#define XO_STYLE_TEXT 0 /** Generate text output */
@@ -58,6 +79,8 @@ typedef unsigned long long xo_xof_flags_t;
#define XOF_FLUSH_LINE XOF_BIT(23) /** Flush after each newline */
#define XOF_NO_CLOSE XOF_BIT(24) /** xo_finish won't close open elements */
+#define XOF_COLOR_ALLOWED XOF_BIT(25) /** Allow color/effects to be enabled */
+#define XOF_COLOR XOF_BIT(26) /** Enable color and effects */
/*
* The xo_info_t structure provides a mapping between names and
@@ -260,64 +283,116 @@ void
xo_set_leading_xpath (xo_handle_t *xop, const char *path);
void
-xo_warn_hc (xo_handle_t *xop, int code, const char *fmt, ...);
+xo_warn_hc (xo_handle_t *xop, int code, const char *fmt, ...) PRINTFLIKE(3, 4);
void
-xo_warn_c (int code, const char *fmt, ...);
+xo_warn_c (int code, const char *fmt, ...) PRINTFLIKE(2, 3);
void
-xo_warn (const char *fmt, ...);
+xo_warn (const char *fmt, ...) PRINTFLIKE(1, 2);
void
-xo_warnx (const char *fmt, ...);
+xo_warnx (const char *fmt, ...) PRINTFLIKE(1, 2);
void
-xo_err (int eval, const char *fmt, ...) __dead2;
+xo_err (int eval, const char *fmt, ...) NORETURN PRINTFLIKE(2, 3);
void
-xo_errx (int eval, const char *fmt, ...) __dead2;
+xo_errx (int eval, const char *fmt, ...) NORETURN PRINTFLIKE(2, 3);
void
-xo_errc (int eval, int code, const char *fmt, ...) __dead2;
+xo_errc (int eval, int code, const char *fmt, ...) NORETURN PRINTFLIKE(3, 4);
void
xo_message_hcv (xo_handle_t *xop, int code, const char *fmt, va_list vap);
void
-xo_message_hc (xo_handle_t *xop, int code, const char *fmt, ...);
+xo_message_hc (xo_handle_t *xop, int code, const char *fmt, ...) PRINTFLIKE(3, 4);
void
-xo_message_c (int code, const char *fmt, ...);
+xo_message_c (int code, const char *fmt, ...) PRINTFLIKE(2, 3);
void
-xo_message (const char *fmt, ...);
+xo_message (const char *fmt, ...) PRINTFLIKE(1, 2);
void
xo_no_setlocale (void);
+/**
+ * @brief Lift libxo-specific arguments from a set of arguments
+ *
+ * libxo-enable programs typically use command line options to enable
+ * all the nifty-cool libxo features. xo_parse_args() makes this simple
+ * by pre-processing the command line arguments given to main(), handling
+ * and removing the libxo-specific ones, meaning anything starting with
+ * "--libxo". A full description of these arguments is in the base
+ * documentation.
+ * @param[in] argc Number of arguments (ala #main())
+ * @param[in] argc Array of argument strings (ala #main())
+ * @return New number of arguments, or -1 for failure.
+ */
int
xo_parse_args (int argc, char **argv);
-/*
+/**
* This is the "magic" number returned by libxo-supporting commands
* when passed the equally magic "--libxo-check" option. If you
- * return this, we can assume that since you know the magic handshake,
- * you'll happily handle future --libxo options and not do something
- * violent like reboot the box or create another hole in the ozone
- * layer.
+ * return this, we can (unsafely) assume that since you know the magic
+ * handshake, you'll happily handle future --libxo options and not do
+ * something violent like reboot the box or create another hole in the
+ * ozone layer.
*/
#define XO_HAS_LIBXO 121
-/*
- * externs for our version number strings
+/**
+ * externs for libxo's version number strings
*/
-extern const char xo_version[];
-extern const char xo_version_extra[];
+extern const char xo_version[]; /** Base version triple string */
+extern const char xo_version_extra[]; /** Extra version magic content */
+/**
+ * @brief Dump the internal stack of a libxo handle.
+ *
+ * This diagnostic function is something I will ask you to call from
+ * your program when you write to tell me libxo has gone bat-stink
+ * crazy and has discarded your list or container or content. Output
+ * content will be what we lovingly call "developer entertainment".
+ * @param[in] xop A valid libxo handle, or NULL for the default handle
+ */
void
xo_dump_stack (xo_handle_t *xop);
+/**
+ * @brief Recode the name of the program, suitable for error output.
+ *
+ * libxo will record the given name for use while generating error
+ * messages. The contents are not copied, so the value must continue
+ * to point to a valid memory location. This allows the caller to change
+ * the value, but requires the caller to manage the memory. Typically
+ * this is called with argv[0] from main().
+ * @param[in] name The name of the current application program
+ */
void
xo_set_program (const char *name);
+/**
+ * @brief Add a version string to the output, where possible.
+ *
+ * Adds a version number to the output, suitable for tracking
+ * changes in the content. This is only important for the "encoding"
+ * format styles (XML and JSON) and allows a user of the data to
+ * discern which version of the data model is in use.
+ * @param[in] version The version number, encoded as a string
+ */
+void
+xo_set_version (const char *version);
+
+/**
+ * #xo_set_version with a handle.
+ * @param[in] xop A valid libxo handle, or NULL for the default handle
+ * @param[in] version The version number, encoded as a string
+ */
+void
+xo_set_version_h (xo_handle_t *xop, const char *version);
+
#endif /* INCLUDE_XO_H */
diff --git a/contrib/libxo/libxo/xo_error.3 b/contrib/libxo/libxo/xo_error.3
index da91785928d5..01431cb04345 100644
--- a/contrib/libxo/libxo/xo_error.3
+++ b/contrib/libxo/libxo/xo_error.3
@@ -28,12 +28,13 @@ The
argument is a string containing printf-style formatting
instructions that describe the remaining arguments.
.Pp
-When converting an application to libxo, one can replace
+When converting an application to
+.Nm libxo ,
+one can replace
.Em "fprintf(stderr,...)"
calls with
.Fn xo_error
calls.
-.Pp
.Sh ADDITIONAL DOCUMENTATION
Complete documentation can be found on github:
.Bd -literal -offset indent
@@ -53,7 +54,7 @@ is available at:
https://github.com/Juniper/libxo/releases
.Ed
.Sh SEE ALSO
-.Xr printf 3
+.Xr printf 3 ,
.Xr xo_emit 3
.Sh HISTORY
The
diff --git a/contrib/libxo/libxo/xo_format.5 b/contrib/libxo/libxo/xo_format.5
index b021b98fd559..bce5dc5ae33d 100644
--- a/contrib/libxo/libxo/xo_format.5
+++ b/contrib/libxo/libxo/xo_format.5
@@ -74,7 +74,7 @@ function as an unsigned integer.
.Ed
.Pp
This single line of code can generate text ("In stock: 65\\n"), XML
-("<in-stock>65</in-stock>"), JSON ('"in-stock": 6'), or HTML (too
+("<in-stock>65</in-stock>"), JSON ('"in-stock": 65'), or HTML (too
lengthy to be listed here).
.Ss Modifier Roles
Modifiers are optional, and indicate the role and formatting of the
@@ -96,6 +96,55 @@ The roles are listed below; only one role is permitted:
.It \&] "stop anchor " "End a section of anchored variable-width text"
.El
.Pp
+.Ss The Color Role ({C:})
+Colors and effects control how text values are displayed; they are
+used for display styles (TEXT and HTML).
+The color content can be
+either static, when placed directly within the field descriptor, or a
+printf-style format descriptor can be used, if preceded by a slash ("/"):
+.Bd -literal -offset indent
+ xo_emit("{C:bold}{Lwc:Cost}{:cost/%u}{C:reset}\n", cost);
+ xo_emit("{C:/fg-%s,bg-%s}{Lwc:Cost}{:cost/%u}{C:reset}\n",
+ fg_color, bg_color, cost);
+.Ed
+.Pp
+The content should be a comma-separated list of zero or more colors or
+display effects.
+.Pp
+Colors and effects remain in effect until modified by other "C" roles.
+.Pp
+If the content is empty, the "reset" action is performed.
+.Pp
+.Bl -column "no-underline"
+.It Sy "Name Description"
+.It "bg-xxxxx " "Change background color"
+.It "bold " "Start bold text effect"
+.It "fg-xxxxx " "Change foreground color"
+.It "inverse " "Start inverse (aka reverse) text effect"
+.It "no-bold " "Stop bold text effect"
+.It "no-inverse " "Stop inverse (aka reverse) text effect"
+.It "no-underline " "Stop underline text effect"
+.It "normal " "Reset effects (only)"
+.It "reset " "Reset colors and effects (restore defaults)"
+.It "underline " "Start underline text effect"
+.El
+.Pp
+The following color names are supported:
+.Bl -column "no-underline"
+.It Sy "Name"
+.It black
+.It blue
+.It cyan
+.It default
+.It green
+.It magenta
+.It red
+.It white
+.It yellow
+.El
+.Pp
+Color names are prefixed with either "fg-" or "bg-" to change the
+foreground and background colors, respectively.
.Ss The Decoration Role ({D:})
Decorations are typically punctuation marks such as colons,
semi-colons, and commas used to decorate the text and make it simpler
@@ -230,6 +279,7 @@ content emitted for some output styles:
.It d "display " "Only emit field for display styles (text/HTML)"
.It e "encoding " "Only emit for encoding styles (XML/JSON)"
.It k "key " "Field is a key, suitable for XPath predicates"
+.It l "leaf " "Field is a leaf-list, a list of leaf values"
.It n "no-quotes " "Do not quote the field when using JSON style"
.It q "quotes " "Quote the field when using JSON style"
.It w "white space " "A blank ("" "") is appended after the label"
@@ -269,8 +319,8 @@ the display output styles, TEXT and HTML.
The display modifier is the opposite of the encoding modifier, and
they are often used to give to distinct views of the underlying data.
.Ss The Encoding Modifier ({e:})
-The display modifier indicated the field should only be generated for
-the display output styles, TEXT and HTML.
+The encoding modifier indicated the field should only be generated for
+the encoding output styles, such as JSON and XML.
.Bd -literal -offset indent
EXAMPLE:
xo_emit("{Lcw:Name}{:name} {e:id/%d}\\n", "phil", 1);
diff --git a/contrib/libxo/libxo/xo_open_container.3 b/contrib/libxo/libxo/xo_open_container.3
index 86412ca91da7..364955628964 100644
--- a/contrib/libxo/libxo/xo_open_container.3
+++ b/contrib/libxo/libxo/xo_open_container.3
@@ -11,8 +11,8 @@
.Dt LIBXO 3
.Os
.Sh NAME
-.Nm xo_emit
-.Nd emit formatted output based on format string and arguments
+.Nm xo_open_container
+.Nd open (and close) container constructs
.Sh LIBRARY
.Lb libxo
.Sh SYNOPSIS
@@ -48,7 +48,7 @@
.Fn xo_close_container_d "void"
.Sh DESCRIPTION
.Nm libxo
-represents to types of hierarchy:
+represents two types of hierarchy:
.Dq containers
and
.Dq lists .
@@ -72,7 +72,7 @@ or
.Fn xo_close_container_h
functions.
.Pp
-Each open call must have a matching close call.
+Each open call should have a matching close call.
If the
.Dv XOF_WARN
flag is set and the name given does not match the name of
diff --git a/contrib/libxo/libxo/xo_open_marker.3 b/contrib/libxo/libxo/xo_open_marker.3
new file mode 100644
index 000000000000..d7a858c8c207
--- /dev/null
+++ b/contrib/libxo/libxo/xo_open_marker.3
@@ -0,0 +1,138 @@
+.\" #
+.\" # Copyright (c) 2015, Juniper Networks, Inc.
+.\" # All rights reserved.
+.\" # This SOFTWARE is licensed under the LICENSE provided in the
+.\" # ../Copyright file. By downloading, installing, copying, or
+.\" # using the SOFTWARE, you agree to be bound by the terms of that
+.\" # LICENSE.
+.\" # Phil Shafer, January 2015
+.\"
+.Dd January 22, 2015
+.Dt LIBXO 3
+.Os
+.Sh NAME
+.Nm xo_open_marker
+.Nd prevent and allow closing of open constructs
+.Sh LIBRARY
+.Lb libxo
+.Sh SYNOPSIS
+.In libxo/xo.h
+.Sh NAME
+.Nm xo_open_marker
+.Nm xo_open_marker_h
+.Nm xo_close_marker
+.Nm xo_close_marker_h
+.Nd open and close markers
+.Sh LIBRARY
+.Lb libxo
+.Sh SYNOPSIS
+.Ft int
+.Fn xo_open_marker "const char *name"
+.Ft int
+.Fn xo_open_marker_h "xo_handle_t *handle" "const char *name"
+.Ft int
+.Fn xo_close_marker "const char *name"
+.Ft int
+.Fn xo_close_marker_h "xo_handle_t *handle" "const char *name"
+.Sh DESCRIPTION
+.Nm libxo
+represents hierarchy using two constructs:
+.Dq containers
+and
+.Dq lists .
+A marker can be used to affect how open constructs are closed, either
+by preventing their (implicit or explicit) closure or by forcing their
+closure.
+While a marker is open, no other open constructs can be closed.
+When a marker is closed, all constructs open since the marker was opened
+will be closed.
+A marker is used to "freeze" any open constructs.
+Calls to
+.Fn xo_close_*
+functions that would normally close them will be ignored, effectively
+blocking their closure.
+However when
+.Fn xo_close_marker
+is called, any containers, lists, or leaf-lists open since the
+matching
+.Fn xo_open_marker
+call will be close and the marker discarded.
+Markers use names which are not user-visible, allowing the caller to
+choose appropriate internal names.
+The marker has no value and is not emitted in any form.
+.Pp
+To open a marker, call
+.Fn xo_open_marker
+or
+.Fn xo_open_marker_h .
+The former uses the default handle and
+the latter accepts a specific handle.
+.Pp
+To close a marker, use the
+.Fn xo_close_marker
+or
+.Fn xo_close_marker_h
+functions.
+.Pp
+Each open call must have a matching close call.
+.Pp
+In this example, the
+.Fn xo_close_container
+call on line [1] will be ignored, since the open marker "outer"
+will prevent close of any open constructs that precede it.
+The
+.Fn xo_close_marker
+call on line [2] will close the "system" container, since it was
+opened after the "outer" marker.
+.Bd -literal -offset indent -compact
+ Example:
+
+ xo_open_container("top");
+ xo_open_marker("outer");
+ xo_open_container("system");
+ xo_emit("{:host-name/%s%s%s", hostname,
+ domainname ? "." : "", domainname ?: "");
+ xo_close_container("top"); /* [1] */
+ xo_close_marker("outer"); /* [2] */
+ xo_close_container("top");
+.Ed
+.Pp
+In this example, the code whiffles through a list of fish, calling a
+function to emit details about each fish. The marker "fish-guts" is
+used to ensure that any constructs opened by the function are closed
+properly.
+.Bd -literal -offset indent
+ for (i = 0; fish[i]; i++) {
+ xo_open_instance("fish");
+ xo_open_marker("fish-guts");
+ dump_fish_details(i);
+ xo_close_marker("fish-guts");
+ }
+.Ed
+.Sh ADDITIONAL DOCUMENTATION
+Complete documentation can be found on github:
+.Bd -literal -offset indent
+http://juniper.github.io/libxo/libxo-manual.html
+.Ed
+.Pp
+.Nm libxo
+lives on github as:
+.Bd -literal -offset indent
+https://github.com/Juniper/libxo
+.Ed
+.Pp
+The latest release of
+.Nm libxo
+is available at:
+.Bd -literal -offset indent
+https://github.com/Juniper/libxo/releases
+.Ed
+.Sh SEE ALSO
+.Xr xo_emit 3
+.Sh HISTORY
+The
+.Nm libxo
+library was added in
+.Fx 11.0 .
+.Sh AUTHOR
+Phil Shafer
diff --git a/contrib/libxo/libxo/xo_set_version.3 b/contrib/libxo/libxo/xo_set_version.3
new file mode 100644
index 000000000000..888aef5e61ff
--- /dev/null
+++ b/contrib/libxo/libxo/xo_set_version.3
@@ -0,0 +1,59 @@
+.\" #
+.\" # Copyright (c) 2015, Juniper Networks, Inc.
+.\" # All rights reserved.
+.\" # This SOFTWARE is licensed under the LICENSE provided in the
+.\" # ../Copyright file. By downloading, installing, copying, or
+.\" # using the SOFTWARE, you agree to be bound by the terms of that
+.\" # LICENSE.
+.\" # Phil Shafer, July 2014
+.\"
+.Dd December 4, 2014
+.Dt LIBXO 3
+.Os
+.Sh NAME
+.Nm xo_set_version
+.Nd record content version information in encoded output
+.Sh LIBRARY
+.Lb libxo
+.Sh SYNOPSIS
+.In libxo/xo.h
+.Ft void
+.Fn xo_set_version "const char *version"
+.Ft void
+.Fn xo_set_version_h "xo_handle_t *xop" "const char *version"
+.Sh DESCRIPTION
+The
+.Nm xo_set_version
+function records a version number to be emitted as
+part of the data for encoding styles (XML and JSON).
+This version number is suitable for tracking changes in the content,
+allowing a user of the data to discern which version of the data model
+is in use.
+.Sh ADDITIONAL DOCUMENTATION
+Complete documentation can be found on github:
+.Bd -literal -offset indent
+http://juniper.github.io/libxo/libxo-manual.html
+.Ed
+.Pp
+.Nm libxo
+lives on github as:
+.Bd -literal -offset indent
+https://github.com/Juniper/libxo
+.Ed
+.Pp
+The latest release of
+.Nm libxo
+is available at:
+.Bd -literal -offset indent
+https://github.com/Juniper/libxo/releases
+.Ed
+.Sh SEE ALSO
+.Xr xo_emit 3 ,
+.Xr libxo 3
+.Sh HISTORY
+The
+.Nm libxo
+library was added in
+.Fx 11.0 .
+.Sh AUTHOR
+Phil Shafer
diff --git a/contrib/libxo/libxo/xoconfig.h b/contrib/libxo/libxo/xoconfig.h
index 4c596b4adf6e..dd1823e54be2 100644
--- a/contrib/libxo/libxo/xoconfig.h
+++ b/contrib/libxo/libxo/xoconfig.h
@@ -150,8 +150,10 @@
/* Enable debugging */
/* #undef LIBXO_DEBUG */
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
- */
+/* Enable text-only rendering */
+/* #undef LIBXO_TEXT_ONLY */
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
#define LT_OBJDIR ".libs/"
/* Name of package */
@@ -164,7 +166,7 @@
#define PACKAGE_NAME "libxo"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "libxo 0.2.0"
+#define PACKAGE_STRING "libxo 0.3.2"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libxo"
@@ -173,7 +175,7 @@
#define PACKAGE_URL ""
/* Define to the version of this package. */
-#define PACKAGE_VERSION "0.2.0"
+#define PACKAGE_VERSION "0.3.2"
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
@@ -187,7 +189,7 @@
#define STDC_HEADERS 1
/* Version number of package */
-#define VERSION "0.2.0"
+#define VERSION "0.3.2"
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
diff --git a/contrib/libxo/libxo/xoconfig.h.in b/contrib/libxo/libxo/xoconfig.h.in
index 467f5644d6b7..ad992f35527a 100644
--- a/contrib/libxo/libxo/xoconfig.h.in
+++ b/contrib/libxo/libxo/xoconfig.h.in
@@ -149,8 +149,10 @@
/* Enable debugging */
#undef LIBXO_DEBUG
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
- */
+/* Enable text-only rendering */
+#undef LIBXO_TEXT_ONLY
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
#undef LT_OBJDIR
/* Name of package */
diff --git a/contrib/libxo/libxo/xoversion.h b/contrib/libxo/libxo/xoversion.h
index 4c29e82963eb..6a60596594a5 100644
--- a/contrib/libxo/libxo/xoversion.h
+++ b/contrib/libxo/libxo/xoversion.h
@@ -18,17 +18,17 @@
/**
* The version string
*/
-#define LIBXO_VERSION "0.2.0"
+#define LIBXO_VERSION "0.3.2"
/**
* The version number
*/
-#define LIBXO_VERSION_NUMBER 2000
+#define LIBXO_VERSION_NUMBER 3002
/**
* The version number as a string
*/
-#define LIBXO_VERSION_STRING "2000"
+#define LIBXO_VERSION_STRING "3002"
/**
* The version number extra info as a string
diff --git a/contrib/libxo/m4/libtool.m4 b/contrib/libxo/m4/libtool.m4
index 44e0ecff11e3..a3bc337b79ad 100644
--- a/contrib/libxo/m4/libtool.m4
+++ b/contrib/libxo/m4/libtool.m4
@@ -1,8 +1,6 @@
# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
#
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
-# 2006, 2007, 2008, 2009, 2010, 2011 Free Software
-# Foundation, Inc.
+# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc.
# Written by Gordon Matzigkeit, 1996
#
# This file is free software; the Free Software Foundation gives
@@ -10,36 +8,30 @@
# modifications, as long as this notice is preserved.
m4_define([_LT_COPYING], [dnl
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
-# 2006, 2007, 2008, 2009, 2010, 2011 Free Software
-# Foundation, Inc.
-# Written by Gordon Matzigkeit, 1996
-#
-# This file is part of GNU Libtool.
-#
-# GNU Libtool is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of
-# the License, or (at your option) any later version.
+# Copyright (C) 2014 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of of the License, or
+# (at your option) any later version.
#
-# As a special exception to the GNU General Public License,
-# if you distribute this file as part of a program or library that
-# is built using GNU Libtool, you may include this file under the
-# same distribution terms that you use for the rest of that program.
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program or library that is built
+# using GNU Libtool, you may include this file under the same
+# distribution terms that you use for the rest of that program.
#
-# GNU Libtool is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy
-# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
-# obtained by writing to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
])
-# serial 57 LT_INIT
+# serial 58 LT_INIT
# LT_PREREQ(VERSION)
@@ -67,7 +59,7 @@ esac
# LT_INIT([OPTIONS])
# ------------------
AC_DEFUN([LT_INIT],
-[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT
+[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK
AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
AC_BEFORE([$0], [LT_LANG])dnl
AC_BEFORE([$0], [LT_OUTPUT])dnl
@@ -91,7 +83,7 @@ dnl Parse OPTIONS
_LT_SET_OPTIONS([$0], [$1])
# This can be used to rebuild libtool when needed
-LIBTOOL_DEPS="$ltmain"
+LIBTOOL_DEPS=$ltmain
# Always use our own libtool.
LIBTOOL='$(SHELL) $(top_builddir)/libtool'
@@ -111,26 +103,43 @@ dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
+# _LT_PREPARE_CC_BASENAME
+# -----------------------
+m4_defun([_LT_PREPARE_CC_BASENAME], [
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+func_cc_basename ()
+{
+ for cc_temp in @S|@*""; do
+ case $cc_temp in
+ compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+ distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+ done
+ func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+}
+])# _LT_PREPARE_CC_BASENAME
+
+
# _LT_CC_BASENAME(CC)
# -------------------
-# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME,
+# but that macro is also expanded into generated libtool script, which
+# arranges for $SED and $ECHO to be set by different means.
m4_defun([_LT_CC_BASENAME],
-[for cc_temp in $1""; do
- case $cc_temp in
- compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
- distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
- \-*) ;;
- *) break;;
- esac
-done
-cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+[m4_require([_LT_PREPARE_CC_BASENAME])dnl
+AC_REQUIRE([_LT_DECL_SED])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
+func_cc_basename $1
+cc_basename=$func_cc_basename_result
])
# _LT_FILEUTILS_DEFAULTS
# ----------------------
# It is okay to use these file commands and assume they have been set
-# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'.
+# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'.
m4_defun([_LT_FILEUTILS_DEFAULTS],
[: ${CP="cp -f"}
: ${MV="mv -f"}
@@ -177,15 +186,16 @@ m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
m4_require([_LT_CMD_OLD_ARCHIVE])dnl
m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
m4_require([_LT_WITH_SYSROOT])dnl
+m4_require([_LT_CMD_TRUNCATE])dnl
_LT_CONFIG_LIBTOOL_INIT([
-# See if we are running on zsh, and set the options which allow our
+# See if we are running on zsh, and set the options that allow our
# commands through without removal of \ escapes INIT.
-if test -n "\${ZSH_VERSION+set}" ; then
+if test -n "\${ZSH_VERSION+set}"; then
setopt NO_GLOB_SUBST
fi
])
-if test -n "${ZSH_VERSION+set}" ; then
+if test -n "${ZSH_VERSION+set}"; then
setopt NO_GLOB_SUBST
fi
@@ -198,7 +208,7 @@ aix3*)
# AIX sometimes has problems with the GCC collect2 program. For some
# reason, if we set the COLLECT_NAMES environment variable, the problems
# vanish in a puff of smoke.
- if test "X${COLLECT_NAMES+set}" != Xset; then
+ if test set != "${COLLECT_NAMES+set}"; then
COLLECT_NAMES=
export COLLECT_NAMES
fi
@@ -209,14 +219,14 @@ esac
ofile=libtool
can_build_shared=yes
-# All known linkers require a `.a' archive for static linking (except MSVC,
+# All known linkers require a '.a' archive for static linking (except MSVC,
# which needs '.lib').
libext=a
-with_gnu_ld="$lt_cv_prog_gnu_ld"
+with_gnu_ld=$lt_cv_prog_gnu_ld
-old_CC="$CC"
-old_CFLAGS="$CFLAGS"
+old_CC=$CC
+old_CFLAGS=$CFLAGS
# Set sane defaults for various variables
test -z "$CC" && CC=cc
@@ -269,14 +279,14 @@ no_glob_subst='s/\*/\\\*/g'
# _LT_PROG_LTMAIN
# ---------------
-# Note that this code is called both from `configure', and `config.status'
+# Note that this code is called both from 'configure', and 'config.status'
# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably,
-# `config.status' has no value for ac_aux_dir unless we are using Automake,
+# 'config.status' has no value for ac_aux_dir unless we are using Automake,
# so we pass a copy along to make sure it has a sensible value anyway.
m4_defun([_LT_PROG_LTMAIN],
[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
-ltmain="$ac_aux_dir/ltmain.sh"
+ltmain=$ac_aux_dir/ltmain.sh
])# _LT_PROG_LTMAIN
@@ -286,7 +296,7 @@ ltmain="$ac_aux_dir/ltmain.sh"
# So that we can recreate a full libtool script including additional
# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
-# in macros and then make a single call at the end using the `libtool'
+# in macros and then make a single call at the end using the 'libtool'
# label.
@@ -421,8 +431,8 @@ m4_define([_lt_decl_all_varnames],
# _LT_CONFIG_STATUS_DECLARE([VARNAME])
# ------------------------------------
-# Quote a variable value, and forward it to `config.status' so that its
-# declaration there will have the same value as in `configure'. VARNAME
+# Quote a variable value, and forward it to 'config.status' so that its
+# declaration there will have the same value as in 'configure'. VARNAME
# must have a single quote delimited value for this to work.
m4_define([_LT_CONFIG_STATUS_DECLARE],
[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`'])
@@ -446,7 +456,7 @@ m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
# Output comment and list of tags supported by the script
m4_defun([_LT_LIBTOOL_TAGS],
[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
-available_tags="_LT_TAGS"dnl
+available_tags='_LT_TAGS'dnl
])
@@ -474,7 +484,7 @@ m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
# _LT_LIBTOOL_CONFIG_VARS
# -----------------------
# Produce commented declarations of non-tagged libtool config variables
-# suitable for insertion in the LIBTOOL CONFIG section of the `libtool'
+# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool'
# script. Tagged libtool config variables (even for the LIBTOOL CONFIG
# section) are produced by _LT_LIBTOOL_TAG_VARS.
m4_defun([_LT_LIBTOOL_CONFIG_VARS],
@@ -500,8 +510,8 @@ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of
# variables for single and double quote escaping we saved from calls
# to _LT_DECL, we can put quote escaped variables declarations
-# into `config.status', and then the shell code to quote escape them in
-# for loops in `config.status'. Finally, any additional code accumulated
+# into 'config.status', and then the shell code to quote escape them in
+# for loops in 'config.status'. Finally, any additional code accumulated
# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
m4_defun([_LT_CONFIG_COMMANDS],
[AC_PROVIDE_IFELSE([LT_OUTPUT],
@@ -547,7 +557,7 @@ for var in lt_decl_all_varnames([[ \
]], lt_decl_quote_varnames); do
case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
*[[\\\\\\\`\\"\\\$]]*)
- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
;;
*)
eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
@@ -560,7 +570,7 @@ for var in lt_decl_all_varnames([[ \
]], lt_decl_dquote_varnames); do
case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
*[[\\\\\\\`\\"\\\$]]*)
- eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
;;
*)
eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
@@ -576,7 +586,7 @@ _LT_OUTPUT_LIBTOOL_INIT
# Generate a child script FILE with all initialization necessary to
# reuse the environment learned by the parent script, and make the
# file executable. If COMMENT is supplied, it is inserted after the
-# `#!' sequence but before initialization text begins. After this
+# '#!' sequence but before initialization text begins. After this
# macro, additional text can be appended to FILE to form the body of
# the child script. The macro ends with non-zero status if the
# file could not be fully written (such as if the disk is full).
@@ -598,7 +608,7 @@ AS_SHELL_SANITIZE
_AS_PREPARE
exec AS_MESSAGE_FD>&1
_ASEOF
-test $lt_write_fail = 0 && chmod +x $1[]dnl
+test 0 = "$lt_write_fail" && chmod +x $1[]dnl
m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT
# LT_OUTPUT
@@ -621,7 +631,7 @@ exec AS_MESSAGE_LOG_FD>>config.log
} >&AS_MESSAGE_LOG_FD
lt_cl_help="\
-\`$as_me' creates a local libtool stub from the current configuration,
+'$as_me' creates a local libtool stub from the current configuration,
for use in further configure time tests before the real libtool is
generated.
@@ -643,7 +653,7 @@ Copyright (C) 2011 Free Software Foundation, Inc.
This config.lt script is free software; the Free Software Foundation
gives unlimited permision to copy, distribute and modify it."
-while test $[#] != 0
+while test 0 != $[#]
do
case $[1] in
--version | --v* | -V )
@@ -656,10 +666,10 @@ do
lt_cl_silent=: ;;
-*) AC_MSG_ERROR([unrecognized option: $[1]
-Try \`$[0] --help' for more information.]) ;;
+Try '$[0] --help' for more information.]) ;;
*) AC_MSG_ERROR([unrecognized argument: $[1]
-Try \`$[0] --help' for more information.]) ;;
+Try '$[0] --help' for more information.]) ;;
esac
shift
done
@@ -685,7 +695,7 @@ chmod +x "$CONFIG_LT"
# open by configure. Here we exec the FD to /dev/null, effectively closing
# config.log, so it can be properly (re)opened and appended to by config.lt.
lt_cl_success=:
-test "$silent" = yes &&
+test yes = "$silent" &&
lt_config_lt_args="$lt_config_lt_args --quiet"
exec AS_MESSAGE_LOG_FD>/dev/null
$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
@@ -705,27 +715,31 @@ m4_defun([_LT_CONFIG],
_LT_CONFIG_SAVE_COMMANDS([
m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
m4_if(_LT_TAG, [C], [
- # See if we are running on zsh, and set the options which allow our
+ # See if we are running on zsh, and set the options that allow our
# commands through without removal of \ escapes.
- if test -n "${ZSH_VERSION+set}" ; then
+ if test -n "${ZSH_VERSION+set}"; then
setopt NO_GLOB_SUBST
fi
- cfgfile="${ofile}T"
+ cfgfile=${ofile}T
trap "$RM \"$cfgfile\"; exit 1" 1 2 15
$RM "$cfgfile"
cat <<_LT_EOF >> "$cfgfile"
#! $SHELL
-
-# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
-# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Generated automatically by $as_me ($PACKAGE) $VERSION
# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
# NOTE: Changes made to this file will be lost: look at ltmain.sh.
-#
+
+# Provide generalized library-building support services.
+# Written by Gordon Matzigkeit, 1996
+
_LT_COPYING
_LT_LIBTOOL_TAGS
+# Configured defaults for sys_lib_dlsearch_path munging.
+: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}
+
# ### BEGIN LIBTOOL CONFIG
_LT_LIBTOOL_CONFIG_VARS
_LT_LIBTOOL_TAG_VARS
@@ -733,13 +747,24 @@ _LT_LIBTOOL_TAG_VARS
_LT_EOF
+ cat <<'_LT_EOF' >> "$cfgfile"
+
+# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE
+
+_LT_PREPARE_MUNGE_PATH_LIST
+_LT_PREPARE_CC_BASENAME
+
+# ### END FUNCTIONS SHARED WITH CONFIGURE
+
+_LT_EOF
+
case $host_os in
aix3*)
cat <<\_LT_EOF >> "$cfgfile"
# AIX sometimes has problems with the GCC collect2 program. For some
# reason, if we set the COLLECT_NAMES environment variable, the problems
# vanish in a puff of smoke.
-if test "X${COLLECT_NAMES+set}" != Xset; then
+if test set != "${COLLECT_NAMES+set}"; then
COLLECT_NAMES=
export COLLECT_NAMES
fi
@@ -756,8 +781,6 @@ _LT_EOF
sed '$q' "$ltmain" >> "$cfgfile" \
|| (rm -f "$cfgfile"; exit 1)
- _LT_PROG_REPLACE_SHELLFNS
-
mv -f "$cfgfile" "$ofile" ||
(rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
chmod +x "$ofile"
@@ -775,7 +798,6 @@ _LT_EOF
[m4_if([$1], [], [
PACKAGE='$PACKAGE'
VERSION='$VERSION'
- TIMESTAMP='$TIMESTAMP'
RM='$RM'
ofile='$ofile'], [])
])dnl /_LT_CONFIG_SAVE_COMMANDS
@@ -974,7 +996,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
[lt_cv_apple_cc_single_mod=no
- if test -z "${LT_MULTI_MODULE}"; then
+ if test -z "$LT_MULTI_MODULE"; then
# By default we will add the -single_module flag. You can override
# by either setting the environment variable LT_MULTI_MODULE
# non-empty at configure time, or by adding -multi_module to the
@@ -992,7 +1014,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
cat conftest.err >&AS_MESSAGE_LOG_FD
# Otherwise, if the output was created with a 0 exit code from
# the compiler, it worked.
- elif test -f libconftest.dylib && test $_lt_result -eq 0; then
+ elif test -f libconftest.dylib && test 0 = "$_lt_result"; then
lt_cv_apple_cc_single_mod=yes
else
cat conftest.err >&AS_MESSAGE_LOG_FD
@@ -1010,7 +1032,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
[lt_cv_ld_exported_symbols_list=yes],
[lt_cv_ld_exported_symbols_list=no])
- LDFLAGS="$save_LDFLAGS"
+ LDFLAGS=$save_LDFLAGS
])
AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],
@@ -1032,7 +1054,7 @@ _LT_EOF
_lt_result=$?
if test -s conftest.err && $GREP force_load conftest.err; then
cat conftest.err >&AS_MESSAGE_LOG_FD
- elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
+ elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then
lt_cv_ld_force_load=yes
else
cat conftest.err >&AS_MESSAGE_LOG_FD
@@ -1042,32 +1064,32 @@ _LT_EOF
])
case $host_os in
rhapsody* | darwin1.[[012]])
- _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+ _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
darwin1.*)
- _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
darwin*) # darwin 5.x on
# if running on 10.5 or later, the deployment target defaults
# to the OS version, if on x86, and 10.4, the deployment
# target defaults to 10.4. Don't you love it?
case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
- _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
- 10.[[012]]*)
- _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+ 10.[[012]][[,.]]*)
+ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
10.*)
- _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
esac
;;
esac
- if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+ if test yes = "$lt_cv_apple_cc_single_mod"; then
_lt_dar_single_mod='$single_module'
fi
- if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
- _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+ if test yes = "$lt_cv_ld_exported_symbols_list"; then
+ _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
else
- _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'
fi
- if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
+ if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then
_lt_dsymutil='~$DSYMUTIL $lib || :'
else
_lt_dsymutil=
@@ -1087,29 +1109,29 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES],
_LT_TAGVAR(hardcode_direct, $1)=no
_LT_TAGVAR(hardcode_automatic, $1)=yes
_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
- if test "$lt_cv_ld_force_load" = "yes"; then
- _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+ if test yes = "$lt_cv_ld_force_load"; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],
[FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes])
else
_LT_TAGVAR(whole_archive_flag_spec, $1)=''
fi
_LT_TAGVAR(link_all_deplibs, $1)=yes
- _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined"
+ _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined
case $cc_basename in
- ifort*) _lt_dar_can_shared=yes ;;
+ ifort*|nagfor*) _lt_dar_can_shared=yes ;;
*) _lt_dar_can_shared=$GCC ;;
esac
- if test "$_lt_dar_can_shared" = "yes"; then
+ if test yes = "$_lt_dar_can_shared"; then
output_verbose_link_cmd=func_echo_all
- _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
- _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
- _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
- _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
+ _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
+ _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
m4_if([$1], [CXX],
-[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then
- _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
- _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
+[ if test yes != "$lt_cv_apple_cc_single_mod"; then
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
fi
],[])
else
@@ -1129,7 +1151,7 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES],
# Allow to override them for all tags through lt_cv_aix_libpath.
m4_defun([_LT_SYS_MODULE_PATH_AIX],
[m4_require([_LT_DECL_SED])dnl
-if test "${lt_cv_aix_libpath+set}" = set; then
+if test set = "${lt_cv_aix_libpath+set}"; then
aix_libpath=$lt_cv_aix_libpath
else
AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],
@@ -1147,7 +1169,7 @@ else
_LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
fi],[])
if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
- _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib"
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib
fi
])
aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])
@@ -1167,8 +1189,8 @@ m4_define([_LT_SHELL_INIT],
# -----------------------
# Find how we can fake an echo command that does not interpret backslash.
# In particular, with Autoconf 2.60 or later we add some code to the start
-# of the generated configure script which will find a shell with a builtin
-# printf (which we can use as an echo command).
+# of the generated configure script that will find a shell with a builtin
+# printf (that we can use as an echo command).
m4_defun([_LT_PROG_ECHO_BACKSLASH],
[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
@@ -1196,10 +1218,10 @@ fi
# Invoke $ECHO with all args, space-separated.
func_echo_all ()
{
- $ECHO "$*"
+ $ECHO "$*"
}
-case "$ECHO" in
+case $ECHO in
printf*) AC_MSG_RESULT([printf]) ;;
print*) AC_MSG_RESULT([print -r]) ;;
*) AC_MSG_RESULT([cat]) ;;
@@ -1225,16 +1247,17 @@ _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
AC_DEFUN([_LT_WITH_SYSROOT],
[AC_MSG_CHECKING([for sysroot])
AC_ARG_WITH([sysroot],
-[ --with-sysroot[=DIR] Search for dependent libraries within DIR
- (or the compiler's sysroot if not specified).],
+[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@],
+ [Search for dependent libraries within DIR (or the compiler's sysroot
+ if not specified).])],
[], [with_sysroot=no])
dnl lt_sysroot will always be passed unquoted. We quote it here
dnl in case the user passed a directory name.
lt_sysroot=
-case ${with_sysroot} in #(
+case $with_sysroot in #(
yes)
- if test "$GCC" = yes; then
+ if test yes = "$GCC"; then
lt_sysroot=`$CC --print-sysroot 2>/dev/null`
fi
;; #(
@@ -1244,14 +1267,14 @@ case ${with_sysroot} in #(
no|'')
;; #(
*)
- AC_MSG_RESULT([${with_sysroot}])
+ AC_MSG_RESULT([$with_sysroot])
AC_MSG_ERROR([The sysroot must be an absolute path.])
;;
esac
AC_MSG_RESULT([${lt_sysroot:-no}])
_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl
-[dependent libraries, and in which our libraries should be installed.])])
+[dependent libraries, and where our libraries should be installed.])])
# _LT_ENABLE_LOCK
# ---------------
@@ -1259,31 +1282,33 @@ m4_defun([_LT_ENABLE_LOCK],
[AC_ARG_ENABLE([libtool-lock],
[AS_HELP_STRING([--disable-libtool-lock],
[avoid locking (might break parallel builds)])])
-test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+test no = "$enable_libtool_lock" || enable_libtool_lock=yes
# Some flags need to be propagated to the compiler or linker for good
# libtool support.
case $host in
ia64-*-hpux*)
- # Find out which ABI we are using.
+ # Find out what ABI is being produced by ac_compile, and set mode
+ # options accordingly.
echo 'int i;' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then
case `/usr/bin/file conftest.$ac_objext` in
*ELF-32*)
- HPUX_IA64_MODE="32"
+ HPUX_IA64_MODE=32
;;
*ELF-64*)
- HPUX_IA64_MODE="64"
+ HPUX_IA64_MODE=64
;;
esac
fi
rm -rf conftest*
;;
*-*-irix6*)
- # Find out which ABI we are using.
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then
- if test "$lt_cv_prog_gnu_ld" = yes; then
+ if test yes = "$lt_cv_prog_gnu_ld"; then
case `/usr/bin/file conftest.$ac_objext` in
*32-bit*)
LD="${LD-ld} -melf32bsmip"
@@ -1312,9 +1337,46 @@ ia64-*-hpux*)
rm -rf conftest*
;;
-x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+mips64*-*linux*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ emul=elf
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ emul="${emul}32"
+ ;;
+ *64-bit*)
+ emul="${emul}64"
+ ;;
+ esac
+ case `/usr/bin/file conftest.$ac_objext` in
+ *MSB*)
+ emul="${emul}btsmip"
+ ;;
+ *LSB*)
+ emul="${emul}ltsmip"
+ ;;
+ esac
+ case `/usr/bin/file conftest.$ac_objext` in
+ *N32*)
+ emul="${emul}n32"
+ ;;
+ esac
+ LD="${LD-ld} -m $emul"
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
- # Find out which ABI we are using.
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly. Note that the listed cases only cover the
+ # situations where additional linker options are needed (such as when
+ # doing 32-bit compilation for a host where ld defaults to 64-bit, or
+ # vice versa); the common cases where no linker options are needed do
+ # not appear in the list.
echo 'int i;' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then
case `/usr/bin/file conftest.o` in
@@ -1324,9 +1386,19 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
LD="${LD-ld} -m elf_i386_fbsd"
;;
x86_64-*linux*)
- LD="${LD-ld} -m elf_i386"
+ case `/usr/bin/file conftest.o` in
+ *x86-64*)
+ LD="${LD-ld} -m elf32_x86_64"
+ ;;
+ *)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ esac
;;
- ppc64-*linux*|powerpc64-*linux*)
+ powerpc64le-*linux*)
+ LD="${LD-ld} -m elf32lppclinux"
+ ;;
+ powerpc64-*linux*)
LD="${LD-ld} -m elf32ppclinux"
;;
s390x-*linux*)
@@ -1345,7 +1417,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
x86_64-*linux*)
LD="${LD-ld} -m elf_x86_64"
;;
- ppc*-*linux*|powerpc*-*linux*)
+ powerpcle-*linux*)
+ LD="${LD-ld} -m elf64lppc"
+ ;;
+ powerpc-*linux*)
LD="${LD-ld} -m elf64ppc"
;;
s390*-*linux*|s390*-*tpf*)
@@ -1363,19 +1438,20 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
*-*-sco3.2v5*)
# On SCO OpenServer 5, we need -belf to get full-featured binaries.
- SAVE_CFLAGS="$CFLAGS"
+ SAVE_CFLAGS=$CFLAGS
CFLAGS="$CFLAGS -belf"
AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
[AC_LANG_PUSH(C)
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
AC_LANG_POP])
- if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ if test yes != "$lt_cv_cc_needs_belf"; then
# this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
- CFLAGS="$SAVE_CFLAGS"
+ CFLAGS=$SAVE_CFLAGS
fi
;;
*-*solaris*)
- # Find out which ABI we are using.
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
echo 'int i;' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then
case `/usr/bin/file conftest.o` in
@@ -1383,7 +1459,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
case $lt_cv_prog_gnu_ld in
yes*)
case $host in
- i?86-*-solaris*)
+ i?86-*-solaris*|x86_64-*-solaris*)
LD="${LD-ld} -m elf_x86_64"
;;
sparc*-*-solaris*)
@@ -1392,7 +1468,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
esac
# GNU ld 2.21 introduced _sol2 emulations. Use them if available.
if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
- LD="${LD-ld}_sol2"
+ LD=${LD-ld}_sol2
fi
;;
*)
@@ -1408,7 +1484,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
;;
esac
-need_locks="$enable_libtool_lock"
+need_locks=$enable_libtool_lock
])# _LT_ENABLE_LOCK
@@ -1427,11 +1503,11 @@ AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
[echo conftest.$ac_objext > conftest.lst
lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'
AC_TRY_EVAL([lt_ar_try])
- if test "$ac_status" -eq 0; then
+ if test 0 -eq "$ac_status"; then
# Ensure the archiver fails upon bogus file names.
rm -f conftest.$ac_objext libconftest.a
AC_TRY_EVAL([lt_ar_try])
- if test "$ac_status" -ne 0; then
+ if test 0 -ne "$ac_status"; then
lt_cv_ar_at_file=@
fi
fi
@@ -1439,7 +1515,7 @@ AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
])
])
-if test "x$lt_cv_ar_at_file" = xno; then
+if test no = "$lt_cv_ar_at_file"; then
archiver_list_spec=
else
archiver_list_spec=$lt_cv_ar_at_file
@@ -1470,7 +1546,7 @@ old_postuninstall_cmds=
if test -n "$RANLIB"; then
case $host_os in
- openbsd*)
+ bitrig* | openbsd*)
old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
;;
*)
@@ -1506,7 +1582,7 @@ AC_CACHE_CHECK([$1], [$2],
[$2=no
m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
echo "$lt_simple_compile_test_code" > conftest.$ac_ext
- lt_compiler_flag="$3"
+ lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment
# Insert the option either (1) after the last *FLAGS variable, or
# (2) before a word containing "conftest.", or (3) at the end.
# Note that $ac_compile itself does not contain backslashes and begins
@@ -1533,7 +1609,7 @@ AC_CACHE_CHECK([$1], [$2],
$RM conftest*
])
-if test x"[$]$2" = xyes; then
+if test yes = "[$]$2"; then
m4_if([$5], , :, [$5])
else
m4_if([$6], , :, [$6])
@@ -1555,7 +1631,7 @@ AC_DEFUN([_LT_LINKER_OPTION],
m4_require([_LT_DECL_SED])dnl
AC_CACHE_CHECK([$1], [$2],
[$2=no
- save_LDFLAGS="$LDFLAGS"
+ save_LDFLAGS=$LDFLAGS
LDFLAGS="$LDFLAGS $3"
echo "$lt_simple_link_test_code" > conftest.$ac_ext
if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
@@ -1574,10 +1650,10 @@ AC_CACHE_CHECK([$1], [$2],
fi
fi
$RM -r conftest*
- LDFLAGS="$save_LDFLAGS"
+ LDFLAGS=$save_LDFLAGS
])
-if test x"[$]$2" = xyes; then
+if test yes = "[$]$2"; then
m4_if([$4], , :, [$4])
else
m4_if([$5], , :, [$5])
@@ -1598,7 +1674,7 @@ AC_DEFUN([LT_CMD_MAX_LEN],
AC_MSG_CHECKING([the maximum length of command line arguments])
AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
i=0
- teststring="ABCD"
+ teststring=ABCD
case $build_os in
msdosdjgpp*)
@@ -1638,7 +1714,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
lt_cv_sys_max_cmd_len=8192;
;;
- netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+ bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
# This has been around since 386BSD, at least. Likely further.
if test -x /sbin/sysctl; then
lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
@@ -1688,22 +1764,23 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
;;
*)
lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
- if test -n "$lt_cv_sys_max_cmd_len"; then
+ if test -n "$lt_cv_sys_max_cmd_len" && \
+ test undefined != "$lt_cv_sys_max_cmd_len"; then
lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
else
# Make teststring a little bigger before we do anything with it.
# a 1K string should be a reasonable start.
- for i in 1 2 3 4 5 6 7 8 ; do
+ for i in 1 2 3 4 5 6 7 8; do
teststring=$teststring$teststring
done
SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
# If test is not a shell built-in, we'll probably end up computing a
# maximum length that is only half of the actual maximum length, but
# we can't tell.
- while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
+ while { test X`env echo "$teststring$teststring" 2>/dev/null` \
= "X$teststring$teststring"; } >/dev/null 2>&1 &&
- test $i != 17 # 1/2 MB should be enough
+ test 17 != "$i" # 1/2 MB should be enough
do
i=`expr $i + 1`
teststring=$teststring$teststring
@@ -1719,7 +1796,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
;;
esac
])
-if test -n $lt_cv_sys_max_cmd_len ; then
+if test -n "$lt_cv_sys_max_cmd_len"; then
AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
else
AC_MSG_RESULT(none)
@@ -1747,7 +1824,7 @@ m4_defun([_LT_HEADER_DLFCN],
# ----------------------------------------------------------------
m4_defun([_LT_TRY_DLOPEN_SELF],
[m4_require([_LT_HEADER_DLFCN])dnl
-if test "$cross_compiling" = yes; then :
+if test yes = "$cross_compiling"; then :
[$4]
else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
@@ -1794,9 +1871,9 @@ else
# endif
#endif
-/* When -fvisbility=hidden is used, assume the code has been annotated
+/* When -fvisibility=hidden is used, assume the code has been annotated
correspondingly for the symbols needed. */
-#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
int fnord () __attribute__((visibility("default")));
#endif
@@ -1822,7 +1899,7 @@ int main ()
return status;
}]
_LT_EOF
- if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
+ if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then
(./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
lt_status=$?
case x$lt_status in
@@ -1843,7 +1920,7 @@ rm -fr conftest*
# ------------------
AC_DEFUN([LT_SYS_DLOPEN_SELF],
[m4_require([_LT_HEADER_DLFCN])dnl
-if test "x$enable_dlopen" != xyes; then
+if test yes != "$enable_dlopen"; then
enable_dlopen=unknown
enable_dlopen_self=unknown
enable_dlopen_self_static=unknown
@@ -1853,44 +1930,52 @@ else
case $host_os in
beos*)
- lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen=load_add_on
lt_cv_dlopen_libs=
lt_cv_dlopen_self=yes
;;
mingw* | pw32* | cegcc*)
- lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen=LoadLibrary
lt_cv_dlopen_libs=
;;
cygwin*)
- lt_cv_dlopen="dlopen"
+ lt_cv_dlopen=dlopen
lt_cv_dlopen_libs=
;;
darwin*)
- # if libdl is installed we need to link against it
+ # if libdl is installed we need to link against it
AC_CHECK_LIB([dl], [dlopen],
- [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
- lt_cv_dlopen="dyld"
+ [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[
+ lt_cv_dlopen=dyld
lt_cv_dlopen_libs=
lt_cv_dlopen_self=yes
])
;;
+ tpf*)
+ # Don't try to run any link tests for TPF. We know it's impossible
+ # because TPF is a cross-compiler, and we know how we open DSOs.
+ lt_cv_dlopen=dlopen
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=no
+ ;;
+
*)
AC_CHECK_FUNC([shl_load],
- [lt_cv_dlopen="shl_load"],
+ [lt_cv_dlopen=shl_load],
[AC_CHECK_LIB([dld], [shl_load],
- [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"],
+ [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld],
[AC_CHECK_FUNC([dlopen],
- [lt_cv_dlopen="dlopen"],
+ [lt_cv_dlopen=dlopen],
[AC_CHECK_LIB([dl], [dlopen],
- [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
+ [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],
[AC_CHECK_LIB([svld], [dlopen],
- [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
+ [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld],
[AC_CHECK_LIB([dld], [dld_link],
- [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"])
+ [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld])
])
])
])
@@ -1899,21 +1984,21 @@ else
;;
esac
- if test "x$lt_cv_dlopen" != xno; then
- enable_dlopen=yes
- else
+ if test no = "$lt_cv_dlopen"; then
enable_dlopen=no
+ else
+ enable_dlopen=yes
fi
case $lt_cv_dlopen in
dlopen)
- save_CPPFLAGS="$CPPFLAGS"
- test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+ save_CPPFLAGS=$CPPFLAGS
+ test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
- save_LDFLAGS="$LDFLAGS"
+ save_LDFLAGS=$LDFLAGS
wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
- save_LIBS="$LIBS"
+ save_LIBS=$LIBS
LIBS="$lt_cv_dlopen_libs $LIBS"
AC_CACHE_CHECK([whether a program can dlopen itself],
@@ -1923,7 +2008,7 @@ else
lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
])
- if test "x$lt_cv_dlopen_self" = xyes; then
+ if test yes = "$lt_cv_dlopen_self"; then
wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
lt_cv_dlopen_self_static, [dnl
@@ -1933,9 +2018,9 @@ else
])
fi
- CPPFLAGS="$save_CPPFLAGS"
- LDFLAGS="$save_LDFLAGS"
- LIBS="$save_LIBS"
+ CPPFLAGS=$save_CPPFLAGS
+ LDFLAGS=$save_LDFLAGS
+ LIBS=$save_LIBS
;;
esac
@@ -2027,8 +2112,8 @@ m4_defun([_LT_COMPILER_FILE_LOCKS],
m4_require([_LT_FILEUTILS_DEFAULTS])dnl
_LT_COMPILER_C_O([$1])
-hard_links="nottested"
-if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
+hard_links=nottested
+if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then
# do not overwrite the value of need_locks provided by the user
AC_MSG_CHECKING([if we can lock with hard links])
hard_links=yes
@@ -2038,8 +2123,8 @@ if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" !=
ln conftest.a conftest.b 2>&5 || hard_links=no
ln conftest.a conftest.b 2>/dev/null && hard_links=no
AC_MSG_RESULT([$hard_links])
- if test "$hard_links" = no; then
- AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
+ if test no = "$hard_links"; then
+ AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe])
need_locks=warn
fi
else
@@ -2066,8 +2151,8 @@ objdir=$lt_cv_objdir
_LT_DECL([], [objdir], [0],
[The name of the directory that contains temporary libtool files])dnl
m4_pattern_allow([LT_OBJDIR])dnl
-AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/",
- [Define to the sub-directory in which libtool stores uninstalled libraries.])
+AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/",
+ [Define to the sub-directory where libtool stores uninstalled libraries.])
])# _LT_CHECK_OBJDIR
@@ -2079,15 +2164,15 @@ m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
_LT_TAGVAR(hardcode_action, $1)=
if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
test -n "$_LT_TAGVAR(runpath_var, $1)" ||
- test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
+ test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then
# We can hardcode non-existent directories.
- if test "$_LT_TAGVAR(hardcode_direct, $1)" != no &&
+ if test no != "$_LT_TAGVAR(hardcode_direct, $1)" &&
# If the only mechanism to avoid hardcoding is shlibpath_var, we
# have to relink, otherwise we might link with an installed library
# when we should be linking with a yet-to-be-installed one
- ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
- test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then
+ ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" &&
+ test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then
# Linking always hardcodes the temporary library directory.
_LT_TAGVAR(hardcode_action, $1)=relink
else
@@ -2101,12 +2186,12 @@ else
fi
AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
-if test "$_LT_TAGVAR(hardcode_action, $1)" = relink ||
- test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then
+if test relink = "$_LT_TAGVAR(hardcode_action, $1)" ||
+ test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then
# Fast installation is not supported
enable_fast_install=no
-elif test "$shlibpath_overrides_runpath" = yes ||
- test "$enable_shared" = no; then
+elif test yes = "$shlibpath_overrides_runpath" ||
+ test no = "$enable_shared"; then
# Fast installation is not necessary
enable_fast_install=needless
fi
@@ -2130,7 +2215,7 @@ else
# FIXME - insert some real tests, host_os isn't really good enough
case $host_os in
darwin*)
- if test -n "$STRIP" ; then
+ if test -n "$STRIP"; then
striplib="$STRIP -x"
old_striplib="$STRIP -S"
AC_MSG_RESULT([yes])
@@ -2148,6 +2233,47 @@ _LT_DECL([], [striplib], [1])
])# _LT_CMD_STRIPLIB
+# _LT_PREPARE_MUNGE_PATH_LIST
+# ---------------------------
+# Make sure func_munge_path_list() is defined correctly.
+m4_defun([_LT_PREPARE_MUNGE_PATH_LIST],
+[[# func_munge_path_list VARIABLE PATH
+# -----------------------------------
+# VARIABLE is name of variable containing _space_ separated list of
+# directories to be munged by the contents of PATH, which is string
+# having a format:
+# "DIR[:DIR]:"
+# string "DIR[ DIR]" will be prepended to VARIABLE
+# ":DIR[:DIR]"
+# string "DIR[ DIR]" will be appended to VARIABLE
+# "DIRP[:DIRP]::[DIRA:]DIRA"
+# string "DIRP[ DIRP]" will be prepended to VARIABLE and string
+# "DIRA[ DIRA]" will be appended to VARIABLE
+# "DIR[:DIR]"
+# VARIABLE will be replaced by "DIR[ DIR]"
+func_munge_path_list ()
+{
+ case x@S|@2 in
+ x)
+ ;;
+ *:)
+ eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\"
+ ;;
+ x:*)
+ eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\"
+ ;;
+ *::*)
+ eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
+ eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\"
+ ;;
+ *)
+ eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\"
+ ;;
+ esac
+}
+]])# _LT_PREPARE_PATH_LIST
+
+
# _LT_SYS_DYNAMIC_LINKER([TAG])
# -----------------------------
# PORTME Fill in your ld.so characteristics
@@ -2158,17 +2284,18 @@ m4_require([_LT_FILEUTILS_DEFAULTS])dnl
m4_require([_LT_DECL_OBJDUMP])dnl
m4_require([_LT_DECL_SED])dnl
m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl
AC_MSG_CHECKING([dynamic linker characteristics])
m4_if([$1],
[], [
-if test "$GCC" = yes; then
+if test yes = "$GCC"; then
case $host_os in
- darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
- *) lt_awk_arg="/^libraries:/" ;;
+ darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;
+ *) lt_awk_arg='/^libraries:/' ;;
esac
case $host_os in
- mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;;
- *) lt_sed_strip_eq="s,=/,/,g" ;;
+ mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;;
+ *) lt_sed_strip_eq='s|=/|/|g' ;;
esac
lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
case $lt_search_path_spec in
@@ -2184,28 +2311,35 @@ if test "$GCC" = yes; then
;;
esac
# Ok, now we have the path, separated by spaces, we can step through it
- # and add multilib dir if necessary.
+ # and add multilib dir if necessary...
lt_tmp_lt_search_path_spec=
- lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ # ...but if some path component already ends with the multilib dir we assume
+ # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).
+ case "$lt_multi_os_dir; $lt_search_path_spec " in
+ "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)
+ lt_multi_os_dir=
+ ;;
+ esac
for lt_sys_path in $lt_search_path_spec; do
- if test -d "$lt_sys_path/$lt_multi_os_dir"; then
- lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
- else
+ if test -d "$lt_sys_path$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"
+ elif test -n "$lt_multi_os_dir"; then
test -d "$lt_sys_path" && \
lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
fi
done
lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
-BEGIN {RS=" "; FS="/|\n";} {
- lt_foo="";
- lt_count=0;
+BEGIN {RS = " "; FS = "/|\n";} {
+ lt_foo = "";
+ lt_count = 0;
for (lt_i = NF; lt_i > 0; lt_i--) {
if ($lt_i != "" && $lt_i != ".") {
if ($lt_i == "..") {
lt_count++;
} else {
if (lt_count == 0) {
- lt_foo="/" $lt_i lt_foo;
+ lt_foo = "/" $lt_i lt_foo;
} else {
lt_count--;
}
@@ -2219,7 +2353,7 @@ BEGIN {RS=" "; FS="/|\n";} {
# for these hosts.
case $host_os in
mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
- $SED 's,/\([[A-Za-z]]:\),\1,g'` ;;
+ $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;;
esac
sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
else
@@ -2228,7 +2362,7 @@ fi])
library_names_spec=
libname_spec='lib$name'
soname_spec=
-shrext_cmds=".so"
+shrext_cmds=.so
postinstall_cmds=
postuninstall_cmds=
finish_cmds=
@@ -2245,14 +2379,17 @@ hardcode_into_libs=no
# flags to be left without arguments
need_version=unknown
+AC_ARG_VAR([LT_SYS_LIBRARY_PATH],
+[User-defined run-time library search path.])
+
case $host_os in
aix3*)
version_type=linux # correct to gnu/linux during the next big refactor
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
shlibpath_var=LIBPATH
# AIX 3 has no versioning support, so we append a major version to the name.
- soname_spec='${libname}${release}${shared_ext}$major'
+ soname_spec='$libname$release$shared_ext$major'
;;
aix[[4-9]]*)
@@ -2260,41 +2397,91 @@ aix[[4-9]]*)
need_lib_prefix=no
need_version=no
hardcode_into_libs=yes
- if test "$host_cpu" = ia64; then
+ if test ia64 = "$host_cpu"; then
# AIX 5 supports IA64
- library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+ library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
shlibpath_var=LD_LIBRARY_PATH
else
# With GCC up to 2.95.x, collect2 would create an import file
# for dependence libraries. The import file would start with
- # the line `#! .'. This would cause the generated library to
- # depend on `.', always an invalid library. This was fixed in
+ # the line '#! .'. This would cause the generated library to
+ # depend on '.', always an invalid library. This was fixed in
# development snapshots of GCC prior to 3.0.
case $host_os in
aix4 | aix4.[[01]] | aix4.[[01]].*)
if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
echo ' yes '
- echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+ echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
:
else
can_build_shared=no
fi
;;
esac
- # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+ # Using Import Files as archive members, it is possible to support
+ # filename-based versioning of shared library archives on AIX. While
+ # this would work for both with and without runtime linking, it will
+ # prevent static linking of such archives. So we do filename-based
+ # shared library versioning with .so extension only, which is used
+ # when both runtime linking and shared linking is enabled.
+ # Unfortunately, runtime linking may impact performance, so we do
+ # not want this to be the default eventually. Also, we use the
+ # versioned .so libs for executables only if there is the -brtl
+ # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
+ # To allow for filename-based versioning support, we need to create
+ # libNAME.so.V as an archive file, containing:
+ # *) an Import File, referring to the versioned filename of the
+ # archive as well as the shared archive member, telling the
+ # bitwidth (32 or 64) of that shared object, and providing the
+ # list of exported symbols of that shared object, eventually
+ # decorated with the 'weak' keyword
+ # *) the shared object with the F_LOADONLY flag set, to really avoid
+ # it being seen by the linker.
+ # At run time we better use the real file rather than another symlink,
+ # but for link time we create the symlink libNAME.so -> libNAME.so.V
+
+ case $with_aix_soname,$aix_use_runtimelinking in
+ # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
# soname into executable. Probably we can add versioning support to
# collect2, so additional links can be useful in future.
- if test "$aix_use_runtimelinking" = yes; then
+ aix,yes) # traditional libtool
+ dynamic_linker='AIX unversionable lib.so'
# If using run time linking (on AIX 4.2 or later) use lib<name>.so
# instead of lib<name>.a to let people know that these are not
# typical AIX shared libraries.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- else
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ ;;
+ aix,no) # traditional AIX only
+ dynamic_linker='AIX lib.a[(]lib.so.V[)]'
# We preserve .a as extension for shared libraries through AIX4.2
# and later when we are not doing run time linking.
- library_names_spec='${libname}${release}.a $libname.a'
- soname_spec='${libname}${release}${shared_ext}$major'
- fi
+ library_names_spec='$libname$release.a $libname.a'
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+ svr4,*) # full svr4 only
+ dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]"
+ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+ # We do not specify a path in Import Files, so LIBPATH fires.
+ shlibpath_overrides_runpath=yes
+ ;;
+ *,yes) # both, prefer svr4
+ dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]"
+ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+ # unpreferred sharedlib libNAME.a needs extra handling
+ postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
+ postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
+ # We do not specify a path in Import Files, so LIBPATH fires.
+ shlibpath_overrides_runpath=yes
+ ;;
+ *,no) # both, prefer aix
+ dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]"
+ library_names_spec='$libname$release.a $libname.a'
+ soname_spec='$libname$release$shared_ext$major'
+ # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
+ postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
+ postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
+ ;;
+ esac
shlibpath_var=LIBPATH
fi
;;
@@ -2304,18 +2491,18 @@ amigaos*)
powerpc)
# Since July 2007 AmigaOS4 officially supports .so libraries.
# When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
;;
m68k)
library_names_spec='$libname.ixlibrary $libname.a'
# Create ${libname}_ixlibrary.a entries in /sys/libs.
- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
;;
esac
;;
beos*)
- library_names_spec='${libname}${shared_ext}'
+ library_names_spec='$libname$shared_ext'
dynamic_linker="$host_os ld.so"
shlibpath_var=LIBRARY_PATH
;;
@@ -2323,8 +2510,8 @@ beos*)
bsdi[[45]]*)
version_type=linux # correct to gnu/linux during the next big refactor
need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
shlibpath_var=LD_LIBRARY_PATH
sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
@@ -2336,7 +2523,7 @@ bsdi[[45]]*)
cygwin* | mingw* | pw32* | cegcc*)
version_type=windows
- shrext_cmds=".dll"
+ shrext_cmds=.dll
need_version=no
need_lib_prefix=no
@@ -2345,8 +2532,8 @@ cygwin* | mingw* | pw32* | cegcc*)
# gcc
library_names_spec='$libname.dll.a'
# DLL is installed to $(libdir)/../bin by postinstall_cmds
- postinstall_cmds='base_file=`basename \${file}`~
- dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
dldir=$destdir/`dirname \$dlpath`~
test -d \$dldir || mkdir -p \$dldir~
$install_prog $dir/$dlname \$dldir/$dlname~
@@ -2362,17 +2549,17 @@ cygwin* | mingw* | pw32* | cegcc*)
case $host_os in
cygwin*)
# Cygwin DLLs use 'cyg' prefix rather than 'lib'
- soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
m4_if([$1], [],[
sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
;;
mingw* | cegcc*)
# MinGW DLLs use traditional 'lib' prefix
- soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
;;
pw32*)
# pw32 DLLs use 'pw' prefix rather than 'lib'
- library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
;;
esac
dynamic_linker='Win32 ld.exe'
@@ -2381,8 +2568,8 @@ m4_if([$1], [],[
*,cl*)
# Native MSVC
libname_spec='$name'
- soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
- library_names_spec='${libname}.dll.lib'
+ soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+ library_names_spec='$libname.dll.lib'
case $build_os in
mingw*)
@@ -2409,7 +2596,7 @@ m4_if([$1], [],[
sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
;;
*)
- sys_lib_search_path_spec="$LIB"
+ sys_lib_search_path_spec=$LIB
if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
# It is most probably a Windows format PATH.
sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
@@ -2422,8 +2609,8 @@ m4_if([$1], [],[
esac
# DLL is installed to $(libdir)/../bin by postinstall_cmds
- postinstall_cmds='base_file=`basename \${file}`~
- dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
dldir=$destdir/`dirname \$dlpath`~
test -d \$dldir || mkdir -p \$dldir~
$install_prog $dir/$dlname \$dldir/$dlname'
@@ -2436,7 +2623,7 @@ m4_if([$1], [],[
*)
# Assume MSVC wrapper
- library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib'
dynamic_linker='Win32 ld.exe'
;;
esac
@@ -2449,8 +2636,8 @@ darwin* | rhapsody*)
version_type=darwin
need_lib_prefix=no
need_version=no
- library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
- soname_spec='${libname}${release}${major}$shared_ext'
+ library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$major$shared_ext'
shlibpath_overrides_runpath=yes
shlibpath_var=DYLD_LIBRARY_PATH
shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
@@ -2463,8 +2650,8 @@ dgux*)
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
- soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
shlibpath_var=LD_LIBRARY_PATH
;;
@@ -2482,12 +2669,13 @@ freebsd* | dragonfly*)
version_type=freebsd-$objformat
case $version_type in
freebsd-elf*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
need_version=no
need_lib_prefix=no
;;
freebsd-*)
- library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
need_version=yes
;;
esac
@@ -2512,26 +2700,15 @@ freebsd* | dragonfly*)
esac
;;
-gnu*)
- version_type=linux # correct to gnu/linux during the next big refactor
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- ;;
-
haiku*)
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
dynamic_linker="$host_os runtime_loader"
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
shlibpath_var=LIBRARY_PATH
- shlibpath_overrides_runpath=yes
+ shlibpath_overrides_runpath=no
sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
hardcode_into_libs=yes
;;
@@ -2549,14 +2726,15 @@ hpux9* | hpux10* | hpux11*)
dynamic_linker="$host_os dld.so"
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- if test "X$HPUX_IA64_MODE" = X32; then
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ if test 32 = "$HPUX_IA64_MODE"; then
sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ sys_lib_dlsearch_path_spec=/usr/lib/hpux32
else
sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ sys_lib_dlsearch_path_spec=/usr/lib/hpux64
fi
- sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
;;
hppa*64*)
shrext_cmds='.sl'
@@ -2564,8 +2742,8 @@ hpux9* | hpux10* | hpux11*)
dynamic_linker="$host_os dld.sl"
shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
;;
@@ -2574,8 +2752,8 @@ hpux9* | hpux10* | hpux11*)
dynamic_linker="$host_os dld.sl"
shlibpath_var=SHLIB_PATH
shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
;;
esac
# HP-UX runs *really* slowly unless shared libraries are mode 555, ...
@@ -2588,8 +2766,8 @@ interix[[3-9]]*)
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=no
@@ -2600,7 +2778,7 @@ irix5* | irix6* | nonstopux*)
case $host_os in
nonstopux*) version_type=nonstopux ;;
*)
- if test "$lt_cv_prog_gnu_ld" = yes; then
+ if test yes = "$lt_cv_prog_gnu_ld"; then
version_type=linux # correct to gnu/linux during the next big refactor
else
version_type=irix
@@ -2608,8 +2786,8 @@ irix5* | irix6* | nonstopux*)
esac
need_lib_prefix=no
need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
case $host_os in
irix5* | nonstopux*)
libsuff= shlibsuff=
@@ -2628,8 +2806,8 @@ irix5* | irix6* | nonstopux*)
esac
shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
shlibpath_overrides_runpath=no
- sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
- sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
+ sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
hardcode_into_libs=yes
;;
@@ -2638,13 +2816,33 @@ linux*oldld* | linux*aout* | linux*coff*)
dynamic_linker=no
;;
+linux*android*)
+ version_type=none # Android doesn't support versioned libraries.
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext'
+ soname_spec='$libname$release$shared_ext'
+ finish_cmds=
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ dynamic_linker='Android linker'
+ # Don't embed -rpath directories since the linker doesn't support them.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ ;;
+
# This must be glibc/ELF.
-linux* | k*bsd*-gnu | kopensolaris*-gnu)
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=no
@@ -2669,7 +2867,12 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu)
# before this can be enabled.
hardcode_into_libs=yes
- # Append ld.so.conf contents to the search path
+ # Ideally, we could use ldconfig to report *all* directores which are
+ # searched for libraries, however this is still not possible. Aside from not
+ # being certain /sbin/ldconfig is available, command
+ # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
+ # even though it is searched at run-time. Try to do the best guess by
+ # appending ld.so.conf contents (and includes) to the search path.
if test -f /etc/ld.so.conf; then
lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
@@ -2689,12 +2892,12 @@ netbsd*)
need_lib_prefix=no
need_version=no
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
dynamic_linker='NetBSD (a.out) ld.so'
else
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
dynamic_linker='NetBSD ld.elf_so'
fi
shlibpath_var=LD_LIBRARY_PATH
@@ -2704,7 +2907,7 @@ netbsd*)
newsos6)
version_type=linux # correct to gnu/linux during the next big refactor
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=yes
;;
@@ -2713,58 +2916,68 @@ newsos6)
version_type=qnx
need_lib_prefix=no
need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=no
hardcode_into_libs=yes
dynamic_linker='ldqnx.so'
;;
-openbsd*)
+openbsd* | bitrig*)
version_type=sunos
- sys_lib_dlsearch_path_spec="/usr/lib"
+ sys_lib_dlsearch_path_spec=/usr/lib
need_lib_prefix=no
- # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
- case $host_os in
- openbsd3.3 | openbsd3.3.*) need_version=yes ;;
- *) need_version=no ;;
- esac
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
- finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
- shlibpath_var=LD_LIBRARY_PATH
- if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- case $host_os in
- openbsd2.[[89]] | openbsd2.[[89]].*)
- shlibpath_overrides_runpath=no
- ;;
- *)
- shlibpath_overrides_runpath=yes
- ;;
- esac
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ need_version=no
else
- shlibpath_overrides_runpath=yes
+ need_version=yes
fi
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
;;
os2*)
libname_spec='$name'
- shrext_cmds=".dll"
+ version_type=windows
+ shrext_cmds=.dll
+ need_version=no
need_lib_prefix=no
- library_names_spec='$libname${shared_ext} $libname.a'
+ # OS/2 can only load a DLL with a base name of 8 characters or less.
+ soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
+ v=$($ECHO $release$versuffix | tr -d .-);
+ n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
+ $ECHO $n$v`$shared_ext'
+ library_names_spec='${libname}_dll.$libext'
dynamic_linker='OS/2 ld.exe'
- shlibpath_var=LIBPATH
+ shlibpath_var=BEGINLIBPATH
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
;;
osf3* | osf4* | osf5*)
version_type=osf
need_lib_prefix=no
need_version=no
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
shlibpath_var=LD_LIBRARY_PATH
sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
- sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
;;
rdos*)
@@ -2775,8 +2988,8 @@ solaris*)
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=yes
hardcode_into_libs=yes
@@ -2786,11 +2999,11 @@ solaris*)
sunos4*)
version_type=sunos
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=yes
- if test "$with_gnu_ld" = yes; then
+ if test yes = "$with_gnu_ld"; then
need_lib_prefix=no
fi
need_version=yes
@@ -2798,8 +3011,8 @@ sunos4*)
sysv4 | sysv4.3*)
version_type=linux # correct to gnu/linux during the next big refactor
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
shlibpath_var=LD_LIBRARY_PATH
case $host_vendor in
sni)
@@ -2820,24 +3033,24 @@ sysv4 | sysv4.3*)
;;
sysv4*MP*)
- if test -d /usr/nec ;then
+ if test -d /usr/nec; then
version_type=linux # correct to gnu/linux during the next big refactor
- library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
- soname_spec='$libname${shared_ext}.$major'
+ library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
+ soname_spec='$libname$shared_ext.$major'
shlibpath_var=LD_LIBRARY_PATH
fi
;;
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
- version_type=freebsd-elf
+ version_type=sco
need_lib_prefix=no
need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=yes
hardcode_into_libs=yes
- if test "$with_gnu_ld" = yes; then
+ if test yes = "$with_gnu_ld"; then
sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
else
sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
@@ -2855,7 +3068,7 @@ tpf*)
version_type=linux # correct to gnu/linux during the next big refactor
need_lib_prefix=no
need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=no
hardcode_into_libs=yes
@@ -2863,8 +3076,8 @@ tpf*)
uts4*)
version_type=linux # correct to gnu/linux during the next big refactor
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
shlibpath_var=LD_LIBRARY_PATH
;;
@@ -2873,20 +3086,30 @@ uts4*)
;;
esac
AC_MSG_RESULT([$dynamic_linker])
-test "$dynamic_linker" = no && can_build_shared=no
+test no = "$dynamic_linker" && can_build_shared=no
variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test "$GCC" = yes; then
+if test yes = "$GCC"; then
variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
fi
-if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
- sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
+ sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
fi
-if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
- sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+
+if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
+ sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
fi
+# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
+configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
+
+# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
+func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
+
+# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
+configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
+
_LT_DECL([], [variables_saved_for_relink], [1],
[Variables whose values should be saved in libtool wrapper scripts and
restored at link time])
@@ -2919,39 +3142,41 @@ _LT_DECL([], [hardcode_into_libs], [0],
[Whether we should hardcode library paths into libraries])
_LT_DECL([], [sys_lib_search_path_spec], [2],
[Compile-time system search path for libraries])
-_LT_DECL([], [sys_lib_dlsearch_path_spec], [2],
- [Run-time system search path for libraries])
+_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2],
+ [Detected run-time system search path for libraries])
+_LT_DECL([], [configure_time_lt_sys_library_path], [2],
+ [Explicit LT_SYS_LIBRARY_PATH set during ./configure time])
])# _LT_SYS_DYNAMIC_LINKER
# _LT_PATH_TOOL_PREFIX(TOOL)
# --------------------------
-# find a file program which can recognize shared library
+# find a file program that can recognize shared library
AC_DEFUN([_LT_PATH_TOOL_PREFIX],
[m4_require([_LT_DECL_EGREP])dnl
AC_MSG_CHECKING([for $1])
AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
[case $MAGIC_CMD in
[[\\/*] | ?:[\\/]*])
- lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
;;
*)
- lt_save_MAGIC_CMD="$MAGIC_CMD"
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ lt_save_MAGIC_CMD=$MAGIC_CMD
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
dnl $ac_dummy forces splitting on constant user-supplied paths.
dnl POSIX.2 word splitting is done only on the output of word expansions,
dnl not every word. This closes a longstanding sh security hole.
ac_dummy="m4_if([$2], , $PATH, [$2])"
for ac_dir in $ac_dummy; do
- IFS="$lt_save_ifs"
+ IFS=$lt_save_ifs
test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$1; then
- lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+ if test -f "$ac_dir/$1"; then
+ lt_cv_path_MAGIC_CMD=$ac_dir/"$1"
if test -n "$file_magic_test_file"; then
case $deplibs_check_method in
"file_magic "*)
file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
- MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ MAGIC_CMD=$lt_cv_path_MAGIC_CMD
if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
$EGREP "$file_magic_regex" > /dev/null; then
:
@@ -2974,11 +3199,11 @@ _LT_EOF
break
fi
done
- IFS="$lt_save_ifs"
- MAGIC_CMD="$lt_save_MAGIC_CMD"
+ IFS=$lt_save_ifs
+ MAGIC_CMD=$lt_save_MAGIC_CMD
;;
esac])
-MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+MAGIC_CMD=$lt_cv_path_MAGIC_CMD
if test -n "$MAGIC_CMD"; then
AC_MSG_RESULT($MAGIC_CMD)
else
@@ -2996,7 +3221,7 @@ dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
# _LT_PATH_MAGIC
# --------------
-# find a file program which can recognize a shared library
+# find a file program that can recognize a shared library
m4_defun([_LT_PATH_MAGIC],
[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
if test -z "$lt_cv_path_MAGIC_CMD"; then
@@ -3023,16 +3248,16 @@ m4_require([_LT_PROG_ECHO_BACKSLASH])dnl
AC_ARG_WITH([gnu-ld],
[AS_HELP_STRING([--with-gnu-ld],
[assume the C compiler uses GNU ld @<:@default=no@:>@])],
- [test "$withval" = no || with_gnu_ld=yes],
+ [test no = "$withval" || with_gnu_ld=yes],
[with_gnu_ld=no])dnl
ac_prog=ld
-if test "$GCC" = yes; then
+if test yes = "$GCC"; then
# Check if gcc -print-prog-name=ld gives a path.
AC_MSG_CHECKING([for ld used by $CC])
case $host in
*-*-mingw*)
- # gcc leaves a trailing carriage return which upsets mingw
+ # gcc leaves a trailing carriage return, which upsets mingw
ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
*)
ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
@@ -3046,7 +3271,7 @@ if test "$GCC" = yes; then
while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
done
- test -z "$LD" && LD="$ac_prog"
+ test -z "$LD" && LD=$ac_prog
;;
"")
# If it fails, then pretend we aren't using GCC.
@@ -3057,37 +3282,37 @@ if test "$GCC" = yes; then
with_gnu_ld=unknown
;;
esac
-elif test "$with_gnu_ld" = yes; then
+elif test yes = "$with_gnu_ld"; then
AC_MSG_CHECKING([for GNU ld])
else
AC_MSG_CHECKING([for non-GNU ld])
fi
AC_CACHE_VAL(lt_cv_path_LD,
[if test -z "$LD"; then
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
for ac_dir in $PATH; do
- IFS="$lt_save_ifs"
+ IFS=$lt_save_ifs
test -z "$ac_dir" && ac_dir=.
if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
- lt_cv_path_LD="$ac_dir/$ac_prog"
+ lt_cv_path_LD=$ac_dir/$ac_prog
# Check to see if the program is GNU ld. I'd rather use --version,
# but apparently some variants of GNU ld only accept -v.
# Break only if it was the GNU/non-GNU ld that we prefer.
case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
*GNU* | *'with BFD'*)
- test "$with_gnu_ld" != no && break
+ test no != "$with_gnu_ld" && break
;;
*)
- test "$with_gnu_ld" != yes && break
+ test yes != "$with_gnu_ld" && break
;;
esac
fi
done
- IFS="$lt_save_ifs"
+ IFS=$lt_save_ifs
else
- lt_cv_path_LD="$LD" # Let the user override the test with a path.
+ lt_cv_path_LD=$LD # Let the user override the test with a path.
fi])
-LD="$lt_cv_path_LD"
+LD=$lt_cv_path_LD
if test -n "$LD"; then
AC_MSG_RESULT($LD)
else
@@ -3141,13 +3366,13 @@ esac
reload_cmds='$LD$reload_flag -o $output$reload_objs'
case $host_os in
cygwin* | mingw* | pw32* | cegcc*)
- if test "$GCC" != yes; then
+ if test yes != "$GCC"; then
reload_cmds=false
fi
;;
darwin*)
- if test "$GCC" = yes; then
- reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+ if test yes = "$GCC"; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs'
else
reload_cmds='$LD$reload_flag -o $output$reload_objs'
fi
@@ -3158,6 +3383,43 @@ _LT_TAGDECL([], [reload_cmds], [2])dnl
])# _LT_CMD_RELOAD
+# _LT_PATH_DD
+# -----------
+# find a working dd
+m4_defun([_LT_PATH_DD],
+[AC_CACHE_CHECK([for a working dd], [ac_cv_path_lt_DD],
+[printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+: ${lt_DD:=$DD}
+AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd],
+[if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+ cmp -s conftest.i conftest.out \
+ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:
+fi])
+rm -f conftest.i conftest2.i conftest.out])
+])# _LT_PATH_DD
+
+
+# _LT_CMD_TRUNCATE
+# ----------------
+# find command to truncate a binary pipe
+m4_defun([_LT_CMD_TRUNCATE],
+[m4_require([_LT_PATH_DD])
+AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin],
+[printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+lt_cv_truncate_bin=
+if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+ cmp -s conftest.i conftest.out \
+ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"
+fi
+rm -f conftest.i conftest2.i conftest.out
+test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"])
+_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1],
+ [Command to truncate a binary pipe])
+])# _LT_CMD_TRUNCATE
+
+
# _LT_CHECK_MAGIC_METHOD
# ----------------------
# how to check for library dependencies
@@ -3173,13 +3435,13 @@ lt_cv_deplibs_check_method='unknown'
# Need to set the preceding variable on all platforms that support
# interlibrary dependencies.
# 'none' -- dependencies not supported.
-# `unknown' -- same as none, but documents that we really don't know.
+# 'unknown' -- same as none, but documents that we really don't know.
# 'pass_all' -- all dependencies passed with no checks.
# 'test_compile' -- check by making test program.
# 'file_magic [[regex]]' -- check by looking for files in library path
-# which responds to the $file_magic_cmd with a given extended regex.
-# If you have `file' or equivalent on your system and you're not sure
-# whether `pass_all' will *always* work, you probably want this one.
+# that responds to the $file_magic_cmd with a given extended regex.
+# If you have 'file' or equivalent on your system and you're not sure
+# whether 'pass_all' will *always* work, you probably want this one.
case $host_os in
aix[[4-9]]*)
@@ -3206,8 +3468,7 @@ mingw* | pw32*)
# Base MSYS/MinGW do not provide the 'file' command needed by
# func_win32_libid shell function, so use a weaker test based on 'objdump',
# unless we find 'file', for example because we are cross-compiling.
- # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
- if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
+ if ( file / ) >/dev/null 2>&1; then
lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
lt_cv_file_magic_cmd='func_win32_libid'
else
@@ -3243,10 +3504,6 @@ freebsd* | dragonfly*)
fi
;;
-gnu*)
- lt_cv_deplibs_check_method=pass_all
- ;;
-
haiku*)
lt_cv_deplibs_check_method=pass_all
;;
@@ -3285,7 +3542,7 @@ irix5* | irix6* | nonstopux*)
;;
# This must be glibc/ELF.
-linux* | k*bsd*-gnu | kopensolaris*-gnu)
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
lt_cv_deplibs_check_method=pass_all
;;
@@ -3307,8 +3564,8 @@ newos6*)
lt_cv_deplibs_check_method=pass_all
;;
-openbsd*)
- if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+openbsd* | bitrig*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
else
lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
@@ -3361,6 +3618,9 @@ sysv4 | sysv4.3*)
tpf*)
lt_cv_deplibs_check_method=pass_all
;;
+os2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
esac
])
@@ -3401,33 +3661,38 @@ AC_DEFUN([LT_PATH_NM],
AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
[if test -n "$NM"; then
# Let the user override the test.
- lt_cv_path_NM="$NM"
+ lt_cv_path_NM=$NM
else
- lt_nm_to_check="${ac_tool_prefix}nm"
+ lt_nm_to_check=${ac_tool_prefix}nm
if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
lt_nm_to_check="$lt_nm_to_check nm"
fi
for lt_tmp_nm in $lt_nm_to_check; do
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
- IFS="$lt_save_ifs"
+ IFS=$lt_save_ifs
test -z "$ac_dir" && ac_dir=.
- tmp_nm="$ac_dir/$lt_tmp_nm"
- if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+ tmp_nm=$ac_dir/$lt_tmp_nm
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then
# Check to see if the nm accepts a BSD-compat flag.
- # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # Adding the 'sed 1q' prevents false positives on HP-UX, which says:
# nm: unknown option "B" ignored
# Tru64's nm complains that /dev/null is an invalid object file
- case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
- */dev/null* | *'Invalid file or object type'*)
+ # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
+ case $build_os in
+ mingw*) lt_bad_file=conftest.nm/nofile ;;
+ *) lt_bad_file=/dev/null ;;
+ esac
+ case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
+ *$lt_bad_file* | *'Invalid file or object type'*)
lt_cv_path_NM="$tmp_nm -B"
- break
+ break 2
;;
*)
case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
*/dev/null*)
lt_cv_path_NM="$tmp_nm -p"
- break
+ break 2
;;
*)
lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
@@ -3438,21 +3703,21 @@ else
esac
fi
done
- IFS="$lt_save_ifs"
+ IFS=$lt_save_ifs
done
: ${lt_cv_path_NM=no}
fi])
-if test "$lt_cv_path_NM" != "no"; then
- NM="$lt_cv_path_NM"
+if test no != "$lt_cv_path_NM"; then
+ NM=$lt_cv_path_NM
else
# Didn't find any BSD compatible name lister, look for dumpbin.
if test -n "$DUMPBIN"; then :
# Let the user override the test.
else
AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
- case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+ case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
*COFF*)
- DUMPBIN="$DUMPBIN -symbols"
+ DUMPBIN="$DUMPBIN -symbols -headers"
;;
*)
DUMPBIN=:
@@ -3460,8 +3725,8 @@ else
esac
fi
AC_SUBST([DUMPBIN])
- if test "$DUMPBIN" != ":"; then
- NM="$DUMPBIN"
+ if test : != "$DUMPBIN"; then
+ NM=$DUMPBIN
fi
fi
test -z "$NM" && NM=nm
@@ -3507,8 +3772,8 @@ lt_cv_sharedlib_from_linklib_cmd,
case $host_os in
cygwin* | mingw* | pw32* | cegcc*)
- # two different shell functions defined in ltmain.sh
- # decide which to use based on capabilities of $DLLTOOL
+ # two different shell functions defined in ltmain.sh;
+ # decide which one to use based on capabilities of $DLLTOOL
case `$DLLTOOL --help 2>&1` in
*--identify-strict*)
lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
@@ -3520,7 +3785,7 @@ cygwin* | mingw* | pw32* | cegcc*)
;;
*)
# fallback: assume linklib IS sharedlib
- lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+ lt_cv_sharedlib_from_linklib_cmd=$ECHO
;;
esac
])
@@ -3547,13 +3812,28 @@ AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool
lt_cv_path_mainfest_tool=yes
fi
rm -f conftest*])
-if test "x$lt_cv_path_mainfest_tool" != xyes; then
+if test yes != "$lt_cv_path_mainfest_tool"; then
MANIFEST_TOOL=:
fi
_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
])# _LT_PATH_MANIFEST_TOOL
+# _LT_DLL_DEF_P([FILE])
+# ---------------------
+# True iff FILE is a Windows DLL '.def' file.
+# Keep in sync with func_dll_def_p in the libtool script
+AC_DEFUN([_LT_DLL_DEF_P],
+[dnl
+ test DEF = "`$SED -n dnl
+ -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace
+ -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments
+ -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl
+ -e q dnl Only consider the first "real" line
+ $1`" dnl
+])# _LT_DLL_DEF_P
+
+
# LT_LIB_M
# --------
# check for math library
@@ -3565,11 +3845,11 @@ case $host in
# These system don't have libm, or don't need it
;;
*-ncr-sysv4.3*)
- AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw)
AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
;;
*)
- AC_CHECK_LIB(m, cos, LIBM="-lm")
+ AC_CHECK_LIB(m, cos, LIBM=-lm)
;;
esac
AC_SUBST([LIBM])
@@ -3588,7 +3868,7 @@ m4_defun([_LT_COMPILER_NO_RTTI],
_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
-if test "$GCC" = yes; then
+if test yes = "$GCC"; then
case $cc_basename in
nvcc*)
_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;
@@ -3640,7 +3920,7 @@ cygwin* | mingw* | pw32* | cegcc*)
symcode='[[ABCDGISTW]]'
;;
hpux*)
- if test "$host_cpu" = ia64; then
+ if test ia64 = "$host_cpu"; then
symcode='[[ABCDEGRST]]'
fi
;;
@@ -3673,14 +3953,44 @@ case `$NM -V 2>&1` in
symcode='[[ABCDGIRSTW]]' ;;
esac
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Gets list of data symbols to import.
+ lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
+ # Adjust the below global symbol transforms to fixup imported variables.
+ lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
+ lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'"
+ lt_c_name_lib_hook="\
+ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\
+ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'"
+else
+ # Disable hooks by default.
+ lt_cv_sys_global_symbol_to_import=
+ lt_cdecl_hook=
+ lt_c_name_hook=
+ lt_c_name_lib_hook=
+fi
+
# Transform an extracted symbol line into a proper C declaration.
# Some systems (esp. on ia64) link data and code symbols differently,
# so use this general approach.
-lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+lt_cv_sys_global_symbol_to_cdecl="sed -n"\
+$lt_cdecl_hook\
+" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
# Transform an extracted symbol line into symbol name and symbol address
-lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'"
-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
+$lt_c_name_hook\
+" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'"
+
+# Transform an extracted symbol line into symbol name with lib prefix and
+# symbol address.
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
+$lt_c_name_lib_hook\
+" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'"
# Handle CRLF in mingw tool chain
opt_cr=
@@ -3698,21 +4008,24 @@ for ac_symprfx in "" "_"; do
# Write the raw and C identifiers.
if test "$lt_cv_nm_interface" = "MS dumpbin"; then
- # Fake it for dumpbin and say T for any non-static function
- # and D for any global variable.
+ # Fake it for dumpbin and say T for any non-static function,
+ # D for any global variable and I for any imported variable.
# Also find C++ and __fastcall symbols from MSVC++,
# which start with @ or ?.
lt_cv_sys_global_symbol_pipe="$AWK ['"\
" {last_section=section; section=\$ 3};"\
" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\
+" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\
+" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\
" \$ 0!~/External *\|/{next};"\
" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
" {if(hide[section]) next};"\
-" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
-" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
-" s[1]~/^[@?]/{print s[1], s[1]; next};"\
-" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\
+" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\
+" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
" ' prfx=^$ac_symprfx]"
else
lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
@@ -3752,11 +4065,11 @@ _LT_EOF
if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
cat <<_LT_EOF > conftest.$ac_ext
/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
-#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
-/* DATA imports from DLLs on WIN32 con't be const, because runtime
+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
+/* DATA imports from DLLs on WIN32 can't be const, because runtime
relocations are performed -- see ld's documentation on pseudo-relocs. */
# define LT@&t@_DLSYM_CONST
-#elif defined(__osf__)
+#elif defined __osf__
/* This system does not cope well with relocations in const data. */
# define LT@&t@_DLSYM_CONST
#else
@@ -3782,7 +4095,7 @@ lt__PROGRAM__LTX_preloaded_symbols[[]] =
{
{ "@PROGRAM@", (void *) 0 },
_LT_EOF
- $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
cat <<\_LT_EOF >> conftest.$ac_ext
{0, (void *) 0}
};
@@ -3802,9 +4115,9 @@ _LT_EOF
mv conftest.$ac_objext conftstm.$ac_objext
lt_globsym_save_LIBS=$LIBS
lt_globsym_save_CFLAGS=$CFLAGS
- LIBS="conftstm.$ac_objext"
+ LIBS=conftstm.$ac_objext
CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
- if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
+ if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then
pipe_works=yes
fi
LIBS=$lt_globsym_save_LIBS
@@ -3825,7 +4138,7 @@ _LT_EOF
rm -rf conftest* conftst*
# Do not use the global_symbol_pipe unless it works.
- if test "$pipe_works" = yes; then
+ if test yes = "$pipe_works"; then
break
else
lt_cv_sys_global_symbol_pipe=
@@ -3852,12 +4165,16 @@ _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
[Take the output of nm and produce a listing of raw symbols and C names])
_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
[Transform the output of nm in a proper C declaration])
+_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1],
+ [Transform the output of nm into a list of symbols to manually relocate])
_LT_DECL([global_symbol_to_c_name_address],
[lt_cv_sys_global_symbol_to_c_name_address], [1],
[Transform the output of nm in a C name address pair])
_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
[lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
[Transform the output of nm in a C name address pair when lib prefix is needed])
+_LT_DECL([nm_interface], [lt_cv_nm_interface], [1],
+ [The name lister interface])
_LT_DECL([], [nm_file_list_spec], [1],
[Specify filename containing input files for $NM])
]) # _LT_CMD_GLOBAL_SYMBOLS
@@ -3873,17 +4190,18 @@ _LT_TAGVAR(lt_prog_compiler_static, $1)=
m4_if([$1], [CXX], [
# C++ specific cases for pic, static, wl, etc.
- if test "$GXX" = yes; then
+ if test yes = "$GXX"; then
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
case $host_os in
aix*)
# All AIX code is PIC.
- if test "$host_cpu" = ia64; then
+ if test ia64 = "$host_cpu"; then
# AIX 5 now supports IA64 processor
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
fi
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
;;
amigaos*)
@@ -3894,8 +4212,8 @@ m4_if([$1], [CXX], [
;;
m68k)
# FIXME: we need at least 68020 code to build shared libraries, but
- # adding the `-m68020' flag to GCC prevents building anything better,
- # like `-m68040'.
+ # adding the '-m68020' flag to GCC prevents building anything better,
+ # like '-m68040'.
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
;;
esac
@@ -3911,6 +4229,11 @@ m4_if([$1], [CXX], [
# (--disable-auto-import) libraries
m4_if([$1], [GCJ], [],
[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ case $host_os in
+ os2*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
+ ;;
+ esac
;;
darwin* | rhapsody*)
# PIC is the default on this platform
@@ -3960,7 +4283,7 @@ m4_if([$1], [CXX], [
case $host_os in
aix[[4-9]]*)
# All AIX code is PIC.
- if test "$host_cpu" = ia64; then
+ if test ia64 = "$host_cpu"; then
# AIX 5 now supports IA64 processor
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
else
@@ -4001,14 +4324,14 @@ m4_if([$1], [CXX], [
case $cc_basename in
CC*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
- if test "$host_cpu" != ia64; then
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+ if test ia64 != "$host_cpu"; then
_LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
fi
;;
aCC*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
case $host_cpu in
hppa*64*|ia64*)
# +Z the default
@@ -4037,7 +4360,7 @@ m4_if([$1], [CXX], [
;;
esac
;;
- linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
case $cc_basename in
KCC*)
# KAI C++ Compiler
@@ -4045,7 +4368,7 @@ m4_if([$1], [CXX], [
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
;;
ecpc* )
- # old Intel C++ for x86_64 which still supported -KPIC.
+ # old Intel C++ for x86_64, which still supported -KPIC.
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
@@ -4190,17 +4513,18 @@ m4_if([$1], [CXX], [
fi
],
[
- if test "$GCC" = yes; then
+ if test yes = "$GCC"; then
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
case $host_os in
aix*)
# All AIX code is PIC.
- if test "$host_cpu" = ia64; then
+ if test ia64 = "$host_cpu"; then
# AIX 5 now supports IA64 processor
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
fi
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
;;
amigaos*)
@@ -4211,8 +4535,8 @@ m4_if([$1], [CXX], [
;;
m68k)
# FIXME: we need at least 68020 code to build shared libraries, but
- # adding the `-m68020' flag to GCC prevents building anything better,
- # like `-m68040'.
+ # adding the '-m68020' flag to GCC prevents building anything better,
+ # like '-m68040'.
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
;;
esac
@@ -4229,6 +4553,11 @@ m4_if([$1], [CXX], [
# (--disable-auto-import) libraries
m4_if([$1], [GCJ], [],
[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ case $host_os in
+ os2*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
+ ;;
+ esac
;;
darwin* | rhapsody*)
@@ -4299,7 +4628,7 @@ m4_if([$1], [CXX], [
case $host_os in
aix*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- if test "$host_cpu" = ia64; then
+ if test ia64 = "$host_cpu"; then
# AIX 5 now supports IA64 processor
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
else
@@ -4307,11 +4636,30 @@ m4_if([$1], [CXX], [
fi
;;
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ case $cc_basename in
+ nagfor*)
+ # NAG Fortran compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+
mingw* | cygwin* | pw32* | os2* | cegcc*)
# This hack is so that the source file can tell whether it is being
# built for inclusion in a dll (and should export symbols for example).
m4_if([$1], [GCJ], [],
[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ case $host_os in
+ os2*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
+ ;;
+ esac
;;
hpux9* | hpux10* | hpux11*)
@@ -4327,7 +4675,7 @@ m4_if([$1], [CXX], [
;;
esac
# Is there a better lt_prog_compiler_static that works with the bundled CC?
- _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
;;
irix5* | irix6* | nonstopux*)
@@ -4336,9 +4684,9 @@ m4_if([$1], [CXX], [
_LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
;;
- linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
case $cc_basename in
- # old Intel for x86_64 which still supported -KPIC.
+ # old Intel for x86_64, which still supported -KPIC.
ecc*)
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
@@ -4363,6 +4711,12 @@ m4_if([$1], [CXX], [
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
;;
+ tcc*)
+ # Fabrice Bellard et al's Tiny C Compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
# Portland Group compilers (*not* the Pentium gcc compiler,
# which looks to be a dead project)
@@ -4460,7 +4814,7 @@ m4_if([$1], [CXX], [
;;
sysv4*MP*)
- if test -d /usr/nec ;then
+ if test -d /usr/nec; then
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
fi
@@ -4489,7 +4843,7 @@ m4_if([$1], [CXX], [
fi
])
case $host_os in
- # For platforms which do not support PIC, -DPIC is meaningless:
+ # For platforms that do not support PIC, -DPIC is meaningless:
*djgpp*)
_LT_TAGVAR(lt_prog_compiler_pic, $1)=
;;
@@ -4555,17 +4909,21 @@ m4_if([$1], [CXX], [
case $host_os in
aix[[4-9]]*)
# If we're using GNU nm, then we don't want the "-C" option.
- # -C means demangle to AIX nm, but means don't demangle with GNU nm
- # Also, AIX nm treats weak defined symbols like other global defined
- # symbols, whereas GNU nm marks them as "W".
+ # -C means demangle to GNU nm, but means don't demangle to AIX nm.
+ # Without the "-l" option, or with the "-B" option, AIX nm treats
+ # weak defined symbols like other global defined symbols, whereas
+ # GNU nm marks them as "W".
+ # While the 'weak' keyword is ignored in the Export File, we need
+ # it in the Import File for the 'aix-soname' feature, so we have
+ # to replace the "-B" option with "-P" for AIX nm.
if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
- _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
else
- _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
fi
;;
pw32*)
- _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
+ _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds
;;
cygwin* | mingw* | cegcc*)
case $cc_basename in
@@ -4611,9 +4969,9 @@ m4_if([$1], [CXX], [
# included in the symbol list
_LT_TAGVAR(include_expsyms, $1)=
# exclude_expsyms can be an extended regexp of symbols to exclude
- # it will be wrapped by ` (' and `)$', so one must not match beginning or
- # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
- # as well as any symbol that contains `d'.
+ # it will be wrapped by ' (' and ')$', so one must not match beginning or
+ # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',
+ # as well as any symbol that contains 'd'.
_LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
# platforms (ab)use it in PIC code, but their linkers get confused if
@@ -4629,7 +4987,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
# FIXME: the MSVC++ port hasn't been tested in a loooong time
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
- if test "$GCC" != yes; then
+ if test yes != "$GCC"; then
with_gnu_ld=no
fi
;;
@@ -4637,7 +4995,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
# we just hope/assume this is gcc and not c89 (= MSVC++)
with_gnu_ld=yes
;;
- openbsd*)
+ openbsd* | bitrig*)
with_gnu_ld=no
;;
esac
@@ -4647,7 +5005,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
# On some targets, GNU ld is compatible enough with the native linker
# that we're better off using the native interface for both.
lt_use_gnu_ld_interface=no
- if test "$with_gnu_ld" = yes; then
+ if test yes = "$with_gnu_ld"; then
case $host_os in
aix*)
# The AIX port of GNU ld has always aspired to compatibility
@@ -4669,24 +5027,24 @@ dnl Note also adjust exclude_expsyms for C++ above.
esac
fi
- if test "$lt_use_gnu_ld_interface" = yes; then
+ if test yes = "$lt_use_gnu_ld_interface"; then
# If archive_cmds runs LD, not CC, wlarc should be empty
- wlarc='${wl}'
+ wlarc='$wl'
# Set some defaults for GNU ld with shared library support. These
# are reset later if shared libraries are not supported. Putting them
# here allows them to be overridden if necessary.
runpath_var=LD_RUN_PATH
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
# ancient GNU ld didn't support --whole-archive et. al.
if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
- _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
else
_LT_TAGVAR(whole_archive_flag_spec, $1)=
fi
supports_anon_versioning=no
- case `$LD -v 2>&1` in
+ case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in
*GNU\ gold*) supports_anon_versioning=yes ;;
*\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
*\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
@@ -4699,7 +5057,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
case $host_os in
aix[[3-9]]*)
# On AIX/PPC, the GNU linker is very broken
- if test "$host_cpu" != ia64; then
+ if test ia64 != "$host_cpu"; then
_LT_TAGVAR(ld_shlibs, $1)=no
cat <<_LT_EOF 1>&2
@@ -4718,7 +5076,7 @@ _LT_EOF
case $host_cpu in
powerpc)
# see comment about AmigaOS4 .so support
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)=''
;;
m68k)
@@ -4734,7 +5092,7 @@ _LT_EOF
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
# Joseph Beckenbach <jrb3@best.com> says some releases of gcc
# support --undefined. This deserves some investigation. FIXME
- _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
else
_LT_TAGVAR(ld_shlibs, $1)=no
fi
@@ -4744,7 +5102,7 @@ _LT_EOF
# _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
# as there is no search path for DLLs.
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
_LT_TAGVAR(always_export_symbols, $1)=no
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
@@ -4752,61 +5110,89 @@ _LT_EOF
_LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- # If the export-symbols file already is a .def file (1st line
- # is EXPORTS), use it as is; otherwise, prepend...
- _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
- cp $export_symbols $output_objdir/$soname.def;
- else
- echo EXPORTS > $output_objdir/$soname.def;
- cat $export_symbols >> $output_objdir/$soname.def;
- fi~
- $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file, use it as
+ # is; otherwise, prepend EXPORTS...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
else
_LT_TAGVAR(ld_shlibs, $1)=no
fi
;;
haiku*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
_LT_TAGVAR(link_all_deplibs, $1)=yes
;;
+ os2*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ shrext_cmds=.dll
+ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+
interix[[3-9]]*)
_LT_TAGVAR(hardcode_direct, $1)=no
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
# Instead, shared libraries are loaded at an image base (0x10000000 by
# default) and relocated if they conflict, which is a slow very memory
# consuming and fragmenting process. To avoid this, we pick a random,
# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
# time. Moving up from 0x10000000 also allows more sbrk(2) space.
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
;;
gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
tmp_diet=no
- if test "$host_os" = linux-dietlibc; then
+ if test linux-dietlibc = "$host_os"; then
case $cc_basename in
diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
esac
fi
if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
- && test "$tmp_diet" = no
+ && test no = "$tmp_diet"
then
tmp_addflag=' $pic_flag'
tmp_sharedflag='-shared'
case $cc_basename,$host_cpu in
pgcc*) # Portland Group C compiler
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
tmp_addflag=' $pic_flag'
;;
pgf77* | pgf90* | pgf95* | pgfortran*)
# Portland Group f77 and f90 compilers
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
tmp_addflag=' $pic_flag -Mnomain' ;;
ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
tmp_addflag=' -i_dynamic' ;;
@@ -4817,42 +5203,47 @@ _LT_EOF
lf95*) # Lahey Fortran 8.1
_LT_TAGVAR(whole_archive_flag_spec, $1)=
tmp_sharedflag='--shared' ;;
+ nagfor*) # NAGFOR 5.3
+ tmp_sharedflag='-Wl,-shared' ;;
xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
tmp_sharedflag='-qmkshrobj'
tmp_addflag= ;;
nvcc*) # Cuda Compiler Driver 2.2
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
_LT_TAGVAR(compiler_needs_object, $1)=yes
;;
esac
case `$CC -V 2>&1 | sed 5q` in
*Sun\ C*) # Sun C 5.9
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
_LT_TAGVAR(compiler_needs_object, $1)=yes
tmp_sharedflag='-G' ;;
*Sun\ F*) # Sun Fortran 8.3
tmp_sharedflag='-G' ;;
esac
- _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
- if test "x$supports_anon_versioning" = xyes; then
+ if test yes = "$supports_anon_versioning"; then
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
- cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
- echo "local: *; };" >> $output_objdir/$libname.ver~
- $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
fi
case $cc_basename in
+ tcc*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic'
+ ;;
xlf* | bgf* | bgxlf* | mpixlf*)
# IBM XL Fortran 10.1 on PPC cannot create shared libs itself
_LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
_LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
- if test "x$supports_anon_versioning" = xyes; then
+ if test yes = "$supports_anon_versioning"; then
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
- cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
- echo "local: *; };" >> $output_objdir/$libname.ver~
- $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
fi
;;
esac
@@ -4866,8 +5257,8 @@ _LT_EOF
_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
wlarc=
else
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
fi
;;
@@ -4885,8 +5276,8 @@ _LT_EOF
_LT_EOF
elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
else
_LT_TAGVAR(ld_shlibs, $1)=no
fi
@@ -4898,7 +5289,7 @@ _LT_EOF
_LT_TAGVAR(ld_shlibs, $1)=no
cat <<_LT_EOF 1>&2
-*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot
*** reliably create shared libraries on SCO systems. Therefore, libtool
*** is disabling shared libraries support. We urge you to upgrade GNU
*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
@@ -4913,9 +5304,9 @@ _LT_EOF
# DT_RUNPATH tag from executables and libraries. But doing so
# requires that you compile everything twice, which is a pain.
if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
else
_LT_TAGVAR(ld_shlibs, $1)=no
fi
@@ -4932,15 +5323,15 @@ _LT_EOF
*)
if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
else
_LT_TAGVAR(ld_shlibs, $1)=no
fi
;;
esac
- if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then
+ if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then
runpath_var=
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
_LT_TAGVAR(export_dynamic_flag_spec, $1)=
@@ -4956,7 +5347,7 @@ _LT_EOF
# Note: this linker hardcodes the directories in LIBPATH if there
# are no directories specified by -L.
_LT_TAGVAR(hardcode_minus_L, $1)=yes
- if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+ if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then
# Neither direct hardcoding nor static linking is supported with a
# broken collect2.
_LT_TAGVAR(hardcode_direct, $1)=unsupported
@@ -4964,34 +5355,57 @@ _LT_EOF
;;
aix[[4-9]]*)
- if test "$host_cpu" = ia64; then
+ if test ia64 = "$host_cpu"; then
# On IA64, the linker does run time linking by default, so we don't
# have to do anything special.
aix_use_runtimelinking=no
exp_sym_flag='-Bexport'
- no_entry_flag=""
+ no_entry_flag=
else
# If we're using GNU nm, then we don't want the "-C" option.
- # -C means demangle to AIX nm, but means don't demangle with GNU nm
- # Also, AIX nm treats weak defined symbols like other global
- # defined symbols, whereas GNU nm marks them as "W".
+ # -C means demangle to GNU nm, but means don't demangle to AIX nm.
+ # Without the "-l" option, or with the "-B" option, AIX nm treats
+ # weak defined symbols like other global defined symbols, whereas
+ # GNU nm marks them as "W".
+ # While the 'weak' keyword is ignored in the Export File, we need
+ # it in the Import File for the 'aix-soname' feature, so we have
+ # to replace the "-B" option with "-P" for AIX nm.
if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
- _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
else
- _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
fi
aix_use_runtimelinking=no
# Test if we are trying to use run time linking or normal
# AIX style linking. If -brtl is somewhere in LDFLAGS, we
- # need to do runtime linking.
+ # have runtime linking enabled, and use it for executables.
+ # For shared libraries, we enable/disable runtime linking
+ # depending on the kind of the shared library created -
+ # when "with_aix_soname,aix_use_runtimelinking" is:
+ # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables
+ # "aix,yes" lib.so shared, rtl:yes, for executables
+ # lib.a static archive
+ # "both,no" lib.so.V(shr.o) shared, rtl:yes
+ # lib.a(lib.so.V) shared, rtl:no, for executables
+ # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a(lib.so.V) shared, rtl:no
+ # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a static archive
case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
for ld_flag in $LDFLAGS; do
- if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then
aix_use_runtimelinking=yes
break
fi
done
+ if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # With aix-soname=svr4, we create the lib.so.V shared archives only,
+ # so we don't have lib.a shared libs to link our executables.
+ # We have to force runtime linking in this case.
+ aix_use_runtimelinking=yes
+ LDFLAGS="$LDFLAGS -Wl,-brtl"
+ fi
;;
esac
@@ -5010,13 +5424,21 @@ _LT_EOF
_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
_LT_TAGVAR(hardcode_libdir_separator, $1)=':'
_LT_TAGVAR(link_all_deplibs, $1)=yes
- _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+ _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
+ case $with_aix_soname,$aix_use_runtimelinking in
+ aix,*) ;; # traditional, no import file
+ svr4,* | *,yes) # use import file
+ # The Import File defines what to hardcode.
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+ ;;
+ esac
- if test "$GCC" = yes; then
+ if test yes = "$GCC"; then
case $host_os in aix4.[[012]]|aix4.[[012]].*)
# We only want to do this on AIX 4.2 and lower, the check
# below for broken collect2 doesn't work under 4.3+
- collect2name=`${CC} -print-prog-name=collect2`
+ collect2name=`$CC -print-prog-name=collect2`
if test -f "$collect2name" &&
strings "$collect2name" | $GREP resolve_lib_name >/dev/null
then
@@ -5035,61 +5457,80 @@ _LT_EOF
;;
esac
shared_flag='-shared'
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag="$shared_flag "'${wl}-G'
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag="$shared_flag "'$wl-G'
fi
+ # Need to ensure runtime linking is disabled for the traditional
+ # shared library, or the linker may eventually find shared libraries
+ # /with/ Import File - we do not want to mix them.
+ shared_flag_aix='-shared'
+ shared_flag_svr4='-shared $wl-G'
else
# not using gcc
- if test "$host_cpu" = ia64; then
+ if test ia64 = "$host_cpu"; then
# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
# chokes on -Wl,-G. The following line is correct:
shared_flag='-G'
else
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag='${wl}-G'
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag='$wl-G'
else
- shared_flag='${wl}-bM:SRE'
+ shared_flag='$wl-bM:SRE'
fi
+ shared_flag_aix='$wl-bM:SRE'
+ shared_flag_svr4='$wl-G'
fi
fi
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
# It seems that -bexpall does not export symbols beginning with
# underscore (_), so it is better to generate a list of symbols to export.
_LT_TAGVAR(always_export_symbols, $1)=yes
- if test "$aix_use_runtimelinking" = yes; then
+ if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
# Warning - without using the other runtime loading flags (-brtl),
# -berok will link without error, but may produce a broken library.
_LT_TAGVAR(allow_undefined_flag, $1)='-berok'
# Determine the default libpath from the value encoded in an
# empty executable.
_LT_SYS_MODULE_PATH_AIX([$1])
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
else
- if test "$host_cpu" = ia64; then
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+ if test ia64 = "$host_cpu"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
_LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
- _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
else
# Determine the default libpath from the value encoded in an
# empty executable.
_LT_SYS_MODULE_PATH_AIX([$1])
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
# Warning - without using the other run time loading flags,
# -berok will link without error, but may produce a broken library.
- _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
- _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
- if test "$with_gnu_ld" = yes; then
+ _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
+ if test yes = "$with_gnu_ld"; then
# We only use this code for GNU lds that support --whole-archive.
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
else
# Exported symbols can be pulled into shared objects from archives
_LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
fi
_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
- # This is similar to how AIX traditionally builds its shared libraries.
- _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
+ # -brtl affects multiple linker settings, -berok does not and is overridden later
+ compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
+ if test svr4 != "$with_aix_soname"; then
+ # This is similar to how AIX traditionally builds its shared libraries.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
+ fi
+ if test aix != "$with_aix_soname"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
+ else
+ # used by -dlpreopen to get the symbols
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir'
+ fi
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
fi
fi
;;
@@ -5098,7 +5539,7 @@ _LT_EOF
case $host_cpu in
powerpc)
# see comment about AmigaOS4 .so support
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)=''
;;
m68k)
@@ -5128,16 +5569,17 @@ _LT_EOF
# Tell ltmain to make .lib files, not .a files.
libext=lib
# Tell ltmain to make .dll files, not .so files.
- shrext_cmds=".dll"
+ shrext_cmds=.dll
# FIXME: Setting linknames here is a bad hack.
- _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
- _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
- sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
- else
- sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
- fi~
- $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
- linknames='
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+ cp "$export_symbols" "$output_objdir/$soname.def";
+ echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+ else
+ $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
# The linker will not automatically build a static lib if we build a DLL.
# _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
@@ -5146,18 +5588,18 @@ _LT_EOF
# Don't use ranlib
_LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
_LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
- lt_tool_outputfile="@TOOL_OUTPUT@"~
- case $lt_outputfile in
- *.exe|*.EXE) ;;
- *)
- lt_outputfile="$lt_outputfile.exe"
- lt_tool_outputfile="$lt_tool_outputfile.exe"
- ;;
- esac~
- if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
- $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
- $RM "$lt_outputfile.manifest";
- fi'
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile=$lt_outputfile.exe
+ lt_tool_outputfile=$lt_tool_outputfile.exe
+ ;;
+ esac~
+ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
;;
*)
# Assume MSVC wrapper
@@ -5166,7 +5608,7 @@ _LT_EOF
# Tell ltmain to make .lib files, not .a files.
libext=lib
# Tell ltmain to make .dll files, not .so files.
- shrext_cmds=".dll"
+ shrext_cmds=.dll
# FIXME: Setting linknames here is a bad hack.
_LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
# The linker will automatically build a .lib file if we build a DLL.
@@ -5216,33 +5658,33 @@ _LT_EOF
;;
hpux9*)
- if test "$GCC" = yes; then
- _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
else
- _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
fi
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
_LT_TAGVAR(hardcode_direct, $1)=yes
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
_LT_TAGVAR(hardcode_minus_L, $1)=yes
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
;;
hpux10*)
- if test "$GCC" = yes && test "$with_gnu_ld" = no; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ if test yes,no = "$GCC,$with_gnu_ld"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
else
_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
fi
- if test "$with_gnu_ld" = no; then
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ if test no = "$with_gnu_ld"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
_LT_TAGVAR(hardcode_minus_L, $1)=yes
@@ -5250,25 +5692,25 @@ _LT_EOF
;;
hpux11*)
- if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ if test yes,no = "$GCC,$with_gnu_ld"; then
case $host_cpu in
hppa*64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
;;
esac
else
case $host_cpu in
hppa*64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
;;
ia64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
*)
m4_if($1, [], [
@@ -5276,14 +5718,14 @@ _LT_EOF
# (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
_LT_LINKER_OPTION([if $CC understands -b],
_LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
- [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
+ [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
[_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],
- [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
+ [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
;;
esac
fi
- if test "$with_gnu_ld" = no; then
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ if test no = "$with_gnu_ld"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
case $host_cpu in
@@ -5294,7 +5736,7 @@ _LT_EOF
*)
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
@@ -5305,16 +5747,16 @@ _LT_EOF
;;
irix5* | irix6* | nonstopux*)
- if test "$GCC" = yes; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
# Try to use the -exported_symbol ld option, if it does not
# work, assume that -exports_file does not work either and
# implicitly export all symbols.
# This should be the same for all languages, so no per-tag cache variable.
AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],
[lt_cv_irix_exported_symbol],
- [save_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+ [save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"
AC_LINK_IFELSE(
[AC_LANG_SOURCE(
[AC_LANG_CASE([C], [[int foo (void) { return 0; }]],
@@ -5327,21 +5769,31 @@ _LT_EOF
end]])])],
[lt_cv_irix_exported_symbol=yes],
[lt_cv_irix_exported_symbol=no])
- LDFLAGS="$save_LDFLAGS"])
- if test "$lt_cv_irix_exported_symbol" = yes; then
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+ LDFLAGS=$save_LDFLAGS])
+ if test yes = "$lt_cv_irix_exported_symbol"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
fi
else
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
fi
_LT_TAGVAR(archive_cmds_need_lc, $1)='no'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
_LT_TAGVAR(inherit_rpath, $1)=yes
_LT_TAGVAR(link_all_deplibs, $1)=yes
;;
+ linux*)
+ case $cc_basename in
+ tcc*)
+ # Fabrice Bellard et al's Tiny C Compiler
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
netbsd*)
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
@@ -5356,7 +5808,7 @@ _LT_EOF
newsos6)
_LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
_LT_TAGVAR(hardcode_direct, $1)=yes
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
;;
@@ -5364,27 +5816,19 @@ _LT_EOF
*nto* | *qnx*)
;;
- openbsd*)
+ openbsd* | bitrig*)
if test -f /usr/libexec/ld.so; then
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
- if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
else
- case $host_os in
- openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
- _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
- ;;
- *)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- ;;
- esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
fi
else
_LT_TAGVAR(ld_shlibs, $1)=no
@@ -5395,33 +5839,53 @@ _LT_EOF
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
_LT_TAGVAR(hardcode_minus_L, $1)=yes
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
- _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
- _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ shrext_cmds=.dll
+ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
;;
osf3*)
- if test "$GCC" = yes; then
- _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
else
_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
fi
_LT_TAGVAR(archive_cmds_need_lc, $1)='no'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
;;
osf4* | osf5*) # as osf3* with the addition of -msym flag
- if test "$GCC" = yes; then
- _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
else
_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
- $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'
# Both c and cxx compiler support -rpath directly
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
@@ -5432,24 +5896,24 @@ _LT_EOF
solaris*)
_LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
- if test "$GCC" = yes; then
- wlarc='${wl}'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ if test yes = "$GCC"; then
+ wlarc='$wl'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
else
case `$CC -V 2>&1` in
*"Compilers 5.0"*)
wlarc=''
- _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
;;
*)
- wlarc='${wl}'
- _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ wlarc='$wl'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
;;
esac
fi
@@ -5459,11 +5923,11 @@ _LT_EOF
solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
*)
# The compiler driver will combine and reorder linker options,
- # but understands `-z linker_flag'. GCC discards it without `$wl',
+ # but understands '-z linker_flag'. GCC discards it without '$wl',
# but is careful enough not to reorder.
# Supported since Solaris 2.6 (maybe 2.5.1?)
- if test "$GCC" = yes; then
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
else
_LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
fi
@@ -5473,10 +5937,10 @@ _LT_EOF
;;
sunos4*)
- if test "x$host_vendor" = xsequent; then
+ if test sequent = "$host_vendor"; then
# Use $CC to link under sequent, because it throws in some extra .o
# files that make .init and .fini sections work.
- _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'
else
_LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
fi
@@ -5525,43 +5989,43 @@ _LT_EOF
;;
sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
- _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
_LT_TAGVAR(archive_cmds_need_lc, $1)=no
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
runpath_var='LD_RUN_PATH'
- if test "$GCC" = yes; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
else
- _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
fi
;;
sysv5* | sco3.2v5* | sco5v6*)
- # Note: We can NOT use -z defs as we might desire, because we do not
+ # Note: We CANNOT use -z defs as we might desire, because we do not
# link with -lc, and that would cause any symbols used from libc to
# always be unresolved, which means just about no library would
# ever link correctly. If we're not using GNU ld we use -z text
# though, which does catch some bad symbols but isn't as heavy-handed
# as -z defs.
- _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
- _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
_LT_TAGVAR(archive_cmds_need_lc, $1)=no
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=':'
_LT_TAGVAR(link_all_deplibs, $1)=yes
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
runpath_var='LD_RUN_PATH'
- if test "$GCC" = yes; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
else
- _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
fi
;;
@@ -5576,17 +6040,17 @@ _LT_EOF
;;
esac
- if test x$host_vendor = xsni; then
+ if test sni = "$host_vendor"; then
case $host in
sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym'
;;
esac
fi
fi
])
AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
-test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
@@ -5603,7 +6067,7 @@ x|xyes)
# Assume -lc should be added
_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
- if test "$enable_shared" = yes && test "$GCC" = yes; then
+ if test yes,yes = "$GCC,$enable_shared"; then
case $_LT_TAGVAR(archive_cmds, $1) in
*'~'*)
# FIXME: we may have to deal with multi-command sequences.
@@ -5683,12 +6147,12 @@ _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
_LT_TAGDECL([], [hardcode_libdir_separator], [1],
[Whether we need a single "-rpath" flag with a separated argument])
_LT_TAGDECL([], [hardcode_direct], [0],
- [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+ [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
DIR into the resulting binary])
_LT_TAGDECL([], [hardcode_direct_absolute], [0],
- [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+ [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
DIR into the resulting binary and the resulting library dependency is
- "absolute", i.e impossible to change by setting ${shlibpath_var} if the
+ "absolute", i.e impossible to change by setting $shlibpath_var if the
library is relocated])
_LT_TAGDECL([], [hardcode_minus_L], [0],
[Set to "yes" if using the -LDIR flag during linking hardcodes DIR
@@ -5729,10 +6193,10 @@ dnl [Compiler flag to generate thread safe objects])
# ------------------------
# Ensure that the configuration variables for a C compiler are suitably
# defined. These variables are subsequently used by _LT_CONFIG to write
-# the compiler configuration to `libtool'.
+# the compiler configuration to 'libtool'.
m4_defun([_LT_LANG_C_CONFIG],
[m4_require([_LT_DECL_EGREP])dnl
-lt_save_CC="$CC"
+lt_save_CC=$CC
AC_LANG_PUSH(C)
# Source file extension for C test sources.
@@ -5772,18 +6236,18 @@ if test -n "$compiler"; then
LT_SYS_DLOPEN_SELF
_LT_CMD_STRIPLIB
- # Report which library types will actually be built
+ # Report what library types will actually be built
AC_MSG_CHECKING([if libtool supports shared libraries])
AC_MSG_RESULT([$can_build_shared])
AC_MSG_CHECKING([whether to build shared libraries])
- test "$can_build_shared" = "no" && enable_shared=no
+ test no = "$can_build_shared" && enable_shared=no
# On AIX, shared libraries and static libraries use the same namespace, and
# are all built from PIC.
case $host_os in
aix3*)
- test "$enable_shared" = yes && enable_static=no
+ test yes = "$enable_shared" && enable_static=no
if test -n "$RANLIB"; then
archive_cmds="$archive_cmds~\$RANLIB \$lib"
postinstall_cmds='$RANLIB $lib'
@@ -5791,8 +6255,12 @@ if test -n "$compiler"; then
;;
aix[[4-9]]*)
- if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
- test "$enable_shared" = yes && enable_static=no
+ if test ia64 != "$host_cpu"; then
+ case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+ yes,aix,yes) ;; # shared object as lib.so file only
+ yes,svr4,*) ;; # shared object as lib.so archive member only
+ yes,*) enable_static=no ;; # shared object in lib.a archive as well
+ esac
fi
;;
esac
@@ -5800,13 +6268,13 @@ if test -n "$compiler"; then
AC_MSG_CHECKING([whether to build static libraries])
# Make sure either enable_shared or enable_static is yes.
- test "$enable_shared" = yes || enable_static=yes
+ test yes = "$enable_shared" || enable_static=yes
AC_MSG_RESULT([$enable_static])
_LT_CONFIG($1)
fi
AC_LANG_POP
-CC="$lt_save_CC"
+CC=$lt_save_CC
])# _LT_LANG_C_CONFIG
@@ -5814,14 +6282,14 @@ CC="$lt_save_CC"
# --------------------------
# Ensure that the configuration variables for a C++ compiler are suitably
# defined. These variables are subsequently used by _LT_CONFIG to write
-# the compiler configuration to `libtool'.
+# the compiler configuration to 'libtool'.
m4_defun([_LT_LANG_CXX_CONFIG],
[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
m4_require([_LT_DECL_EGREP])dnl
m4_require([_LT_PATH_MANIFEST_TOOL])dnl
-if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
- ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
- (test "X$CXX" != "Xg++"))) ; then
+if test -n "$CXX" && ( test no != "$CXX" &&
+ ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) ||
+ (test g++ != "$CXX"))); then
AC_PROG_CXXCPP
else
_lt_caught_CXX_error=yes
@@ -5863,7 +6331,7 @@ _LT_TAGVAR(objext, $1)=$objext
# the CXX compiler isn't working. Some variables (like enable_shared)
# are currently assumed to apply to all compilers on this platform,
# and will be corrupted by setting them based on a non-working compiler.
-if test "$_lt_caught_CXX_error" != yes; then
+if test yes != "$_lt_caught_CXX_error"; then
# Code to be used in simple compile tests
lt_simple_compile_test_code="int some_variable = 0;"
@@ -5905,35 +6373,35 @@ if test "$_lt_caught_CXX_error" != yes; then
if test -n "$compiler"; then
# We don't want -fno-exception when compiling C++ code, so set the
# no_builtin_flag separately
- if test "$GXX" = yes; then
+ if test yes = "$GXX"; then
_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
else
_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
fi
- if test "$GXX" = yes; then
+ if test yes = "$GXX"; then
# Set up default GNU C++ configuration
LT_PATH_LD
# Check if GNU C++ uses GNU ld as the underlying linker, since the
# archiving commands below assume that GNU ld is being used.
- if test "$with_gnu_ld" = yes; then
- _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ if test yes = "$with_gnu_ld"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
# If archive_cmds runs LD, not CC, wlarc should be empty
# XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
# investigate it a little bit more. (MM)
- wlarc='${wl}'
+ wlarc='$wl'
# ancient GNU ld didn't support --whole-archive et. al.
if eval "`$CC -print-prog-name=ld` --help 2>&1" |
$GREP 'no-whole-archive' > /dev/null; then
- _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
else
_LT_TAGVAR(whole_archive_flag_spec, $1)=
fi
@@ -5969,18 +6437,30 @@ if test "$_lt_caught_CXX_error" != yes; then
_LT_TAGVAR(ld_shlibs, $1)=no
;;
aix[[4-9]]*)
- if test "$host_cpu" = ia64; then
+ if test ia64 = "$host_cpu"; then
# On IA64, the linker does run time linking by default, so we don't
# have to do anything special.
aix_use_runtimelinking=no
exp_sym_flag='-Bexport'
- no_entry_flag=""
+ no_entry_flag=
else
aix_use_runtimelinking=no
# Test if we are trying to use run time linking or normal
# AIX style linking. If -brtl is somewhere in LDFLAGS, we
- # need to do runtime linking.
+ # have runtime linking enabled, and use it for executables.
+ # For shared libraries, we enable/disable runtime linking
+ # depending on the kind of the shared library created -
+ # when "with_aix_soname,aix_use_runtimelinking" is:
+ # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables
+ # "aix,yes" lib.so shared, rtl:yes, for executables
+ # lib.a static archive
+ # "both,no" lib.so.V(shr.o) shared, rtl:yes
+ # lib.a(lib.so.V) shared, rtl:no, for executables
+ # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a(lib.so.V) shared, rtl:no
+ # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a static archive
case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
for ld_flag in $LDFLAGS; do
case $ld_flag in
@@ -5990,6 +6470,13 @@ if test "$_lt_caught_CXX_error" != yes; then
;;
esac
done
+ if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # With aix-soname=svr4, we create the lib.so.V shared archives only,
+ # so we don't have lib.a shared libs to link our executables.
+ # We have to force runtime linking in this case.
+ aix_use_runtimelinking=yes
+ LDFLAGS="$LDFLAGS -Wl,-brtl"
+ fi
;;
esac
@@ -6008,13 +6495,21 @@ if test "$_lt_caught_CXX_error" != yes; then
_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
_LT_TAGVAR(hardcode_libdir_separator, $1)=':'
_LT_TAGVAR(link_all_deplibs, $1)=yes
- _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+ _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
+ case $with_aix_soname,$aix_use_runtimelinking in
+ aix,*) ;; # no import file
+ svr4,* | *,yes) # use import file
+ # The Import File defines what to hardcode.
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+ ;;
+ esac
- if test "$GXX" = yes; then
+ if test yes = "$GXX"; then
case $host_os in aix4.[[012]]|aix4.[[012]].*)
# We only want to do this on AIX 4.2 and lower, the check
# below for broken collect2 doesn't work under 4.3+
- collect2name=`${CC} -print-prog-name=collect2`
+ collect2name=`$CC -print-prog-name=collect2`
if test -f "$collect2name" &&
strings "$collect2name" | $GREP resolve_lib_name >/dev/null
then
@@ -6032,64 +6527,84 @@ if test "$_lt_caught_CXX_error" != yes; then
fi
esac
shared_flag='-shared'
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag="$shared_flag "'${wl}-G'
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag=$shared_flag' $wl-G'
fi
+ # Need to ensure runtime linking is disabled for the traditional
+ # shared library, or the linker may eventually find shared libraries
+ # /with/ Import File - we do not want to mix them.
+ shared_flag_aix='-shared'
+ shared_flag_svr4='-shared $wl-G'
else
# not using gcc
- if test "$host_cpu" = ia64; then
+ if test ia64 = "$host_cpu"; then
# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
# chokes on -Wl,-G. The following line is correct:
shared_flag='-G'
else
- if test "$aix_use_runtimelinking" = yes; then
- shared_flag='${wl}-G'
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag='$wl-G'
else
- shared_flag='${wl}-bM:SRE'
+ shared_flag='$wl-bM:SRE'
fi
+ shared_flag_aix='$wl-bM:SRE'
+ shared_flag_svr4='$wl-G'
fi
fi
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
# It seems that -bexpall does not export symbols beginning with
# underscore (_), so it is better to generate a list of symbols to
# export.
_LT_TAGVAR(always_export_symbols, $1)=yes
- if test "$aix_use_runtimelinking" = yes; then
+ if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
# Warning - without using the other runtime loading flags (-brtl),
# -berok will link without error, but may produce a broken library.
- _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+ # The "-G" linker flag allows undefined symbols.
+ _LT_TAGVAR(no_undefined_flag, $1)='-bernotok'
# Determine the default libpath from the value encoded in an empty
# executable.
_LT_SYS_MODULE_PATH_AIX([$1])
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
else
- if test "$host_cpu" = ia64; then
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+ if test ia64 = "$host_cpu"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
_LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
- _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
else
# Determine the default libpath from the value encoded in an
# empty executable.
_LT_SYS_MODULE_PATH_AIX([$1])
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
# Warning - without using the other run time loading flags,
# -berok will link without error, but may produce a broken library.
- _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
- _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
- if test "$with_gnu_ld" = yes; then
+ _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
+ if test yes = "$with_gnu_ld"; then
# We only use this code for GNU lds that support --whole-archive.
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
else
# Exported symbols can be pulled into shared objects from archives
_LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
fi
_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
- # This is similar to how AIX traditionally builds its shared
- # libraries.
- _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
+ # -brtl affects multiple linker settings, -berok does not and is overridden later
+ compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
+ if test svr4 != "$with_aix_soname"; then
+ # This is similar to how AIX traditionally builds its shared
+ # libraries. Need -bnortl late, we may have -brtl in LDFLAGS.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
+ fi
+ if test aix != "$with_aix_soname"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
+ else
+ # used by -dlpreopen to get the symbols
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir'
+ fi
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
fi
fi
;;
@@ -6099,7 +6614,7 @@ if test "$_lt_caught_CXX_error" != yes; then
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
# Joseph Beckenbach <jrb3@best.com> says some releases of gcc
# support --undefined. This deserves some investigation. FIXME
- _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
else
_LT_TAGVAR(ld_shlibs, $1)=no
fi
@@ -6127,57 +6642,58 @@ if test "$_lt_caught_CXX_error" != yes; then
# Tell ltmain to make .lib files, not .a files.
libext=lib
# Tell ltmain to make .dll files, not .so files.
- shrext_cmds=".dll"
+ shrext_cmds=.dll
# FIXME: Setting linknames here is a bad hack.
- _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
- _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
- $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
- else
- $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
- fi~
- $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
- linknames='
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+ cp "$export_symbols" "$output_objdir/$soname.def";
+ echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+ else
+ $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
# The linker will not automatically build a static lib if we build a DLL.
# _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
# Don't use ranlib
_LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
_LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
- lt_tool_outputfile="@TOOL_OUTPUT@"~
- case $lt_outputfile in
- *.exe|*.EXE) ;;
- *)
- lt_outputfile="$lt_outputfile.exe"
- lt_tool_outputfile="$lt_tool_outputfile.exe"
- ;;
- esac~
- func_to_tool_file "$lt_outputfile"~
- if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
- $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
- $RM "$lt_outputfile.manifest";
- fi'
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile=$lt_outputfile.exe
+ lt_tool_outputfile=$lt_tool_outputfile.exe
+ ;;
+ esac~
+ func_to_tool_file "$lt_outputfile"~
+ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
;;
*)
# g++
# _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
# as there is no search path for DLLs.
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
_LT_TAGVAR(always_export_symbols, $1)=no
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
- # If the export-symbols file already is a .def file (1st line
- # is EXPORTS), use it as is; otherwise, prepend...
- _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
- cp $export_symbols $output_objdir/$soname.def;
- else
- echo EXPORTS > $output_objdir/$soname.def;
- cat $export_symbols >> $output_objdir/$soname.def;
- fi~
- $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file, use it as
+ # is; otherwise, prepend EXPORTS...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
else
_LT_TAGVAR(ld_shlibs, $1)=no
fi
@@ -6188,6 +6704,34 @@ if test "$_lt_caught_CXX_error" != yes; then
_LT_DARWIN_LINKER_FEATURES($1)
;;
+ os2*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ shrext_cmds=.dll
+ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+
dgux*)
case $cc_basename in
ec++*)
@@ -6222,18 +6766,15 @@ if test "$_lt_caught_CXX_error" != yes; then
_LT_TAGVAR(ld_shlibs, $1)=yes
;;
- gnu*)
- ;;
-
haiku*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
_LT_TAGVAR(link_all_deplibs, $1)=yes
;;
hpux9*)
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
# but as the default
@@ -6245,7 +6786,7 @@ if test "$_lt_caught_CXX_error" != yes; then
_LT_TAGVAR(ld_shlibs, $1)=no
;;
aCC*)
- _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
@@ -6254,11 +6795,11 @@ if test "$_lt_caught_CXX_error" != yes; then
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
;;
*)
- if test "$GXX" = yes; then
- _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ if test yes = "$GXX"; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
else
# FIXME: insert proper C++ library support
_LT_TAGVAR(ld_shlibs, $1)=no
@@ -6268,15 +6809,15 @@ if test "$_lt_caught_CXX_error" != yes; then
;;
hpux10*|hpux11*)
- if test $with_gnu_ld = no; then
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ if test no = "$with_gnu_ld"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
case $host_cpu in
hppa*64*|ia64*)
;;
*)
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
;;
esac
fi
@@ -6302,13 +6843,13 @@ if test "$_lt_caught_CXX_error" != yes; then
aCC*)
case $host_cpu in
hppa*64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
ia64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
esac
# Commands to make compiler produce verbose output that lists
@@ -6319,20 +6860,20 @@ if test "$_lt_caught_CXX_error" != yes; then
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
;;
*)
- if test "$GXX" = yes; then
- if test $with_gnu_ld = no; then
+ if test yes = "$GXX"; then
+ if test no = "$with_gnu_ld"; then
case $host_cpu in
hppa*64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
ia64*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
esac
fi
@@ -6347,22 +6888,22 @@ if test "$_lt_caught_CXX_error" != yes; then
interix[[3-9]]*)
_LT_TAGVAR(hardcode_direct, $1)=no
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
# Instead, shared libraries are loaded at an image base (0x10000000 by
# default) and relocated if they conflict, which is a slow very memory
# consuming and fragmenting process. To avoid this, we pick a random,
# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
# time. Moving up from 0x10000000 also allows more sbrk(2) space.
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
;;
irix5* | irix6*)
case $cc_basename in
CC*)
# SGI C++
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
# Archives containing C++ object files must be created using
# "CC -ar", where "CC" is the IRIX C++ compiler. This is
@@ -6371,22 +6912,22 @@ if test "$_lt_caught_CXX_error" != yes; then
_LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
;;
*)
- if test "$GXX" = yes; then
- if test "$with_gnu_ld" = no; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ if test yes = "$GXX"; then
+ if test no = "$with_gnu_ld"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
else
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib'
fi
fi
_LT_TAGVAR(link_all_deplibs, $1)=yes
;;
esac
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
_LT_TAGVAR(inherit_rpath, $1)=yes
;;
- linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
case $cc_basename in
KCC*)
# Kuck and Associates, Inc. (KAI) C++ Compiler
@@ -6394,8 +6935,8 @@ if test "$_lt_caught_CXX_error" != yes; then
# KCC will only create a shared library if the output file
# ends with ".so" (or ".sl" for HP-UX), so rename the library
# to its proper name (with version) after linking.
- _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib'
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
@@ -6404,10 +6945,10 @@ if test "$_lt_caught_CXX_error" != yes; then
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
# Archives containing C++ object files must be created using
# "CC -Bstatic", where "CC" is the KAI C++ compiler.
@@ -6421,59 +6962,59 @@ if test "$_lt_caught_CXX_error" != yes; then
# earlier do not add the objects themselves.
case `$CC -V 2>&1` in
*"Version 7."*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
;;
*) # Version 8.0 or newer
tmp_idyn=
case $host_cpu in
ia64*) tmp_idyn=' -i_dynamic';;
esac
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
;;
esac
_LT_TAGVAR(archive_cmds_need_lc, $1)=no
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
;;
pgCC* | pgcpp*)
# Portland Group C++ compiler
case `$CC -V` in
*pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*)
_LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
- rm -rf $tpldir~
- $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
- compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
_LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
- rm -rf $tpldir~
- $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
- $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
- $RANLIB $oldlib'
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+ $RANLIB $oldlib'
_LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
- rm -rf $tpldir~
- $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
- $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
- rm -rf $tpldir~
- $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
- $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
;;
*) # Version 6 and above use weak symbols
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
;;
esac
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
;;
cxx*)
# Compaq C++
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols'
runpath_var=LD_RUN_PATH
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
@@ -6487,18 +7028,18 @@ if test "$_lt_caught_CXX_error" != yes; then
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
;;
xl* | mpixl* | bgxl*)
# IBM XL 8.0 on PPC, with GNU ld
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
- _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- if test "x$supports_anon_versioning" = xyes; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ if test yes = "$supports_anon_versioning"; then
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
- cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
- echo "local: *; };" >> $output_objdir/$libname.ver~
- $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
fi
;;
*)
@@ -6506,10 +7047,10 @@ if test "$_lt_caught_CXX_error" != yes; then
*Sun\ C*)
# Sun C++ 5.9
_LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
- _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
_LT_TAGVAR(compiler_needs_object, $1)=yes
# Not sure whether something based on
@@ -6567,22 +7108,17 @@ if test "$_lt_caught_CXX_error" != yes; then
_LT_TAGVAR(ld_shlibs, $1)=yes
;;
- openbsd2*)
- # C++ shared libraries are fairly broken
- _LT_TAGVAR(ld_shlibs, $1)=no
- ;;
-
- openbsd*)
+ openbsd* | bitrig*)
if test -f /usr/libexec/ld.so; then
_LT_TAGVAR(hardcode_direct, $1)=yes
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
- _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
fi
output_verbose_link_cmd=func_echo_all
else
@@ -6598,9 +7134,9 @@ if test "$_lt_caught_CXX_error" != yes; then
# KCC will only create a shared library if the output file
# ends with ".so" (or ".sl" for HP-UX), so rename the library
# to its proper name (with version) after linking.
- _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
# Archives containing C++ object files must be created using
@@ -6618,17 +7154,17 @@ if test "$_lt_caught_CXX_error" != yes; then
cxx*)
case $host in
osf3*)
- _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
;;
*)
_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
- echo "-hidden">> $lib.exp~
- $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
- $RM $lib.exp'
+ echo "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~
+ $RM $lib.exp'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
;;
esac
@@ -6643,21 +7179,21 @@ if test "$_lt_caught_CXX_error" != yes; then
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
;;
*)
- if test "$GXX" = yes && test "$with_gnu_ld" = no; then
- _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ if test yes,no = "$GXX,$with_gnu_ld"; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
case $host in
osf3*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
;;
*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
;;
esac
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=:
# Commands to make compiler produce verbose output that lists
@@ -6703,9 +7239,9 @@ if test "$_lt_caught_CXX_error" != yes; then
# Sun C++ 4.2, 5.x and Centerline C++
_LT_TAGVAR(archive_cmds_need_lc,$1)=yes
_LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
- _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
@@ -6713,7 +7249,7 @@ if test "$_lt_caught_CXX_error" != yes; then
solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
*)
# The compiler driver will combine and reorder linker options,
- # but understands `-z linker_flag'.
+ # but understands '-z linker_flag'.
# Supported since Solaris 2.6 (maybe 2.5.1?)
_LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
;;
@@ -6730,30 +7266,30 @@ if test "$_lt_caught_CXX_error" != yes; then
;;
gcx*)
# Green Hills C++ Compiler
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
# The C++ compiler must be used to create the archive.
_LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
;;
*)
# GNU C++ compiler with Solaris linker
- if test "$GXX" = yes && test "$with_gnu_ld" = no; then
- _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
+ if test yes,no = "$GXX,$with_gnu_ld"; then
+ _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs'
if $CC --version | $GREP -v '^2\.7' > /dev/null; then
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
else
- # g++ 2.7 appears to require `-G' NOT `-shared' on this
+ # g++ 2.7 appears to require '-G' NOT '-shared' on this
# platform.
- _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
- $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
@@ -6761,11 +7297,11 @@ if test "$_lt_caught_CXX_error" != yes; then
output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
fi
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
case $host_os in
solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
*)
- _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
;;
esac
fi
@@ -6774,52 +7310,52 @@ if test "$_lt_caught_CXX_error" != yes; then
;;
sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
- _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
_LT_TAGVAR(archive_cmds_need_lc, $1)=no
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
runpath_var='LD_RUN_PATH'
case $cc_basename in
CC*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
;;
*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
;;
esac
;;
sysv5* | sco3.2v5* | sco5v6*)
- # Note: We can NOT use -z defs as we might desire, because we do not
+ # Note: We CANNOT use -z defs as we might desire, because we do not
# link with -lc, and that would cause any symbols used from libc to
# always be unresolved, which means just about no library would
# ever link correctly. If we're not using GNU ld we use -z text
# though, which does catch some bad symbols but isn't as heavy-handed
# as -z defs.
- _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
- _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
_LT_TAGVAR(archive_cmds_need_lc, $1)=no
_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
- _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
_LT_TAGVAR(hardcode_libdir_separator, $1)=':'
_LT_TAGVAR(link_all_deplibs, $1)=yes
- _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
runpath_var='LD_RUN_PATH'
case $cc_basename in
CC*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
_LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~
- '"$_LT_TAGVAR(old_archive_cmds, $1)"
+ '"$_LT_TAGVAR(old_archive_cmds, $1)"
_LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~
- '"$_LT_TAGVAR(reload_cmds, $1)"
+ '"$_LT_TAGVAR(reload_cmds, $1)"
;;
*)
- _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
- _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
;;
esac
;;
@@ -6850,10 +7386,10 @@ if test "$_lt_caught_CXX_error" != yes; then
esac
AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
- test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+ test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
- _LT_TAGVAR(GCC, $1)="$GXX"
- _LT_TAGVAR(LD, $1)="$LD"
+ _LT_TAGVAR(GCC, $1)=$GXX
+ _LT_TAGVAR(LD, $1)=$LD
## CAVEAT EMPTOR:
## There is no encapsulation within the following macros, do not change
@@ -6880,7 +7416,7 @@ if test "$_lt_caught_CXX_error" != yes; then
lt_cv_path_LD=$lt_save_path_LD
lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
-fi # test "$_lt_caught_CXX_error" != yes
+fi # test yes != "$_lt_caught_CXX_error"
AC_LANG_POP
])# _LT_LANG_CXX_CONFIG
@@ -6902,13 +7438,14 @@ AC_REQUIRE([_LT_DECL_SED])
AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])
func_stripname_cnf ()
{
- case ${2} in
- .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
- *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+ case @S|@2 in
+ .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;;
+ *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;;
esac
} # func_stripname_cnf
])# _LT_FUNC_STRIPNAME_CNF
+
# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
# ---------------------------------
# Figure out "hidden" library dependencies from verbose
@@ -6992,13 +7529,13 @@ if AC_TRY_EVAL(ac_compile); then
pre_test_object_deps_done=no
for p in `eval "$output_verbose_link_cmd"`; do
- case ${prev}${p} in
+ case $prev$p in
-L* | -R* | -l*)
# Some compilers place space between "-{L,R}" and the path.
# Remove the space.
- if test $p = "-L" ||
- test $p = "-R"; then
+ if test x-L = "$p" ||
+ test x-R = "$p"; then
prev=$p
continue
fi
@@ -7014,16 +7551,16 @@ if AC_TRY_EVAL(ac_compile); then
case $p in
=*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
esac
- if test "$pre_test_object_deps_done" = no; then
- case ${prev} in
+ if test no = "$pre_test_object_deps_done"; then
+ case $prev in
-L | -R)
# Internal compiler library paths should come after those
# provided the user. The postdeps already come after the
# user supplied libs so there is no need to process them.
if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
- _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
+ _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p
else
- _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
+ _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p"
fi
;;
# The "-l" case would never come before the object being
@@ -7031,9 +7568,9 @@ if AC_TRY_EVAL(ac_compile); then
esac
else
if test -z "$_LT_TAGVAR(postdeps, $1)"; then
- _LT_TAGVAR(postdeps, $1)="${prev}${p}"
+ _LT_TAGVAR(postdeps, $1)=$prev$p
else
- _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}"
+ _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p"
fi
fi
prev=
@@ -7048,15 +7585,15 @@ if AC_TRY_EVAL(ac_compile); then
continue
fi
- if test "$pre_test_object_deps_done" = no; then
+ if test no = "$pre_test_object_deps_done"; then
if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
- _LT_TAGVAR(predep_objects, $1)="$p"
+ _LT_TAGVAR(predep_objects, $1)=$p
else
_LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
fi
else
if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
- _LT_TAGVAR(postdep_objects, $1)="$p"
+ _LT_TAGVAR(postdep_objects, $1)=$p
else
_LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
fi
@@ -7087,51 +7624,6 @@ interix[[3-9]]*)
_LT_TAGVAR(postdep_objects,$1)=
_LT_TAGVAR(postdeps,$1)=
;;
-
-linux*)
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*)
- # Sun C++ 5.9
-
- # The more standards-conforming stlport4 library is
- # incompatible with the Cstd library. Avoid specifying
- # it if it's in CXXFLAGS. Ignore libCrun as
- # -library=stlport4 depends on it.
- case " $CXX $CXXFLAGS " in
- *" -library=stlport4 "*)
- solaris_use_stlport4=yes
- ;;
- esac
-
- if test "$solaris_use_stlport4" != yes; then
- _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
- fi
- ;;
- esac
- ;;
-
-solaris*)
- case $cc_basename in
- CC* | sunCC*)
- # The more standards-conforming stlport4 library is
- # incompatible with the Cstd library. Avoid specifying
- # it if it's in CXXFLAGS. Ignore libCrun as
- # -library=stlport4 depends on it.
- case " $CXX $CXXFLAGS " in
- *" -library=stlport4 "*)
- solaris_use_stlport4=yes
- ;;
- esac
-
- # Adding this requires a known-good setup of shared libraries for
- # Sun compiler versions before 5.6, else PIC objects from an old
- # archive will be linked into the output, leading to subtle bugs.
- if test "$solaris_use_stlport4" != yes; then
- _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
- fi
- ;;
- esac
- ;;
esac
])
@@ -7140,7 +7632,7 @@ case " $_LT_TAGVAR(postdeps, $1) " in
esac
_LT_TAGVAR(compiler_lib_search_dirs, $1)=
if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
- _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'`
fi
_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
[The directories searched by this compiler when creating a shared library])
@@ -7160,10 +7652,10 @@ _LT_TAGDECL([], [compiler_lib_search_path], [1],
# --------------------------
# Ensure that the configuration variables for a Fortran 77 compiler are
# suitably defined. These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to `libtool'.
+# to write the compiler configuration to 'libtool'.
m4_defun([_LT_LANG_F77_CONFIG],
[AC_LANG_PUSH(Fortran 77)
-if test -z "$F77" || test "X$F77" = "Xno"; then
+if test -z "$F77" || test no = "$F77"; then
_lt_disable_F77=yes
fi
@@ -7200,7 +7692,7 @@ _LT_TAGVAR(objext, $1)=$objext
# the F77 compiler isn't working. Some variables (like enable_shared)
# are currently assumed to apply to all compilers on this platform,
# and will be corrupted by setting them based on a non-working compiler.
-if test "$_lt_disable_F77" != yes; then
+if test yes != "$_lt_disable_F77"; then
# Code to be used in simple compile tests
lt_simple_compile_test_code="\
subroutine t
@@ -7222,7 +7714,7 @@ if test "$_lt_disable_F77" != yes; then
_LT_LINKER_BOILERPLATE
# Allow CC to be a program name with arguments.
- lt_save_CC="$CC"
+ lt_save_CC=$CC
lt_save_GCC=$GCC
lt_save_CFLAGS=$CFLAGS
CC=${F77-"f77"}
@@ -7236,21 +7728,25 @@ if test "$_lt_disable_F77" != yes; then
AC_MSG_RESULT([$can_build_shared])
AC_MSG_CHECKING([whether to build shared libraries])
- test "$can_build_shared" = "no" && enable_shared=no
+ test no = "$can_build_shared" && enable_shared=no
# On AIX, shared libraries and static libraries use the same namespace, and
# are all built from PIC.
case $host_os in
aix3*)
- test "$enable_shared" = yes && enable_static=no
+ test yes = "$enable_shared" && enable_static=no
if test -n "$RANLIB"; then
archive_cmds="$archive_cmds~\$RANLIB \$lib"
postinstall_cmds='$RANLIB $lib'
fi
;;
aix[[4-9]]*)
- if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
- test "$enable_shared" = yes && enable_static=no
+ if test ia64 != "$host_cpu"; then
+ case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+ yes,aix,yes) ;; # shared object as lib.so file only
+ yes,svr4,*) ;; # shared object as lib.so archive member only
+ yes,*) enable_static=no ;; # shared object in lib.a archive as well
+ esac
fi
;;
esac
@@ -7258,11 +7754,11 @@ if test "$_lt_disable_F77" != yes; then
AC_MSG_CHECKING([whether to build static libraries])
# Make sure either enable_shared or enable_static is yes.
- test "$enable_shared" = yes || enable_static=yes
+ test yes = "$enable_shared" || enable_static=yes
AC_MSG_RESULT([$enable_static])
- _LT_TAGVAR(GCC, $1)="$G77"
- _LT_TAGVAR(LD, $1)="$LD"
+ _LT_TAGVAR(GCC, $1)=$G77
+ _LT_TAGVAR(LD, $1)=$LD
## CAVEAT EMPTOR:
## There is no encapsulation within the following macros, do not change
@@ -7279,9 +7775,9 @@ if test "$_lt_disable_F77" != yes; then
fi # test -n "$compiler"
GCC=$lt_save_GCC
- CC="$lt_save_CC"
- CFLAGS="$lt_save_CFLAGS"
-fi # test "$_lt_disable_F77" != yes
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+fi # test yes != "$_lt_disable_F77"
AC_LANG_POP
])# _LT_LANG_F77_CONFIG
@@ -7291,11 +7787,11 @@ AC_LANG_POP
# -------------------------
# Ensure that the configuration variables for a Fortran compiler are
# suitably defined. These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to `libtool'.
+# to write the compiler configuration to 'libtool'.
m4_defun([_LT_LANG_FC_CONFIG],
[AC_LANG_PUSH(Fortran)
-if test -z "$FC" || test "X$FC" = "Xno"; then
+if test -z "$FC" || test no = "$FC"; then
_lt_disable_FC=yes
fi
@@ -7332,7 +7828,7 @@ _LT_TAGVAR(objext, $1)=$objext
# the FC compiler isn't working. Some variables (like enable_shared)
# are currently assumed to apply to all compilers on this platform,
# and will be corrupted by setting them based on a non-working compiler.
-if test "$_lt_disable_FC" != yes; then
+if test yes != "$_lt_disable_FC"; then
# Code to be used in simple compile tests
lt_simple_compile_test_code="\
subroutine t
@@ -7354,7 +7850,7 @@ if test "$_lt_disable_FC" != yes; then
_LT_LINKER_BOILERPLATE
# Allow CC to be a program name with arguments.
- lt_save_CC="$CC"
+ lt_save_CC=$CC
lt_save_GCC=$GCC
lt_save_CFLAGS=$CFLAGS
CC=${FC-"f95"}
@@ -7370,21 +7866,25 @@ if test "$_lt_disable_FC" != yes; then
AC_MSG_RESULT([$can_build_shared])
AC_MSG_CHECKING([whether to build shared libraries])
- test "$can_build_shared" = "no" && enable_shared=no
+ test no = "$can_build_shared" && enable_shared=no
# On AIX, shared libraries and static libraries use the same namespace, and
# are all built from PIC.
case $host_os in
aix3*)
- test "$enable_shared" = yes && enable_static=no
+ test yes = "$enable_shared" && enable_static=no
if test -n "$RANLIB"; then
archive_cmds="$archive_cmds~\$RANLIB \$lib"
postinstall_cmds='$RANLIB $lib'
fi
;;
aix[[4-9]]*)
- if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
- test "$enable_shared" = yes && enable_static=no
+ if test ia64 != "$host_cpu"; then
+ case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+ yes,aix,yes) ;; # shared object as lib.so file only
+ yes,svr4,*) ;; # shared object as lib.so archive member only
+ yes,*) enable_static=no ;; # shared object in lib.a archive as well
+ esac
fi
;;
esac
@@ -7392,11 +7892,11 @@ if test "$_lt_disable_FC" != yes; then
AC_MSG_CHECKING([whether to build static libraries])
# Make sure either enable_shared or enable_static is yes.
- test "$enable_shared" = yes || enable_static=yes
+ test yes = "$enable_shared" || enable_static=yes
AC_MSG_RESULT([$enable_static])
- _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu"
- _LT_TAGVAR(LD, $1)="$LD"
+ _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu
+ _LT_TAGVAR(LD, $1)=$LD
## CAVEAT EMPTOR:
## There is no encapsulation within the following macros, do not change
@@ -7416,7 +7916,7 @@ if test "$_lt_disable_FC" != yes; then
GCC=$lt_save_GCC
CC=$lt_save_CC
CFLAGS=$lt_save_CFLAGS
-fi # test "$_lt_disable_FC" != yes
+fi # test yes != "$_lt_disable_FC"
AC_LANG_POP
])# _LT_LANG_FC_CONFIG
@@ -7426,7 +7926,7 @@ AC_LANG_POP
# --------------------------
# Ensure that the configuration variables for the GNU Java Compiler compiler
# are suitably defined. These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to `libtool'.
+# to write the compiler configuration to 'libtool'.
m4_defun([_LT_LANG_GCJ_CONFIG],
[AC_REQUIRE([LT_PROG_GCJ])dnl
AC_LANG_SAVE
@@ -7460,7 +7960,7 @@ CC=${GCJ-"gcj"}
CFLAGS=$GCJFLAGS
compiler=$CC
_LT_TAGVAR(compiler, $1)=$CC
-_LT_TAGVAR(LD, $1)="$LD"
+_LT_TAGVAR(LD, $1)=$LD
_LT_CC_BASENAME([$compiler])
# GCJ did not exist at the time GCC didn't implicitly link libc in.
@@ -7497,7 +7997,7 @@ CFLAGS=$lt_save_CFLAGS
# --------------------------
# Ensure that the configuration variables for the GNU Go compiler
# are suitably defined. These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to `libtool'.
+# to write the compiler configuration to 'libtool'.
m4_defun([_LT_LANG_GO_CONFIG],
[AC_REQUIRE([LT_PROG_GO])dnl
AC_LANG_SAVE
@@ -7531,7 +8031,7 @@ CC=${GOC-"gccgo"}
CFLAGS=$GOFLAGS
compiler=$CC
_LT_TAGVAR(compiler, $1)=$CC
-_LT_TAGVAR(LD, $1)="$LD"
+_LT_TAGVAR(LD, $1)=$LD
_LT_CC_BASENAME([$compiler])
# Go did not exist at the time GCC didn't implicitly link libc in.
@@ -7568,7 +8068,7 @@ CFLAGS=$lt_save_CFLAGS
# -------------------------
# Ensure that the configuration variables for the Windows resource compiler
# are suitably defined. These variables are subsequently used by _LT_CONFIG
-# to write the compiler configuration to `libtool'.
+# to write the compiler configuration to 'libtool'.
m4_defun([_LT_LANG_RC_CONFIG],
[AC_REQUIRE([LT_PROG_RC])dnl
AC_LANG_SAVE
@@ -7584,7 +8084,7 @@ _LT_TAGVAR(objext, $1)=$objext
lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
# Code to be used in simple link tests
-lt_simple_link_test_code="$lt_simple_compile_test_code"
+lt_simple_link_test_code=$lt_simple_compile_test_code
# ltmain only uses $CC for tagged configurations so make sure $CC is set.
_LT_TAG_COMPILER
@@ -7594,7 +8094,7 @@ _LT_COMPILER_BOILERPLATE
_LT_LINKER_BOILERPLATE
# Allow CC to be a program name with arguments.
-lt_save_CC="$CC"
+lt_save_CC=$CC
lt_save_CFLAGS=$CFLAGS
lt_save_GCC=$GCC
GCC=
@@ -7623,7 +8123,7 @@ AC_DEFUN([LT_PROG_GCJ],
[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
[m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
[AC_CHECK_TOOL(GCJ, gcj,)
- test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
+ test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2"
AC_SUBST(GCJFLAGS)])])[]dnl
])
@@ -7734,7 +8234,7 @@ lt_ac_count=0
# Add /usr/xpg4/bin/sed as it is typically found on Solaris
# along with /bin/sed that truncates output.
for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
- test ! -f $lt_ac_sed && continue
+ test ! -f "$lt_ac_sed" && continue
cat /dev/null > conftest.in
lt_ac_count=0
echo $ECHO_N "0123456789$ECHO_C" >conftest.in
@@ -7751,9 +8251,9 @@ for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
$lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
cmp -s conftest.out conftest.nl || break
# 10000 chars as input seems more than enough
- test $lt_ac_count -gt 10 && break
+ test 10 -lt "$lt_ac_count" && break
lt_ac_count=`expr $lt_ac_count + 1`
- if test $lt_ac_count -gt $lt_ac_max; then
+ if test "$lt_ac_count" -gt "$lt_ac_max"; then
lt_ac_max=$lt_ac_count
lt_cv_path_SED=$lt_ac_sed
fi
@@ -7777,27 +8277,7 @@ dnl AC_DEFUN([LT_AC_PROG_SED], [])
# Find out whether the shell is Bourne or XSI compatible,
# or has some other useful features.
m4_defun([_LT_CHECK_SHELL_FEATURES],
-[AC_MSG_CHECKING([whether the shell understands some XSI constructs])
-# Try some XSI features
-xsi_shell=no
-( _lt_dummy="a/b/c"
- test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
- = c,a/b,b/c, \
- && eval 'test $(( 1 + 1 )) -eq 2 \
- && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
- && xsi_shell=yes
-AC_MSG_RESULT([$xsi_shell])
-_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell'])
-
-AC_MSG_CHECKING([whether the shell understands "+="])
-lt_shell_append=no
-( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \
- >/dev/null 2>&1 \
- && lt_shell_append=yes
-AC_MSG_RESULT([$lt_shell_append])
-_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append'])
-
-if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
lt_unset=unset
else
lt_unset=false
@@ -7821,102 +8301,9 @@ _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
])# _LT_CHECK_SHELL_FEATURES
-# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY)
-# ------------------------------------------------------
-# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and
-# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY.
-m4_defun([_LT_PROG_FUNCTION_REPLACE],
-[dnl {
-sed -e '/^$1 ()$/,/^} # $1 /c\
-$1 ()\
-{\
-m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1])
-} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \
- && mv -f "$cfgfile.tmp" "$cfgfile" \
- || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
-test 0 -eq $? || _lt_function_replace_fail=:
-])
-
-
-# _LT_PROG_REPLACE_SHELLFNS
-# -------------------------
-# Replace existing portable implementations of several shell functions with
-# equivalent extended shell implementations where those features are available..
-m4_defun([_LT_PROG_REPLACE_SHELLFNS],
-[if test x"$xsi_shell" = xyes; then
- _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl
- case ${1} in
- */*) func_dirname_result="${1%/*}${2}" ;;
- * ) func_dirname_result="${3}" ;;
- esac])
-
- _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl
- func_basename_result="${1##*/}"])
-
- _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl
- case ${1} in
- */*) func_dirname_result="${1%/*}${2}" ;;
- * ) func_dirname_result="${3}" ;;
- esac
- func_basename_result="${1##*/}"])
-
- _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl
- # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
- # positional parameters, so assign one to ordinary parameter first.
- func_stripname_result=${3}
- func_stripname_result=${func_stripname_result#"${1}"}
- func_stripname_result=${func_stripname_result%"${2}"}])
-
- _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl
- func_split_long_opt_name=${1%%=*}
- func_split_long_opt_arg=${1#*=}])
-
- _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl
- func_split_short_opt_arg=${1#??}
- func_split_short_opt_name=${1%"$func_split_short_opt_arg"}])
-
- _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl
- case ${1} in
- *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
- *) func_lo2o_result=${1} ;;
- esac])
-
- _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo])
-
- _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))])
-
- _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}])
-fi
-
-if test x"$lt_shell_append" = xyes; then
- _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"])
-
- _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl
- func_quote_for_eval "${2}"
-dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \
- eval "${1}+=\\\\ \\$func_quote_for_eval_result"])
-
- # Save a `func_append' function call where possible by direct use of '+='
- sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
- && mv -f "$cfgfile.tmp" "$cfgfile" \
- || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
- test 0 -eq $? || _lt_function_replace_fail=:
-else
- # Save a `func_append' function call even when '+=' is not available
- sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
- && mv -f "$cfgfile.tmp" "$cfgfile" \
- || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
- test 0 -eq $? || _lt_function_replace_fail=:
-fi
-
-if test x"$_lt_function_replace_fail" = x":"; then
- AC_MSG_WARN([Unable to substitute extended shell functions in $ofile])
-fi
-])
-
# _LT_PATH_CONVERSION_FUNCTIONS
# -----------------------------
-# Determine which file name conversion functions should be used by
+# Determine what file name conversion functions should be used by
# func_to_host_file (and, implicitly, by func_to_host_path). These are needed
# for certain cross-compile configurations and native mingw.
m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
diff --git a/contrib/libxo/m4/ltoptions.m4 b/contrib/libxo/m4/ltoptions.m4
index 5d9acd8e23bc..94b082976667 100644
--- a/contrib/libxo/m4/ltoptions.m4
+++ b/contrib/libxo/m4/ltoptions.m4
@@ -1,14 +1,14 @@
# Helper functions for option handling. -*- Autoconf -*-
#
-# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,
-# Inc.
+# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software
+# Foundation, Inc.
# Written by Gary V. Vaughan, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
-# serial 7 ltoptions.m4
+# serial 8 ltoptions.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
@@ -29,7 +29,7 @@ m4_define([_LT_SET_OPTION],
[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
_LT_MANGLE_DEFUN([$1], [$2]),
- [m4_warning([Unknown $1 option `$2'])])[]dnl
+ [m4_warning([Unknown $1 option '$2'])])[]dnl
])
@@ -75,13 +75,15 @@ m4_if([$1],[LT_INIT],[
dnl
dnl If no reference was made to various pairs of opposing options, then
dnl we run the default mode handler for the pair. For example, if neither
- dnl `shared' nor `disable-shared' was passed, we enable building of shared
+ dnl 'shared' nor 'disable-shared' was passed, we enable building of shared
dnl archives by default:
_LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
_LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
_LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
_LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
- [_LT_ENABLE_FAST_INSTALL])
+ [_LT_ENABLE_FAST_INSTALL])
+ _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4],
+ [_LT_WITH_AIX_SONAME([aix])])
])
])# _LT_SET_OPTIONS
@@ -112,7 +114,7 @@ AU_DEFUN([AC_LIBTOOL_DLOPEN],
[_LT_SET_OPTION([LT_INIT], [dlopen])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
-put the `dlopen' option into LT_INIT's first parameter.])
+put the 'dlopen' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
@@ -148,7 +150,7 @@ AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
_LT_SET_OPTION([LT_INIT], [win32-dll])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
-put the `win32-dll' option into LT_INIT's first parameter.])
+put the 'win32-dll' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
@@ -157,9 +159,9 @@ dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
# _LT_ENABLE_SHARED([DEFAULT])
# ----------------------------
-# implement the --enable-shared flag, and supports the `shared' and
-# `disable-shared' LT_INIT options.
-# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+# implement the --enable-shared flag, and supports the 'shared' and
+# 'disable-shared' LT_INIT options.
+# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
m4_define([_LT_ENABLE_SHARED],
[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([shared],
@@ -172,14 +174,14 @@ AC_ARG_ENABLE([shared],
*)
enable_shared=no
# Look at the argument we got. We use all the common list separators.
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
for pkg in $enableval; do
- IFS="$lt_save_ifs"
+ IFS=$lt_save_ifs
if test "X$pkg" = "X$p"; then
enable_shared=yes
fi
done
- IFS="$lt_save_ifs"
+ IFS=$lt_save_ifs
;;
esac],
[enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
@@ -211,9 +213,9 @@ dnl AC_DEFUN([AM_DISABLE_SHARED], [])
# _LT_ENABLE_STATIC([DEFAULT])
# ----------------------------
-# implement the --enable-static flag, and support the `static' and
-# `disable-static' LT_INIT options.
-# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+# implement the --enable-static flag, and support the 'static' and
+# 'disable-static' LT_INIT options.
+# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
m4_define([_LT_ENABLE_STATIC],
[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([static],
@@ -226,14 +228,14 @@ AC_ARG_ENABLE([static],
*)
enable_static=no
# Look at the argument we got. We use all the common list separators.
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
for pkg in $enableval; do
- IFS="$lt_save_ifs"
+ IFS=$lt_save_ifs
if test "X$pkg" = "X$p"; then
enable_static=yes
fi
done
- IFS="$lt_save_ifs"
+ IFS=$lt_save_ifs
;;
esac],
[enable_static=]_LT_ENABLE_STATIC_DEFAULT)
@@ -265,9 +267,9 @@ dnl AC_DEFUN([AM_DISABLE_STATIC], [])
# _LT_ENABLE_FAST_INSTALL([DEFAULT])
# ----------------------------------
-# implement the --enable-fast-install flag, and support the `fast-install'
-# and `disable-fast-install' LT_INIT options.
-# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+# implement the --enable-fast-install flag, and support the 'fast-install'
+# and 'disable-fast-install' LT_INIT options.
+# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
m4_define([_LT_ENABLE_FAST_INSTALL],
[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([fast-install],
@@ -280,14 +282,14 @@ AC_ARG_ENABLE([fast-install],
*)
enable_fast_install=no
# Look at the argument we got. We use all the common list separators.
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
for pkg in $enableval; do
- IFS="$lt_save_ifs"
+ IFS=$lt_save_ifs
if test "X$pkg" = "X$p"; then
enable_fast_install=yes
fi
done
- IFS="$lt_save_ifs"
+ IFS=$lt_save_ifs
;;
esac],
[enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
@@ -304,14 +306,14 @@ AU_DEFUN([AC_ENABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
-the `fast-install' option into LT_INIT's first parameter.])
+the 'fast-install' option into LT_INIT's first parameter.])
])
AU_DEFUN([AC_DISABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
-the `disable-fast-install' option into LT_INIT's first parameter.])
+the 'disable-fast-install' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
@@ -319,11 +321,64 @@ dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
+# _LT_WITH_AIX_SONAME([DEFAULT])
+# ----------------------------------
+# implement the --with-aix-soname flag, and support the `aix-soname=aix'
+# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT
+# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'.
+m4_define([_LT_WITH_AIX_SONAME],
+[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl
+shared_archive_member_spec=
+case $host,$enable_shared in
+power*-*-aix[[5-9]]*,yes)
+ AC_MSG_CHECKING([which variant of shared library versioning to provide])
+ AC_ARG_WITH([aix-soname],
+ [AS_HELP_STRING([--with-aix-soname=aix|svr4|both],
+ [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])],
+ [case $withval in
+ aix|svr4|both)
+ ;;
+ *)
+ AC_MSG_ERROR([Unknown argument to --with-aix-soname])
+ ;;
+ esac
+ lt_cv_with_aix_soname=$with_aix_soname],
+ [AC_CACHE_VAL([lt_cv_with_aix_soname],
+ [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT)
+ with_aix_soname=$lt_cv_with_aix_soname])
+ AC_MSG_RESULT([$with_aix_soname])
+ if test aix != "$with_aix_soname"; then
+ # For the AIX way of multilib, we name the shared archive member
+ # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
+ # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
+ # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
+ # the AIX toolchain works better with OBJECT_MODE set (default 32).
+ if test 64 = "${OBJECT_MODE-32}"; then
+ shared_archive_member_spec=shr_64
+ else
+ shared_archive_member_spec=shr
+ fi
+ fi
+ ;;
+*)
+ with_aix_soname=aix
+ ;;
+esac
+
+_LT_DECL([], [shared_archive_member_spec], [0],
+ [Shared archive member basename, for filename based shared library versioning on AIX])dnl
+])# _LT_WITH_AIX_SONAME
+
+LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])])
+LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])])
+LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])])
+
+
# _LT_WITH_PIC([MODE])
# --------------------
-# implement the --with-pic flag, and support the `pic-only' and `no-pic'
+# implement the --with-pic flag, and support the 'pic-only' and 'no-pic'
# LT_INIT options.
-# MODE is either `yes' or `no'. If omitted, it defaults to `both'.
+# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'.
m4_define([_LT_WITH_PIC],
[AC_ARG_WITH([pic],
[AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
@@ -334,19 +389,17 @@ m4_define([_LT_WITH_PIC],
*)
pic_mode=default
# Look at the argument we got. We use all the common list separators.
- lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
for lt_pkg in $withval; do
- IFS="$lt_save_ifs"
+ IFS=$lt_save_ifs
if test "X$lt_pkg" = "X$lt_p"; then
pic_mode=yes
fi
done
- IFS="$lt_save_ifs"
+ IFS=$lt_save_ifs
;;
esac],
- [pic_mode=default])
-
-test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
+ [pic_mode=m4_default([$1], [default])])
_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
])# _LT_WITH_PIC
@@ -359,7 +412,7 @@ AU_DEFUN([AC_LIBTOOL_PICMODE],
[_LT_SET_OPTION([LT_INIT], [pic-only])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
-put the `pic-only' option into LT_INIT's first parameter.])
+put the 'pic-only' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
diff --git a/contrib/libxo/m4/ltversion.m4 b/contrib/libxo/m4/ltversion.m4
index 07a8602d48d6..fa04b52a3bf8 100644
--- a/contrib/libxo/m4/ltversion.m4
+++ b/contrib/libxo/m4/ltversion.m4
@@ -1,6 +1,6 @@
# ltversion.m4 -- version numbers -*- Autoconf -*-
#
-# Copyright (C) 2004 Free Software Foundation, Inc.
+# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc.
# Written by Scott James Remnant, 2004
#
# This file is free software; the Free Software Foundation gives
@@ -9,15 +9,15 @@
# @configure_input@
-# serial 3337 ltversion.m4
+# serial 4179 ltversion.m4
# This file is part of GNU Libtool
-m4_define([LT_PACKAGE_VERSION], [2.4.2])
-m4_define([LT_PACKAGE_REVISION], [1.3337])
+m4_define([LT_PACKAGE_VERSION], [2.4.6])
+m4_define([LT_PACKAGE_REVISION], [2.4.6])
AC_DEFUN([LTVERSION_VERSION],
-[macro_version='2.4.2'
-macro_revision='1.3337'
+[macro_version='2.4.6'
+macro_revision='2.4.6'
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
_LT_DECL(, macro_revision, 0)
])
diff --git a/contrib/libxo/tests/core/Makefile.am b/contrib/libxo/tests/core/Makefile.am
index f145d183d81c..92f5f364b74b 100644
--- a/contrib/libxo/tests/core/Makefile.am
+++ b/contrib/libxo/tests/core/Makefile.am
@@ -20,7 +20,8 @@ test_05.c \
test_06.c \
test_07.c \
test_08.c \
-test_09.c
+test_09.c \
+test_10.c
test_01_test_SOURCES = test_01.c
test_02_test_SOURCES = test_02.c
@@ -31,6 +32,7 @@ test_06_test_SOURCES = test_06.c
test_07_test_SOURCES = test_07.c
test_08_test_SOURCES = test_08.c
test_09_test_SOURCES = test_09.c
+test_10_test_SOURCES = test_10.c
# TEST_CASES := $(shell cd ${srcdir} ; echo *.c )
diff --git a/contrib/libxo/tests/core/saved/test_01.JP.out b/contrib/libxo/tests/core/saved/test_01.JP.out
index e1fd2318d670..479006525306 100644
--- a/contrib/libxo/tests/core/saved/test_01.JP.out
+++ b/contrib/libxo/tests/core/saved/test_01.JP.out
@@ -91,7 +91,11 @@
},
"data": {
"item": [
- "gum", "rope", "ladder", "bolt", "water"
+ "gum",
+ "rope",
+ "ladder",
+ "bolt",
+ "water"
]
},
"cost": 425,
diff --git a/contrib/libxo/tests/core/saved/test_02.JP.out b/contrib/libxo/tests/core/saved/test_02.JP.out
index 21b168bdad77..ade2dc22c81f 100644
--- a/contrib/libxo/tests/core/saved/test_02.JP.out
+++ b/contrib/libxo/tests/core/saved/test_02.JP.out
@@ -26,7 +26,9 @@
"cur": 20,
"max": 125,
"flag": [
- "one", "two", "three"
+ "one",
+ "two",
+ "three"
],
"empty-tag": true,
"t1": "1000",
diff --git a/contrib/libxo/tests/core/saved/test_05.H.out b/contrib/libxo/tests/core/saved/test_05.H.out
index b75d728878b4..136b95601ce8 100644
--- a/contrib/libxo/tests/core/saved/test_05.H.out
+++ b/contrib/libxo/tests/core/saved/test_05.H.out
@@ -1 +1 @@
-<div class="line"><div class="text">Οὐχὶ ταὐτὰ παρίσταταί μοι </div><div class="data" data-tag="v1">γιγνώσκειν</div><div class="text">, </div><div class="data" data-tag="v2">ὦ ἄνδρες ᾿Αθηναῖοι</div></div><div class="line"><div class="text">გთხოვთ </div><div class="data" data-tag="v1">ახლავე გაიაროთ რეგისტრაცია</div><div class="text"> </div><div class="data" data-tag="v2">Unicode-ის მეათე საერთაშორისო</div></div><div class="line"><div class="title">First Name </div><div class="title">Last Name </div><div class="title">Department </div><div class="title">Time (%)</div></div><div class="line"><div class="data" data-tag="first-name">Jim</div><div class="text"> (</div><div class="data" data-tag="nic-name">"რეგტ"</div><div class="text">)</div><div class="padding"> </div><div class="data" data-tag="last-name">გთხოვთ ახ </div><div class="data" data-tag="department"> 431</div><div class="data" data-tag="percent-time"> 90</div></div><div class="line"><div class="data" data-tag="first-name">Terry</div><div class="text"> (</div><div class="data" data-tag="nic-name">"&lt;one"</div><div class="text">)</div><div class="padding"> </div><div class="data" data-tag="last-name">Οὐχὶ ταὐτὰ παρ</div><div class="data" data-tag="department"> 660</div><div class="data" data-tag="percent-time"> 90</div></div><div class="line"><div class="data" data-tag="first-name">Leslie</div><div class="text"> (</div><div class="data" data-tag="nic-name">"Les"</div><div class="text">)</div><div class="padding"> </div><div class="data" data-tag="last-name">Patterson </div><div class="data" data-tag="department"> 341</div><div class="data" data-tag="percent-time"> 60</div></div><div class="line"><div class="data" data-tag="first-name">Ashley</div><div class="text"> (</div><div class="data" data-tag="nic-name">"Ash"</div><div class="text">)</div><div class="padding"> </div><div class="data" data-tag="last-name">Meter &amp; Smith </div><div class="data" data-tag="department"> 1440</div><div class="data" data-tag="percent-time"> 40</div></div><div class="line"><div class="data" data-tag="first-name">0123456789</div><div class="text"> (</div><div class="data" data-tag="nic-name">"0123456789"</div><div class="text">)</div><div class="data" data-tag="last-name">01234567890123</div><div class="data" data-tag="department"> 1440</div><div class="data" data-tag="percent-time"> 40</div></div><div class="line"><div class="data" data-tag="first-name">ახლა</div><div class="text"> (</div><div class="data" data-tag="nic-name">"გაიარო"</div><div class="text">)</div><div class="padding"> </div><div class="data" data-tag="last-name">საერთაშორისო </div><div class="data" data-tag="department"> 123</div><div class="data" data-tag="percent-time"> 90</div></div> \ No newline at end of file
+<div class="line"><div class="text">Οὐχὶ ταὐτὰ παρίσταταί μοι </div><div class="data" data-tag="v1">γιγνώσκειν</div><div class="text">, </div><div class="data" data-tag="v2">ὦ ἄνδρες ᾿Αθηναῖοι</div></div><div class="line"><div class="text">გთხოვთ </div><div class="data" data-tag="v1">ახლავე გაიაროთ რეგისტრაცია</div><div class="text"> </div><div class="data" data-tag="v2">Unicode-ის მეათე საერთაშორისო</div></div><div class="line"><div class="title">Width</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="width">63</div></div><div class="line"><div class="text">[</div><div class="data" data-tag="sinhala">෴ණ්ණ෴</div><div class="text">]</div></div><div class="line"><div class="title">Width</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="width">7</div></div><div class="line"><div class="text">[</div><div class="data" data-tag="sinhala">෴</div><div class="text">]</div></div><div class="line"><div class="title">Width</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="width">3</div></div><div class="line"><div class="text">[</div><div class="data" data-tag="sinhala">෴ණ්ණ</div><div class="text">]</div></div><div class="line"><div class="text">[</div><div class="data" data-tag="not-sinhala">1234</div><div class="text">]</div></div><div class="line"><div class="text">[</div><div class="data" data-tag="tag">ර්‍ඝ</div><div class="text">]</div></div><div class="line"><div class="title">Width</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="width">5</div></div><div class="line"><div class="title">First Name </div><div class="title">Last Name </div><div class="title">Department </div><div class="title">Time (%)</div></div><div class="line"><div class="data" data-tag="first-name">Jim</div><div class="text"> (</div><div class="data" data-tag="nic-name">"რეგტ"</div><div class="text">)</div><div class="padding"> </div><div class="data" data-tag="last-name">გთხოვთ ახ </div><div class="data" data-tag="department"> 431</div><div class="data" data-tag="percent-time"> 90</div></div><div class="line"><div class="data" data-tag="first-name">Terry</div><div class="text"> (</div><div class="data" data-tag="nic-name">"&lt;one"</div><div class="text">)</div><div class="padding"> </div><div class="data" data-tag="last-name">Οὐχὶ ταὐτὰ παρ</div><div class="data" data-tag="department"> 660</div><div class="data" data-tag="percent-time"> 90</div></div><div class="line"><div class="data" data-tag="first-name">Leslie</div><div class="text"> (</div><div class="data" data-tag="nic-name">"Les"</div><div class="text">)</div><div class="padding"> </div><div class="data" data-tag="last-name">Patterson </div><div class="data" data-tag="department"> 341</div><div class="data" data-tag="percent-time"> 60</div></div><div class="line"><div class="data" data-tag="first-name">Ashley</div><div class="text"> (</div><div class="data" data-tag="nic-name">"Ash"</div><div class="text">)</div><div class="padding"> </div><div class="data" data-tag="last-name">Meter &amp; Smith </div><div class="data" data-tag="department"> 1440</div><div class="data" data-tag="percent-time"> 40</div></div><div class="line"><div class="data" data-tag="first-name">0123456789</div><div class="text"> (</div><div class="data" data-tag="nic-name">"0123456789"</div><div class="text">)</div><div class="data" data-tag="last-name">01234567890123</div><div class="data" data-tag="department"> 1440</div><div class="data" data-tag="percent-time"> 40</div></div><div class="line"><div class="data" data-tag="first-name">ახლა</div><div class="text"> (</div><div class="data" data-tag="nic-name">"გაიარო"</div><div class="text">)</div><div class="padding"> </div><div class="data" data-tag="last-name">საერთაშორისო </div><div class="data" data-tag="department"> 123</div><div class="data" data-tag="percent-time"> 90</div></div><div class="line"><div class="data" data-tag="first-name">෴ණ්ණ෴෴ණ්ණ෴</div><div class="text"> (</div><div class="data" data-tag="nic-name">"Mick"</div><div class="text">)</div><div class="padding"> </div><div class="data" data-tag="last-name">෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ</div><div class="data" data-tag="department"> 110</div><div class="data" data-tag="percent-time"> 20</div></div> \ No newline at end of file
diff --git a/contrib/libxo/tests/core/saved/test_05.HIPx.out b/contrib/libxo/tests/core/saved/test_05.HIPx.out
index 2054de13b7f4..105f8482785e 100644
--- a/contrib/libxo/tests/core/saved/test_05.HIPx.out
+++ b/contrib/libxo/tests/core/saved/test_05.HIPx.out
@@ -11,6 +11,55 @@
<div class="data" data-tag="v2" data-xpath="/employees/v2">Unicode-ის მეათე საერთაშორისო</div>
</div>
<div class="line">
+ <div class="title">Width</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="width" data-xpath="/employees/width">63</div>
+</div>
+<div class="line">
+ <div class="text">[</div>
+ <div class="data" data-tag="sinhala" data-xpath="/employees/sinhala">෴ණ්ණ෴</div>
+ <div class="text">]</div>
+</div>
+<div class="line">
+ <div class="title">Width</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="width" data-xpath="/employees/width">7</div>
+</div>
+<div class="line">
+ <div class="text">[</div>
+ <div class="data" data-tag="sinhala" data-xpath="/employees/sinhala">෴</div>
+ <div class="text">]</div>
+</div>
+<div class="line">
+ <div class="title">Width</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="width" data-xpath="/employees/width">3</div>
+</div>
+<div class="line">
+ <div class="text">[</div>
+ <div class="data" data-tag="sinhala" data-xpath="/employees/sinhala">෴ණ්ණ</div>
+ <div class="text">]</div>
+</div>
+<div class="line">
+ <div class="text">[</div>
+ <div class="data" data-tag="not-sinhala" data-xpath="/employees/not-sinhala">1234</div>
+ <div class="text">]</div>
+</div>
+<div class="line">
+ <div class="text">[</div>
+ <div class="data" data-tag="tag" data-xpath="/employees/tag">ර්‍ඝ</div>
+ <div class="text">]</div>
+</div>
+<div class="line">
+ <div class="title">Width</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="width" data-xpath="/employees/width">5</div>
+</div>
+<div class="line">
<div class="title">First Name </div>
<div class="title">Last Name </div>
<div class="title">Department </div>
@@ -75,3 +124,13 @@
<div class="data" data-tag="department" data-xpath="/employees/employee/department"> 123</div>
<div class="data" data-tag="percent-time" data-xpath="/employees/employee/percent-time" data-type="number" data-help="Percentage of full &amp; part time (%)"> 90</div>
</div>
+<div class="line">
+ <div class="data" data-tag="first-name" data-xpath="/employees/employee/first-name" data-type="string" data-help="First name of employee">෴ණ්ණ෴෴ණ්ණ෴</div>
+ <div class="text"> (</div>
+ <div class="data" data-tag="nic-name" data-xpath="/employees/employee/nic-name">"Mick"</div>
+ <div class="text">)</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="last-name" data-xpath="/employees/employee/last-name" data-type="string" data-help="Last name of employee">෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ</div>
+ <div class="data" data-tag="department" data-xpath="/employees/employee/department"> 110</div>
+ <div class="data" data-tag="percent-time" data-xpath="/employees/employee/percent-time" data-type="number" data-help="Percentage of full &amp; part time (%)"> 20</div>
+</div>
diff --git a/contrib/libxo/tests/core/saved/test_05.HP.out b/contrib/libxo/tests/core/saved/test_05.HP.out
index 1c34b950ba2f..e66cf2b59642 100644
--- a/contrib/libxo/tests/core/saved/test_05.HP.out
+++ b/contrib/libxo/tests/core/saved/test_05.HP.out
@@ -11,6 +11,55 @@
<div class="data" data-tag="v2">Unicode-ის მეათე საერთაშორისო</div>
</div>
<div class="line">
+ <div class="title">Width</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="width">63</div>
+</div>
+<div class="line">
+ <div class="text">[</div>
+ <div class="data" data-tag="sinhala">෴ණ්ණ෴</div>
+ <div class="text">]</div>
+</div>
+<div class="line">
+ <div class="title">Width</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="width">7</div>
+</div>
+<div class="line">
+ <div class="text">[</div>
+ <div class="data" data-tag="sinhala">෴</div>
+ <div class="text">]</div>
+</div>
+<div class="line">
+ <div class="title">Width</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="width">3</div>
+</div>
+<div class="line">
+ <div class="text">[</div>
+ <div class="data" data-tag="sinhala">෴ණ්ණ</div>
+ <div class="text">]</div>
+</div>
+<div class="line">
+ <div class="text">[</div>
+ <div class="data" data-tag="not-sinhala">1234</div>
+ <div class="text">]</div>
+</div>
+<div class="line">
+ <div class="text">[</div>
+ <div class="data" data-tag="tag">ර්‍ඝ</div>
+ <div class="text">]</div>
+</div>
+<div class="line">
+ <div class="title">Width</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="width">5</div>
+</div>
+<div class="line">
<div class="title">First Name </div>
<div class="title">Last Name </div>
<div class="title">Department </div>
@@ -75,3 +124,13 @@
<div class="data" data-tag="department"> 123</div>
<div class="data" data-tag="percent-time"> 90</div>
</div>
+<div class="line">
+ <div class="data" data-tag="first-name">෴ණ්ණ෴෴ණ්ණ෴</div>
+ <div class="text"> (</div>
+ <div class="data" data-tag="nic-name">"Mick"</div>
+ <div class="text">)</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="last-name">෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ</div>
+ <div class="data" data-tag="department"> 110</div>
+ <div class="data" data-tag="percent-time"> 20</div>
+</div>
diff --git a/contrib/libxo/tests/core/saved/test_05.J.out b/contrib/libxo/tests/core/saved/test_05.J.out
index 515548954ac9..25d13ea03037 100644
--- a/contrib/libxo/tests/core/saved/test_05.J.out
+++ b/contrib/libxo/tests/core/saved/test_05.J.out
@@ -1,2 +1,2 @@
-{"employees": {"v1":"γιγνώσκειν","v2":"ὦ ἄνδρες ᾿Αθηναῖοι","v1":"ახლავე გაიაროთ რეგისტრაცია","v2":"Unicode-ის მეათე საერთაშორისო", "employee": [{"first-name":"Jim","nic-name":"\"რეგტ\"","last-name":"გთხოვთ ახ","department":431,"percent-time":90,"benefits":"full"}, {"first-name":"Terry","nic-name":"\"<one\"","last-name":"Οὐχὶ ταὐτὰ παρίσταταί μοι Jones","department":660,"percent-time":90,"benefits":"full"}, {"first-name":"Leslie","nic-name":"\"Les\"","last-name":"Patterson","department":341,"percent-time":60,"benefits":"full"}, {"first-name":"Ashley","nic-name":"\"Ash\"","last-name":"Meter & Smith","department":1440,"percent-time":40}, {"first-name":"0123456789","nic-name":"\"0123456789\"","last-name":"012345678901234567890","department":1440,"percent-time":40}, {"first-name":"ახლა","nic-name":"\"გაიარო\"","last-name":"საერთაშორისო","department":123,"percent-time":90,"benefits":"full"}]}
+{"employees": {"v1":"γιγνώσκειν","v2":"ὦ ἄνδρες ᾿Αθηναῖοι","v1":"ახლავე გაიაროთ რეგისტრაცია","v2":"Unicode-ის მეათე საერთაშორისო","width":55,"sinhala":"෴ණ්ණ෴","width":5,"sinhala":"෴","width":1,"sinhala":"෴ණ්ණ෴෴ණ්ණ෴","not-sinhala":"123456","tag":"ර්‍ඝ","width":3, "employee": [{"first-name":"Jim","nic-name":"\"რეგტ\"","last-name":"გთხოვთ ახ","department":431,"percent-time":90,"benefits":"full"}, {"first-name":"Terry","nic-name":"\"<one\"","last-name":"Οὐχὶ ταὐτὰ παρίσταταί μοι Jones","department":660,"percent-time":90,"benefits":"full"}, {"first-name":"Leslie","nic-name":"\"Les\"","last-name":"Patterson","department":341,"percent-time":60,"benefits":"full"}, {"first-name":"Ashley","nic-name":"\"Ash\"","last-name":"Meter & Smith","department":1440,"percent-time":40}, {"first-name":"0123456789","nic-name":"\"0123456789\"","last-name":"012345678901234567890","department":1440,"percent-time":40}, {"first-name":"ახლა","nic-name":"\"გაიარო\"","last-name":"საერთაშორისო","department":123,"percent-time":90,"benefits":"full"}, {"first-name":"෴ණ්ණ෴෴ණ්ණ෴","nic-name":"\"Mick\"","last-name":"෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴","department":110,"percent-time":20}]}
}
diff --git a/contrib/libxo/tests/core/saved/test_05.JP.out b/contrib/libxo/tests/core/saved/test_05.JP.out
index 7d77d70cae7b..c3219172d6f3 100644
--- a/contrib/libxo/tests/core/saved/test_05.JP.out
+++ b/contrib/libxo/tests/core/saved/test_05.JP.out
@@ -4,6 +4,15 @@
"v2": "ὦ ἄνδρες ᾿Αθηναῖοι",
"v1": "ახლავე გაიაროთ რეგისტრაცია",
"v2": "Unicode-ის მეათე საერთაშორისო",
+ "width": 55,
+ "sinhala": "෴ණ්ණ෴",
+ "width": 5,
+ "sinhala": "෴",
+ "width": 1,
+ "sinhala": "෴ණ්ණ෴෴ණ්ණ෴",
+ "not-sinhala": "123456",
+ "tag": "ර්‍ඝ",
+ "width": 3,
"employee": [
{
"first-name": "Jim",
@@ -50,6 +59,13 @@
"department": 123,
"percent-time": 90,
"benefits": "full"
+ },
+ {
+ "first-name": "෴ණ්ණ෴෴ණ්ණ෴",
+ "nic-name": "\"Mick\"",
+ "last-name": "෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴",
+ "department": 110,
+ "percent-time": 20
}
]
}
diff --git a/contrib/libxo/tests/core/saved/test_05.T.out b/contrib/libxo/tests/core/saved/test_05.T.out
index c709f6cbb216..db713a6b0c06 100644
--- a/contrib/libxo/tests/core/saved/test_05.T.out
+++ b/contrib/libxo/tests/core/saved/test_05.T.out
@@ -1,5 +1,14 @@
Οὐχὶ ταὐτὰ παρίσταταί μοι γιγνώσκειν, ὦ ἄνδρες ᾿Αθηναῖοι
გთხოვთ ახლავე გაიაროთ რეგისტრაცია Unicode-ის მეათე საერთაშორისო
+Width: 63
+[෴ණ්ණ෴]
+Width: 7
+[෴]
+Width: 3
+[෴ණ්ණ]
+[1234]
+[ර්‍ඝ]
+Width: 5
First Name Last Name Department Time (%)
Jim ("რეგტ") გთხოვთ ახ 431 90
Terry ("<one") Οὐχὶ ταὐτὰ παρ 660 90
@@ -7,3 +16,4 @@ Leslie ("Les") Patterson 341 60
Ashley ("Ash") Meter & Smith 1440 40
0123456789 ("0123456789")01234567890123 1440 40
ახლა ("გაიარო") საერთაშორისო 123 90
+෴ණ්ණ෴෴ණ්ණ෴ ("Mick") ෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ 110 20
diff --git a/contrib/libxo/tests/core/saved/test_05.X.out b/contrib/libxo/tests/core/saved/test_05.X.out
index 85ecbbcf62af..7cd29260de26 100644
--- a/contrib/libxo/tests/core/saved/test_05.X.out
+++ b/contrib/libxo/tests/core/saved/test_05.X.out
@@ -1 +1 @@
-<employees><v1>γιγνώσκειν</v1><v2>ὦ ἄνδρες ᾿Αθηναῖοι</v2><v1>ახლავე გაიაროთ რეგისტრაცია</v1><v2>Unicode-ის მეათე საერთაშორისო</v2><employee><first-name>Jim</first-name><nic-name>"რეგტ"</nic-name><last-name>გთხოვთ ახ</last-name><department>431</department><percent-time>90</percent-time><benefits full-time="honest &amp; for true">full</benefits></employee><employee><first-name>Terry</first-name><nic-name>"&lt;one"</nic-name><last-name>Οὐχὶ ταὐτὰ παρίσταταί μοι Jones</last-name><department>660</department><percent-time>90</percent-time><benefits full-time="honest &amp; for true">full</benefits></employee><employee><first-name>Leslie</first-name><nic-name>"Les"</nic-name><last-name>Patterson</last-name><department>341</department><percent-time>60</percent-time><benefits full-time="honest &amp; for true">full</benefits></employee><employee><first-name>Ashley</first-name><nic-name>"Ash"</nic-name><last-name>Meter &amp; Smith</last-name><department>1440</department><percent-time>40</percent-time></employee><employee><first-name>0123456789</first-name><nic-name>"0123456789"</nic-name><last-name>012345678901234567890</last-name><department>1440</department><percent-time>40</percent-time></employee><employee><first-name>ახლა</first-name><nic-name>"გაიარო"</nic-name><last-name>საერთაშორისო</last-name><department>123</department><percent-time>90</percent-time><benefits full-time="honest &amp; for true">full</benefits></employee></employees> \ No newline at end of file
+<employees><v1>γιγνώσκειν</v1><v2>ὦ ἄνδρες ᾿Αθηναῖοι</v2><v1>ახლავე გაიაროთ რეგისტრაცია</v1><v2>Unicode-ის მეათე საერთაშორისო</v2><width>55</width><sinhala>෴ණ්ණ෴</sinhala><width>5</width><sinhala>෴</sinhala><width>1</width><sinhala>෴ණ්ණ෴෴ණ්ණ෴</sinhala><not-sinhala>123456</not-sinhala><tag>ර්‍ඝ</tag><width>3</width><employee><first-name>Jim</first-name><nic-name>"რეგტ"</nic-name><last-name>გთხოვთ ახ</last-name><department>431</department><percent-time>90</percent-time><benefits full-time="honest &amp; for true">full</benefits></employee><employee><first-name>Terry</first-name><nic-name>"&lt;one"</nic-name><last-name>Οὐχὶ ταὐτὰ παρίσταταί μοι Jones</last-name><department>660</department><percent-time>90</percent-time><benefits full-time="honest &amp; for true">full</benefits></employee><employee><first-name>Leslie</first-name><nic-name>"Les"</nic-name><last-name>Patterson</last-name><department>341</department><percent-time>60</percent-time><benefits full-time="honest &amp; for true">full</benefits></employee><employee><first-name>Ashley</first-name><nic-name>"Ash"</nic-name><last-name>Meter &amp; Smith</last-name><department>1440</department><percent-time>40</percent-time></employee><employee><first-name>0123456789</first-name><nic-name>"0123456789"</nic-name><last-name>012345678901234567890</last-name><department>1440</department><percent-time>40</percent-time></employee><employee><first-name>ახლა</first-name><nic-name>"გაიარო"</nic-name><last-name>საერთაშორისო</last-name><department>123</department><percent-time>90</percent-time><benefits full-time="honest &amp; for true">full</benefits></employee><employee><first-name>෴ණ්ණ෴෴ණ්ණ෴</first-name><nic-name>"Mick"</nic-name><last-name>෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴</last-name><department>110</department><percent-time>20</percent-time></employee></employees> \ No newline at end of file
diff --git a/contrib/libxo/tests/core/saved/test_05.XP.out b/contrib/libxo/tests/core/saved/test_05.XP.out
index 55507eb42a48..6ef573f3a8ba 100644
--- a/contrib/libxo/tests/core/saved/test_05.XP.out
+++ b/contrib/libxo/tests/core/saved/test_05.XP.out
@@ -3,6 +3,15 @@
<v2>ὦ ἄνδρες ᾿Αθηναῖοι</v2>
<v1>ახლავე გაიაროთ რეგისტრაცია</v1>
<v2>Unicode-ის მეათე საერთაშორისო</v2>
+ <width>55</width>
+ <sinhala>෴ණ්ණ෴</sinhala>
+ <width>5</width>
+ <sinhala>෴</sinhala>
+ <width>1</width>
+ <sinhala>෴ණ්ණ෴෴ණ්ණ෴</sinhala>
+ <not-sinhala>123456</not-sinhala>
+ <tag>ර්‍ඝ</tag>
+ <width>3</width>
<employee>
<first-name>Jim</first-name>
<nic-name>"რეგტ"</nic-name>
@@ -49,4 +58,11 @@
<percent-time>90</percent-time>
<benefits full-time="honest &amp; for true">full</benefits>
</employee>
+ <employee>
+ <first-name>෴ණ්ණ෴෴ණ්ණ෴</first-name>
+ <nic-name>"Mick"</nic-name>
+ <last-name>෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴</last-name>
+ <department>110</department>
+ <percent-time>20</percent-time>
+ </employee>
</employees>
diff --git a/contrib/libxo/tests/core/saved/test_09.JP.out b/contrib/libxo/tests/core/saved/test_09.JP.out
index 8340b275606b..48e20c146673 100644
--- a/contrib/libxo/tests/core/saved/test_09.JP.out
+++ b/contrib/libxo/tests/core/saved/test_09.JP.out
@@ -3,22 +3,34 @@
"data": {
"contents": {
"name": [
- "gum", "rope", "ladder", "bolt", "water"
+ "gum",
+ "rope",
+ "ladder",
+ "bolt",
+ "water"
]
},
"contents": {
"item": [
- "gum", "rope", "ladder", "bolt", "water"
+ "gum",
+ "rope",
+ "ladder",
+ "bolt",
+ "water"
]
},
"contents": {
"item": [
- "gum", "rope", "ladder", "bolt", "water"
+ "gum",
+ "rope",
+ "ladder",
+ "bolt",
+ "water"
],
"total": "six",
"one": "one",
"two": [
- "two"
+ "two"
],
"three": "three"
}
diff --git a/contrib/libxo/tests/core/saved/test_10.H.err b/contrib/libxo/tests/core/saved/test_10.H.err
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/contrib/libxo/tests/core/saved/test_10.H.err
diff --git a/contrib/libxo/tests/core/saved/test_10.H.out b/contrib/libxo/tests/core/saved/test_10.H.out
new file mode 100644
index 000000000000..d4ec07da82e6
--- /dev/null
+++ b/contrib/libxo/tests/core/saved/test_10.H.out
@@ -0,0 +1 @@
+<div class="line"><div class="title color-fg-blue">blue</div><div class="title color-fg-green color-bg-blue">green</div><div class="title color-fg-red color-bg-green">red</div><div class="title color-fg-yellow color-bg-red">yellow</div><div class="title color-bg-yellow">default</div></div><div class="line"><div class="data effect-bold" data-tag="data">bold</div><div class="text effect-bold"> </div><div class="data effect-bold effect-underline" data-tag="data">bold-ul</div><div class="text effect-bold effect-underline"> </div><div class="data effect-bold effect-underline effect-inverse color-fg-inverse color-bg-inverse" data-tag="data">triple</div><div class="text effect-bold effect-underline effect-inverse color-fg-inverse color-bg-inverse"> </div><div class="data effect-underline effect-inverse color-fg-inverse color-bg-inverse" data-tag="data">inv-ul</div><div class="text effect-underline effect-inverse color-fg-inverse color-bg-inverse"> </div><div class="data effect-underline" data-tag="data">underline</div><div class="text effect-underline"> </div><div class="data" data-tag="data">plain</div></div><div class="line"><div class="title">Item </div><div class="title effect-bold effect-underline"> Total Sold</div><div class="title effect-underline"> In Stock</div><div class="title effect-underline effect-inverse color-fg-inverse color-bg-inverse"> On Order</div><div class="title"> SKU</div></div><div class="line"><div class="data" data-tag="name" data-key="key">gum </div><div class="data" data-tag="sold"> 1412</div><div class="data" data-tag="in-stock"> 54</div><div class="data color-fg-yellow" data-tag="on-order"> 10</div><div class="data" data-tag="sku" data-key="key"> GRO-000-415</div></div><div class="line"><div class="data" data-tag="name" data-key="key">rope </div><div class="data" data-tag="sold"> 85</div><div class="data effect-inverse color-fg-inverse color-bg-inverse" data-tag="in-stock"> 4</div><div class="data" data-tag="on-order"> 2</div><div class="data" data-tag="sku" data-key="key"> HRD-000-212</div></div><div class="line"><div class="data" data-tag="name" data-key="key">ladder </div><div class="data" data-tag="sold"> 0</div><div class="data effect-inverse color-fg-inverse color-bg-inverse" data-tag="in-stock"> 2</div><div class="data" data-tag="on-order"> 1</div><div class="data" data-tag="sku" data-key="key"> HRD-000-517</div></div><div class="line"><div class="data" data-tag="name" data-key="key">bolt </div><div class="data" data-tag="sold"> 4123</div><div class="data" data-tag="in-stock"> 144</div><div class="data color-fg-yellow" data-tag="on-order"> 42</div><div class="data" data-tag="sku" data-key="key"> HRD-000-632</div></div><div class="line"><div class="data" data-tag="name" data-key="key">water </div><div class="data" data-tag="sold"> 17</div><div class="data" data-tag="in-stock"> 14</div><div class="data" data-tag="on-order"> 2</div><div class="data" data-tag="sku" data-key="key"> GRO-000-2331</div></div><div class="line"></div><div class="line"></div><div class="line"><div class="label">Item</div><div class="text"> '</div><div class="data" data-tag="name" data-key="key">gum</div><div class="text">':</div></div><div class="line"><div class="padding"> </div><div class="label">Total sold</div><div class="text">: </div><div class="data" data-tag="sold">1412.0</div></div><div class="line"><div class="padding"> </div><div class="label">In stock</div><div class="decoration">:</div><div class="padding"> </div><div class="data effect-inverse color-fg-inverse color-bg-inverse" data-tag="in-stock">54</div></div><div class="line"><div class="padding"> </div><div class="label">On order</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="on-order">10</div></div><div class="line"><div class="padding"> </div><div class="label">SKU</div><div class="text">: </div><div class="data" data-tag="sku" data-key="key">GRO-000-415</div></div><div class="line"><div class="label">Item</div><div class="text"> '</div><div class="data" data-tag="name" data-key="key">rope</div><div class="text">':</div></div><div class="line"><div class="padding"> </div><div class="label">Total sold</div><div class="text">: </div><div class="data" data-tag="sold">85.0</div></div><div class="line"><div class="padding"> </div><div class="label">In stock</div><div class="decoration">:</div><div class="padding"> </div><div class="data effect-inverse color-fg-inverse color-bg-inverse" data-tag="in-stock">4</div></div><div class="line"><div class="padding"> </div><div class="label">On order</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="on-order">2</div></div><div class="line"><div class="padding"> </div><div class="label">SKU</div><div class="text">: </div><div class="data" data-tag="sku" data-key="key">HRD-000-212</div></div><div class="line"><div class="label">Item</div><div class="text"> '</div><div class="data" data-tag="name" data-key="key">ladder</div><div class="text">':</div></div><div class="line"><div class="padding"> </div><div class="label">Total sold</div><div class="text">: </div><div class="data" data-tag="sold">0</div></div><div class="line"><div class="padding"> </div><div class="label">In stock</div><div class="decoration">:</div><div class="padding"> </div><div class="data effect-inverse color-fg-inverse color-bg-inverse" data-tag="in-stock">2</div></div><div class="line"><div class="padding"> </div><div class="label">On order</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="on-order">1</div></div><div class="line"><div class="padding"> </div><div class="label">SKU</div><div class="text">: </div><div class="data" data-tag="sku" data-key="key">HRD-000-517</div></div><div class="line"><div class="label">Item</div><div class="text"> '</div><div class="data" data-tag="name" data-key="key">bolt</div><div class="text">':</div></div><div class="line"><div class="padding"> </div><div class="label">Total sold</div><div class="text">: </div><div class="data" data-tag="sold">4123.0</div></div><div class="line"><div class="padding"> </div><div class="label">In stock</div><div class="decoration">:</div><div class="padding"> </div><div class="data effect-inverse color-fg-inverse color-bg-inverse" data-tag="in-stock">144</div></div><div class="line"><div class="padding"> </div><div class="label">On order</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="on-order">42</div></div><div class="line"><div class="padding"> </div><div class="label">SKU</div><div class="text">: </div><div class="data" data-tag="sku" data-key="key">HRD-000-632</div></div><div class="line"><div class="label">Item</div><div class="text"> '</div><div class="data" data-tag="name" data-key="key">water</div><div class="text">':</div></div><div class="line"><div class="padding"> </div><div class="label">Total sold</div><div class="text">: </div><div class="data" data-tag="sold">17.0</div></div><div class="line"><div class="padding"> </div><div class="label">In stock</div><div class="decoration">:</div><div class="padding"> </div><div class="data effect-inverse color-fg-inverse color-bg-inverse" data-tag="in-stock">14</div></div><div class="line"><div class="padding"> </div><div class="label">On order</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="on-order">2</div></div><div class="line"><div class="padding"> </div><div class="label">SKU</div><div class="text">: </div><div class="data" data-tag="sku" data-key="key">GRO-000-2331</div></div><div class="line"><div class="label">Item</div><div class="text"> '</div><div class="data" data-tag="name" data-key="key">fish</div><div class="text">':</div></div><div class="line"><div class="padding"> </div><div class="label effect-bold color-fg-white color-bg-blue">Total sold</div><div class="text effect-bold color-fg-white color-bg-blue">: </div><div class="data effect-bold color-fg-white color-bg-blue" data-tag="sold">1321.0</div></div><div class="line"><div class="padding"> </div><div class="label">In stock</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="in-stock">45</div></div><div class="line"><div class="padding"> </div><div class="label">On order</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="on-order">1</div></div><div class="line"><div class="padding"> </div><div class="label">SKU</div><div class="text">: </div><div class="data" data-tag="sku" data-key="key">GRO-000-533</div></div><div class="line"><div class="label">Item</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="item">gum</div></div><div class="line"><div class="label">Item</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="item">rope</div></div><div class="line"><div class="label">Item</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="item">ladder</div></div><div class="line"><div class="label">Item</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="item">bolt</div></div><div class="line"><div class="label">Item</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="item">water</div></div><div class="line"><div class="text">X</div><div class="text">X</div><div class="text">X</div><div class="text">X</div><div class="text">X</div><div class="text">X</div><div class="text">X</div><div class="text">X</div></div><div class="line"><div class="text">X</div><div class="padding"> </div><div class="text">X</div><div class="label">Cost</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="cost">425</div></div><div class="line"><div class="text">X</div><div class="padding"> </div><div class="text">X</div><div class="label">Cost</div><div class="decoration">:</div><div class="padding"> </div><div class="data" data-tag="cost">455</div></div> \ No newline at end of file
diff --git a/contrib/libxo/tests/core/saved/test_10.HIPx.err b/contrib/libxo/tests/core/saved/test_10.HIPx.err
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/contrib/libxo/tests/core/saved/test_10.HIPx.err
diff --git a/contrib/libxo/tests/core/saved/test_10.HIPx.out b/contrib/libxo/tests/core/saved/test_10.HIPx.out
new file mode 100644
index 000000000000..ef64173f54a5
--- /dev/null
+++ b/contrib/libxo/tests/core/saved/test_10.HIPx.out
@@ -0,0 +1,316 @@
+<div class="line">
+ <div class="title color-fg-blue">blue</div>
+ <div class="title color-fg-green color-bg-blue">green</div>
+ <div class="title color-fg-red color-bg-green">red</div>
+ <div class="title color-fg-yellow color-bg-red">yellow</div>
+ <div class="title color-bg-yellow">default</div>
+</div>
+<div class="line">
+ <div class="data effect-bold" data-tag="data" data-xpath="/top/data/data">bold</div>
+ <div class="text effect-bold"> </div>
+ <div class="data effect-bold effect-underline" data-tag="data" data-xpath="/top/data/data">bold-ul</div>
+ <div class="text effect-bold effect-underline"> </div>
+ <div class="data effect-bold effect-underline effect-inverse color-fg-inverse color-bg-inverse" data-tag="data" data-xpath="/top/data/data">triple</div>
+ <div class="text effect-bold effect-underline effect-inverse color-fg-inverse color-bg-inverse"> </div>
+ <div class="data effect-underline effect-inverse color-fg-inverse color-bg-inverse" data-tag="data" data-xpath="/top/data/data">inv-ul</div>
+ <div class="text effect-underline effect-inverse color-fg-inverse color-bg-inverse"> </div>
+ <div class="data effect-underline" data-tag="data" data-xpath="/top/data/data">underline</div>
+ <div class="text effect-underline"> </div>
+ <div class="data" data-tag="data" data-xpath="/top/data/data">plain</div>
+</div>
+<div class="line">
+ <div class="title">Item </div>
+ <div class="title effect-bold effect-underline"> Total Sold</div>
+ <div class="title effect-underline"> In Stock</div>
+ <div class="title effect-underline effect-inverse color-fg-inverse color-bg-inverse"> On Order</div>
+ <div class="title"> SKU</div>
+</div>
+<div class="line">
+ <div class="data" data-tag="name" data-xpath="/top/data/item/name" data-type="string" data-help="Name of the item" data-key="key">gum </div>
+ <div class="data" data-tag="sold" data-xpath="/top/data/item[sku = 'GRO-000-415'][name = 'gum']/sold" data-type="number" data-help="Number of items sold"> 1412</div>
+ <div class="data" data-tag="in-stock" data-xpath="/top/data/item[sku = 'GRO-000-415'][name = 'gum']/in-stock" data-type="number" data-help="Number of items in stock"> 54</div>
+ <div class="data color-fg-yellow" data-tag="on-order" data-xpath="/top/data/item[sku = 'GRO-000-415'][name = 'gum']/on-order" data-type="number" data-help="Number of items on order"> 10</div>
+ <div class="data" data-tag="sku" data-xpath="/top/data/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key"> GRO-000-415</div>
+</div>
+<div class="line">
+ <div class="data" data-tag="name" data-xpath="/top/data/item/name" data-type="string" data-help="Name of the item" data-key="key">rope </div>
+ <div class="data" data-tag="sold" data-xpath="/top/data/item[sku = 'HRD-000-212'][name = 'rope']/sold" data-type="number" data-help="Number of items sold"> 85</div>
+ <div class="data effect-inverse color-fg-inverse color-bg-inverse" data-tag="in-stock" data-xpath="/top/data/item[sku = 'HRD-000-212'][name = 'rope']/in-stock" data-type="number" data-help="Number of items in stock"> 4</div>
+ <div class="data" data-tag="on-order" data-xpath="/top/data/item[sku = 'HRD-000-212'][name = 'rope']/on-order" data-type="number" data-help="Number of items on order"> 2</div>
+ <div class="data" data-tag="sku" data-xpath="/top/data/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key"> HRD-000-212</div>
+</div>
+<div class="line">
+ <div class="data" data-tag="name" data-xpath="/top/data/item/name" data-type="string" data-help="Name of the item" data-key="key">ladder </div>
+ <div class="data" data-tag="sold" data-xpath="/top/data/item[sku = 'HRD-000-517'][name = 'ladder']/sold" data-type="number" data-help="Number of items sold"> 0</div>
+ <div class="data effect-inverse color-fg-inverse color-bg-inverse" data-tag="in-stock" data-xpath="/top/data/item[sku = 'HRD-000-517'][name = 'ladder']/in-stock" data-type="number" data-help="Number of items in stock"> 2</div>
+ <div class="data" data-tag="on-order" data-xpath="/top/data/item[sku = 'HRD-000-517'][name = 'ladder']/on-order" data-type="number" data-help="Number of items on order"> 1</div>
+ <div class="data" data-tag="sku" data-xpath="/top/data/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key"> HRD-000-517</div>
+</div>
+<div class="line">
+ <div class="data" data-tag="name" data-xpath="/top/data/item/name" data-type="string" data-help="Name of the item" data-key="key">bolt </div>
+ <div class="data" data-tag="sold" data-xpath="/top/data/item[sku = 'HRD-000-632'][name = 'bolt']/sold" data-type="number" data-help="Number of items sold"> 4123</div>
+ <div class="data" data-tag="in-stock" data-xpath="/top/data/item[sku = 'HRD-000-632'][name = 'bolt']/in-stock" data-type="number" data-help="Number of items in stock"> 144</div>
+ <div class="data color-fg-yellow" data-tag="on-order" data-xpath="/top/data/item[sku = 'HRD-000-632'][name = 'bolt']/on-order" data-type="number" data-help="Number of items on order"> 42</div>
+ <div class="data" data-tag="sku" data-xpath="/top/data/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key"> HRD-000-632</div>
+</div>
+<div class="line">
+ <div class="data" data-tag="name" data-xpath="/top/data/item/name" data-type="string" data-help="Name of the item" data-key="key">water </div>
+ <div class="data" data-tag="sold" data-xpath="/top/data/item[sku = 'GRO-000-2331'][name = 'water']/sold" data-type="number" data-help="Number of items sold"> 17</div>
+ <div class="data" data-tag="in-stock" data-xpath="/top/data/item[sku = 'GRO-000-2331'][name = 'water']/in-stock" data-type="number" data-help="Number of items in stock"> 14</div>
+ <div class="data" data-tag="on-order" data-xpath="/top/data/item[sku = 'GRO-000-2331'][name = 'water']/on-order" data-type="number" data-help="Number of items on order"> 2</div>
+ <div class="data" data-tag="sku" data-xpath="/top/data/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key"> GRO-000-2331</div>
+</div>
+<div class="line">
+</div>
+<div class="line">
+</div>
+<div class="line">
+ <div class="label">Item</div>
+ <div class="text"> '</div>
+ <div class="data" data-tag="name" data-xpath="/top/data/item/name" data-type="string" data-help="Name of the item" data-key="key">gum</div>
+ <div class="text">':</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">Total sold</div>
+ <div class="text">: </div>
+ <div class="data" data-tag="sold" data-xpath="/top/data/item[sku = 'GRO-000-415'][name = 'gum']/sold" data-type="number" data-help="Number of items sold">1412.0</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">In stock</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data effect-inverse color-fg-inverse color-bg-inverse" data-tag="in-stock" data-xpath="/top/data/item[sku = 'GRO-000-415'][name = 'gum']/in-stock" data-type="number" data-help="Number of items in stock">54</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">On order</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="on-order" data-xpath="/top/data/item[sku = 'GRO-000-415'][name = 'gum']/on-order" data-type="number" data-help="Number of items on order">10</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">SKU</div>
+ <div class="text">: </div>
+ <div class="data" data-tag="sku" data-xpath="/top/data/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key">GRO-000-415</div>
+</div>
+<div class="line">
+ <div class="label">Item</div>
+ <div class="text"> '</div>
+ <div class="data" data-tag="name" data-xpath="/top/data/item/name" data-type="string" data-help="Name of the item" data-key="key">rope</div>
+ <div class="text">':</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">Total sold</div>
+ <div class="text">: </div>
+ <div class="data" data-tag="sold" data-xpath="/top/data/item[sku = 'HRD-000-212'][name = 'rope']/sold" data-type="number" data-help="Number of items sold">85.0</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">In stock</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data effect-inverse color-fg-inverse color-bg-inverse" data-tag="in-stock" data-xpath="/top/data/item[sku = 'HRD-000-212'][name = 'rope']/in-stock" data-type="number" data-help="Number of items in stock">4</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">On order</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="on-order" data-xpath="/top/data/item[sku = 'HRD-000-212'][name = 'rope']/on-order" data-type="number" data-help="Number of items on order">2</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">SKU</div>
+ <div class="text">: </div>
+ <div class="data" data-tag="sku" data-xpath="/top/data/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key">HRD-000-212</div>
+</div>
+<div class="line">
+ <div class="label">Item</div>
+ <div class="text"> '</div>
+ <div class="data" data-tag="name" data-xpath="/top/data/item/name" data-type="string" data-help="Name of the item" data-key="key">ladder</div>
+ <div class="text">':</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">Total sold</div>
+ <div class="text">: </div>
+ <div class="data" data-tag="sold" data-xpath="/top/data/item[sku = 'HRD-000-517'][name = 'ladder']/sold" data-type="number" data-help="Number of items sold">0</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">In stock</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data effect-inverse color-fg-inverse color-bg-inverse" data-tag="in-stock" data-xpath="/top/data/item[sku = 'HRD-000-517'][name = 'ladder']/in-stock" data-type="number" data-help="Number of items in stock">2</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">On order</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="on-order" data-xpath="/top/data/item[sku = 'HRD-000-517'][name = 'ladder']/on-order" data-type="number" data-help="Number of items on order">1</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">SKU</div>
+ <div class="text">: </div>
+ <div class="data" data-tag="sku" data-xpath="/top/data/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key">HRD-000-517</div>
+</div>
+<div class="line">
+ <div class="label">Item</div>
+ <div class="text"> '</div>
+ <div class="data" data-tag="name" data-xpath="/top/data/item/name" data-type="string" data-help="Name of the item" data-key="key">bolt</div>
+ <div class="text">':</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">Total sold</div>
+ <div class="text">: </div>
+ <div class="data" data-tag="sold" data-xpath="/top/data/item[sku = 'HRD-000-632'][name = 'bolt']/sold" data-type="number" data-help="Number of items sold">4123.0</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">In stock</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data effect-inverse color-fg-inverse color-bg-inverse" data-tag="in-stock" data-xpath="/top/data/item[sku = 'HRD-000-632'][name = 'bolt']/in-stock" data-type="number" data-help="Number of items in stock">144</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">On order</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="on-order" data-xpath="/top/data/item[sku = 'HRD-000-632'][name = 'bolt']/on-order" data-type="number" data-help="Number of items on order">42</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">SKU</div>
+ <div class="text">: </div>
+ <div class="data" data-tag="sku" data-xpath="/top/data/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key">HRD-000-632</div>
+</div>
+<div class="line">
+ <div class="label">Item</div>
+ <div class="text"> '</div>
+ <div class="data" data-tag="name" data-xpath="/top/data/item/name" data-type="string" data-help="Name of the item" data-key="key">water</div>
+ <div class="text">':</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">Total sold</div>
+ <div class="text">: </div>
+ <div class="data" data-tag="sold" data-xpath="/top/data/item[sku = 'GRO-000-2331'][name = 'water']/sold" data-type="number" data-help="Number of items sold">17.0</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">In stock</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data effect-inverse color-fg-inverse color-bg-inverse" data-tag="in-stock" data-xpath="/top/data/item[sku = 'GRO-000-2331'][name = 'water']/in-stock" data-type="number" data-help="Number of items in stock">14</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">On order</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="on-order" data-xpath="/top/data/item[sku = 'GRO-000-2331'][name = 'water']/on-order" data-type="number" data-help="Number of items on order">2</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">SKU</div>
+ <div class="text">: </div>
+ <div class="data" data-tag="sku" data-xpath="/top/data/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key">GRO-000-2331</div>
+</div>
+<div class="line">
+ <div class="label">Item</div>
+ <div class="text"> '</div>
+ <div class="data" data-tag="name" data-xpath="/top/data/item/name" data-type="string" data-help="Name of the item" data-key="key">fish</div>
+ <div class="text">':</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label effect-bold color-fg-white color-bg-blue">Total sold</div>
+ <div class="text effect-bold color-fg-white color-bg-blue">: </div>
+ <div class="data effect-bold color-fg-white color-bg-blue" data-tag="sold" data-xpath="/top/data/item[sku = 'GRO-000-533'][name = 'fish']/sold" data-type="number" data-help="Number of items sold">1321.0</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">In stock</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="in-stock" data-xpath="/top/data/item[sku = 'GRO-000-533'][name = 'fish']/in-stock" data-type="number" data-help="Number of items in stock">45</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">On order</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="on-order" data-xpath="/top/data/item[sku = 'GRO-000-533'][name = 'fish']/on-order" data-type="number" data-help="Number of items on order">1</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">SKU</div>
+ <div class="text">: </div>
+ <div class="data" data-tag="sku" data-xpath="/top/data/item/sku" data-type="string" data-help="Stock Keeping Unit" data-key="key">GRO-000-533</div>
+</div>
+<div class="line">
+ <div class="label">Item</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="item" data-xpath="/top/data/item">gum</div>
+</div>
+<div class="line">
+ <div class="label">Item</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="item" data-xpath="/top/data/item">rope</div>
+</div>
+<div class="line">
+ <div class="label">Item</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="item" data-xpath="/top/data/item">ladder</div>
+</div>
+<div class="line">
+ <div class="label">Item</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="item" data-xpath="/top/data/item">bolt</div>
+</div>
+<div class="line">
+ <div class="label">Item</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="item" data-xpath="/top/data/item">water</div>
+</div>
+<div class="line">
+ <div class="text">X</div>
+ <div class="text">X</div>
+ <div class="text">X</div>
+ <div class="text">X</div>
+ <div class="text">X</div>
+ <div class="text">X</div>
+ <div class="text">X</div>
+ <div class="text">X</div>
+</div>
+<div class="line">
+ <div class="text">X</div>
+ <div class="padding"> </div>
+ <div class="text">X</div>
+ <div class="label">Cost</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="cost" data-xpath="/top/cost">425</div>
+</div>
+<div class="line">
+ <div class="text">X</div>
+ <div class="padding"> </div>
+ <div class="text">X</div>
+ <div class="label">Cost</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="cost" data-xpath="/top/cost">455</div>
+</div>
diff --git a/contrib/libxo/tests/core/saved/test_10.HP.err b/contrib/libxo/tests/core/saved/test_10.HP.err
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/contrib/libxo/tests/core/saved/test_10.HP.err
diff --git a/contrib/libxo/tests/core/saved/test_10.HP.out b/contrib/libxo/tests/core/saved/test_10.HP.out
new file mode 100644
index 000000000000..abb1b0183656
--- /dev/null
+++ b/contrib/libxo/tests/core/saved/test_10.HP.out
@@ -0,0 +1,316 @@
+<div class="line">
+ <div class="title color-fg-blue">blue</div>
+ <div class="title color-fg-green color-bg-blue">green</div>
+ <div class="title color-fg-red color-bg-green">red</div>
+ <div class="title color-fg-yellow color-bg-red">yellow</div>
+ <div class="title color-bg-yellow">default</div>
+</div>
+<div class="line">
+ <div class="data effect-bold" data-tag="data">bold</div>
+ <div class="text effect-bold"> </div>
+ <div class="data effect-bold effect-underline" data-tag="data">bold-ul</div>
+ <div class="text effect-bold effect-underline"> </div>
+ <div class="data effect-bold effect-underline effect-inverse color-fg-inverse color-bg-inverse" data-tag="data">triple</div>
+ <div class="text effect-bold effect-underline effect-inverse color-fg-inverse color-bg-inverse"> </div>
+ <div class="data effect-underline effect-inverse color-fg-inverse color-bg-inverse" data-tag="data">inv-ul</div>
+ <div class="text effect-underline effect-inverse color-fg-inverse color-bg-inverse"> </div>
+ <div class="data effect-underline" data-tag="data">underline</div>
+ <div class="text effect-underline"> </div>
+ <div class="data" data-tag="data">plain</div>
+</div>
+<div class="line">
+ <div class="title">Item </div>
+ <div class="title effect-bold effect-underline"> Total Sold</div>
+ <div class="title effect-underline"> In Stock</div>
+ <div class="title effect-underline effect-inverse color-fg-inverse color-bg-inverse"> On Order</div>
+ <div class="title"> SKU</div>
+</div>
+<div class="line">
+ <div class="data" data-tag="name" data-key="key">gum </div>
+ <div class="data" data-tag="sold"> 1412</div>
+ <div class="data" data-tag="in-stock"> 54</div>
+ <div class="data color-fg-yellow" data-tag="on-order"> 10</div>
+ <div class="data" data-tag="sku" data-key="key"> GRO-000-415</div>
+</div>
+<div class="line">
+ <div class="data" data-tag="name" data-key="key">rope </div>
+ <div class="data" data-tag="sold"> 85</div>
+ <div class="data effect-inverse color-fg-inverse color-bg-inverse" data-tag="in-stock"> 4</div>
+ <div class="data" data-tag="on-order"> 2</div>
+ <div class="data" data-tag="sku" data-key="key"> HRD-000-212</div>
+</div>
+<div class="line">
+ <div class="data" data-tag="name" data-key="key">ladder </div>
+ <div class="data" data-tag="sold"> 0</div>
+ <div class="data effect-inverse color-fg-inverse color-bg-inverse" data-tag="in-stock"> 2</div>
+ <div class="data" data-tag="on-order"> 1</div>
+ <div class="data" data-tag="sku" data-key="key"> HRD-000-517</div>
+</div>
+<div class="line">
+ <div class="data" data-tag="name" data-key="key">bolt </div>
+ <div class="data" data-tag="sold"> 4123</div>
+ <div class="data" data-tag="in-stock"> 144</div>
+ <div class="data color-fg-yellow" data-tag="on-order"> 42</div>
+ <div class="data" data-tag="sku" data-key="key"> HRD-000-632</div>
+</div>
+<div class="line">
+ <div class="data" data-tag="name" data-key="key">water </div>
+ <div class="data" data-tag="sold"> 17</div>
+ <div class="data" data-tag="in-stock"> 14</div>
+ <div class="data" data-tag="on-order"> 2</div>
+ <div class="data" data-tag="sku" data-key="key"> GRO-000-2331</div>
+</div>
+<div class="line">
+</div>
+<div class="line">
+</div>
+<div class="line">
+ <div class="label">Item</div>
+ <div class="text"> '</div>
+ <div class="data" data-tag="name" data-key="key">gum</div>
+ <div class="text">':</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">Total sold</div>
+ <div class="text">: </div>
+ <div class="data" data-tag="sold">1412.0</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">In stock</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data effect-inverse color-fg-inverse color-bg-inverse" data-tag="in-stock">54</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">On order</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="on-order">10</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">SKU</div>
+ <div class="text">: </div>
+ <div class="data" data-tag="sku" data-key="key">GRO-000-415</div>
+</div>
+<div class="line">
+ <div class="label">Item</div>
+ <div class="text"> '</div>
+ <div class="data" data-tag="name" data-key="key">rope</div>
+ <div class="text">':</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">Total sold</div>
+ <div class="text">: </div>
+ <div class="data" data-tag="sold">85.0</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">In stock</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data effect-inverse color-fg-inverse color-bg-inverse" data-tag="in-stock">4</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">On order</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="on-order">2</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">SKU</div>
+ <div class="text">: </div>
+ <div class="data" data-tag="sku" data-key="key">HRD-000-212</div>
+</div>
+<div class="line">
+ <div class="label">Item</div>
+ <div class="text"> '</div>
+ <div class="data" data-tag="name" data-key="key">ladder</div>
+ <div class="text">':</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">Total sold</div>
+ <div class="text">: </div>
+ <div class="data" data-tag="sold">0</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">In stock</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data effect-inverse color-fg-inverse color-bg-inverse" data-tag="in-stock">2</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">On order</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="on-order">1</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">SKU</div>
+ <div class="text">: </div>
+ <div class="data" data-tag="sku" data-key="key">HRD-000-517</div>
+</div>
+<div class="line">
+ <div class="label">Item</div>
+ <div class="text"> '</div>
+ <div class="data" data-tag="name" data-key="key">bolt</div>
+ <div class="text">':</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">Total sold</div>
+ <div class="text">: </div>
+ <div class="data" data-tag="sold">4123.0</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">In stock</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data effect-inverse color-fg-inverse color-bg-inverse" data-tag="in-stock">144</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">On order</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="on-order">42</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">SKU</div>
+ <div class="text">: </div>
+ <div class="data" data-tag="sku" data-key="key">HRD-000-632</div>
+</div>
+<div class="line">
+ <div class="label">Item</div>
+ <div class="text"> '</div>
+ <div class="data" data-tag="name" data-key="key">water</div>
+ <div class="text">':</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">Total sold</div>
+ <div class="text">: </div>
+ <div class="data" data-tag="sold">17.0</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">In stock</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data effect-inverse color-fg-inverse color-bg-inverse" data-tag="in-stock">14</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">On order</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="on-order">2</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">SKU</div>
+ <div class="text">: </div>
+ <div class="data" data-tag="sku" data-key="key">GRO-000-2331</div>
+</div>
+<div class="line">
+ <div class="label">Item</div>
+ <div class="text"> '</div>
+ <div class="data" data-tag="name" data-key="key">fish</div>
+ <div class="text">':</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label effect-bold color-fg-white color-bg-blue">Total sold</div>
+ <div class="text effect-bold color-fg-white color-bg-blue">: </div>
+ <div class="data effect-bold color-fg-white color-bg-blue" data-tag="sold">1321.0</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">In stock</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="in-stock">45</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">On order</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="on-order">1</div>
+</div>
+<div class="line">
+ <div class="padding"> </div>
+ <div class="label">SKU</div>
+ <div class="text">: </div>
+ <div class="data" data-tag="sku" data-key="key">GRO-000-533</div>
+</div>
+<div class="line">
+ <div class="label">Item</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="item">gum</div>
+</div>
+<div class="line">
+ <div class="label">Item</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="item">rope</div>
+</div>
+<div class="line">
+ <div class="label">Item</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="item">ladder</div>
+</div>
+<div class="line">
+ <div class="label">Item</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="item">bolt</div>
+</div>
+<div class="line">
+ <div class="label">Item</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="item">water</div>
+</div>
+<div class="line">
+ <div class="text">X</div>
+ <div class="text">X</div>
+ <div class="text">X</div>
+ <div class="text">X</div>
+ <div class="text">X</div>
+ <div class="text">X</div>
+ <div class="text">X</div>
+ <div class="text">X</div>
+</div>
+<div class="line">
+ <div class="text">X</div>
+ <div class="padding"> </div>
+ <div class="text">X</div>
+ <div class="label">Cost</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="cost">425</div>
+</div>
+<div class="line">
+ <div class="text">X</div>
+ <div class="padding"> </div>
+ <div class="text">X</div>
+ <div class="label">Cost</div>
+ <div class="decoration">:</div>
+ <div class="padding"> </div>
+ <div class="data" data-tag="cost">455</div>
+</div>
diff --git a/contrib/libxo/tests/core/saved/test_10.J.err b/contrib/libxo/tests/core/saved/test_10.J.err
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/contrib/libxo/tests/core/saved/test_10.J.err
diff --git a/contrib/libxo/tests/core/saved/test_10.J.out b/contrib/libxo/tests/core/saved/test_10.J.out
new file mode 100644
index 000000000000..5091685fc745
--- /dev/null
+++ b/contrib/libxo/tests/core/saved/test_10.J.out
@@ -0,0 +1,2 @@
+{"__version": "3.1.4", "top": {"data": {"item": [],"data":"bold","data":"bold-ul","data":"triple","data":"inv-ul","data":"underline","data":"plain", "item": [{"sku":"GRO-000-415","name":"gum","sold":1412,"in-stock":54,"on-order":10}, {"sku":"HRD-000-212","name":"rope","sold":85,"in-stock":4,"on-order":2}, {"sku":"HRD-000-517","name":"ladder","sold":0,"in-stock":2,"on-order":1}, {"sku":"HRD-000-632","name":"bolt","sold":4123,"in-stock":144,"on-order":42}, {"sku":"GRO-000-2331","name":"water","sold":17,"in-stock":14,"on-order":2}]}, "data": {"item": [{"sku":"GRO-000-415","name":"gum","sold":1412.0,"in-stock":54,"on-order":10}, {"sku":"HRD-000-212","name":"rope","sold":85.0,"in-stock":4,"on-order":2}, {"sku":"HRD-000-517","name":"ladder","sold":0,"in-stock":2,"on-order":1}, {"sku":"HRD-000-632","name":"bolt","sold":4123.0,"in-stock":144,"on-order":42}, {"sku":"GRO-000-2331","name":"water","sold":17.0,"in-stock":14,"on-order":2}]}, "data": {"item": [{"sku":"GRO-000-533","name":"fish","sold":1321.0,"in-stock":45,"on-order":1}]}, "data": {"item": ["gum","rope","ladder","bolt","water"]},"cost":425,"cost":455}
+}
diff --git a/contrib/libxo/tests/core/saved/test_10.JP.err b/contrib/libxo/tests/core/saved/test_10.JP.err
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/contrib/libxo/tests/core/saved/test_10.JP.err
diff --git a/contrib/libxo/tests/core/saved/test_10.JP.out b/contrib/libxo/tests/core/saved/test_10.JP.out
new file mode 100644
index 000000000000..0ca326995a7b
--- /dev/null
+++ b/contrib/libxo/tests/core/saved/test_10.JP.out
@@ -0,0 +1,113 @@
+{
+ "__version": "3.1.4",
+ "top": {
+ "data": {
+ "item": [
+ ],
+ "data": "bold",
+ "data": "bold-ul",
+ "data": "triple",
+ "data": "inv-ul",
+ "data": "underline",
+ "data": "plain",
+ "item": [
+ {
+ "sku": "GRO-000-415",
+ "name": "gum",
+ "sold": 1412,
+ "in-stock": 54,
+ "on-order": 10
+ },
+ {
+ "sku": "HRD-000-212",
+ "name": "rope",
+ "sold": 85,
+ "in-stock": 4,
+ "on-order": 2
+ },
+ {
+ "sku": "HRD-000-517",
+ "name": "ladder",
+ "sold": 0,
+ "in-stock": 2,
+ "on-order": 1
+ },
+ {
+ "sku": "HRD-000-632",
+ "name": "bolt",
+ "sold": 4123,
+ "in-stock": 144,
+ "on-order": 42
+ },
+ {
+ "sku": "GRO-000-2331",
+ "name": "water",
+ "sold": 17,
+ "in-stock": 14,
+ "on-order": 2
+ }
+ ]
+ },
+ "data": {
+ "item": [
+ {
+ "sku": "GRO-000-415",
+ "name": "gum",
+ "sold": 1412.0,
+ "in-stock": 54,
+ "on-order": 10
+ },
+ {
+ "sku": "HRD-000-212",
+ "name": "rope",
+ "sold": 85.0,
+ "in-stock": 4,
+ "on-order": 2
+ },
+ {
+ "sku": "HRD-000-517",
+ "name": "ladder",
+ "sold": 0,
+ "in-stock": 2,
+ "on-order": 1
+ },
+ {
+ "sku": "HRD-000-632",
+ "name": "bolt",
+ "sold": 4123.0,
+ "in-stock": 144,
+ "on-order": 42
+ },
+ {
+ "sku": "GRO-000-2331",
+ "name": "water",
+ "sold": 17.0,
+ "in-stock": 14,
+ "on-order": 2
+ }
+ ]
+ },
+ "data": {
+ "item": [
+ {
+ "sku": "GRO-000-533",
+ "name": "fish",
+ "sold": 1321.0,
+ "in-stock": 45,
+ "on-order": 1
+ }
+ ]
+ },
+ "data": {
+ "item": [
+ "gum",
+ "rope",
+ "ladder",
+ "bolt",
+ "water"
+ ]
+ },
+ "cost": 425,
+ "cost": 455
+ }
+}
diff --git a/contrib/libxo/tests/core/saved/test_10.T.err b/contrib/libxo/tests/core/saved/test_10.T.err
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/contrib/libxo/tests/core/saved/test_10.T.err
diff --git a/contrib/libxo/tests/core/saved/test_10.T.out b/contrib/libxo/tests/core/saved/test_10.T.out
new file mode 100644
index 000000000000..21fa81bc9aae
--- /dev/null
+++ b/contrib/libxo/tests/core/saved/test_10.T.out
@@ -0,0 +1,48 @@
+bluegreenredyellowdefault
+bold bold-ul triple inv-ul underline plain
+Item  Total Sold In Stock On Order SKU
+gum 1412 54 10 GRO-000-415
+rope 85 4 2 HRD-000-212
+ladder 0 2 1 HRD-000-517
+bolt 4123 144 42 HRD-000-632
+water 17 14 2 GRO-000-2331
+
+
+Item 'gum':
+ Total sold: 1412.0
+ In stock: 54
+ On order: 10
+ SKU: GRO-000-415
+Item 'rope':
+ Total sold: 85.0
+ In stock: 4
+ On order: 2
+ SKU: HRD-000-212
+Item 'ladder':
+ Total sold: 0
+ In stock: 2
+ On order: 1
+ SKU: HRD-000-517
+Item 'bolt':
+ Total sold: 4123.0
+ In stock: 144
+ On order: 42
+ SKU: HRD-000-632
+Item 'water':
+ Total sold: 17.0
+ In stock: 14
+ On order: 2
+ SKU: GRO-000-2331
+Item 'fish':
+ Total sold: 1321.0
+ In stock: 45
+ On order: 1
+ SKU: GRO-000-533
+Item: gum
+Item: rope
+Item: ladder
+Item: bolt
+Item: water
+XXXXXXXX
+X XCost: 425
+X XCost: 455
diff --git a/contrib/libxo/tests/core/saved/test_10.X.err b/contrib/libxo/tests/core/saved/test_10.X.err
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/contrib/libxo/tests/core/saved/test_10.X.err
diff --git a/contrib/libxo/tests/core/saved/test_10.X.out b/contrib/libxo/tests/core/saved/test_10.X.out
new file mode 100644
index 000000000000..49c6dd88c4fd
--- /dev/null
+++ b/contrib/libxo/tests/core/saved/test_10.X.out
@@ -0,0 +1 @@
+<top __version="3.1.4"><data test="value"><data test2="value2">bold</data><data>bold-ul</data><data>triple</data><data>inv-ul</data><data>underline</data><data>plain</data><item><sku test3="value3" key="key">GRO-000-415</sku><name key="key">gum</name><sold>1412</sold><in-stock>54</in-stock><on-order>10</on-order></item><item><sku test3="value3" key="key">HRD-000-212</sku><name key="key">rope</name><sold>85</sold><in-stock>4</in-stock><on-order>2</on-order></item><item><sku test3="value3" key="key">HRD-000-517</sku><name key="key">ladder</name><sold>0</sold><in-stock>2</in-stock><on-order>1</on-order></item><item><sku test3="value3" key="key">HRD-000-632</sku><name key="key">bolt</name><sold>4123</sold><in-stock>144</in-stock><on-order>42</on-order></item><item><sku test3="value3" key="key">GRO-000-2331</sku><name key="key">water</name><sold>17</sold><in-stock>14</in-stock><on-order>2</on-order></item></data><data><item><sku key="key">GRO-000-415</sku><name key="key">gum</name><sold>1412.0</sold><in-stock>54</in-stock><on-order>10</on-order></item><item><sku key="key">HRD-000-212</sku><name key="key">rope</name><sold>85.0</sold><in-stock>4</in-stock><on-order>2</on-order></item><item><sku key="key">HRD-000-517</sku><name key="key">ladder</name><sold>0</sold><in-stock>2</in-stock><on-order>1</on-order></item><item><sku key="key">HRD-000-632</sku><name key="key">bolt</name><sold>4123.0</sold><in-stock>144</in-stock><on-order>42</on-order></item><item><sku key="key">GRO-000-2331</sku><name key="key">water</name><sold>17.0</sold><in-stock>14</in-stock><on-order>2</on-order></item></data><data><item><sku key="key">GRO-000-533</sku><name key="key">fish</name><sold>1321.0</sold><in-stock>45</in-stock><on-order>1</on-order></item></data><data><item test4="value4">gum</item><item test4="value4">rope</item><item test4="value4">ladder</item><item test4="value4">bolt</item><item test4="value4">water</item></data><cost>425</cost><cost>455</cost></top> \ No newline at end of file
diff --git a/contrib/libxo/tests/core/saved/test_10.XP.err b/contrib/libxo/tests/core/saved/test_10.XP.err
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/contrib/libxo/tests/core/saved/test_10.XP.err
diff --git a/contrib/libxo/tests/core/saved/test_10.XP.out b/contrib/libxo/tests/core/saved/test_10.XP.out
new file mode 100644
index 000000000000..33c88d96214f
--- /dev/null
+++ b/contrib/libxo/tests/core/saved/test_10.XP.out
@@ -0,0 +1,100 @@
+<top __version="3.1.4">
+ <data test="value">
+ <data test2="value2">bold</data>
+ <data>bold-ul</data>
+ <data>triple</data>
+ <data>inv-ul</data>
+ <data>underline</data>
+ <data>plain</data>
+ <item>
+ <sku test3="value3" key="key">GRO-000-415</sku>
+ <name key="key">gum</name>
+ <sold>1412</sold>
+ <in-stock>54</in-stock>
+ <on-order>10</on-order>
+ </item>
+ <item>
+ <sku test3="value3" key="key">HRD-000-212</sku>
+ <name key="key">rope</name>
+ <sold>85</sold>
+ <in-stock>4</in-stock>
+ <on-order>2</on-order>
+ </item>
+ <item>
+ <sku test3="value3" key="key">HRD-000-517</sku>
+ <name key="key">ladder</name>
+ <sold>0</sold>
+ <in-stock>2</in-stock>
+ <on-order>1</on-order>
+ </item>
+ <item>
+ <sku test3="value3" key="key">HRD-000-632</sku>
+ <name key="key">bolt</name>
+ <sold>4123</sold>
+ <in-stock>144</in-stock>
+ <on-order>42</on-order>
+ </item>
+ <item>
+ <sku test3="value3" key="key">GRO-000-2331</sku>
+ <name key="key">water</name>
+ <sold>17</sold>
+ <in-stock>14</in-stock>
+ <on-order>2</on-order>
+ </item>
+ </data>
+ <data>
+ <item>
+ <sku key="key">GRO-000-415</sku>
+ <name key="key">gum</name>
+ <sold>1412.0</sold>
+ <in-stock>54</in-stock>
+ <on-order>10</on-order>
+ </item>
+ <item>
+ <sku key="key">HRD-000-212</sku>
+ <name key="key">rope</name>
+ <sold>85.0</sold>
+ <in-stock>4</in-stock>
+ <on-order>2</on-order>
+ </item>
+ <item>
+ <sku key="key">HRD-000-517</sku>
+ <name key="key">ladder</name>
+ <sold>0</sold>
+ <in-stock>2</in-stock>
+ <on-order>1</on-order>
+ </item>
+ <item>
+ <sku key="key">HRD-000-632</sku>
+ <name key="key">bolt</name>
+ <sold>4123.0</sold>
+ <in-stock>144</in-stock>
+ <on-order>42</on-order>
+ </item>
+ <item>
+ <sku key="key">GRO-000-2331</sku>
+ <name key="key">water</name>
+ <sold>17.0</sold>
+ <in-stock>14</in-stock>
+ <on-order>2</on-order>
+ </item>
+ </data>
+ <data>
+ <item>
+ <sku key="key">GRO-000-533</sku>
+ <name key="key">fish</name>
+ <sold>1321.0</sold>
+ <in-stock>45</in-stock>
+ <on-order>1</on-order>
+ </item>
+ </data>
+ <data>
+ <item test4="value4">gum</item>
+ <item test4="value4">rope</item>
+ <item test4="value4">ladder</item>
+ <item test4="value4">bolt</item>
+ <item test4="value4">water</item>
+ </data>
+ <cost>425</cost>
+ <cost>455</cost>
+</top>
diff --git a/contrib/libxo/tests/core/saved/test_10.err b/contrib/libxo/tests/core/saved/test_10.err
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/contrib/libxo/tests/core/saved/test_10.err
diff --git a/contrib/libxo/tests/core/saved/test_10.out b/contrib/libxo/tests/core/saved/test_10.out
new file mode 100644
index 000000000000..c2ad7a005274
--- /dev/null
+++ b/contrib/libxo/tests/core/saved/test_10.out
@@ -0,0 +1,38 @@
+Item Total Sold In Stock On Order SKU
+gum 1412 54 10 GRO-000-415
+rope 85 4 2 HRD-000-212
+ladder 0 2 1 HRD-000-517
+bolt 4123 144 42 HRD-000-632
+water 17 14 2 GRO-000-2331
+
+
+Item 'gum':
+ Total sold: 1412.0
+ In stock: 54
+ On order: 10
+ SKU: GRO-000-415
+Item 'rope':
+ Total sold: 85.0
+ In stock: 4
+ On order: 2
+ SKU: HRD-000-212
+Item 'ladder':
+ Total sold: 0
+ In stock: 2
+ On order: 1
+ SKU: HRD-000-517
+Item 'bolt':
+ Total sold: 4123.0
+ In stock: 144
+ On order: 42
+ SKU: HRD-000-632
+Item 'water':
+ Total sold: 17.0
+ In stock: 14
+ On order: 2
+ SKU: GRO-000-2331
+Item 'fish':
+ Total sold: 1321.0
+ In stock: 45
+ On order: 1
+ SKU: GRO-000-533
diff --git a/contrib/libxo/tests/core/test_05.c b/contrib/libxo/tests/core/test_05.c
index 61241b822b09..a883a8889906 100644
--- a/contrib/libxo/tests/core/test_05.c
+++ b/contrib/libxo/tests/core/test_05.c
@@ -39,23 +39,38 @@ main (int argc, char **argv)
{ "Ashley", "Ash", "Meter & Smith", 1440, 40 },
{ "0123456789", "0123456789", "012345678901234567890", 1440, 40 },
{ "ახლა", "გაიარო", "საერთაშორისო", 123, 90 },
+ { "෴ණ්ණ෴෴ණ්ණ෴", "Mick",
+ "෴ණ්ණ෴෴ණ්ණ෴෴ණ්ණ෴෴෴", 110, 20 },
{ NULL, NULL }
}, *ep = employees;
+ int rc;
argc = xo_parse_args(argc, argv);
if (argc < 0)
return 1;
xo_set_info(NULL, info, info_count);
+ xo_set_flags(NULL, XOF_COLUMNS);
xo_open_container("employees");
xo_emit("Οὐχὶ ταὐτὰ παρίσταταί μοι {:v1/%s}, {:v2/%s}\n",
"γιγνώσκειν", "ὦ ἄνδρες ᾿Αθηναῖοι");
- xo_emit("გთხოვთ {:v1/%s} {:v2/%s}\n",
+ rc = xo_emit("გთხოვთ {:v1/%s} {:v2/%s}\n",
"ახლავე გაიაროთ რეგისტრაცია",
"Unicode-ის მეათე საერთაშორისო");
+ xo_emit("{Twc:Width}{:width/%d}\n", rc);
+
+ /* Okay, Sinhala is uber cool ... */
+ rc = xo_emit("[{:sinhala}]\n", "෴ණ්ණ෴");
+ xo_emit("{Twc:Width}{:width/%d}\n", rc);
+ rc = xo_emit("[{:sinhala}]\n", "෴");
+ xo_emit("{Twc:Width}{:width/%d}\n", rc);
+ rc = xo_emit("[{:sinhala/%-4..4s/%s}]\n", "෴ණ්ණ෴෴ණ්ණ෴");
+ xo_emit("[{:not-sinhala/%-4..4s/%s}]\n", "123456");
+ rc = xo_emit("[{:tag/%s}]\n", "ර්‍ඝ");
+ xo_emit("{Twc:Width}{:width/%d}\n", rc);
xo_open_list("employee");
diff --git a/contrib/libxo/tests/core/test_10.c b/contrib/libxo/tests/core/test_10.c
new file mode 100644
index 000000000000..223ec55d47f9
--- /dev/null
+++ b/contrib/libxo/tests/core/test_10.c
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2014, Juniper Networks, Inc.
+ * All rights reserved.
+ * This SOFTWARE is licensed under the LICENSE provided in the
+ * ../Copyright file. By downloading, installing, copying, or otherwise
+ * using the SOFTWARE, you agree to be bound by the terms of that
+ * LICENSE.
+ * Phil Shafer, July 2014
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <ctype.h>
+
+#include "xo.h"
+
+int
+main (int argc, char **argv)
+{
+ static char base_grocery[] = "GRO";
+ static char base_hardware[] = "HRD";
+ struct item {
+ const char *i_title;
+ int i_sold;
+ int i_instock;
+ int i_onorder;
+ const char *i_sku_base;
+ int i_sku_num;
+ };
+ struct item list[] = {
+ { "gum", 1412, 54, 10, base_grocery, 415 },
+ { "rope", 85, 4, 2, base_hardware, 212 },
+ { "ladder", 0, 2, 1, base_hardware, 517 },
+ { "bolt", 4123, 144, 42, base_hardware, 632 },
+ { "water", 17, 14, 2, base_grocery, 2331 },
+ { NULL, 0, 0, 0, NULL, 0 }
+ };
+ struct item list2[] = {
+ { "fish", 1321, 45, 1, base_grocery, 533 },
+ { NULL, 0, 0, 0, NULL, 0 }
+ };
+ struct item *ip;
+ xo_info_t info[] = {
+ { "in-stock", "number", "Number of items in stock" },
+ { "name", "string", "Name of the item" },
+ { "on-order", "number", "Number of items on order" },
+ { "sku", "string", "Stock Keeping Unit" },
+ { "sold", "number", "Number of items sold" },
+ { NULL, NULL, NULL },
+ };
+ int info_count = (sizeof(info) / sizeof(info[0])) - 1;
+
+ argc = xo_parse_args(argc, argv);
+ if (argc < 0)
+ return 1;
+
+ for (argc = 1; argv[argc]; argc++) {
+ if (strcmp(argv[argc], "xml") == 0)
+ xo_set_style(NULL, XO_STYLE_XML);
+ else if (strcmp(argv[argc], "json") == 0)
+ xo_set_style(NULL, XO_STYLE_JSON);
+ else if (strcmp(argv[argc], "text") == 0)
+ xo_set_style(NULL, XO_STYLE_TEXT);
+ else if (strcmp(argv[argc], "html") == 0)
+ xo_set_style(NULL, XO_STYLE_HTML);
+ else if (strcmp(argv[argc], "pretty") == 0)
+ xo_set_flags(NULL, XOF_PRETTY);
+ else if (strcmp(argv[argc], "xpath") == 0)
+ xo_set_flags(NULL, XOF_XPATH);
+ else if (strcmp(argv[argc], "info") == 0)
+ xo_set_flags(NULL, XOF_INFO);
+ else if (strcmp(argv[argc], "error") == 0) {
+ close(-1);
+ xo_err(1, "error detected");
+ }
+ }
+
+ xo_set_info(NULL, info, info_count);
+ xo_set_flags(NULL, XOF_KEYS);
+
+ /* Normally one would use "XOF_COLOR_ALLOWED", but we want to force it */
+ xo_set_flags(NULL, XOF_COLOR);
+
+ xo_set_version("3.1.4");
+
+ xo_open_container_h(NULL, "top");
+
+ xo_attr("test", "value");
+ xo_open_container("data");
+ xo_open_list("item");
+ xo_attr("test2", "value2");
+
+ static const char *colors[] =
+ { "blue", "green", "red", "yellow", "default", NULL };
+
+ int i;
+ for (i = 0; colors[i]; i++) {
+ if (i > 0)
+ xo_emit("{C:/bg-%s}", colors[i-1]);
+ xo_emit("{C:/fg-%s}{T:/%s}", colors[i], colors[i]);
+ }
+ xo_emit("{C:reset}\n");
+
+ xo_emit("{C:bold}{:data} {C:underline}{:data} {C:inverse}{:data} "
+ "{C:no-bold}{:data} {C:no-inverse}{:data} "
+ "{C:no-underline}{:data}\n",
+ "bold", "bold-ul", "triple", "inv-ul", "underline", "plain");
+
+ xo_emit("{T:Item/%-10s}{C:bold,underline}{T:Total Sold/%12s}{C:no-bold}"
+ "{T:In Stock/%12s}{C:/%s}"
+ "{T:On Order/%12s}{C:normal}{T:SKU/%5s}\n", "inverse");
+
+#if 0
+ xo_finish();
+ return 0;
+#endif
+
+ for (ip = list; ip->i_title; ip++) {
+ xo_open_instance("item");
+ xo_attr("test3", "value3");
+
+ xo_emit("{keq:sku/%s-%u/%s-000-%u}"
+ "{k:name/%-10s/%s}{n:sold/%12u/%u}"
+ "{C:/%s}{:in-stock/%12u/%u}{C:normal}"
+ "{C:/fg-%s}{:on-order/%12u/%u}{C:/fg-default}"
+ "{qkd:sku/%5s-000-%u/%s-000-%u}\n",
+ ip->i_sku_base, ip->i_sku_num,
+ ip->i_title, ip->i_sold,
+ (ip->i_instock < 5) ? "inverse" : "normal", ip->i_instock,
+ (ip->i_onorder > 5) ? "yellow" : "default", ip->i_onorder,
+ ip->i_sku_base, ip->i_sku_num);
+
+ xo_close_instance("item");
+ }
+
+ xo_close_list("item");
+ xo_close_container("data");
+
+ xo_emit("\n\n");
+
+ xo_open_container("data");
+ xo_open_list("item");
+
+ for (ip = list; ip->i_title; ip++) {
+ xo_open_instance("item");
+
+ xo_emit("{keq:sku/%s-%u/%s-000-%u}", ip->i_sku_base, ip->i_sku_num);
+ xo_emit("{L:Item} '{k:name/%s}':\n", ip->i_title);
+ xo_emit("{P: }{L:Total sold}: {n:sold/%u%s}\n",
+ ip->i_sold, ip->i_sold ? ".0" : "");
+ xo_emit("{P: }{Lcw:In stock}{C:inverse}{:in-stock/%u}{C:}\n",
+ ip->i_instock);
+ xo_emit("{P: }{Lcw:On order}{:on-order/%u}\n", ip->i_onorder);
+ xo_emit("{P: }{L:SKU}: {qkd:sku/%s-000-%u}\n",
+ ip->i_sku_base, ip->i_sku_num);
+
+ xo_close_instance("item");
+ }
+
+ xo_close_list("item");
+ xo_close_container("data");
+
+ xo_open_container("data");
+ xo_open_list("item");
+
+ for (ip = list2; ip->i_title; ip++) {
+ xo_open_instance("item");
+
+ xo_emit("{keq:sku/%s-%u/%s-000-%u}", ip->i_sku_base, ip->i_sku_num);
+ xo_emit("{L:Item} '{k:name/%s}':\n", ip->i_title);
+ xo_emit("{P: }{C:bg-blue , fg-white, bold }{L:Total sold}: "
+ "{n:sold/%u%s}{C:}\n",
+ ip->i_sold, ip->i_sold ? ".0" : "");
+ xo_emit("{P: }{Lcw:In stock}{:in-stock/%u}\n", ip->i_instock);
+ xo_emit("{P: }{Lcw:On order}{:on-order/%u}\n", ip->i_onorder);
+ xo_emit("{P: }{L:SKU}: {qkd:sku/%s-000-%u}\n",
+ ip->i_sku_base, ip->i_sku_num);
+
+ xo_close_instance("item");
+ }
+
+ xo_close_list("item");
+ xo_close_container("data");
+
+ xo_open_container("data");
+ xo_open_list("item");
+
+ for (ip = list; ip->i_title; ip++) {
+ xo_attr("test4", "value4");
+ xo_emit("{Lwc:Item}{l:item}\n", ip->i_title);
+ }
+
+ xo_close_list("item");
+ xo_close_container("data");
+
+ xo_emit("X{P:}X", "epic fail");
+ xo_emit("X{T:}X", "epic fail");
+ xo_emit("X{N:}X", "epic fail");
+ xo_emit("X{L:}X\n", "epic fail");
+
+ xo_emit("X{P: }X{Lwc:Cost}{:cost/%u}\n", 425);
+ xo_emit("X{P:/%30s}X{Lwc:Cost}{:cost/%u}\n", "", 455);
+
+ xo_close_container_h(NULL, "top");
+
+ xo_finish();
+
+ return 0;
+}
diff --git a/contrib/libxo/xo/xo.1 b/contrib/libxo/xo/xo.1
index 12fc959481cc..9dcae85f0318 100644
--- a/contrib/libxo/xo/xo.1
+++ b/contrib/libxo/xo/xo.1
@@ -74,7 +74,7 @@ utility accepts a format string suitable for
.Xr xo_emit 3
and a set of zero or more arguments used to supply data for that string.
.Bd -literal -offset indent
- xo "The {k:name} weighs {:weight/%d} pounds.\n" fish 6
+ xo "The {k:name} weighs {:weight/%d} pounds.\\n" fish 6
TEXT:
The fish weighs 6 pounds.
diff --git a/contrib/libxo/xohtml/Makefile.am b/contrib/libxo/xohtml/Makefile.am
new file mode 100644
index 000000000000..49dffeddbac2
--- /dev/null
+++ b/contrib/libxo/xohtml/Makefile.am
@@ -0,0 +1,38 @@
+#
+# Copyright 2015, Juniper Networks, Inc.
+# All rights reserved.
+# This SOFTWARE is licensed under the LICENSE provided in the
+# ../Copyright file. By downloading, installing, copying, or otherwise
+# using the SOFTWARE, you agree to be bound by the terms of that
+# LICENSE.
+
+man_MANS = xohtml.1
+
+EXTERNAL_FILES = \
+ external/jquery.js \
+ external/jquery.qtip.css \
+ external/jquery.qtip.js
+
+INTERNAL_FILES = \
+ xohtml.js \
+ xohtml.css
+
+EXTRA_DIST = \
+ xohtml.1 \
+ xohtml.sh.in \
+ ${INTERNAL_FILES} \
+ ${EXTERNAL_FILES}
+
+install-exec-hook:
+ install xohtml.sh ${DESTDIR}${bindir}/xohtml
+ mkdir -p ${DESTDIR}${XO_SHAREDIR}/external
+ for file in ${INTERNAL_FILES}; do \
+ install ${srcdir}/$$file ${DESTDIR}${XO_SHAREDIR} ; done
+ for file in ${EXTERNAL_FILES}; do \
+ install ${srcdir}/$$file ${DESTDIR}${XO_SHAREDIR}/external ; done
+
+uninstall-hook:
+ for file in ${INTERNAL_FILES} ${EXTERNAL_FILES}; do \
+ rm ${DESTDIR}${XO_SHAREDIR}/$$file ; done
+ rmdir ${DESTDIR}${XO_SHAREDIR}/external
+ rm -f ${DESTDIR}${bindir}/xohtml
diff --git a/contrib/libxo/xohtml/xohtml.1 b/contrib/libxo/xohtml/xohtml.1
new file mode 100644
index 000000000000..d520cb31592e
--- /dev/null
+++ b/contrib/libxo/xohtml/xohtml.1
@@ -0,0 +1,125 @@
+.\" #
+.\" # Copyright (c) 2015, Juniper Networks, Inc.
+.\" # All rights reserved.
+.\" # This SOFTWARE is licensed under the LICENSE provided in the
+.\" # ../Copyright file. By downloading, installing, copying, or
+.\" # using the SOFTWARE, you agree to be bound by the terms of that
+.\" # LICENSE.
+.\" # Phil Shafer, July 2014
+.\"
+.Dd December 4, 2014
+.Dt XOHTML 1
+.Os
+.Sh NAME
+.Nm xohtml
+.Nd display libxo html output
+.Xr xo_emit 3
+.Sh SYNOPSIS
+.Nm xohtml
+.Op Fl c
+.Op Fl "b <base>"
+.Op Fl "c" <command>"
+.Op Fl "f" <output>
+.Op Ar command argument...
+.Sh DESCRIPTION
+.Nm
+is a tool for preparing
+.Xr libxo 3
+HTML output for display in modern HTML web browsers.
+.Nm
+can operate in two modes.
+If command is provided
+either with the
+.Fl c
+option or as argument(s) to the
+.Nm
+command, that command is executed and the resulting output is processed.
+If no command is given, the
+standard input is used.
+.Pp
+.Nm
+is typically used to wrap
+.Nm libxo
+output with sufficient HTML content to allow display in a web browser.
+This includes parent HTML tags as well as
+.Nm CSS
+stylesheets and
+.Nm Javascript
+files.
+.Pp
+If the command is given directly on the command line,
+.Nm
+will add the "--libxo=html" option needed to generate HTML output
+from
+.Nm libxo "-enabled"
+applications. See
+.Xr libxo 3
+for details.
+.Pp
+The following options are available:
+.Bl -tag -width indent
+.It Fl "b <base>"
+.It Fl "-base <base>"
+Supplies a source path for the CSS and Javascript files referenced in
+the output of
+.Nm xohtml .
+.It Fl "c <command>"
+.It Fl "-command <command>"
+Use the given command instead of one on the command line.
+This command should be quoted if it consists of multiple tokens, and
+should contain the "--libxo=html" option or equivalent, since the
+command is used directly.
+.It Fl "f <file>"
+.It Fl "-file <file>"
+Output is saved to the given file, rather than to the standard output
+descriptor.
+.El
+.Pp
+.Sh EXAMPLES
+The following command line will run "du --libxo=html ~/src" and save
+the output to /tmp/src.html:
+.Bd -literal -offset indent
+ xohtml du ~/src > /tmp/src.html
+.Ed
+.Pp
+The following command line will run "du --libxo=html,warn ~/src" and save
+the output to /tmp/src.html:
+.Bd -literal -offset indent
+ du --libxo=html,warn ~/src | xohtml -f /tmp/src.html
+.Ed
+.Pp
+The following command line will run "du --libxo=html,warn ~/src" and save
+the output to /tmp/src.html:
+.Bd -literal -offset indent
+ xohtml -c "du --libxo=html,warn ~/src" -f /tmp/src.html
+.Ed
+.Pp
+.Sh ADDITIONAL DOCUMENTATION
+Complete documentation can be found on github:
+.Bd -literal -offset indent
+http://juniper.github.io/libxo/libxo-manual.html
+.Ed
+.Pp
+.Nm libxo
+lives on github as:
+.Bd -literal -offset indent
+https://github.com/Juniper/libxo
+.Ed
+.Pp
+The latest release of
+.Nm libxo
+is available at:
+.Bd -literal -offset indent
+https://github.com/Juniper/libxo/releases
+.Ed
+.Sh SEE ALSO
+.Xr libxo 3 ,
+.Xr xo_emit 3
+.Sh HISTORY
+The
+.Nm libxo
+library was added in
+.Fx 11.0 .
+.Sh AUTHOR
+Phil Shafer
+
diff --git a/contrib/libxo/xohtml/xohtml.css b/contrib/libxo/xohtml/xohtml.css
index 655bf122617f..fc9ea066860e 100644
--- a/contrib/libxo/xohtml/xohtml.css
+++ b/contrib/libxo/xohtml/xohtml.css
@@ -1014,3 +1014,27 @@ div.xpath {
position: relative;
top: 1px;
}
+
+div.color-fg-black { color: black; }
+div.color-fg-red { color: red; }
+div.color-fg-green { color: green; }
+div.color-fg-yellow { color: yellow; }
+div.color-fg-blue { color: blue; }
+div.color-fg-magenta { color: magenta; }
+div.color-fg-cyan { color: cyan; }
+div.color-fg-white { color: white; }
+
+div.color-bg-black { background-color: black; }
+div.color-bg-red { background-color: red; }
+div.color-bg-green { background-color: green; }
+div.color-bg-yellow { background-color: yellow; }
+div.color-bg-blue { background-color: blue; }
+div.color-bg-magenta { background-color: magenta; }
+div.color-bg-cyan { background-color: cyan; }
+div.color-bg-white { background-color: white; }
+
+div.color-fg-inverse { color: white; }
+div.color-bg-inverse { background-color: black; }
+
+div.effect-bold { font-weight:bold; }
+div.effect-underline { text-decoration: underline; }
diff --git a/contrib/libxo/xohtml/xohtml.sh.in b/contrib/libxo/xohtml/xohtml.sh.in
index cbd3066b13ee..a15d82e3276a 100644
--- a/contrib/libxo/xohtml/xohtml.sh.in
+++ b/contrib/libxo/xohtml/xohtml.sh.in
@@ -13,6 +13,16 @@ BASE=@XO_SHAREDIR@
CMD=cat
DONE=
+do_help () {
+ echo "xohtml: wrap libxo-enabled output in HTML"
+ echo "Usage: xohtml [options] [command [arguments]]"
+ echo "Valid options are:"
+ echo " -b <basepath> | --base <basepath>"
+ echo " -c <command> | --command <command>"
+ echo " -f <output-file> | --file <output-file>"
+ exit 1
+}
+
while [ -z "$DONE" -a ! -z "$1" ]; do
case "$1" in
-b|--base)
@@ -31,12 +41,22 @@ while [ -z "$DONE" -a ! -z "$1" ]; do
shift;
exec > "$FILE";
;;
+ -*)
+ do_help
+ ;;
*)
DONE=1;
+ XX=$1;
+ shift;
+ CMD="$XX --libxo=html $@"
;;
esac
done
+if [ "$CMD" = "cat" -a -t 0 ]; then
+ do_help
+fi
+
echo "<html>\n<head>\n"
echo '<meta http-equiv="content-type" content="text/html; charset=utf-8"/>'
echo '<link rel="stylesheet" href="'$BASE'/xohtml.css">'
diff --git a/contrib/libxo/xolint/Makefile.am b/contrib/libxo/xolint/Makefile.am
index a847e72c784c..ec5c36d86b00 100644
--- a/contrib/libxo/xolint/Makefile.am
+++ b/contrib/libxo/xolint/Makefile.am
@@ -12,3 +12,6 @@ EXTRA_DIST = xolint.1 xolint.pl
install-exec-hook:
install ${srcdir}/xolint.pl ${DESTDIR}${bindir}/xolint
+
+uninstall-hook:
+ rm -f ${DESTDIR}${bindir}/xolint
diff --git a/contrib/libxo/xolint/xolint.1 b/contrib/libxo/xolint/xolint.1
index fcf7bcdeec73..16a59fc91fdd 100644
--- a/contrib/libxo/xolint/xolint.1
+++ b/contrib/libxo/xolint/xolint.1
@@ -99,6 +99,6 @@ https://github.com/Juniper/libxo/releases
The
.Nm libxo
library was added in
-.Fx 10.1 .
+.Fx 11.0 .
.Sh AUTHOR
Phil Shafer
diff --git a/contrib/libxo/xolint/xolint.pl b/contrib/libxo/xolint/xolint.pl
index 427edf7aa95d..515f7faaf77f 100755
--- a/contrib/libxo/xolint/xolint.pl
+++ b/contrib/libxo/xolint/xolint.pl
@@ -347,32 +347,32 @@ sub check_field {
error("only one field role can be used (" . join(", ", @roles) . ")")
if $#roles > 0;
- # Field is a note, label, or title
- if ($field[0] =~ /[DLNT]/) {
+ # Field is a color, note, label, or title
+ if ($field[0] =~ /[CDLNT]/) {
- #@ Potential missing slash after N, L, or T with format
+ #@ Potential missing slash after C, D, N, L, or T with format
#@ xo_emit("{T:%6.6s}\n", "Max");
#@ should be:
#@ xo_emit("{T:/%6.6s}\n", "Max");
#@ The "%6.6s" will be a literal, not a field format. While
#@ it's possibly valid, it's likely a missing "/".
- info("potential missing slash after N, L, or T with format")
+ info("potential missing slash after C, D, N, L, or T with format")
if $field[1] =~ /%/;
#@ An encoding format cannot be given (roles: DNLT)
#@ xo_emit("{T:Max//%s}", "Max");
- #@ Fields with the D, N, L, and T roles are not emitted in
+ #@ Fields with the C, D, N, L, and T roles are not emitted in
#@ the 'encoding' style (JSON, XML), so an encoding format
#@ would make no sense.
error("encoding format cannot be given when content is present")
if $field[3];
}
- # Field is a decoration, label, or title
- if ($field[0] =~ /DLN/) {
- #@ Format cannot be given when content is present (roles: DLN)
+ # Field is a color, decoration, label, or title
+ if ($field[0] =~ /[CDLN]/) {
+ #@ Format cannot be given when content is present (roles: CDLN)
#@ xo_emit("{N:Max/%6.6s}", "Max");
- #@ Fields with the D, L, or N roles can't have both
+ #@ Fields with the C, D, L, or N roles can't have both
#@ static literal content ("{L:Label}") and a
#@ format ("{L:/%s}").
#@ This error will also occur when the content has a backslash
@@ -383,6 +383,49 @@ sub check_field {
if $field[1] && $field[2];
}
+ # Field is a color/effect
+ if ($field[0] =~ /C/) {
+ if ($field[1]) {
+ my $val;
+ my @sub = split(/,/, $field[1]);
+ grep { s/^\s*//; s/\s*$//; } @sub;
+
+ for $val (@sub) {
+ if ($val =~ /^(default,black,red,green,yellow,blue,magenta,cyan,white)$/) {
+
+ #@ Field has color without fg- or bg- (role: C)
+ #@ xo_emit("{C:green}{:foo}{C:}", x);
+ #@ Should be:
+ #@ xo_emit("{C:fg-green}{:foo}{C:}", x);
+ #@ Colors must be prefixed by either "fg-" or "bg-".
+ error("Field has color without fg- or bg- (role: C)");
+
+ } elsif ($val =~ /^(fg|bg)-(default|black|red|green|yellow|blue|magenta|cyan|white)$/) {
+ # color
+ } elsif ($val =~ /^(bold|underline)$/) {
+ } elsif ($val =~ /^(no-)?(bold|underline|inverse)$/) {
+ # effect
+
+ } elsif ($val =~ /^(reset|normal)$/) {
+ # effect also
+ } else {
+ #@ Field has invalid color or effect (role: C)
+ #@ xo_emit("{C:fg-purple,bold}{:foo}{C:gween}", x);
+ #@ Should be:
+ #@ xo_emit("{C:fg-red,bold}{:foo}{C:fg-green}", x);
+ #@ The list of colors and effects are limited. The
+ #@ set of colors includes default, black, red, green,
+ #@ yellow, blue, magenta, cyan, and white, which must
+ #@ be prefixed by either "fg-" or "bg-". Effects are
+ #@ limited to bold, no-bold, underline, no-underline,
+ #@ inverse, no-inverse, normal, and reset. Values must
+ #@ be separated by commas.
+ error("Field has invalid color or effect (role: C) ($val)");
+ }
+ }
+ }
+ }
+
# A value field
if (length($field[0]) == 0 || $field[0] =~ /V/) {
@@ -456,7 +499,7 @@ sub check_field {
#@ Should be:
#@ xo_emit("{D:((}{:good}{D:))}", "yes");
#@ This is minor, but fields should use proper roles. Decoration
- #@ fields are meant to hold puncuation and other characters used
+ #@ fields are meant to hold punctuation and other characters used
#@ to decorate the content, typically to make it more readable
#@ to human readers.
warn("decoration field contains invalid character")
diff --git a/contrib/netbsd-tests/lib/libm/t_fmod.c b/contrib/netbsd-tests/lib/libm/t_fmod.c
index 7dac93deae52..837e9b24f5c1 100644
--- a/contrib/netbsd-tests/lib/libm/t_fmod.c
+++ b/contrib/netbsd-tests/lib/libm/t_fmod.c
@@ -43,15 +43,21 @@ ATF_TC_BODY(fmod, tc)
{
ATF_CHECK(fmodf(2.0, 1.0) == 0);
ATF_CHECK(fmod(2.0, 1.0) == 0);
+#if !defined(__FreeBSD__) || LDBL_PREC != 53
ATF_CHECK(fmodl(2.0, 1.0) == 0);
+#endif
ATF_CHECK(fmodf(2.0, 0.5) == 0);
ATF_CHECK(fmod(2.0, 0.5) == 0);
+#if !defined(__FreeBSD__) || LDBL_PREC != 53
ATF_CHECK(fmodl(2.0, 0.5) == 0);
+#endif
ATF_CHECK(fabsf(fmodf(1.0, 0.1) - 0.1f) <= 55 * FLT_EPSILON);
ATF_CHECK(fabs(fmod(1.0, 0.1) - 0.1) <= 55 * DBL_EPSILON);
+#if !defined(__FreeBSD__) || LDBL_PREC != 53
ATF_CHECK(fabsl(fmodl(1.0, 0.1L) - 0.1L) <= 55 * LDBL_EPSILON);
+#endif
}
ATF_TP_ADD_TCS(tp)
diff --git a/contrib/netbsd-tests/lib/libpthread/t_swapcontext.c b/contrib/netbsd-tests/lib/libpthread/t_swapcontext.c
index 8fd231404542..c0c375f77331 100644
--- a/contrib/netbsd-tests/lib/libpthread/t_swapcontext.c
+++ b/contrib/netbsd-tests/lib/libpthread/t_swapcontext.c
@@ -28,6 +28,9 @@
#include <sys/cdefs.h>
__RCSID("$NetBSD");
+#ifdef __FreeBSD__
+#include <sys/types.h>
+#endif
#include <pthread.h>
#include <ucontext.h>
#include <stdio.h>
diff --git a/contrib/tcpdump/interface.h b/contrib/tcpdump/interface.h
index 5efecb80c23e..299d010ea279 100644
--- a/contrib/tcpdump/interface.h
+++ b/contrib/tcpdump/interface.h
@@ -148,8 +148,6 @@ extern uint16_t create_osi_cksum(const uint8_t *, int, int);
#include <pcap.h>
-extern void pfsync_ip_print(const u_char *, u_int);
-
extern char *q922_string(const u_char *);
extern char *smb_errstr(int, int);
extern const char *nt_errstr(uint32_t);
diff --git a/contrib/tcpdump/netdissect.h b/contrib/tcpdump/netdissect.h
index 55d45b2a9ea6..a40869c0fd89 100644
--- a/contrib/tcpdump/netdissect.h
+++ b/contrib/tcpdump/netdissect.h
@@ -540,6 +540,8 @@ extern void timed_print(netdissect_options *, const u_char *);
extern void m3ua_print(netdissect_options *, const u_char *, const u_int);
extern void aoe_print(netdissect_options *, const u_char *, const u_int);
+extern void pfsync_ip_print(netdissect_options *, const u_char *, u_int);
+
/* stuff that has not yet been rototiled */
#if 0
diff --git a/contrib/tcpdump/print-ip.c b/contrib/tcpdump/print-ip.c
index 1add0c76335e..0e3ae96530c8 100644
--- a/contrib/tcpdump/print-ip.c
+++ b/contrib/tcpdump/print-ip.c
@@ -487,7 +487,7 @@ again:
#if defined(HAVE_NET_PFVAR_H)
case IPPROTO_PFSYNC:
- pfsync_ip_print(ipds->cp, ipds->len);
+ pfsync_ip_print(ndo, ipds->cp, ipds->len);
break;
#endif
diff --git a/contrib/tcpdump/print-pfsync.c b/contrib/tcpdump/print-pfsync.c
index ed7f8dd56a40..eb9aed8f3dfa 100644
--- a/contrib/tcpdump/print-pfsync.c
+++ b/contrib/tcpdump/print-pfsync.c
@@ -47,10 +47,12 @@
#include "interface.h"
#include "addrtoname.h"
-static void pfsync_print(struct pfsync_header *, const u_char *, u_int);
-static void print_src_dst(const struct pfsync_state_peer *,
+static void pfsync_print(netdissect_options *, struct pfsync_header *,
+ const u_char *, u_int);
+static void print_src_dst(netdissect_options *,
+ const struct pfsync_state_peer *,
const struct pfsync_state_peer *, uint8_t);
-static void print_state(struct pfsync_state *);
+static void print_state(netdissect_options *, struct pfsync_state *);
#ifdef notyet
void
@@ -62,7 +64,7 @@ pfsync_if_print(u_char *user, const struct pcap_pkthdr *h,
ts_print(&h->ts);
if (caplen < PFSYNC_HDRLEN) {
- printf("[|pfsync]");
+ ND_PRINT((ndo, "[|pfsync]"));
goto out;
}
@@ -73,36 +75,36 @@ out:
if (xflag) {
default_print((const u_char *)p, caplen);
}
- putchar('\n');
+ safeputchar(ndo, '\n');
}
#endif /* notyet */
void
-pfsync_ip_print(const u_char *bp, u_int len)
+pfsync_ip_print(netdissect_options *ndo , const u_char *bp, u_int len)
{
struct pfsync_header *hdr = (struct pfsync_header *)bp;
if (len < PFSYNC_HDRLEN)
- printf("[|pfsync]");
+ ND_PRINT((ndo, "[|pfsync]"));
else
- pfsync_print(hdr, bp + sizeof(struct pfsync_header),
+ pfsync_print(ndo, hdr, bp + sizeof(struct pfsync_header),
len - sizeof(struct pfsync_header));
}
struct pfsync_actions {
const char *name;
size_t len;
- void (*print)(const void *);
+ void (*print)(netdissect_options *, const void *);
};
-static void pfsync_print_clr(const void *);
-static void pfsync_print_state(const void *);
-static void pfsync_print_ins_ack(const void *);
-static void pfsync_print_upd_c(const void *);
-static void pfsync_print_upd_req(const void *);
-static void pfsync_print_del_c(const void *);
-static void pfsync_print_bus(const void *);
-static void pfsync_print_tdb(const void *);
+static void pfsync_print_clr(netdissect_options *, const void *);
+static void pfsync_print_state(netdissect_options *, const void *);
+static void pfsync_print_ins_ack(netdissect_options *, const void *);
+static void pfsync_print_upd_c(netdissect_options *, const void *);
+static void pfsync_print_upd_req(netdissect_options *, const void *);
+static void pfsync_print_del_c(netdissect_options *, const void *);
+static void pfsync_print_bus(netdissect_options *, const void *);
+static void pfsync_print_tdb(netdissect_options *, const void *);
struct pfsync_actions actions[] = {
{ "clear all", sizeof(struct pfsync_clr), pfsync_print_clr },
@@ -125,7 +127,8 @@ struct pfsync_actions actions[] = {
};
static void
-pfsync_print(struct pfsync_header *hdr, const u_char *bp, u_int len)
+pfsync_print(netdissect_options *ndo, struct pfsync_header *hdr,
+ const u_char *bp, u_int len)
{
struct pfsync_subheader *subh;
int count, plen, i;
@@ -133,7 +136,7 @@ pfsync_print(struct pfsync_header *hdr, const u_char *bp, u_int len)
plen = ntohs(hdr->len);
- printf("PFSYNCv%d len %d", hdr->version, plen);
+ ND_PRINT((ndo, "PFSYNCv%d len %d", hdr->version, plen));
if (hdr->version != PFSYNC_VERSION)
return;
@@ -150,19 +153,22 @@ pfsync_print(struct pfsync_header *hdr, const u_char *bp, u_int len)
plen -= sizeof(*subh);
if (subh->action >= PFSYNC_ACT_MAX) {
- printf("\n act UNKNOWN id %d", subh->action);
+ ND_PRINT((ndo, "\n act UNKNOWN id %d",
+ subh->action));
return;
}
count = ntohs(subh->count);
- printf("\n %s count %d", actions[subh->action].name, count);
+ ND_PRINT((ndo, "\n %s count %d", actions[subh->action].name,
+ count));
alen = actions[subh->action].len;
if (subh->action == PFSYNC_ACT_EOF)
return;
if (actions[subh->action].print == NULL) {
- printf("\n unimplemented action %hhu", subh->action);
+ ND_PRINT((ndo, "\n unimplemented action %hhu",
+ subh->action));
return;
}
@@ -173,7 +179,7 @@ pfsync_print(struct pfsync_header *hdr, const u_char *bp, u_int len)
}
if (vflag)
- actions[subh->action].print(bp);
+ actions[subh->action].print(ndo, bp);
bp += alen;
len -= alen;
@@ -182,78 +188,78 @@ pfsync_print(struct pfsync_header *hdr, const u_char *bp, u_int len)
}
if (plen > 0) {
- printf("\n ...");
+ ND_PRINT((ndo, "\n ..."));
return;
}
if (plen < 0) {
- printf("\n invalid header length");
+ ND_PRINT((ndo, "\n invalid header length"));
return;
}
if (len > 0)
- printf("\n invalid packet length");
+ ND_PRINT((ndo, "\n invalid packet length"));
}
static void
-pfsync_print_clr(const void *bp)
+pfsync_print_clr(netdissect_options *ndo, const void *bp)
{
const struct pfsync_clr *clr = bp;
- printf("\n\tcreatorid: %08x", htonl(clr->creatorid));
+ ND_PRINT((ndo, "\n\tcreatorid: %08x", htonl(clr->creatorid)));
if (clr->ifname[0] != '\0')
- printf(" interface: %s", clr->ifname);
+ ND_PRINT((ndo, " interface: %s", clr->ifname));
}
static void
-pfsync_print_state(const void *bp)
+pfsync_print_state(netdissect_options *ndo, const void *bp)
{
struct pfsync_state *st = (struct pfsync_state *)bp;
- putchar('\n');
- print_state(st);
+ safeputchar(ndo, '\n');
+ print_state(ndo, st);
}
static void
-pfsync_print_ins_ack(const void *bp)
+pfsync_print_ins_ack(netdissect_options *ndo, const void *bp)
{
const struct pfsync_ins_ack *iack = bp;
- printf("\n\tid: %016jx creatorid: %08x", (uintmax_t )be64toh(iack->id),
- ntohl(iack->creatorid));
+ ND_PRINT((ndo, "\n\tid: %016jx creatorid: %08x",
+ (uintmax_t)be64toh(iack->id), ntohl(iack->creatorid)));
}
static void
-pfsync_print_upd_c(const void *bp)
+pfsync_print_upd_c(netdissect_options *ndo, const void *bp)
{
const struct pfsync_upd_c *u = bp;
- printf("\n\tid: %016jx creatorid: %08x", (uintmax_t )be64toh(u->id),
- ntohl(u->creatorid));
+ ND_PRINT((ndo, "\n\tid: %016jx creatorid: %08x",
+ (uintmax_t)be64toh(u->id), ntohl(u->creatorid)));
if (vflag > 2) {
- printf("\n\tTCP? :");
- print_src_dst(&u->src, &u->dst, IPPROTO_TCP);
+ ND_PRINT((ndo, "\n\tTCP? :"));
+ print_src_dst(ndo, &u->src, &u->dst, IPPROTO_TCP);
}
}
static void
-pfsync_print_upd_req(const void *bp)
+pfsync_print_upd_req(netdissect_options *ndo, const void *bp)
{
const struct pfsync_upd_req *ur = bp;
- printf("\n\tid: %016jx creatorid: %08x", (uintmax_t )be64toh(ur->id),
- ntohl(ur->creatorid));
+ ND_PRINT((ndo, "\n\tid: %016jx creatorid: %08x",
+ (uintmax_t)be64toh(ur->id), ntohl(ur->creatorid)));
}
static void
-pfsync_print_del_c(const void *bp)
+pfsync_print_del_c(netdissect_options *ndo, const void *bp)
{
const struct pfsync_del_c *d = bp;
- printf("\n\tid: %016jx creatorid: %08x", (uintmax_t )be64toh(d->id),
- ntohl(d->creatorid));
+ ND_PRINT((ndo, "\n\tid: %016jx creatorid: %08x",
+ (uintmax_t)be64toh(d->id), ntohl(d->creatorid)));
}
static void
-pfsync_print_bus(const void *bp)
+pfsync_print_bus(netdissect_options *ndo, const void *bp)
{
const struct pfsync_bus *b = bp;
uint32_t endtime;
@@ -278,95 +284,95 @@ pfsync_print_bus(const void *bp)
break;
}
- printf("\n\tcreatorid: %08x age: %.2u:%.2u:%.2u status: %s",
- htonl(b->creatorid), endtime, min, sec, status);
+ ND_PRINT((ndo, "\n\tcreatorid: %08x age: %.2u:%.2u:%.2u status: %s",
+ htonl(b->creatorid), endtime, min, sec, status));
}
static void
-pfsync_print_tdb(const void *bp)
+pfsync_print_tdb(netdissect_options *ndo, const void *bp)
{
const struct pfsync_tdb *t = bp;
- printf("\n\tspi: 0x%08x rpl: %ju cur_bytes: %ju",
+ ND_PRINT((ndo, "\n\tspi: 0x%08x rpl: %ju cur_bytes: %ju",
ntohl(t->spi), (uintmax_t )be64toh(t->rpl),
- (uintmax_t )be64toh(t->cur_bytes));
+ (uintmax_t )be64toh(t->cur_bytes)));
}
static void
-print_host(struct pf_addr *addr, uint16_t port, sa_family_t af,
- const char *proto)
+print_host(netdissect_options *ndo, struct pf_addr *addr, uint16_t port,
+ sa_family_t af, const char *proto)
{
char buf[48];
if (inet_ntop(af, addr, buf, sizeof(buf)) == NULL)
- printf("?");
+ ND_PRINT((ndo, "?"));
else
- printf("%s", buf);
+ ND_PRINT((ndo, "%s", buf));
if (port)
- printf(".%hu", ntohs(port));
+ ND_PRINT((ndo, ".%hu", ntohs(port)));
}
static void
-print_seq(const struct pfsync_state_peer *p)
+print_seq(netdissect_options *ndo, const struct pfsync_state_peer *p)
{
if (p->seqdiff)
- printf("[%u + %u](+%u)", ntohl(p->seqlo),
- ntohl(p->seqhi) - ntohl(p->seqlo), ntohl(p->seqdiff));
+ ND_PRINT((ndo, "[%u + %u](+%u)", ntohl(p->seqlo),
+ ntohl(p->seqhi) - ntohl(p->seqlo), ntohl(p->seqdiff)));
else
- printf("[%u + %u]", ntohl(p->seqlo),
- ntohl(p->seqhi) - ntohl(p->seqlo));
+ ND_PRINT((ndo, "[%u + %u]", ntohl(p->seqlo),
+ ntohl(p->seqhi) - ntohl(p->seqlo)));
}
static void
-print_src_dst(const struct pfsync_state_peer *src,
+print_src_dst(netdissect_options *ndo, const struct pfsync_state_peer *src,
const struct pfsync_state_peer *dst, uint8_t proto)
{
if (proto == IPPROTO_TCP) {
if (src->state <= TCPS_TIME_WAIT &&
dst->state <= TCPS_TIME_WAIT)
- printf(" %s:%s", tcpstates[src->state],
- tcpstates[dst->state]);
+ ND_PRINT((ndo, " %s:%s", tcpstates[src->state],
+ tcpstates[dst->state]));
else if (src->state == PF_TCPS_PROXY_SRC ||
dst->state == PF_TCPS_PROXY_SRC)
- printf(" PROXY:SRC");
+ ND_PRINT((ndo, " PROXY:SRC"));
else if (src->state == PF_TCPS_PROXY_DST ||
dst->state == PF_TCPS_PROXY_DST)
- printf(" PROXY:DST");
+ ND_PRINT((ndo, " PROXY:DST"));
else
- printf(" <BAD STATE LEVELS %u:%u>",
- src->state, dst->state);
+ ND_PRINT((ndo, " <BAD STATE LEVELS %u:%u>",
+ src->state, dst->state));
if (vflag > 1) {
- printf("\n\t");
- print_seq(src);
+ ND_PRINT((ndo, "\n\t"));
+ print_seq(ndo, src);
if (src->wscale && dst->wscale)
- printf(" wscale %u",
- src->wscale & PF_WSCALE_MASK);
- printf(" ");
- print_seq(dst);
+ ND_PRINT((ndo, " wscale %u",
+ src->wscale & PF_WSCALE_MASK));
+ ND_PRINT((ndo, " "));
+ print_seq(ndo, dst);
if (src->wscale && dst->wscale)
- printf(" wscale %u",
- dst->wscale & PF_WSCALE_MASK);
+ ND_PRINT((ndo, " wscale %u",
+ dst->wscale & PF_WSCALE_MASK));
}
} else if (proto == IPPROTO_UDP && src->state < PFUDPS_NSTATES &&
dst->state < PFUDPS_NSTATES) {
const char *states[] = PFUDPS_NAMES;
- printf(" %s:%s", states[src->state], states[dst->state]);
+ ND_PRINT((ndo, " %s:%s", states[src->state], states[dst->state]));
} else if (proto != IPPROTO_ICMP && src->state < PFOTHERS_NSTATES &&
dst->state < PFOTHERS_NSTATES) {
/* XXX ICMP doesn't really have state levels */
const char *states[] = PFOTHERS_NAMES;
- printf(" %s:%s", states[src->state], states[dst->state]);
+ ND_PRINT((ndo, " %s:%s", states[src->state], states[dst->state]));
} else {
- printf(" %u:%u", src->state, dst->state);
+ ND_PRINT((ndo, " %u:%u", src->state, dst->state));
}
}
static void
-print_state(struct pfsync_state *s)
+print_state(netdissect_options *ndo, struct pfsync_state *s)
{
struct pfsync_state_peer *src, *dst;
struct pfsync_state_key *sk, *nk;
@@ -387,29 +393,29 @@ print_state(struct pfsync_state *s)
if (s->proto == IPPROTO_ICMP || s->proto == IPPROTO_ICMPV6)
sk->port[1] = nk->port[1];
}
- printf("\t%s ", s->ifname);
- printf("proto %u ", s->proto);
+ ND_PRINT((ndo, "\t%s ", s->ifname));
+ ND_PRINT((ndo, "proto %u ", s->proto));
- print_host(&nk->addr[1], nk->port[1], s->af, NULL);
+ print_host(ndo, &nk->addr[1], nk->port[1], s->af, NULL);
if (PF_ANEQ(&nk->addr[1], &sk->addr[1], s->af) ||
nk->port[1] != sk->port[1]) {
- printf(" (");
- print_host(&sk->addr[1], sk->port[1], s->af, NULL);
- printf(")");
+ ND_PRINT((ndo, " ("));
+ print_host(ndo, &sk->addr[1], sk->port[1], s->af, NULL);
+ ND_PRINT((ndo, ")"));
}
if (s->direction == PF_OUT)
- printf(" -> ");
+ ND_PRINT((ndo, " -> "));
else
- printf(" <- ");
- print_host(&nk->addr[0], nk->port[0], s->af, NULL);
+ ND_PRINT((ndo, " <- "));
+ print_host(ndo, &nk->addr[0], nk->port[0], s->af, NULL);
if (PF_ANEQ(&nk->addr[0], &sk->addr[0], s->af) ||
nk->port[0] != sk->port[0]) {
- printf(" (");
- print_host(&sk->addr[0], sk->port[0], s->af, NULL);
- printf(")");
+ ND_PRINT((ndo, " ("));
+ print_host(ndo, &sk->addr[0], sk->port[0], s->af, NULL);
+ ND_PRINT((ndo, ")"));
}
- print_src_dst(src, dst, s->proto);
+ print_src_dst(ndo, src, dst, s->proto);
if (vflag > 1) {
uint64_t packets[2];
@@ -421,30 +427,30 @@ print_state(struct pfsync_state *s)
creation /= 60;
min = creation % 60;
creation /= 60;
- printf("\n\tage %.2u:%.2u:%.2u", creation, min, sec);
+ ND_PRINT((ndo, "\n\tage %.2u:%.2u:%.2u", creation, min, sec));
sec = expire % 60;
expire /= 60;
min = expire % 60;
expire /= 60;
- printf(", expires in %.2u:%.2u:%.2u", expire, min, sec);
+ ND_PRINT((ndo, ", expires in %.2u:%.2u:%.2u", expire, min, sec));
bcopy(s->packets[0], &packets[0], sizeof(uint64_t));
bcopy(s->packets[1], &packets[1], sizeof(uint64_t));
bcopy(s->bytes[0], &bytes[0], sizeof(uint64_t));
bcopy(s->bytes[1], &bytes[1], sizeof(uint64_t));
- printf(", %ju:%ju pkts, %ju:%ju bytes",
+ ND_PRINT((ndo, ", %ju:%ju pkts, %ju:%ju bytes",
be64toh(packets[0]), be64toh(packets[1]),
- be64toh(bytes[0]), be64toh(bytes[1]));
+ be64toh(bytes[0]), be64toh(bytes[1])));
if (s->anchor != ntohl(-1))
- printf(", anchor %u", ntohl(s->anchor));
+ ND_PRINT((ndo, ", anchor %u", ntohl(s->anchor)));
if (s->rule != ntohl(-1))
- printf(", rule %u", ntohl(s->rule));
+ ND_PRINT((ndo, ", rule %u", ntohl(s->rule)));
}
if (vflag > 1) {
uint64_t id;
bcopy(&s->id, &id, sizeof(uint64_t));
- printf("\n\tid: %016jx creatorid: %08x",
- (uintmax_t )be64toh(id), ntohl(s->creatorid));
+ ND_PRINT((ndo, "\n\tid: %016jx creatorid: %08x",
+ (uintmax_t )be64toh(id), ntohl(s->creatorid)));
}
}
diff --git a/contrib/unbound/Makefile.in b/contrib/unbound/Makefile.in
index 02532a951d2f..0c7e0c638b9c 100644
--- a/contrib/unbound/Makefile.in
+++ b/contrib/unbound/Makefile.in
@@ -459,8 +459,8 @@ strip:
$(STRIP) unbound$(EXEEXT)
$(STRIP) unbound-checkconf$(EXEEXT)
$(STRIP) unbound-control$(EXEEXT)
- $(STRIP) unbound-host$(EXEEXT)
- $(STRIP) unbound-anchor$(EXEEXT)
+ $(STRIP) unbound-host$(EXEEXT) || $(STRIP) .libs/unbound-host$(EXEEXT)
+ $(STRIP) unbound-anchor$(EXEEXT) || $(STRIP) .libs/unbound-anchor$(EXEEXT)
pythonmod-install:
$(INSTALL) -m 755 -d $(DESTDIR)$(PYTHON_SITE_PKG)
@@ -576,6 +576,7 @@ depend:
-e 's?$$(srcdir)/util/configlexer.c?util/configlexer.c?g' \
-e 's?$$(srcdir)/util/configparser.c?util/configparser.c?g' \
-e 's?$$(srcdir)/util/configparser.h?util/configparser.h?g' \
+ -e 's?$$(srcdir)/dnstap/dnstap_config.h??g' \
-e 's?$$(srcdir)/pythonmod/pythonmod.h?$$(PYTHONMOD_HEADER)?g' \
-e 's!\(.*\)\.o[ :]*!\1.lo \1.o: !g' \
> $(DEPEND_TMP)
@@ -689,13 +690,14 @@ iter_utils.lo iter_utils.o: $(srcdir)/iterator/iter_utils.c config.h $(srcdir)/i
$(srcdir)/validator/val_utils.h $(srcdir)/validator/val_sigcrypt.h $(srcdir)/ldns/sbuffer.h
listen_dnsport.lo listen_dnsport.o: $(srcdir)/services/listen_dnsport.c config.h \
$(srcdir)/services/listen_dnsport.h $(srcdir)/util/netevent.h $(srcdir)/services/outside_network.h \
- $(srcdir)/util/rbtree.h $(srcdir)/util/log.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \
- $(srcdir)/ldns/sbuffer.h
+ $(srcdir)/util/rbtree.h $(srcdir)/util/log.h $(srcdir)/util/config_file.h \
+ $(srcdir)/util/net_help.h $(srcdir)/ldns/sbuffer.h
localzone.lo localzone.o: $(srcdir)/services/localzone.c config.h $(srcdir)/services/localzone.h \
$(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/ldns/str2wire.h $(srcdir)/ldns/rrdef.h \
$(srcdir)/ldns/sbuffer.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/data/dname.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgencode.h \
- $(srcdir)/util/net_help.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/ldns/pkthdr.h
+ $(srcdir)/util/net_help.h $(srcdir)/util/netevent.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/ldns/pkthdr.h
mesh.lo mesh.o: $(srcdir)/services/mesh.c config.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/netevent.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
$(srcdir)/util/log.h $(srcdir)/ldns/pkthdr.h $(srcdir)/ldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
@@ -711,15 +713,16 @@ modstack.lo modstack.o: $(srcdir)/services/modstack.c config.h $(srcdir)/service
$(srcdir)/services/outbound_list.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h
outbound_list.lo outbound_list.o: $(srcdir)/services/outbound_list.c config.h \
$(srcdir)/services/outbound_list.h $(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h \
- $(srcdir)/util/netevent.h
+ $(srcdir)/util/netevent.h
outside_network.lo outside_network.o: $(srcdir)/services/outside_network.c config.h \
$(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h $(srcdir)/util/netevent.h \
- $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/rtt.h $(srcdir)/util/data/msgparse.h $(srcdir)/ldns/pkthdr.h \
- $(srcdir)/ldns/rrdef.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/random.h \
- $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
- $(srcdir)/services/modstack.h $(srcdir)/ldns/sbuffer.h \
+ $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/infra.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/rtt.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/ldns/pkthdr.h $(srcdir)/ldns/rrdef.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h \
+ $(srcdir)/util/net_help.h $(srcdir)/util/random.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h \
+ $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/ldns/sbuffer.h \
+ $(srcdir)/dnstap/dnstap.h \
alloc.lo alloc.o: $(srcdir)/util/alloc.c config.h $(srcdir)/util/alloc.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/regional.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
@@ -732,8 +735,8 @@ config_file.lo config_file.o: $(srcdir)/util/config_file.c config.h $(srcdir)/ut
$(srcdir)/ldns/pkthdr.h $(srcdir)/ldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/regional.h $(srcdir)/util/fptr_wlist.h \
$(srcdir)/util/netevent.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
- $(srcdir)/services/modstack.h $(srcdir)/util/data/dname.h $(srcdir)/ldns/wire2str.h $(srcdir)/ldns/parseutil.h \
- $(srcdir)/util/iana_ports.inc
+ $(srcdir)/services/modstack.h $(srcdir)/util/data/dname.h $(srcdir)/util/rtt.h $(srcdir)/ldns/wire2str.h \
+ $(srcdir)/ldns/parseutil.h $(srcdir)/util/iana_ports.inc
configlexer.lo configlexer.o: util/configlexer.c config.h $(srcdir)/util/configyyrename.h \
$(srcdir)/util/config_file.h util/configparser.h
configparser.lo configparser.o: util/configparser.c config.h $(srcdir)/util/configyyrename.h \
@@ -743,15 +746,16 @@ fptr_wlist.lo fptr_wlist.o: $(srcdir)/util/fptr_wlist.c config.h $(srcdir)/util/
$(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/ldns/pkthdr.h $(srcdir)/ldns/rrdef.h $(srcdir)/util/tube.h \
$(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/util/mini_event.h \
- $(srcdir)/util/rbtree.h $(srcdir)/services/outside_network.h $(srcdir)/services/localzone.h \
- $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/services/cache/rrset.h \
- $(srcdir)/util/storage/slabhash.h $(srcdir)/dns64/dns64.h $(srcdir)/iterator/iterator.h \
- $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/validator/validator.h \
- $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_anchor.h $(srcdir)/validator/val_nsec3.h \
- $(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_kentry.h $(srcdir)/validator/val_neg.h \
- $(srcdir)/validator/autotrust.h $(srcdir)/util/storage/dnstree.h $(srcdir)/libunbound/libworker.h \
- $(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/libunbound/unbound.h \
- $(srcdir)/libunbound/worker.h $(srcdir)/ldns/sbuffer.h $(srcdir)/util/config_file.h
+ $(srcdir)/util/rbtree.h $(srcdir)/services/outside_network.h \
+ $(srcdir)/services/localzone.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
+ $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/dns64/dns64.h \
+ $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h \
+ $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_anchor.h \
+ $(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_kentry.h \
+ $(srcdir)/validator/val_neg.h $(srcdir)/validator/autotrust.h $(srcdir)/util/storage/dnstree.h \
+ $(srcdir)/libunbound/libworker.h $(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h \
+ $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/worker.h $(srcdir)/ldns/sbuffer.h \
+ $(srcdir)/util/config_file.h
locks.lo locks.o: $(srcdir)/util/locks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h
log.lo log.o: $(srcdir)/util/log.c config.h $(srcdir)/util/log.h $(srcdir)/util/locks.h $(srcdir)/ldns/sbuffer.h
mini_event.lo mini_event.o: $(srcdir)/util/mini_event.c config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
@@ -767,6 +771,7 @@ netevent.lo netevent.o: $(srcdir)/util/netevent.c config.h $(srcdir)/util/neteve
$(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/ldns/pkthdr.h $(srcdir)/ldns/rrdef.h $(srcdir)/util/tube.h \
$(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/ldns/sbuffer.h \
+ $(srcdir)/dnstap/dnstap.h \
$(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h
net_help.lo net_help.o: $(srcdir)/util/net_help.c config.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/module.h \
@@ -854,8 +859,8 @@ val_nsec.lo val_nsec.o: $(srcdir)/validator/val_nsec.c config.h $(srcdir)/valida
$(srcdir)/validator/val_utils.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/dname.h \
$(srcdir)/util/net_help.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/ldns/pkthdr.h \
$(srcdir)/ldns/rrdef.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h
-val_secalgo.lo val_secalgo.o: $(srcdir)/validator/val_secalgo.c config.h $(srcdir)/validator/val_secalgo.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+val_secalgo.lo val_secalgo.o: $(srcdir)/validator/val_secalgo.c config.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_secalgo.h \
$(srcdir)/ldns/rrdef.h $(srcdir)/ldns/keyraw.h \
$(srcdir)/ldns/sbuffer.h \
@@ -884,6 +889,11 @@ dns64.lo dns64.o: $(srcdir)/dns64/dns64.c config.h $(srcdir)/dns64/dns64.h $(src
$(srcdir)/util/regional.h
checklocks.lo checklocks.o: $(srcdir)/testcode/checklocks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/testcode/checklocks.h
+dnstap.lo dnstap.o: $(srcdir)/dnstap/dnstap.c config.h $(srcdir)/ldns/sbuffer.h \
+ $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/util/netevent.h \
+ $(srcdir)/dnstap/dnstap.h \
+ $(srcdir)/dnstap/dnstap.pb-c.h
+dnstap.pb-c.lo dnstap.pb-c.o: $(srcdir)/dnstap/dnstap.pb-c.c $(srcdir)/dnstap/dnstap.pb-c.h
unitanchor.lo unitanchor.o: $(srcdir)/testcode/unitanchor.c config.h $(srcdir)/util/log.h $(srcdir)/util/data/dname.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/testcode/unitmain.h \
$(srcdir)/validator/val_anchor.h $(srcdir)/util/rbtree.h $(srcdir)/ldns/sbuffer.h $(srcdir)/ldns/rrdef.h
@@ -894,7 +904,8 @@ unitlruhash.lo unitlruhash.o: $(srcdir)/testcode/unitlruhash.c config.h $(srcdir
$(srcdir)/util/log.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/storage/slabhash.h
unitmain.lo unitmain.o: $(srcdir)/testcode/unitmain.c config.h \
$(srcdir)/ldns/rrdef.h $(srcdir)/ldns/keyraw.h \
- $(srcdir)/util/log.h $(srcdir)/testcode/unitmain.h $(srcdir)/util/alloc.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h \
+ $(srcdir)/util/log.h \
+ $(srcdir)/testcode/unitmain.h $(srcdir)/util/alloc.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h \
$(srcdir)/util/config_file.h $(srcdir)/util/rtt.h $(srcdir)/services/cache/infra.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/random.h
unitmsgparse.lo unitmsgparse.o: $(srcdir)/testcode/unitmsgparse.c config.h $(srcdir)/util/log.h \
@@ -935,19 +946,21 @@ cachedump.lo cachedump.o: $(srcdir)/daemon/cachedump.c config.h \
$(srcdir)/ldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/netevent.h $(srcdir)/util/alloc.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/ldns/pkthdr.h $(srcdir)/ldns/rrdef.h \
- $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/util/module.h $(srcdir)/services/cache/rrset.h \
- $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/infra.h \
- $(srcdir)/util/rtt.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h \
- $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_delegpt.h \
- $(srcdir)/iterator/iter_utils.h $(srcdir)/iterator/iter_resptype.h $(srcdir)/iterator/iter_fwd.h \
- $(srcdir)/util/rbtree.h $(srcdir)/iterator/iter_hints.h $(srcdir)/util/storage/dnstree.h \
- $(srcdir)/ldns/wire2str.h $(srcdir)/ldns/str2wire.h
+ $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
+ $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
+ $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/util/regional.h \
+ $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h $(srcdir)/iterator/iterator.h \
+ $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/iterator/iter_utils.h \
+ $(srcdir)/iterator/iter_resptype.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/iterator/iter_hints.h $(srcdir)/util/storage/dnstree.h $(srcdir)/ldns/wire2str.h \
+ $(srcdir)/ldns/str2wire.h
daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h \
$(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
- $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/ldns/sbuffer.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/netevent.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/ldns/pkthdr.h $(srcdir)/ldns/rrdef.h \
- $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/util/module.h $(srcdir)/daemon/remote.h \
+ $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h \
+ $(srcdir)/ldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
+ $(srcdir)/util/netevent.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/ldns/pkthdr.h \
+ $(srcdir)/ldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/util/module.h \
+ $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/remote.h \
$(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/config_file.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h \
@@ -959,11 +972,12 @@ remote.lo remote.o: $(srcdir)/daemon/remote.c config.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/netevent.h $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/ldns/pkthdr.h $(srcdir)/ldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/util/module.h \
- $(srcdir)/daemon/daemon.h $(srcdir)/services/modstack.h $(srcdir)/daemon/cachedump.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/services/listen_dnsport.h \
- $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h \
- $(srcdir)/util/rtt.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/localzone.h \
- $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/data/dname.h $(srcdir)/validator/validator.h \
+ $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \
+ $(srcdir)/services/modstack.h $(srcdir)/daemon/cachedump.h $(srcdir)/util/config_file.h \
+ $(srcdir)/util/net_help.h $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
+ $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/localzone.h $(srcdir)/util/fptr_wlist.h \
+ $(srcdir)/util/tube.h $(srcdir)/util/data/dname.h $(srcdir)/validator/validator.h \
$(srcdir)/validator/val_utils.h $(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_kentry.h \
$(srcdir)/validator/val_anchor.h $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h \
$(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h $(srcdir)/util/storage/dnstree.h \
@@ -973,14 +987,15 @@ stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(s
$(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/ldns/sbuffer.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/netevent.h $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \
- $(srcdir)/ldns/pkthdr.h $(srcdir)/ldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/daemon/daemon.h \
- $(srcdir)/services/modstack.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
- $(srcdir)/services/outside_network.h $(srcdir)/util/config_file.h $(srcdir)/util/tube.h \
- $(srcdir)/util/net_help.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \
- $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h \
- $(srcdir)/util/rtt.h $(srcdir)/validator/val_kcache.h
+ $(srcdir)/ldns/pkthdr.h $(srcdir)/ldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
+ $(srcdir)/daemon/daemon.h $(srcdir)/services/modstack.h \
+ $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/outside_network.h \
+ $(srcdir)/util/config_file.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/validator/validator.h \
+ $(srcdir)/validator/val_utils.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
+ $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/validator/val_kcache.h
unbound.lo unbound.o: $(srcdir)/daemon/unbound.c config.h $(srcdir)/util/log.h $(srcdir)/daemon/daemon.h \
- $(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h \
+ $(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
+ $(srcdir)/daemon/remote.h \
$(srcdir)/util/config_file.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/services/listen_dnsport.h $(srcdir)/util/netevent.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
@@ -993,7 +1008,8 @@ worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(sr
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
$(srcdir)/util/netevent.h $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/ldns/pkthdr.h $(srcdir)/ldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/util/module.h \
- $(srcdir)/daemon/daemon.h $(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h \
+ $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \
+ $(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h \
$(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/config_file.h $(srcdir)/util/regional.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/services/listen_dnsport.h $(srcdir)/services/outside_network.h \
@@ -1008,9 +1024,10 @@ testbound.lo testbound.o: $(srcdir)/testcode/testbound.c config.h $(srcdir)/test
$(srcdir)/daemon/remote.h \
$(srcdir)/util/config_file.h $(srcdir)/ldns/keyraw.h $(srcdir)/daemon/unbound.c $(srcdir)/util/log.h \
$(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
- $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h $(srcdir)/services/listen_dnsport.h \
- $(srcdir)/services/cache/rrset.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h \
- $(srcdir)/util/rtt.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h \
+ $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
+ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/ldns/pkthdr.h $(srcdir)/ldns/rrdef.h $(srcdir)/util/tube.h \
$(srcdir)/services/mesh.h $(srcdir)/util/net_help.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h
testpkts.lo testpkts.o: $(srcdir)/testcode/testpkts.c config.h $(srcdir)/testcode/testpkts.h \
@@ -1021,7 +1038,8 @@ worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(sr
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
$(srcdir)/util/netevent.h $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/ldns/pkthdr.h $(srcdir)/ldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/util/module.h \
- $(srcdir)/daemon/daemon.h $(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h \
+ $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \
+ $(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h \
$(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/config_file.h $(srcdir)/util/regional.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/services/listen_dnsport.h $(srcdir)/services/outside_network.h \
@@ -1036,10 +1054,11 @@ acl_list.lo acl_list.o: $(srcdir)/daemon/acl_list.c config.h $(srcdir)/daemon/ac
$(srcdir)/util/config_file.h $(srcdir)/util/net_help.h
daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h \
$(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
- $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/ldns/sbuffer.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/netevent.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/ldns/pkthdr.h $(srcdir)/ldns/rrdef.h \
- $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/util/module.h $(srcdir)/daemon/remote.h \
+ $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h \
+ $(srcdir)/ldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
+ $(srcdir)/util/netevent.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/ldns/pkthdr.h \
+ $(srcdir)/ldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/util/module.h \
+ $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/remote.h \
$(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/config_file.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h \
@@ -1049,12 +1068,12 @@ stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(s
$(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/ldns/sbuffer.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/netevent.h $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \
- $(srcdir)/ldns/pkthdr.h $(srcdir)/ldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/daemon/daemon.h \
- $(srcdir)/services/modstack.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
- $(srcdir)/services/outside_network.h $(srcdir)/util/config_file.h $(srcdir)/util/tube.h \
- $(srcdir)/util/net_help.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \
- $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h \
- $(srcdir)/util/rtt.h $(srcdir)/validator/val_kcache.h
+ $(srcdir)/ldns/pkthdr.h $(srcdir)/ldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
+ $(srcdir)/daemon/daemon.h $(srcdir)/services/modstack.h \
+ $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/outside_network.h \
+ $(srcdir)/util/config_file.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/validator/validator.h \
+ $(srcdir)/validator/val_utils.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
+ $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/validator/val_kcache.h
replay.lo replay.o: $(srcdir)/testcode/replay.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
$(srcdir)/util/config_file.h $(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/testcode/testpkts.h \
$(srcdir)/util/rbtree.h $(srcdir)/testcode/fake_event.h $(srcdir)/ldns/str2wire.h $(srcdir)/ldns/rrdef.h
@@ -1063,10 +1082,10 @@ fake_event.lo fake_event.o: $(srcdir)/testcode/fake_event.c config.h $(srcdir)/t
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/ldns/pkthdr.h $(srcdir)/ldns/rrdef.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgencode.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/config_file.h $(srcdir)/services/listen_dnsport.h \
- $(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h $(srcdir)/services/cache/infra.h \
- $(srcdir)/util/rtt.h $(srcdir)/testcode/replay.h $(srcdir)/testcode/testpkts.h $(srcdir)/util/fptr_wlist.h \
- $(srcdir)/util/module.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h \
- $(srcdir)/ldns/sbuffer.h $(srcdir)/ldns/wire2str.h $(srcdir)/ldns/str2wire.h
+ $(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/testcode/replay.h $(srcdir)/testcode/testpkts.h \
+ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
+ $(srcdir)/services/modstack.h $(srcdir)/ldns/sbuffer.h $(srcdir)/ldns/wire2str.h $(srcdir)/ldns/str2wire.h
lock_verify.lo lock_verify.o: $(srcdir)/testcode/lock_verify.c config.h $(srcdir)/util/log.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/locks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
@@ -1118,13 +1137,14 @@ libworker.lo libworker.o: $(srcdir)/libunbound/libworker.c config.h \
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h \
$(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/worker.h \
$(srcdir)/ldns/sbuffer.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/services/outside_network.h \
- $(srcdir)/util/netevent.h $(srcdir)/services/mesh.h $(srcdir)/util/data/msgparse.h $(srcdir)/ldns/pkthdr.h \
- $(srcdir)/ldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/services/localzone.h \
- $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/outbound_list.h \
- $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/regional.h $(srcdir)/util/random.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/net_help.h \
- $(srcdir)/util/data/dname.h $(srcdir)/util/data/msgencode.h $(srcdir)/iterator/iter_fwd.h \
- $(srcdir)/iterator/iter_hints.h $(srcdir)/util/storage/dnstree.h $(srcdir)/ldns/str2wire.h
+ $(srcdir)/util/netevent.h $(srcdir)/services/mesh.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/ldns/pkthdr.h $(srcdir)/ldns/rrdef.h $(srcdir)/util/module.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/services/localzone.h $(srcdir)/services/cache/rrset.h \
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/outbound_list.h $(srcdir)/util/fptr_wlist.h \
+ $(srcdir)/util/tube.h $(srcdir)/util/regional.h $(srcdir)/util/random.h $(srcdir)/util/config_file.h \
+ $(srcdir)/util/storage/lookup3.h $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h \
+ $(srcdir)/util/data/msgencode.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/ldns/str2wire.h
unbound-host.lo unbound-host.o: $(srcdir)/smallapp/unbound-host.c config.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/ldns/rrdef.h $(srcdir)/ldns/wire2str.h
asynclook.lo asynclook.o: $(srcdir)/testcode/asynclook.c config.h $(srcdir)/libunbound/unbound.h \
@@ -1144,7 +1164,8 @@ perf.lo perf.o: $(srcdir)/testcode/perf.c config.h $(srcdir)/util/log.h $(srcdir
delayer.lo delayer.o: $(srcdir)/testcode/delayer.c config.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h \
$(srcdir)/util/config_file.h $(srcdir)/ldns/sbuffer.h
unbound-control.lo unbound-control.o: $(srcdir)/smallapp/unbound-control.c config.h \
- $(srcdir)/util/log.h $(srcdir)/util/config_file.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h
+ $(srcdir)/util/log.h \
+ $(srcdir)/util/config_file.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h
unbound-anchor.lo unbound-anchor.o: $(srcdir)/smallapp/unbound-anchor.c config.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/ldns/rrdef.h \
@@ -1155,13 +1176,14 @@ pythonmod_utils.lo pythonmod_utils.o: $(srcdir)/pythonmod/pythonmod_utils.c conf
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/ldns/pkthdr.h $(srcdir)/ldns/rrdef.h \
$(srcdir)/util/netevent.h $(srcdir)/util/net_help.h $(srcdir)/services/cache/dns.h \
$(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/regional.h \
- $(srcdir)/ldns/sbuffer.h
+ $(srcdir)/iterator/iter_delegpt.h $(srcdir)/ldns/sbuffer.h
win_svc.lo win_svc.o: $(srcdir)/winrc/win_svc.c config.h $(srcdir)/winrc/win_svc.h $(srcdir)/winrc/w_inst.h \
$(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
- $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/ldns/sbuffer.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/netevent.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/ldns/pkthdr.h $(srcdir)/ldns/rrdef.h \
- $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/util/module.h $(srcdir)/daemon/remote.h \
+ $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h \
+ $(srcdir)/ldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
+ $(srcdir)/util/netevent.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/ldns/pkthdr.h \
+ $(srcdir)/ldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/util/module.h \
+ $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/remote.h \
$(srcdir)/util/config_file.h $(srcdir)/util/winsock_event.h
w_inst.lo w_inst.o: $(srcdir)/winrc/w_inst.c config.h $(srcdir)/winrc/w_inst.h $(srcdir)/winrc/win_svc.h
unbound-service-install.lo unbound-service-install.o: $(srcdir)/winrc/unbound-service-install.c config.h \
diff --git a/contrib/unbound/compat/getentropy_linux.c b/contrib/unbound/compat/getentropy_linux.c
index 32d58a7cdbb9..d4adab2852d4 100644
--- a/contrib/unbound/compat/getentropy_linux.c
+++ b/contrib/unbound/compat/getentropy_linux.c
@@ -93,6 +93,13 @@ getentropy(void *buf, size_t len)
return -1;
}
+#ifdef SYS_getrandom
+ /* try to use getrandom syscall introduced with kernel 3.17 */
+ ret = syscall(SYS_getrandom, buf, len, 0);
+ if (ret != -1)
+ return (ret);
+#endif /* SYS_getrandom */
+
/*
* Try to get entropy with /dev/urandom
*
@@ -474,22 +481,24 @@ getentropy_fallback(void *buf, size_t len)
HD(cnt);
}
-#ifdef AT_RANDOM
+#ifdef HAVE_GETAUXVAL
+# ifdef AT_RANDOM
/* Not as random as you think but we take what we are given */
p = (char *) getauxval(AT_RANDOM);
if (p)
HR(p, 16);
-#endif
-#ifdef AT_SYSINFO_EHDR
+# endif
+# ifdef AT_SYSINFO_EHDR
p = (char *) getauxval(AT_SYSINFO_EHDR);
if (p)
HR(p, pgs);
-#endif
-#ifdef AT_BASE
+# endif
+# ifdef AT_BASE
p = (char *) getauxval(AT_BASE);
if (p)
HD(p);
-#endif
+# endif
+#endif /* HAVE_GETAUXVAL */
SHA512_Final(results, &ctx);
memcpy((char*)buf + i, results, min(sizeof(results), len - i));
diff --git a/contrib/unbound/config.h b/contrib/unbound/config.h
index 8c93eb40cb16..641ddd32ab63 100644
--- a/contrib/unbound/config.h
+++ b/contrib/unbound/config.h
@@ -43,7 +43,7 @@
/* Whether the C compiler accepts the "unused" attribute */
#define HAVE_ATTR_UNUSED 1
-/* Define to 1 if your system has a working `chown' function. */
+/* Define to 1 if you have the `chown' function. */
#define HAVE_CHOWN 1
/* Define to 1 if you have the `chroot' function. */
@@ -147,6 +147,9 @@
/* Whether getaddrinfo is available */
#define HAVE_GETADDRINFO 1
+/* Define to 1 if you have the `getauxval' function. */
+/* #undef HAVE_GETAUXVAL */
+
/* Define to 1 if you have the `getentropy' function. */
/* #undef HAVE_GETENTROPY */
@@ -483,7 +486,7 @@
#define PACKAGE_NAME "unbound"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "unbound 1.5.1"
+#define PACKAGE_STRING "unbound 1.5.3"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "unbound"
@@ -492,7 +495,7 @@
#define PACKAGE_URL ""
/* Define to the version of this package. */
-#define PACKAGE_VERSION "1.5.1"
+#define PACKAGE_VERSION "1.5.3"
/* default pidfile location */
#define PIDFILE "/var/unbound/unbound.pid"
@@ -511,7 +514,7 @@
#define ROOT_CERT_FILE "/var/unbound/icannbundle.pem"
/* version number for resource files */
-#define RSRC_PACKAGE_VERSION 1,5,1,0
+#define RSRC_PACKAGE_VERSION 1,5,3,0
/* Directory to chdir to */
#define RUN_DIR "/var/unbound"
@@ -800,6 +803,10 @@
#define ARG_LL "%I64"
#endif
+#ifndef AF_LOCAL
+#define AF_LOCAL AF_UNIX
+#endif
+
#ifdef HAVE_ATTR_FORMAT
diff --git a/contrib/unbound/config.h.in b/contrib/unbound/config.h.in
index a8fd05cb5286..c36d4b98b0f7 100644
--- a/contrib/unbound/config.h.in
+++ b/contrib/unbound/config.h.in
@@ -42,7 +42,7 @@
/* Whether the C compiler accepts the "unused" attribute */
#undef HAVE_ATTR_UNUSED
-/* Define to 1 if your system has a working `chown' function. */
+/* Define to 1 if you have the `chown' function. */
#undef HAVE_CHOWN
/* Define to 1 if you have the `chroot' function. */
@@ -146,6 +146,9 @@
/* Whether getaddrinfo is available */
#undef HAVE_GETADDRINFO
+/* Define to 1 if you have the `getauxval' function. */
+#undef HAVE_GETAUXVAL
+
/* Define to 1 if you have the `getentropy' function. */
#undef HAVE_GETENTROPY
@@ -799,6 +802,10 @@
#define ARG_LL "%I64"
#endif
+#ifndef AF_LOCAL
+#define AF_LOCAL AF_UNIX
+#endif
+
#ifdef HAVE_ATTR_FORMAT
diff --git a/contrib/unbound/configure b/contrib/unbound/configure
index 8c6c0785260c..20ff33d72990 100755
--- a/contrib/unbound/configure
+++ b/contrib/unbound/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for unbound 1.5.1.
+# Generated by GNU Autoconf 2.69 for unbound 1.5.3.
#
# Report bugs to <unbound-bugs@nlnetlabs.nl>.
#
@@ -590,8 +590,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='unbound'
PACKAGE_TARNAME='unbound'
-PACKAGE_VERSION='1.5.1'
-PACKAGE_STRING='unbound 1.5.1'
+PACKAGE_VERSION='1.5.3'
+PACKAGE_STRING='unbound 1.5.3'
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl'
PACKAGE_URL=''
@@ -733,6 +733,7 @@ UNBOUND_PIDFILE
UNBOUND_SHARE_DIR
UNBOUND_CHROOT_DIR
UNBOUND_RUN_DIR
+ub_conf_dir
ub_conf_file
EGREP
GREP
@@ -1387,7 +1388,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures unbound 1.5.1 to adapt to many kinds of systems.
+\`configure' configures unbound 1.5.3 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1452,7 +1453,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of unbound 1.5.1:";;
+ short | recursive ) echo "Configuration of unbound 1.5.3:";;
esac
cat <<\_ACEOF
@@ -1627,7 +1628,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-unbound configure 1.5.1
+unbound configure 1.5.3
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2336,7 +2337,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by unbound $as_me 1.5.1, which was
+It was created by unbound $as_me 1.5.3, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2688,11 +2689,11 @@ UNBOUND_VERSION_MAJOR=1
UNBOUND_VERSION_MINOR=5
-UNBOUND_VERSION_MICRO=1
+UNBOUND_VERSION_MICRO=3
LIBUNBOUND_CURRENT=5
-LIBUNBOUND_REVISION=3
+LIBUNBOUND_REVISION=6
LIBUNBOUND_AGE=3
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
@@ -2732,7 +2733,9 @@ LIBUNBOUND_AGE=3
# 1.4.21 had 4:1:2
# 1.4.22 had 4:1:2
# 1.5.0 had 5:3:3 # adds ub_ctx_add_ta_autr
-# 1.5.1 had 5:4:3
+# 1.5.1 had 5:3:3
+# 1.5.2 had 5:5:3
+# 1.5.3 had 5:6:3
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
@@ -4047,6 +4050,30 @@ cat >>confdefs.h <<_ACEOF
#define CONFIGFILE "$hdr_config"
_ACEOF
+ub_conf_dir=`$as_dirname -- "$ub_conf_file" ||
+$as_expr X"$ub_conf_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ub_conf_file" : 'X\(//\)[^/]' \| \
+ X"$ub_conf_file" : 'X\(//\)$' \| \
+ X"$ub_conf_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ub_conf_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
# Determine run, chroot directory and pidfile locations
@@ -17932,7 +17959,7 @@ if test "$ac_res" != no; then :
fi
-for ac_func in tzset sigprocmask fcntl getpwnam getrlimit setrlimit setsid sbrk chroot kill sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent
+for ac_func in tzset sigprocmask fcntl getpwnam getrlimit setrlimit setsid sbrk chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -18227,6 +18254,62 @@ done
# this lib needed for sha2 on solaris
LIBS="$LIBS -lmd"
fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5
+$as_echo_n "checking for library containing clock_gettime... " >&6; }
+if ${ac_cv_search_clock_gettime+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char clock_gettime ();
+int
+main ()
+{
+return clock_gettime ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' rt; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_clock_gettime=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_clock_gettime+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_clock_gettime+:} false; then :
+
+else
+ ac_cv_search_clock_gettime=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_clock_gettime" >&5
+$as_echo "$ac_cv_search_clock_gettime" >&6; }
+ac_res=$ac_cv_search_clock_gettime
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
;;
Linux|*)
case " $LIBOBJS " in
@@ -18271,6 +18354,17 @@ fi
done
+ for ac_func in getauxval
+do :
+ ac_fn_c_check_func "$LINENO" "getauxval" "ac_cv_func_getauxval"
+if test "x$ac_cv_func_getauxval" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_GETAUXVAL 1
+_ACEOF
+
+fi
+done
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5
$as_echo_n "checking for library containing clock_gettime... " >&6; }
if ${ac_cv_search_clock_gettime+:} false; then :
@@ -18768,7 +18862,7 @@ _ACEOF
-version=1.5.1
+version=1.5.3
date=`date +'%b %e, %Y'`
@@ -19283,7 +19377,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by unbound $as_me 1.5.1, which was
+This file was extended by unbound $as_me 1.5.3, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -19349,7 +19443,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-unbound config.status 1.5.1
+unbound config.status 1.5.3
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/contrib/unbound/configure.ac b/contrib/unbound/configure.ac
index e06c1d6690aa..ae0525b540b0 100644
--- a/contrib/unbound/configure.ac
+++ b/contrib/unbound/configure.ac
@@ -10,14 +10,14 @@ sinclude(dnstap/dnstap.m4)
# must be numbers. ac_defun because of later processing
m4_define([VERSION_MAJOR],[1])
m4_define([VERSION_MINOR],[5])
-m4_define([VERSION_MICRO],[1])
+m4_define([VERSION_MICRO],[3])
AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), unbound-bugs@nlnetlabs.nl, unbound)
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
LIBUNBOUND_CURRENT=5
-LIBUNBOUND_REVISION=3
+LIBUNBOUND_REVISION=6
LIBUNBOUND_AGE=3
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
@@ -57,7 +57,9 @@ LIBUNBOUND_AGE=3
# 1.4.21 had 4:1:2
# 1.4.22 had 4:1:2
# 1.5.0 had 5:3:3 # adds ub_ctx_add_ta_autr
-# 1.5.1 had 5:4:3
+# 1.5.1 had 5:3:3
+# 1.5.2 had 5:5:3
+# 1.5.3 had 5:6:3
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
@@ -118,6 +120,8 @@ AC_ARG_WITH([conf_file],
AC_SUBST(ub_conf_file)
ACX_ESCAPE_BACKSLASH($ub_conf_file, hdr_config)
AC_DEFINE_UNQUOTED(CONFIGFILE, ["$hdr_config"], [Pathname to the Unbound configuration file])
+ub_conf_dir=`AS_DIRNAME(["$ub_conf_file"])`
+AC_SUBST(ub_conf_dir)
# Determine run, chroot directory and pidfile locations
AC_ARG_WITH(run-dir,
@@ -975,7 +979,7 @@ AC_INCLUDES_DEFAULT
#endif
])
AC_SEARCH_LIBS([setusercontext], [util])
-AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam getrlimit setrlimit setsid sbrk chroot kill sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent])
+AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam getrlimit setrlimit setsid sbrk chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent])
AC_CHECK_FUNCS([setresuid],,[AC_CHECK_FUNCS([setreuid])])
AC_CHECK_FUNCS([setresgid],,[AC_CHECK_FUNCS([setregid])])
@@ -1018,6 +1022,7 @@ if test "$USE_NSS" = "no"; then
# this lib needed for sha2 on solaris
LIBS="$LIBS -lmd"
fi
+ AC_SEARCH_LIBS([clock_gettime], [rt])
;;
Linux|*)
AC_LIBOBJ(getentropy_linux)
@@ -1026,6 +1031,7 @@ if test "$USE_NSS" = "no"; then
AC_LIBOBJ(sha512)
])
AC_CHECK_HEADERS([sys/sysctl.h],,, [AC_INCLUDES_DEFAULT])
+ AC_CHECK_FUNCS([getauxval])
AC_SEARCH_LIBS([clock_gettime], [rt])
;;
esac
@@ -1211,6 +1217,10 @@ dnl includes
#else
#define ARG_LL "%I64"
#endif
+
+#ifndef AF_LOCAL
+#define AF_LOCAL AF_UNIX
+#endif
]
AHX_CONFIG_FORMAT_ATTRIBUTE
diff --git a/contrib/unbound/daemon/remote.c b/contrib/unbound/daemon/remote.c
index a5be6d68c882..3ce55ee7ea1a 100644
--- a/contrib/unbound/daemon/remote.c
+++ b/contrib/unbound/daemon/remote.c
@@ -327,9 +327,14 @@ add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err,
* group as the user we run as.
*/
if(fd != -1) {
- if (cfg->username && cfg->username[0])
- chown(ip, cfg->uid, cfg->gid);
+#ifdef HAVE_CHOWN
+ if (cfg->username && cfg->username[0] &&
+ cfg_uid != (uid_t)-1)
+ chown(ip, cfg_uid, cfg_gid);
chmod(ip, (mode_t)(S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP));
+#else
+ (void)cfg;
+#endif
}
} else {
hints.ai_socktype = SOCK_STREAM;
diff --git a/contrib/unbound/daemon/unbound.c b/contrib/unbound/daemon/unbound.c
index a31b0392ffdb..8e07c3895650 100644
--- a/contrib/unbound/daemon/unbound.c
+++ b/contrib/unbound/daemon/unbound.c
@@ -503,26 +503,28 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
#ifdef HAVE_KILL
if(cfg->pidfile && cfg->pidfile[0]) {
writepid(daemon->pidfile, getpid());
- if(cfg->username && cfg->username[0]) {
- if(chown(daemon->pidfile, cfg->uid, cfg->gid) == -1) {
+ if(cfg->username && cfg->username[0] && cfg_uid != (uid_t)-1) {
+# ifdef HAVE_CHOWN
+ if(chown(daemon->pidfile, cfg_uid, cfg_gid) == -1) {
log_err("cannot chown %u.%u %s: %s",
- (unsigned)cfg->uid, (unsigned)cfg->gid,
+ (unsigned)cfg_uid, (unsigned)cfg_gid,
daemon->pidfile, strerror(errno));
}
+# endif /* HAVE_CHOWN */
}
}
#else
(void)daemon;
-#endif
+#endif /* HAVE_KILL */
/* Set user context */
#ifdef HAVE_GETPWNAM
- if(cfg->username && cfg->username[0]) {
+ if(cfg->username && cfg->username[0] && cfg_uid != (uid_t)-1) {
#ifdef HAVE_SETUSERCONTEXT
/* setusercontext does initgroups, setuid, setgid, and
* also resource limits from login config, but we
* still call setresuid, setresgid to be sure to set all uid*/
- if(setusercontext(NULL, pwd, cfg->uid, (unsigned)
+ if(setusercontext(NULL, pwd, cfg_uid, (unsigned)
LOGIN_SETALL & ~LOGIN_SETUSER & ~LOGIN_SETGROUP) != 0)
log_warn("unable to setusercontext %s: %s",
cfg->username, strerror(errno));
@@ -584,29 +586,29 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
/* drop permissions after chroot, getpwnam, pidfile, syslog done*/
#ifdef HAVE_GETPWNAM
- if(cfg->username && cfg->username[0]) {
+ if(cfg->username && cfg->username[0] && cfg_uid != (uid_t)-1) {
# ifdef HAVE_INITGROUPS
- if(initgroups(cfg->username, cfg->gid) != 0)
+ if(initgroups(cfg->username, cfg_gid) != 0)
log_warn("unable to initgroups %s: %s",
cfg->username, strerror(errno));
# endif /* HAVE_INITGROUPS */
endpwent();
#ifdef HAVE_SETRESGID
- if(setresgid(cfg->gid,cfg->gid,cfg->gid) != 0)
+ if(setresgid(cfg_gid,cfg_gid,cfg_gid) != 0)
#elif defined(HAVE_SETREGID) && !defined(DARWIN_BROKEN_SETREUID)
- if(setregid(cfg->gid,cfg->gid) != 0)
+ if(setregid(cfg_gid,cfg_gid) != 0)
#else /* use setgid */
- if(setgid(cfg->gid) != 0)
+ if(setgid(cfg_gid) != 0)
#endif /* HAVE_SETRESGID */
fatal_exit("unable to set group id of %s: %s",
cfg->username, strerror(errno));
#ifdef HAVE_SETRESUID
- if(setresuid(cfg->uid,cfg->uid,cfg->uid) != 0)
+ if(setresuid(cfg_uid,cfg_uid,cfg_uid) != 0)
#elif defined(HAVE_SETREUID) && !defined(DARWIN_BROKEN_SETREUID)
- if(setreuid(cfg->uid,cfg->uid) != 0)
+ if(setreuid(cfg_uid,cfg_uid) != 0)
#else /* use setuid */
- if(setuid(cfg->uid) != 0)
+ if(setuid(cfg_uid) != 0)
#endif /* HAVE_SETRESUID */
fatal_exit("unable to set user id of %s: %s",
cfg->username, strerror(errno));
@@ -651,7 +653,8 @@ run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode)
log_warn("Continuing with default config settings");
}
apply_settings(daemon, cfg, cmdline_verbose, debug_mode);
- config_lookup_uid(cfg);
+ if(!done_setup)
+ config_lookup_uid(cfg);
/* prepare */
if(!daemon_open_shared_ports(daemon))
diff --git a/contrib/unbound/daemon/worker.c b/contrib/unbound/daemon/worker.c
index 59ae9dfcefcb..5edc21dd46e7 100644
--- a/contrib/unbound/daemon/worker.c
+++ b/contrib/unbound/daemon/worker.c
@@ -900,7 +900,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
goto send_reply;
}
if(local_zones_answer(worker->daemon->local_zones, &qinfo, &edns,
- c->buffer, worker->scratchpad)) {
+ c->buffer, worker->scratchpad, repinfo)) {
regional_free_all(worker->scratchpad);
if(sldns_buffer_limit(c->buffer) == 0) {
comm_point_drop_reply(repinfo);
diff --git a/contrib/unbound/doc/Changelog b/contrib/unbound/doc/Changelog
index 1bd19f19c436..a1c2f76cd21d 100644
--- a/contrib/unbound/doc/Changelog
+++ b/contrib/unbound/doc/Changelog
@@ -1,12 +1,112 @@
-8 December 2014: Wouter
- - Fix CVE-2014-8602: denial of service by making resolver chase
- endless series of delegations.
+23 March 2015: Wouter
+ - Fix segfault on user not found at startup (from Maciej Soltysiak).
+
+2 March 2015: Wouter
+ - iana portlist update.
+
+20 February 2015: Wouter
+ - Use the getrandom syscall introduced in Linux 3.17 (from Heiner
+ Kallweit).
+ - Fix #645 Portability to Solaris 10, use AF_LOCAL.
+ - Fix #646 Portability to Solaris, -lrt for getentropy_solaris.
+ - Fix #647 crash in 1.5.2 because pwd.db no longer accessible after
+ reload.
+
+19 February 2015: Wouter
+ - 1.5.2 release tag.
+ - svn trunk contains 1.5.3 under development.
+
+13 February 2015: Wouter
+ - Fix #643: doc/example.conf.in: unnecessary whitespace.
+
+12 February 2015: Wouter
+ - tag 1.5.2rc1
+
+11 February 2015: Wouter
+ - iana portlist update.
+
+10 February 2015: Wouter
+ - Fix scrubber with harden-glue turned off to reject NS (and other
+ not-address) records.
+
+9 February 2015: Wouter
+ - Fix validation failure in case upstream forwarder (ISC BIND) does
+ not have the same trust anchors and decides to insert unsigned NS
+ record in authority section.
+
+2 February 2015: Wouter
+ - infra-cache-min-rtt patch from Florian Riehm, for expected long
+ uplink roundtrip times.
+
+30 January 2015: Wouter
+ - Fix 0x20 capsforid fallback to omit gratuitous NS and additional
+ section changes.
+ - Portability fix for Solaris ('sun' is not usable for a variable).
+
+29 January 2015: Wouter
+ - Fix pyunbound byte string representation for python3.
+
+26 January 2015: Wouter
+ - Fix unintended use of gcc extension for incomplete enum types,
+ compile with pedantic c99 compliance (from Daniel Dickman).
+
+23 January 2015: Wouter
+ - windows port fixes, no AF_LOCAL, no chown, no chmod(grp).
+
+16 January 2015: Wouter
+ - unit test for local unix connection. Documentation and log_addr
+ does not inspect port for AF_LOCAL.
+ - unbound-checkconf -f prints chroot with pidfile path.
+
+13 January 2015: Wouter
+ - iana portlist update.
+
+12 January 2015: Wouter
+ - Cast sun_len sizeof to socklen_t.
+ - Fix pyunbound ord call, portable for python 2 and 3.
+
+7 January 2015: Wouter
+ - Fix warnings in pythonmod changes.
+
+6 January 2015: Wouter
+ - iana portlist update.
- patch for remote control over local sockets, from Dag-Erling
Smorgrav, Ilya Bakulin. Use control-interface: /path/sock and
control-use-cert: no.
- Fixup that patch and uid lookup (only for daemon).
- coded the default of control-use-cert, to yes.
+5 January 2015: Wouter
+ - getauxval test for ppc64 linux compatibility.
+ - make strip works for unbound-host and unbound-anchor.
+ - patch from Stephane Lapie that adds to the python API, that
+ exposes struct delegpt, and adds the find_delegation function.
+ - print query name when max target count is exceeded.
+ - patch from Stuart Henderson that fixes DESTDIR in
+ unbound-control-setup for installs where config is not in
+ the prefix location.
+ - Fix #634: fix fail to start on Linux LTS 3.14.X, ignores missing
+ IP_MTU_DISCOVER OMIT option (fix from Remi Gacogne).
+ - Updated contrib warmup.cmd/sh to support two modes - load
+ from pre-defined list of domains or (with filename as argument)
+ load from user-specified list of domains, and updated contrib
+ unbound_cache.sh/cmd to support loading/save/reload cache to/from
+ default path or (with secondary argument) arbitrary path/filename,
+ from Yuri Voinov.
+ - Patch from Philip Paeps to contrib/unbound_munin_ that uses
+ type ABSOLUTE. Allows munin.conf: [idleserver.example.net]
+ unbound_munin_hits.graph_period minute
+
+9 December 2014: Wouter
+ - svn trunk has 1.5.2 in development.
+ - config.guess and config.sub update from libtoolize.
+ - local-zone: example.com inform makes unbound log a message with
+ client IP for queries in that zone. Eg. for finding infected hosts.
+
+8 December 2014: Wouter
+ - Fix CVE-2014-8602: denial of service by making resolver chase
+ endless series of delegations.
+
1 December 2014: Wouter
- Fix bug#632: unbound fails to build on AArch64, protects
getentropy compat code from calling sysctl if it is has been removed.
diff --git a/contrib/unbound/doc/README b/contrib/unbound/doc/README
index df92fccb5d36..f3530d6eedf4 100644
--- a/contrib/unbound/doc/README
+++ b/contrib/unbound/doc/README
@@ -1,4 +1,4 @@
-README for Unbound 1.5.1
+README for Unbound 1.5.3
Copyright 2007 NLnet Labs
http://unbound.net
diff --git a/contrib/unbound/doc/example.conf b/contrib/unbound/doc/example.conf
index 945e9e308401..acb553b5cf39 100644
--- a/contrib/unbound/doc/example.conf
+++ b/contrib/unbound/doc/example.conf
@@ -1,7 +1,7 @@
#
# Example configuration file.
#
-# See unbound.conf(5) man page, version 1.5.1.
+# See unbound.conf(5) man page, version 1.5.3.
#
# this is a comment.
@@ -138,6 +138,9 @@ server:
# the time to live (TTL) value for cached roundtrip times, lameness and
# EDNS version information for hosts. In seconds.
# infra-host-ttl: 900
+
+ # minimum wait time for responses, increase if uplink is long. In msec.
+ # infra-cache-min-rtt: 50
# the number of slabs to use for the Infrastructure cache.
# the number of slabs must be a power of 2.
@@ -437,7 +440,7 @@ server:
# the amount of memory to use for the negative cache (used for DLV).
# plain value in bytes or you can append k, m or G. default is "1Mb".
# neg-cache-size: 1m
-
+
# By default, for a number of zones a small default 'nothing here'
# reply is built-in. Query traffic is thus blocked. If you
# wish to serve such zone you can unblock them by uncommenting one
@@ -497,6 +500,7 @@ server:
# o redirect serves the zone data for any subdomain in the zone.
# o nodefault can be used to normally resolve AS112 zones.
# o typetransparent resolves normally for other types and other names
+ # o inform resolves normally, but logs client IP address
#
# defaults are localhost address, reverse for 127.0.0.1 and ::1
# and nxdomain for AS112 zones. If you configure one of these zones
@@ -552,6 +556,10 @@ remote-control:
# set up the keys and certificates with unbound-control-setup.
# control-enable: no
+ # Set to no and use an absolute path as control-interface to use
+ # a unix local named pipe for unbound-control.
+ # control-use-cert: yes
+
# what interfaces are listened to for remote control.
# give 0.0.0.0 and ::0 to listen to all interfaces.
# control-interface: 127.0.0.1
diff --git a/contrib/unbound/doc/example.conf.in b/contrib/unbound/doc/example.conf.in
index b95b3a6339c4..60ed5c89f91e 100644
--- a/contrib/unbound/doc/example.conf.in
+++ b/contrib/unbound/doc/example.conf.in
@@ -1,7 +1,7 @@
#
# Example configuration file.
#
-# See unbound.conf(5) man page, version 1.5.1.
+# See unbound.conf(5) man page, version 1.5.3.
#
# this is a comment.
@@ -138,6 +138,9 @@ server:
# the time to live (TTL) value for cached roundtrip times, lameness and
# EDNS version information for hosts. In seconds.
# infra-host-ttl: 900
+
+ # minimum wait time for responses, increase if uplink is long. In msec.
+ # infra-cache-min-rtt: 50
# the number of slabs to use for the Infrastructure cache.
# the number of slabs must be a power of 2.
@@ -437,7 +440,7 @@ server:
# the amount of memory to use for the negative cache (used for DLV).
# plain value in bytes or you can append k, m or G. default is "1Mb".
# neg-cache-size: 1m
-
+
# By default, for a number of zones a small default 'nothing here'
# reply is built-in. Query traffic is thus blocked. If you
# wish to serve such zone you can unblock them by uncommenting one
@@ -497,6 +500,7 @@ server:
# o redirect serves the zone data for any subdomain in the zone.
# o nodefault can be used to normally resolve AS112 zones.
# o typetransparent resolves normally for other types and other names
+ # o inform resolves normally, but logs client IP address
#
# defaults are localhost address, reverse for 127.0.0.1 and ::1
# and nxdomain for AS112 zones. If you configure one of these zones
@@ -552,6 +556,10 @@ remote-control:
# set up the keys and certificates with unbound-control-setup.
# control-enable: no
+ # Set to no and use an absolute path as control-interface to use
+ # a unix local named pipe for unbound-control.
+ # control-use-cert: yes
+
# what interfaces are listened to for remote control.
# give 0.0.0.0 and ::0 to listen to all interfaces.
# control-interface: 127.0.0.1
diff --git a/contrib/unbound/doc/libunbound.3 b/contrib/unbound/doc/libunbound.3
index 55a9cb286e6e..a4c7945aea1b 100644
--- a/contrib/unbound/doc/libunbound.3
+++ b/contrib/unbound/doc/libunbound.3
@@ -1,4 +1,4 @@
-.TH "libunbound" "3" "Dec 8, 2014" "NLnet Labs" "unbound 1.5.1"
+.TH "libunbound" "3" "Mar 10, 2015" "NLnet Labs" "unbound 1.5.3"
.\"
.\" libunbound.3 -- unbound library functions manual
.\"
@@ -42,7 +42,7 @@
.B ub_ctx_zone_remove,
.B ub_ctx_data_add,
.B ub_ctx_data_remove
-\- Unbound DNS validating resolver 1.5.1 functions.
+\- Unbound DNS validating resolver 1.5.3 functions.
.SH "SYNOPSIS"
.B #include <unbound.h>
.LP
diff --git a/contrib/unbound/doc/libunbound.3.in b/contrib/unbound/doc/libunbound.3.in
index 55a9cb286e6e..a4c7945aea1b 100644
--- a/contrib/unbound/doc/libunbound.3.in
+++ b/contrib/unbound/doc/libunbound.3.in
@@ -1,4 +1,4 @@
-.TH "libunbound" "3" "Dec 8, 2014" "NLnet Labs" "unbound 1.5.1"
+.TH "libunbound" "3" "Mar 10, 2015" "NLnet Labs" "unbound 1.5.3"
.\"
.\" libunbound.3 -- unbound library functions manual
.\"
@@ -42,7 +42,7 @@
.B ub_ctx_zone_remove,
.B ub_ctx_data_add,
.B ub_ctx_data_remove
-\- Unbound DNS validating resolver 1.5.1 functions.
+\- Unbound DNS validating resolver 1.5.3 functions.
.SH "SYNOPSIS"
.B #include <unbound.h>
.LP
diff --git a/contrib/unbound/doc/unbound-anchor.8 b/contrib/unbound/doc/unbound-anchor.8
index a0016209bd70..3682d8fd4a97 100644
--- a/contrib/unbound/doc/unbound-anchor.8
+++ b/contrib/unbound/doc/unbound-anchor.8
@@ -1,4 +1,4 @@
-.TH "unbound-anchor" "8" "Dec 8, 2014" "NLnet Labs" "unbound 1.5.1"
+.TH "unbound-anchor" "8" "Mar 10, 2015" "NLnet Labs" "unbound 1.5.3"
.\"
.\" unbound-anchor.8 -- unbound anchor maintenance utility manual
.\"
diff --git a/contrib/unbound/doc/unbound-anchor.8.in b/contrib/unbound/doc/unbound-anchor.8.in
index 80a3438dcaac..fb2136fc1aaf 100644
--- a/contrib/unbound/doc/unbound-anchor.8.in
+++ b/contrib/unbound/doc/unbound-anchor.8.in
@@ -1,4 +1,4 @@
-.TH "unbound-anchor" "8" "Dec 8, 2014" "NLnet Labs" "unbound 1.5.1"
+.TH "unbound-anchor" "8" "Mar 10, 2015" "NLnet Labs" "unbound 1.5.3"
.\"
.\" unbound-anchor.8 -- unbound anchor maintenance utility manual
.\"
diff --git a/contrib/unbound/doc/unbound-checkconf.8 b/contrib/unbound/doc/unbound-checkconf.8
index 3da7ec0a73f5..d2b659e412d2 100644
--- a/contrib/unbound/doc/unbound-checkconf.8
+++ b/contrib/unbound/doc/unbound-checkconf.8
@@ -1,4 +1,4 @@
-.TH "unbound-checkconf" "8" "Dec 8, 2014" "NLnet Labs" "unbound 1.5.1"
+.TH "unbound-checkconf" "8" "Mar 10, 2015" "NLnet Labs" "unbound 1.5.3"
.\"
.\" unbound-checkconf.8 -- unbound configuration checker manual
.\"
@@ -13,6 +13,7 @@ unbound\-checkconf
.SH "SYNOPSIS"
.B unbound\-checkconf
.RB [ \-h ]
+.RB [ \-f ]
.RB [ \-o
.IR option ]
.RI [ cfgfile ]
@@ -29,6 +30,9 @@ The available options are:
.B \-h
Show the version and commandline option help.
.TP
+.B \-f
+Print full pathname, with chroot applied to it. Use with the -o option.
+.TP
.B \-o\fI option
If given, after checking the config file the value of this option is
printed to stdout. For "" (disabled) options an empty line is printed.
diff --git a/contrib/unbound/doc/unbound-checkconf.8.in b/contrib/unbound/doc/unbound-checkconf.8.in
index 5ab53480b6fe..e7db810bbec8 100644
--- a/contrib/unbound/doc/unbound-checkconf.8.in
+++ b/contrib/unbound/doc/unbound-checkconf.8.in
@@ -1,4 +1,4 @@
-.TH "unbound-checkconf" "8" "Dec 8, 2014" "NLnet Labs" "unbound 1.5.1"
+.TH "unbound-checkconf" "8" "Mar 10, 2015" "NLnet Labs" "unbound 1.5.3"
.\"
.\" unbound-checkconf.8 -- unbound configuration checker manual
.\"
@@ -13,6 +13,7 @@ unbound\-checkconf
.SH "SYNOPSIS"
.B unbound\-checkconf
.RB [ \-h ]
+.RB [ \-f ]
.RB [ \-o
.IR option ]
.RI [ cfgfile ]
@@ -29,6 +30,9 @@ The available options are:
.B \-h
Show the version and commandline option help.
.TP
+.B \-f
+Print full pathname, with chroot applied to it. Use with the -o option.
+.TP
.B \-o\fI option
If given, after checking the config file the value of this option is
printed to stdout. For "" (disabled) options an empty line is printed.
diff --git a/contrib/unbound/doc/unbound-control.8 b/contrib/unbound/doc/unbound-control.8
index e768fa96ec72..e6228b75d174 100644
--- a/contrib/unbound/doc/unbound-control.8
+++ b/contrib/unbound/doc/unbound-control.8
@@ -1,4 +1,4 @@
-.TH "unbound-control" "8" "Dec 8, 2014" "NLnet Labs" "unbound 1.5.1"
+.TH "unbound-control" "8" "Mar 10, 2015" "NLnet Labs" "unbound 1.5.3"
.\"
.\" unbound-control.8 -- unbound remote control manual
.\"
diff --git a/contrib/unbound/doc/unbound-control.8.in b/contrib/unbound/doc/unbound-control.8.in
index 92d2d1a9343d..f6eae249abc9 100644
--- a/contrib/unbound/doc/unbound-control.8.in
+++ b/contrib/unbound/doc/unbound-control.8.in
@@ -1,4 +1,4 @@
-.TH "unbound-control" "8" "Dec 8, 2014" "NLnet Labs" "unbound 1.5.1"
+.TH "unbound-control" "8" "Mar 10, 2015" "NLnet Labs" "unbound 1.5.3"
.\"
.\" unbound-control.8 -- unbound remote control manual
.\"
diff --git a/contrib/unbound/doc/unbound-host.1 b/contrib/unbound/doc/unbound-host.1
index 0bd194e169aa..bda99ce474a7 100644
--- a/contrib/unbound/doc/unbound-host.1
+++ b/contrib/unbound/doc/unbound-host.1
@@ -1,4 +1,4 @@
-.TH "unbound\-host" "1" "Dec 8, 2014" "NLnet Labs" "unbound 1.5.1"
+.TH "unbound\-host" "1" "Mar 10, 2015" "NLnet Labs" "unbound 1.5.3"
.\"
.\" unbound-host.1 -- unbound DNS lookup utility
.\"
diff --git a/contrib/unbound/doc/unbound-host.1.in b/contrib/unbound/doc/unbound-host.1.in
index d9e92bbe099a..9129bea66af1 100644
--- a/contrib/unbound/doc/unbound-host.1.in
+++ b/contrib/unbound/doc/unbound-host.1.in
@@ -1,4 +1,4 @@
-.TH "unbound\-host" "1" "Dec 8, 2014" "NLnet Labs" "unbound 1.5.1"
+.TH "unbound\-host" "1" "Mar 10, 2015" "NLnet Labs" "unbound 1.5.3"
.\"
.\" unbound-host.1 -- unbound DNS lookup utility
.\"
diff --git a/contrib/unbound/doc/unbound.8 b/contrib/unbound/doc/unbound.8
index f9c5b6a3e793..8609a0aa6457 100644
--- a/contrib/unbound/doc/unbound.8
+++ b/contrib/unbound/doc/unbound.8
@@ -1,4 +1,4 @@
-.TH "unbound" "8" "Dec 8, 2014" "NLnet Labs" "unbound 1.5.1"
+.TH "unbound" "8" "Mar 10, 2015" "NLnet Labs" "unbound 1.5.3"
.\"
.\" unbound.8 -- unbound manual
.\"
@@ -9,7 +9,7 @@
.\"
.SH "NAME"
.B unbound
-\- Unbound DNS validating resolver 1.5.1.
+\- Unbound DNS validating resolver 1.5.3.
.SH "SYNOPSIS"
.B unbound
.RB [ \-h ]
diff --git a/contrib/unbound/doc/unbound.8.in b/contrib/unbound/doc/unbound.8.in
index 3b74a3242ada..7242469c1f1f 100644
--- a/contrib/unbound/doc/unbound.8.in
+++ b/contrib/unbound/doc/unbound.8.in
@@ -1,4 +1,4 @@
-.TH "unbound" "8" "Dec 8, 2014" "NLnet Labs" "unbound 1.5.1"
+.TH "unbound" "8" "Mar 10, 2015" "NLnet Labs" "unbound 1.5.3"
.\"
.\" unbound.8 -- unbound manual
.\"
@@ -9,7 +9,7 @@
.\"
.SH "NAME"
.B unbound
-\- Unbound DNS validating resolver 1.5.1.
+\- Unbound DNS validating resolver 1.5.3.
.SH "SYNOPSIS"
.B unbound
.RB [ \-h ]
diff --git a/contrib/unbound/doc/unbound.conf.5 b/contrib/unbound/doc/unbound.conf.5
index f5a4471f99b1..c2637aad91d6 100644
--- a/contrib/unbound/doc/unbound.conf.5
+++ b/contrib/unbound/doc/unbound.conf.5
@@ -1,4 +1,4 @@
-.TH "unbound.conf" "5" "Dec 8, 2014" "NLnet Labs" "unbound 1.5.1"
+.TH "unbound.conf" "5" "Mar 10, 2015" "NLnet Labs" "unbound 1.5.3"
.\"
.\" unbound.conf.5 -- unbound.conf manual
.\"
@@ -301,6 +301,11 @@ by threads. Must be set to a power of 2.
.B infra\-cache\-numhosts: \fI<number>
Number of hosts for which information is cached. Default is 10000.
.TP
+.B infra\-cache\-min\-rtt: \fI<msec>
+Lower limit for dynamic retransmit timeout calculation in infrastructure
+cache. Default is 50 milliseconds. Increase this value if using forwarders
+needing more time to do recursive name resolution.
+.TP
.B do\-ip4: \fI<yes or no>
Enable or disable whether ip4 queries are answered or issued. Default is yes.
.TP
@@ -791,7 +796,7 @@ data leakage about the local network to the upstream DNS servers.
.B local\-zone: \fI<zone> <type>
Configure a local zone. The type determines the answer to give if
there is no match from local\-data. The types are deny, refuse, static,
-transparent, redirect, nodefault, typetransparent, and are explained
+transparent, redirect, nodefault, typetransparent, inform, and are explained
below. After that the default settings are listed. Use local\-data: to
enter data into the local zone. Answers for local zones are authoritative
DNS answers. By default the zones are class IN.
@@ -841,6 +846,13 @@ local\-data: "example.com. A 127.0.0.1"
queries for www.example.com and www.foo.example.com are redirected, so
that users with web browsers cannot access sites with suffix example.com.
.TP 10
+\h'5'\fIinform\fR
+The query is answered normally. The client IP address (@portnumber)
+is printed to the logfile. The log message is: timestamp, unbound-pid,
+info: zonename inform IP@port queryname type class. This option can be
+used for normal resolution, but machines looking up infected names are
+logged, eg. to run antivirus on them.
+.TP 10
\h'5'\fInodefault\fR
Used to turn off default contents for AS112 zones. The other types
also turn off default contents for the zone. The 'nodefault' option
diff --git a/contrib/unbound/doc/unbound.conf.5.in b/contrib/unbound/doc/unbound.conf.5.in
index d4420e26a0a4..9b088f372b63 100644
--- a/contrib/unbound/doc/unbound.conf.5.in
+++ b/contrib/unbound/doc/unbound.conf.5.in
@@ -1,4 +1,4 @@
-.TH "unbound.conf" "5" "Dec 8, 2014" "NLnet Labs" "unbound 1.5.1"
+.TH "unbound.conf" "5" "Mar 10, 2015" "NLnet Labs" "unbound 1.5.3"
.\"
.\" unbound.conf.5 -- unbound.conf manual
.\"
@@ -301,6 +301,11 @@ by threads. Must be set to a power of 2.
.B infra\-cache\-numhosts: \fI<number>
Number of hosts for which information is cached. Default is 10000.
.TP
+.B infra\-cache\-min\-rtt: \fI<msec>
+Lower limit for dynamic retransmit timeout calculation in infrastructure
+cache. Default is 50 milliseconds. Increase this value if using forwarders
+needing more time to do recursive name resolution.
+.TP
.B do\-ip4: \fI<yes or no>
Enable or disable whether ip4 queries are answered or issued. Default is yes.
.TP
@@ -791,7 +796,7 @@ data leakage about the local network to the upstream DNS servers.
.B local\-zone: \fI<zone> <type>
Configure a local zone. The type determines the answer to give if
there is no match from local\-data. The types are deny, refuse, static,
-transparent, redirect, nodefault, typetransparent, and are explained
+transparent, redirect, nodefault, typetransparent, inform, and are explained
below. After that the default settings are listed. Use local\-data: to
enter data into the local zone. Answers for local zones are authoritative
DNS answers. By default the zones are class IN.
@@ -841,6 +846,13 @@ local\-data: "example.com. A 127.0.0.1"
queries for www.example.com and www.foo.example.com are redirected, so
that users with web browsers cannot access sites with suffix example.com.
.TP 10
+\h'5'\fIinform\fR
+The query is answered normally. The client IP address (@portnumber)
+is printed to the logfile. The log message is: timestamp, unbound-pid,
+info: zonename inform IP@port queryname type class. This option can be
+used for normal resolution, but machines looking up infected names are
+logged, eg. to run antivirus on them.
+.TP 10
\h'5'\fInodefault\fR
Used to turn off default contents for AS112 zones. The other types
also turn off default contents for the zone. The 'nodefault' option
diff --git a/contrib/unbound/iterator/iter_scrub.c b/contrib/unbound/iterator/iter_scrub.c
index b2248bc0cbc5..1c81975b234f 100644
--- a/contrib/unbound/iterator/iter_scrub.c
+++ b/contrib/unbound/iterator/iter_scrub.c
@@ -680,7 +680,9 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
* (we dont want its glue that was approved
* during the normalize action) */
del_addi = 1;
- } else if(!env->cfg->harden_glue) {
+ } else if(!env->cfg->harden_glue && (
+ rrset->type == LDNS_RR_TYPE_A ||
+ rrset->type == LDNS_RR_TYPE_AAAA)) {
/* store in cache! Since it is relevant
* (from normalize) it will be picked up
* from the cache to be used later */
diff --git a/contrib/unbound/iterator/iter_utils.c b/contrib/unbound/iterator/iter_utils.c
index 9d0aa698f996..10ae12f75c6c 100644
--- a/contrib/unbound/iterator/iter_utils.c
+++ b/contrib/unbound/iterator/iter_utils.c
@@ -715,6 +715,42 @@ reply_equal(struct reply_info* p, struct reply_info* q, struct regional* region)
}
void
+caps_strip_reply(struct reply_info* rep)
+{
+ size_t i;
+ if(!rep) return;
+ /* see if message is a referral, in which case the additional and
+ * NS record cannot be removed */
+ /* referrals have the AA flag unset (strict check, not elsewhere in
+ * unbound, but for 0x20 this is very convenient). */
+ if(!(rep->flags&BIT_AA))
+ return;
+ /* remove the additional section from the reply */
+ if(rep->ar_numrrsets != 0) {
+ verbose(VERB_ALGO, "caps fallback: removing additional section");
+ rep->rrset_count -= rep->ar_numrrsets;
+ rep->ar_numrrsets = 0;
+ }
+ /* is there an NS set in the authority section to remove? */
+ /* the failure case (Cisco firewalls) only has one rrset in authsec */
+ for(i=rep->an_numrrsets; i<rep->an_numrrsets+rep->ns_numrrsets; i++) {
+ struct ub_packed_rrset_key* s = rep->rrsets[i];
+ if(ntohs(s->rk.type) == LDNS_RR_TYPE_NS) {
+ /* remove NS rrset and break from loop (loop limits
+ * have changed) */
+ /* move last rrset into this position (there is no
+ * additional section any more) */
+ verbose(VERB_ALGO, "caps fallback: removing NS rrset");
+ if(i < rep->rrset_count-1)
+ rep->rrsets[i]=rep->rrsets[rep->rrset_count-1];
+ rep->rrset_count --;
+ rep->ns_numrrsets --;
+ break;
+ }
+ }
+}
+
+void
iter_store_parentside_rrset(struct module_env* env,
struct ub_packed_rrset_key* rrset)
{
diff --git a/contrib/unbound/iterator/iter_utils.h b/contrib/unbound/iterator/iter_utils.h
index d7c2b68afa2d..9373487e002c 100644
--- a/contrib/unbound/iterator/iter_utils.h
+++ b/contrib/unbound/iterator/iter_utils.h
@@ -223,6 +223,15 @@ int iter_msg_from_zone(struct dns_msg* msg, struct delegpt* dp,
int reply_equal(struct reply_info* p, struct reply_info* q, struct regional* region);
/**
+ * Remove unused bits from the reply if possible.
+ * So that caps-for-id (0x20) fallback is more likely to be successful.
+ * This removes like, the additional section, and NS record in the authority
+ * section if those records are gratuitous (not for a referral).
+ * @param rep: the reply to strip stuff out of.
+ */
+void caps_strip_reply(struct reply_info* rep);
+
+/**
* Store parent-side rrset in seperate rrset cache entries for later
* last-resort * lookups in case the child-side versions of this information
* fails.
diff --git a/contrib/unbound/iterator/iterator.c b/contrib/unbound/iterator/iterator.c
index 6e05c99a0e95..2037cc8814f2 100644
--- a/contrib/unbound/iterator/iterator.c
+++ b/contrib/unbound/iterator/iterator.c
@@ -1383,8 +1383,10 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
return 0;
if(iq->depth > 0 && iq->target_count &&
iq->target_count[1] > MAX_TARGET_COUNT) {
- verbose(VERB_QUERY, "request has exceeded the maximum "
- "number of glue fetches %d", iq->target_count[1]);
+ char s[LDNS_MAX_DOMAINLEN+1];
+ dname_str(qstate->qinfo.qname, s);
+ verbose(VERB_QUERY, "request %s has exceeded the maximum "
+ "number of glue fetches %d", s, iq->target_count[1]);
return 0;
}
@@ -1581,8 +1583,10 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
}
if(iq->depth > 0 && iq->target_count &&
iq->target_count[1] > MAX_TARGET_COUNT) {
- verbose(VERB_QUERY, "request has exceeded the maximum "
- "number of glue fetches %d", iq->target_count[1]);
+ char s[LDNS_MAX_DOMAINLEN+1];
+ dname_str(qstate->qinfo.qname, s);
+ verbose(VERB_QUERY, "request %s has exceeded the maximum "
+ "number of glue fetches %d", s, iq->target_count[1]);
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
}
/* mark cycle targets for parent-side lookups */
@@ -2878,6 +2882,9 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
iq->response->rep);
if(event == module_event_capsfail || iq->caps_fallback) {
+ /* for fallback we care about main answer, not additionals */
+ /* removing that makes comparison more likely to succeed */
+ caps_strip_reply(iq->response->rep);
if(!iq->caps_fallback) {
/* start fallback */
iq->caps_fallback = 1;
diff --git a/contrib/unbound/libunbound/libworker.c b/contrib/unbound/libunbound/libworker.c
index e388e7956c81..c72b586ab70d 100644
--- a/contrib/unbound/libunbound/libworker.c
+++ b/contrib/unbound/libunbound/libworker.c
@@ -606,7 +606,7 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q)
sldns_buffer_write_u16_at(w->back->udp_buff, 0, qid);
sldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags);
if(local_zones_answer(ctx->local_zones, &qinfo, &edns,
- w->back->udp_buff, w->env->scratch)) {
+ w->back->udp_buff, w->env->scratch, NULL)) {
regional_free_all(w->env->scratch);
libworker_fillup_fg(q, LDNS_RCODE_NOERROR,
w->back->udp_buff, sec_status_insecure, NULL);
@@ -676,7 +676,7 @@ int libworker_attach_mesh(struct ub_ctx* ctx, struct ctx_query* q,
sldns_buffer_write_u16_at(w->back->udp_buff, 0, qid);
sldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags);
if(local_zones_answer(ctx->local_zones, &qinfo, &edns,
- w->back->udp_buff, w->env->scratch)) {
+ w->back->udp_buff, w->env->scratch, NULL)) {
regional_free_all(w->env->scratch);
free(qinfo.qname);
libworker_event_done_cb(q, LDNS_RCODE_NOERROR,
@@ -796,7 +796,7 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len)
sldns_buffer_write_u16_at(w->back->udp_buff, 0, qid);
sldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags);
if(local_zones_answer(w->ctx->local_zones, &qinfo, &edns,
- w->back->udp_buff, w->env->scratch)) {
+ w->back->udp_buff, w->env->scratch, NULL)) {
regional_free_all(w->env->scratch);
q->msg_security = sec_status_insecure;
add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL);
diff --git a/contrib/unbound/libunbound/python/libunbound.i b/contrib/unbound/libunbound/python/libunbound.i
index 313c74862f4d..1bef79f22094 100644
--- a/contrib/unbound/libunbound/python/libunbound.i
+++ b/contrib/unbound/libunbound/python/libunbound.i
@@ -44,6 +44,10 @@
%pythoncode %{
import encodings.idna
+ try:
+ import builtins
+ except ImportError:
+ import __builtin__ as builtins
# Ensure compatibility with older python versions
if 'bytes' not in vars():
@@ -52,7 +56,7 @@
def ord(s):
if isinstance(s, int):
return s
- return __builtins__.ord(s)
+ return builtins.ord(s)
%}
//%include "doc.i"
@@ -699,7 +703,7 @@ Result: ['74.125.43.147', '74.125.43.99', '74.125.43.103', '74.125.43.104']
while (idx < slen):
complen = ord(s[idx])
# In python 3.x `str()` converts the string to unicode which is the expected text string type
- res.append(str(s[idx+1:idx+1+complen]))
+ res.append(str(s[idx+1:idx+1+complen].decode()))
idx += complen + 1
return res
diff --git a/contrib/unbound/services/listen_dnsport.c b/contrib/unbound/services/listen_dnsport.c
index 0ce0a6b7b175..3e5bf4004448 100644
--- a/contrib/unbound/services/listen_dnsport.c
+++ b/contrib/unbound/services/listen_dnsport.c
@@ -372,29 +372,47 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
* (and also uses the interface mtu to determine the size of the packets).
* So there won't be any EMSGSIZE error. Against DNS fragmentation attacks.
* FreeBSD already has same semantics without setting the option. */
-# if defined(IP_PMTUDISC_OMIT)
- int action = IP_PMTUDISC_OMIT;
-# else
- int action = IP_PMTUDISC_DONT;
-# endif
+ int omit_set = 0;
+ int action;
+# if defined(IP_PMTUDISC_OMIT)
+ action = IP_PMTUDISC_OMIT;
if (setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER,
&action, (socklen_t)sizeof(action)) < 0) {
- log_err("setsockopt(..., IP_MTU_DISCOVER, "
-# if defined(IP_PMTUDISC_OMIT)
- "IP_PMTUDISC_OMIT"
+
+ if (errno != EINVAL) {
+ log_err("setsockopt(..., IP_MTU_DISCOVER, IP_PMTUDISC_OMIT...) failed: %s",
+ strerror(errno));
+
+# ifndef USE_WINSOCK
+ close(s);
# else
- "IP_PMTUDISC_DONT"
+ closesocket(s);
# endif
- "...) failed: %s",
- strerror(errno));
+ *noproto = 0;
+ *inuse = 0;
+ return -1;
+ }
+ }
+ else
+ {
+ omit_set = 1;
+ }
+# endif
+ if (omit_set == 0) {
+ action = IP_PMTUDISC_DONT;
+ if (setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER,
+ &action, (socklen_t)sizeof(action)) < 0) {
+ log_err("setsockopt(..., IP_MTU_DISCOVER, IP_PMTUDISC_DONT...) failed: %s",
+ strerror(errno));
# ifndef USE_WINSOCK
- close(s);
+ close(s);
# else
- closesocket(s);
+ closesocket(s);
# endif
- *noproto = 0;
- *inuse = 0;
- return -1;
+ *noproto = 0;
+ *inuse = 0;
+ return -1;
+ }
}
# elif defined(IP_DONTFRAG)
int off = 0;
@@ -580,17 +598,18 @@ create_local_accept_sock(const char *path, int* noproto)
{
#ifdef HAVE_SYS_UN_H
int s;
- struct sockaddr_un sun;
+ struct sockaddr_un usock;
+ verbose(VERB_ALGO, "creating unix socket %s", path);
#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
/* this member exists on BSDs, not Linux */
- sun.sun_len = (sa_family_t)sizeof(sun);
+ usock.sun_len = (socklen_t)sizeof(usock);
#endif
- sun.sun_family = AF_LOCAL;
+ usock.sun_family = AF_LOCAL;
/* length is 92-108, 104 on FreeBSD */
- (void)strlcpy(sun.sun_path, path, sizeof(sun.sun_path));
+ (void)strlcpy(usock.sun_path, path, sizeof(usock.sun_path));
- if ((s = socket(PF_LOCAL, SOCK_STREAM, 0)) == -1) {
+ if ((s = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1) {
log_err("Cannot create local socket %s (%s)",
path, strerror(errno));
return -1;
@@ -603,7 +622,7 @@ create_local_accept_sock(const char *path, int* noproto)
return -1;
}
- if (bind(s, (struct sockaddr *)&sun,
+ if (bind(s, (struct sockaddr *)&usock,
(socklen_t)sizeof(struct sockaddr_un)) == -1) {
log_err("Cannot bind local socket %s (%s)",
path, strerror(errno));
@@ -623,6 +642,7 @@ create_local_accept_sock(const char *path, int* noproto)
(void)noproto; /*unused*/
return s;
#else
+ (void)path;
log_err("Local sockets are not supported");
*noproto = 1;
return -1;
diff --git a/contrib/unbound/services/localzone.c b/contrib/unbound/services/localzone.c
index d285a127cbbf..57510bd27364 100644
--- a/contrib/unbound/services/localzone.c
+++ b/contrib/unbound/services/localzone.c
@@ -48,6 +48,7 @@
#include "util/data/packed_rrset.h"
#include "util/data/msgencode.h"
#include "util/net_help.h"
+#include "util/netevent.h"
#include "util/data/msgreply.h"
#include "util/data/msgparse.h"
@@ -1022,6 +1023,10 @@ void local_zones_print(struct local_zones* zones)
log_nametypeclass(0, "static zone",
z->name, 0, z->dclass);
break;
+ case local_zone_inform:
+ log_nametypeclass(0, "inform zone",
+ z->name, 0, z->dclass);
+ break;
default:
log_nametypeclass(0, "badtyped zone",
z->name, 0, z->dclass);
@@ -1169,9 +1174,25 @@ lz_zone_answer(struct local_zone* z, struct query_info* qinfo,
return 0;
}
+/** print log information for an inform zone query */
+static void
+lz_inform_print(struct local_zone* z, struct query_info* qinfo,
+ struct comm_reply* repinfo)
+{
+ char ip[128], txt[512];
+ char zname[LDNS_MAX_DOMAINLEN+1];
+ uint16_t port = ntohs(((struct sockaddr_in*)&repinfo->addr)->sin_port);
+ dname_str(z->name, zname);
+ addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip));
+ snprintf(txt, sizeof(txt), "%s inform %s@%u", zname, ip,
+ (unsigned)port);
+ log_nametypeclass(0, txt, qinfo->qname, qinfo->qtype, qinfo->qclass);
+}
+
int
local_zones_answer(struct local_zones* zones, struct query_info* qinfo,
- struct edns_data* edns, sldns_buffer* buf, struct regional* temp)
+ struct edns_data* edns, sldns_buffer* buf, struct regional* temp,
+ struct comm_reply* repinfo)
{
/* see if query is covered by a zone,
* if so: - try to match (exact) local data
@@ -1190,6 +1211,9 @@ local_zones_answer(struct local_zones* zones, struct query_info* qinfo,
lock_rw_rdlock(&z->lock);
lock_rw_unlock(&zones->lock);
+ if(z->type == local_zone_inform && repinfo)
+ lz_inform_print(z, qinfo, repinfo);
+
if(local_data_answer(z, qinfo, edns, buf, temp, labs, &ld)) {
lock_rw_unlock(&z->lock);
return 1;
@@ -1209,6 +1233,7 @@ const char* local_zone_type2str(enum localzone_type t)
case local_zone_typetransparent: return "typetransparent";
case local_zone_static: return "static";
case local_zone_nodefault: return "nodefault";
+ case local_zone_inform: return "inform";
}
return "badtyped";
}
@@ -1227,6 +1252,8 @@ int local_zone_str2type(const char* type, enum localzone_type* t)
*t = local_zone_typetransparent;
else if(strcmp(type, "redirect") == 0)
*t = local_zone_redirect;
+ else if(strcmp(type, "inform") == 0)
+ *t = local_zone_inform;
else return 0;
return 1;
}
diff --git a/contrib/unbound/services/localzone.h b/contrib/unbound/services/localzone.h
index 788fbfb3ba2b..29ba8663fd04 100644
--- a/contrib/unbound/services/localzone.h
+++ b/contrib/unbound/services/localzone.h
@@ -49,6 +49,7 @@ struct config_file;
struct edns_data;
struct query_info;
struct sldns_buffer;
+struct comm_reply;
/**
* Local zone type
@@ -70,7 +71,9 @@ enum localzone_type {
local_zone_redirect,
/** remove default AS112 blocking contents for zone
* nodefault is used in config not during service. */
- local_zone_nodefault
+ local_zone_nodefault,
+ /** log client address, but no block (transparent) */
+ local_zone_inform
};
/**
@@ -220,12 +223,14 @@ void local_zones_print(struct local_zones* zones);
* @param edns: edns info (parsed).
* @param buf: buffer with query ID and flags, also for reply.
* @param temp: temporary storage region.
+ * @param repinfo: source address for checks. may be NULL.
* @return true if answer is in buffer. false if query is not answered
* by authority data. If the reply should be dropped altogether, the return
* value is true, but the buffer is cleared (empty).
*/
int local_zones_answer(struct local_zones* zones, struct query_info* qinfo,
- struct edns_data* edns, struct sldns_buffer* buf, struct regional* temp);
+ struct edns_data* edns, struct sldns_buffer* buf, struct regional* temp,
+ struct comm_reply* repinfo);
/**
* Parse the string into localzone type.
diff --git a/contrib/unbound/smallapp/unbound-checkconf.c b/contrib/unbound/smallapp/unbound-checkconf.c
index 7723c3357695..b5d7b9f44419 100644
--- a/contrib/unbound/smallapp/unbound-checkconf.c
+++ b/contrib/unbound/smallapp/unbound-checkconf.c
@@ -78,6 +78,7 @@ usage()
printf(" Checks unbound configuration file for errors.\n");
printf("file if omitted %s is used.\n", CONFIGFILE);
printf("-o option print value of option to stdout.\n");
+ printf("-f output full pathname with chroot applied, eg. with -o pidfile.\n");
printf("-h show this usage help.\n");
printf("Version %s\n", PACKAGE_VERSION);
printf("BSD licensed, see LICENSE in source package for details.\n");
@@ -90,10 +91,15 @@ usage()
* @param cfg: config
* @param opt: option name without trailing :.
* This is different from config_set_option.
+ * @param final: if final pathname with chroot applied has to be printed.
*/
static void
-print_option(struct config_file* cfg, const char* opt)
+print_option(struct config_file* cfg, const char* opt, int final)
{
+ if(strcmp(opt, "pidfile") == 0 && final) {
+ printf("%s\n", fname_after_chroot(cfg->pidfile, cfg, 1));
+ return;
+ }
if(!config_get_option(cfg, opt, config_print_func, stdout))
fatal_exit("cannot print option '%s'", opt);
}
@@ -456,7 +462,7 @@ check_hints(struct config_file* cfg)
/** check config file */
static void
-checkconf(const char* cfgfile, const char* opt)
+checkconf(const char* cfgfile, const char* opt, int final)
{
struct config_file* cfg = config_create();
if(!cfg)
@@ -467,7 +473,7 @@ checkconf(const char* cfgfile, const char* opt)
exit(1);
}
if(opt) {
- print_option(cfg, opt);
+ print_option(cfg, opt, final);
config_delete(cfg);
return;
}
@@ -493,6 +499,7 @@ extern char* optarg;
int main(int argc, char* argv[])
{
int c;
+ int final = 0;
const char* f;
const char* opt = NULL;
const char* cfgfile = CONFIGFILE;
@@ -505,8 +512,11 @@ int main(int argc, char* argv[])
cfgfile = CONFIGFILE;
#endif /* USE_WINSOCK */
/* parse the options */
- while( (c=getopt(argc, argv, "ho:")) != -1) {
+ while( (c=getopt(argc, argv, "fho:")) != -1) {
switch(c) {
+ case 'f':
+ final = 1;
+ break;
case 'o':
opt = optarg;
break;
@@ -523,7 +533,7 @@ int main(int argc, char* argv[])
if(argc == 1)
f = argv[0];
else f = cfgfile;
- checkconf(f, opt);
+ checkconf(f, opt, final);
checklock_stop();
return 0;
}
diff --git a/contrib/unbound/smallapp/unbound-control-setup.sh b/contrib/unbound/smallapp/unbound-control-setup.sh
index f22f4b85f623..010bfd427f0c 100755
--- a/contrib/unbound/smallapp/unbound-control-setup.sh
+++ b/contrib/unbound/smallapp/unbound-control-setup.sh
@@ -36,8 +36,7 @@
# settings:
# directory for files
-prefix=
-DESTDIR=${prefix}/etc/unbound
+DESTDIR=/var/unbound
# issuer and subject name for certificates
SERVERNAME=unbound
diff --git a/contrib/unbound/smallapp/unbound-control-setup.sh.in b/contrib/unbound/smallapp/unbound-control-setup.sh.in
index 79605dc6fd45..75e76e25d967 100755
--- a/contrib/unbound/smallapp/unbound-control-setup.sh.in
+++ b/contrib/unbound/smallapp/unbound-control-setup.sh.in
@@ -36,8 +36,7 @@
# settings:
# directory for files
-prefix=@prefix@
-DESTDIR=@sysconfdir@/unbound
+DESTDIR=@ub_conf_dir@
# issuer and subject name for certificates
SERVERNAME=unbound
diff --git a/contrib/unbound/smallapp/unbound-control.c b/contrib/unbound/smallapp/unbound-control.c
index ac8d96857d47..3b47d3bf885a 100644
--- a/contrib/unbound/smallapp/unbound-control.c
+++ b/contrib/unbound/smallapp/unbound-control.c
@@ -204,12 +204,12 @@ contact_server(const char* svr, struct config_file* cfg, int statuscmd)
fatal_exit("could not parse IP@port: %s", svr);
#ifdef HAVE_SYS_UN_H
} else if(svr[0] == '/') {
- struct sockaddr_un* sun = (struct sockaddr_un *) &addr;
- sun->sun_family = AF_LOCAL;
+ struct sockaddr_un* usock = (struct sockaddr_un *) &addr;
+ usock->sun_family = AF_LOCAL;
#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
- sun->sun_len = (sa_family_t)sizeof(sun);
+ usock->sun_len = (socklen_t)sizeof(usock);
#endif
- (void)strlcpy(sun->sun_path, svr, sizeof(sun->sun_path));
+ (void)strlcpy(usock->sun_path, svr, sizeof(usock->sun_path));
addrlen = (socklen_t)sizeof(struct sockaddr_un);
addrfamily = AF_LOCAL;
#endif
diff --git a/contrib/unbound/util/config_file.c b/contrib/unbound/util/config_file.c
index a2352d5c6a42..cdb2b33364e6 100644
--- a/contrib/unbound/util/config_file.c
+++ b/contrib/unbound/util/config_file.c
@@ -55,6 +55,7 @@
#include "util/regional.h"
#include "util/fptr_wlist.h"
#include "util/data/dname.h"
+#include "util/rtt.h"
#include "ldns/wire2str.h"
#include "ldns/parseutil.h"
#ifdef HAVE_GLOB_H
@@ -64,6 +65,11 @@
#include <pwd.h>
#endif
+/** from cfg username, after daemonise setup performed */
+uid_t cfg_uid = (uid_t)-1;
+/** from cfg username, after daemonise setup performed */
+gid_t cfg_gid = (gid_t)-1;
+
/** global config during parsing */
struct config_parser_state* cfg_parser = 0;
@@ -129,13 +135,12 @@ config_create(void)
cfg->prefetch_key = 0;
cfg->infra_cache_slabs = 4;
cfg->infra_cache_numhosts = 10000;
+ cfg->infra_cache_min_rtt = 50;
cfg->delay_close = 0;
if(!(cfg->outgoing_avail_ports = (int*)calloc(65536, sizeof(int))))
goto error_exit;
init_outgoing_availports(cfg->outgoing_avail_ports, 65536);
if(!(cfg->username = strdup(UB_USERNAME))) goto error_exit;
- cfg->uid = (uid_t)-1;
- cfg->gid = (gid_t)-1;
#ifdef HAVE_CHROOT
if(!(cfg->chrootdir = strdup(CHROOT_DIR))) goto error_exit;
#endif
@@ -375,6 +380,10 @@ int config_set_option(struct config_file* cfg, const char* opt,
{ IS_NUMBER_OR_ZERO; cfg->max_ttl = atoi(val); MAX_TTL=(time_t)cfg->max_ttl;}
else if(strcmp(opt, "cache-min-ttl:") == 0)
{ IS_NUMBER_OR_ZERO; cfg->min_ttl = atoi(val); MIN_TTL=(time_t)cfg->min_ttl;}
+ else if(strcmp(opt, "infra-cache-min-rtt:") == 0) {
+ IS_NUMBER_OR_ZERO; cfg->infra_cache_min_rtt = atoi(val);
+ RTT_MIN_TIMEOUT=cfg->infra_cache_min_rtt;
+ }
else S_NUMBER_OR_ZERO("infra-host-ttl:", host_ttl)
else S_POW2("infra-cache-slabs:", infra_cache_slabs)
else S_SIZET_NONZERO("infra-cache-numhosts:", infra_cache_numhosts)
@@ -623,6 +632,7 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_DEC(opt, "cache-min-ttl", min_ttl)
else O_DEC(opt, "infra-host-ttl", host_ttl)
else O_DEC(opt, "infra-cache-slabs", infra_cache_slabs)
+ else O_DEC(opt, "infra-cache-min-rtt", infra_cache_min_rtt)
else O_MEM(opt, "infra-cache-numhosts", infra_cache_numhosts)
else O_UNS(opt, "delay-close", delay_close)
else O_YNO(opt, "do-ip4", do_ip4)
@@ -1188,6 +1198,7 @@ config_apply(struct config_file* config)
{
MAX_TTL = (time_t)config->max_ttl;
MIN_TTL = (time_t)config->min_ttl;
+ RTT_MIN_TIMEOUT = config->infra_cache_min_rtt;
EDNS_ADVERTISED_SIZE = (uint16_t)config->edns_buffer_size;
MINIMAL_RESPONSES = config->minimal_responses;
RRSET_ROUNDROBIN = config->rrset_roundrobin;
@@ -1200,11 +1211,13 @@ void config_lookup_uid(struct config_file* cfg)
/* translate username into uid and gid */
if(cfg->username && cfg->username[0]) {
struct passwd *pwd;
- if((pwd = getpwnam(cfg->username)) == NULL)
- log_err("user '%s' does not exist.", cfg->username);
- cfg->uid = pwd->pw_uid;
- cfg->gid = pwd->pw_gid;
+ if((pwd = getpwnam(cfg->username)) != NULL) {
+ cfg_uid = pwd->pw_uid;
+ cfg_gid = pwd->pw_gid;
+ }
}
+#else
+ (void)cfg;
#endif
}
diff --git a/contrib/unbound/util/config_file.h b/contrib/unbound/util/config_file.h
index 327eadc76f7b..ca512d720ebd 100644
--- a/contrib/unbound/util/config_file.h
+++ b/contrib/unbound/util/config_file.h
@@ -119,6 +119,8 @@ struct config_file {
size_t infra_cache_slabs;
/** max number of hosts in the infra cache */
size_t infra_cache_numhosts;
+ /** min value for infra cache rtt */
+ int infra_cache_min_rtt;
/** delay close of udp-timeouted ports, if 0 no delayclose. in msec */
int delay_close;
@@ -192,8 +194,6 @@ struct config_file {
char* chrootdir;
/** username to change to, if not "". */
char* username;
- uid_t uid;
- gid_t gid;
/** working directory */
char* directory;
/** filename to log to. */
@@ -343,6 +343,11 @@ struct config_file {
int dnstap_log_forwarder_response_messages;
};
+/** from cfg username, after daemonise setup performed */
+extern uid_t cfg_uid;
+/** from cfg username, after daemonise setup performed */
+extern gid_t cfg_gid;
+
/**
* Stub config options
*/
@@ -427,7 +432,7 @@ void config_delete(struct config_file* config);
void config_apply(struct config_file* config);
/**
- * Find username, sets uid and gid.
+ * Find username, sets cfg_uid and cfg_gid.
* @param config: the config structure.
*/
void config_lookup_uid(struct config_file* config);
diff --git a/contrib/unbound/util/configlexer.lex b/contrib/unbound/util/configlexer.lex
index e13bad07536d..0e2294686c18 100644
--- a/contrib/unbound/util/configlexer.lex
+++ b/contrib/unbound/util/configlexer.lex
@@ -247,6 +247,7 @@ infra-lame-ttl{COLON} { YDVAR(1, VAR_INFRA_LAME_TTL) }
infra-cache-slabs{COLON} { YDVAR(1, VAR_INFRA_CACHE_SLABS) }
infra-cache-numhosts{COLON} { YDVAR(1, VAR_INFRA_CACHE_NUMHOSTS) }
infra-cache-lame-size{COLON} { YDVAR(1, VAR_INFRA_CACHE_LAME_SIZE) }
+infra-cache-min-rtt{COLON} { YDVAR(1, VAR_INFRA_CACHE_MIN_RTT) }
num-queries-per-thread{COLON} { YDVAR(1, VAR_NUM_QUERIES_PER_THREAD) }
jostle-timeout{COLON} { YDVAR(1, VAR_JOSTLE_TIMEOUT) }
delay-close{COLON} { YDVAR(1, VAR_DELAY_CLOSE) }
diff --git a/contrib/unbound/util/configparser.y b/contrib/unbound/util/configparser.y
index cbb5e16bd813..396ea3c64d64 100644
--- a/contrib/unbound/util/configparser.y
+++ b/contrib/unbound/util/configparser.y
@@ -107,6 +107,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_SSL_SERVICE_KEY VAR_SSL_SERVICE_PEM VAR_SSL_PORT VAR_FORWARD_FIRST
%token VAR_STUB_FIRST VAR_MINIMAL_RESPONSES VAR_RRSET_ROUNDROBIN
%token VAR_MAX_UDP_SIZE VAR_DELAY_CLOSE VAR_UNBLOCK_LAN_ZONES
+%token VAR_INFRA_CACHE_MIN_RTT
%token VAR_DNS64_PREFIX VAR_DNS64_SYNTHALL
%token VAR_DNSTAP VAR_DNSTAP_ENABLE VAR_DNSTAP_SOCKET_PATH
%token VAR_DNSTAP_SEND_IDENTITY VAR_DNSTAP_SEND_VERSION
@@ -175,7 +176,8 @@ content_server: server_num_threads | server_verbosity | server_port |
server_ssl_service_key | server_ssl_service_pem | server_ssl_port |
server_minimal_responses | server_rrset_roundrobin | server_max_udp_size |
server_so_reuseport | server_delay_close | server_unblock_lan_zones |
- server_dns64_prefix | server_dns64_synthall
+ server_dns64_prefix | server_dns64_synthall |
+ server_infra_cache_min_rtt
;
stubstart: VAR_STUB_ZONE
{
@@ -768,6 +770,15 @@ server_infra_cache_slabs: VAR_INFRA_CACHE_SLABS STRING_ARG
free($2);
}
;
+server_infra_cache_min_rtt: VAR_INFRA_CACHE_MIN_RTT STRING_ARG
+ {
+ OUTYY(("P(server_infra_cache_min_rtt:%s)\n", $2));
+ if(atoi($2) == 0 && strcmp($2, "0") != 0)
+ yyerror("number expected");
+ else cfg_parser->cfg->infra_cache_min_rtt = atoi($2);
+ free($2);
+ }
+ ;
server_target_fetch_policy: VAR_TARGET_FETCH_POLICY STRING_ARG
{
OUTYY(("P(server_target_fetch_policy:%s)\n", $2));
@@ -1105,10 +1116,11 @@ server_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG
if(strcmp($3, "static")!=0 && strcmp($3, "deny")!=0 &&
strcmp($3, "refuse")!=0 && strcmp($3, "redirect")!=0 &&
strcmp($3, "transparent")!=0 && strcmp($3, "nodefault")!=0
- && strcmp($3, "typetransparent")!=0)
+ && strcmp($3, "typetransparent")!=0 &&
+ strcmp($3, "inform")!=0)
yyerror("local-zone type: expected static, deny, "
"refuse, redirect, transparent, "
- "typetransparent or nodefault");
+ "typetransparent, inform or nodefault");
else if(strcmp($3, "nodefault")==0) {
if(!cfg_strlist_insert(&cfg_parser->cfg->
local_zones_nodefault, $2))
diff --git a/contrib/unbound/util/iana_ports.inc b/contrib/unbound/util/iana_ports.inc
index d318477e56f4..ce939d55ce54 100644
--- a/contrib/unbound/util/iana_ports.inc
+++ b/contrib/unbound/util/iana_ports.inc
@@ -3819,6 +3819,7 @@
4359,
4361,
4362,
+4366,
4368,
4369,
4370,
@@ -4399,6 +4400,7 @@
6163,
6200,
6201,
+6209,
6222,
6241,
6242,
@@ -4488,6 +4490,8 @@
6628,
6633,
6634,
+6635,
+6636,
6653,
6657,
6670,
@@ -4671,6 +4675,7 @@
7778,
7779,
7781,
+7784,
7786,
7787,
7789,
@@ -4839,6 +4844,8 @@
8912,
8913,
8954,
+8980,
+8981,
8989,
8990,
8991,
diff --git a/contrib/unbound/util/net_help.c b/contrib/unbound/util/net_help.c
index 335ee7499e7d..e2b7c38783ab 100644
--- a/contrib/unbound/util/net_help.c
+++ b/contrib/unbound/util/net_help.c
@@ -156,7 +156,12 @@ log_addr(enum verbosity_value v, const char* str,
case AF_INET6: family="ip6";
sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr;
break;
- case AF_LOCAL: family="local"; break;
+ case AF_LOCAL:
+ dest[0]=0;
+ (void)inet_ntop(af, sinaddr, dest,
+ (socklen_t)sizeof(dest));
+ verbose(v, "%s local %s", str, dest);
+ return; /* do not continue and try to get port */
default: break;
}
if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) {
diff --git a/contrib/unbound/util/rtt.c b/contrib/unbound/util/rtt.c
index 4b44fca5060e..5d86f13378e5 100644
--- a/contrib/unbound/util/rtt.c
+++ b/contrib/unbound/util/rtt.c
@@ -42,6 +42,8 @@
#include "config.h"
#include "util/rtt.h"
+/* overwritten by config: infra_cache_min_rtt: */
+int RTT_MIN_TIMEOUT = 50;
/** calculate RTO from rtt information */
static int
calc_rto(const struct rtt_info* rtt)
diff --git a/contrib/unbound/util/rtt.h b/contrib/unbound/util/rtt.h
index 57e904d1407f..d6da98606502 100644
--- a/contrib/unbound/util/rtt.h
+++ b/contrib/unbound/util/rtt.h
@@ -56,7 +56,7 @@ struct rtt_info {
};
/** min retransmit timeout value, in milliseconds */
-#define RTT_MIN_TIMEOUT 50
+extern int RTT_MIN_TIMEOUT;
/** max retransmit timeout value, in milliseconds */
#define RTT_MAX_TIMEOUT 120000
diff --git a/contrib/unbound/validator/val_secalgo.c b/contrib/unbound/validator/val_secalgo.c
index d89675f835b0..3437c8da6047 100644
--- a/contrib/unbound/validator/val_secalgo.c
+++ b/contrib/unbound/validator/val_secalgo.c
@@ -41,8 +41,9 @@
* and do the library calls (for the crypto library in use).
*/
#include "config.h"
-#include "validator/val_secalgo.h"
+/* packed_rrset on top to define enum types (forced by c99 standard) */
#include "util/data/packed_rrset.h"
+#include "validator/val_secalgo.h"
#include "util/log.h"
#include "ldns/rrdef.h"
#include "ldns/keyraw.h"
diff --git a/contrib/unbound/validator/val_utils.c b/contrib/unbound/validator/val_utils.c
index ecf2dfaf05c8..475b0c9054e0 100644
--- a/contrib/unbound/validator/val_utils.c
+++ b/contrib/unbound/validator/val_utils.c
@@ -846,6 +846,18 @@ val_fill_reply(struct reply_info* chase, struct reply_info* orig,
chase->ar_numrrsets;
}
+void val_reply_remove_auth(struct reply_info* rep, size_t index)
+{
+ log_assert(index < rep->rrset_count);
+ log_assert(index >= rep->an_numrrsets);
+ log_assert(index < rep->an_numrrsets+rep->ns_numrrsets);
+ memmove(rep->rrsets+index, rep->rrsets+index+1,
+ sizeof(struct ub_packed_rrset_key*)*
+ (rep->rrset_count - index - 1));
+ rep->ns_numrrsets--;
+ rep->rrset_count--;
+}
+
void
val_check_nonsecure(struct val_env* ve, struct reply_info* rep)
{
diff --git a/contrib/unbound/validator/val_utils.h b/contrib/unbound/validator/val_utils.h
index b0344eff7de9..cdb87697e1c2 100644
--- a/contrib/unbound/validator/val_utils.h
+++ b/contrib/unbound/validator/val_utils.h
@@ -295,6 +295,13 @@ void val_fill_reply(struct reply_info* chase, struct reply_info* orig,
size_t cname_skip, uint8_t* name, size_t len, uint8_t* signer);
/**
+ * Remove rrset with index from reply, from the authority section.
+ * @param rep: reply to remove it from.
+ * @param index: rrset to remove, must be in the authority section.
+ */
+void val_reply_remove_auth(struct reply_info* rep, size_t index);
+
+/**
* Remove all unsigned or non-secure status rrsets from NS and AR sections.
* So that unsigned data does not get let through to clients, when we have
* found the data to be secure.
diff --git a/contrib/unbound/validator/validator.c b/contrib/unbound/validator/validator.c
index 9d5d5c390254..cc07cc2b1525 100644
--- a/contrib/unbound/validator/validator.c
+++ b/contrib/unbound/validator/validator.c
@@ -574,6 +574,61 @@ detect_wrongly_truncated(struct reply_info* rep)
return 1;
}
+/**
+ * For messages that are not referrals, if the chase reply contains an
+ * unsigned NS record in the authority section it could have been
+ * inserted by a (BIND) forwarder that thinks the zone is insecure, and
+ * that has an NS record without signatures in cache. Remove the NS
+ * record since the reply does not hinge on that record (in the authority
+ * section), but do not remove it if it removes the last record from the
+ * answer+authority sections.
+ * @param chase_reply: the chased reply, we have a key for this contents,
+ * so we should have signatures for these rrsets and not having
+ * signatures means it will be bogus.
+ * @param orig_reply: original reply, remove NS from there as well because
+ * we cannot mark the NS record as DNSSEC valid because it is not
+ * validated by signatures.
+ */
+static void
+remove_spurious_authority(struct reply_info* chase_reply,
+ struct reply_info* orig_reply)
+{
+ size_t i, found = 0;
+ int remove = 0;
+ /* if no answer and only 1 auth RRset, do not remove that one */
+ if(chase_reply->an_numrrsets == 0 && chase_reply->ns_numrrsets == 1)
+ return;
+ /* search authority section for unsigned NS records */
+ for(i = chase_reply->an_numrrsets;
+ i < chase_reply->an_numrrsets+chase_reply->ns_numrrsets; i++) {
+ struct packed_rrset_data* d = (struct packed_rrset_data*)
+ chase_reply->rrsets[i]->entry.data;
+ if(ntohs(chase_reply->rrsets[i]->rk.type) == LDNS_RR_TYPE_NS
+ && d->rrsig_count == 0) {
+ found = i;
+ remove = 1;
+ break;
+ }
+ }
+ /* see if we found the entry */
+ if(!remove) return;
+ log_rrset_key(VERB_ALGO, "Removing spurious unsigned NS record "
+ "(likely inserted by forwarder)", chase_reply->rrsets[found]);
+
+ /* find rrset in orig_reply */
+ for(i = orig_reply->an_numrrsets;
+ i < orig_reply->an_numrrsets+orig_reply->ns_numrrsets; i++) {
+ if(ntohs(orig_reply->rrsets[i]->rk.type) == LDNS_RR_TYPE_NS
+ && query_dname_compare(orig_reply->rrsets[i]->rk.dname,
+ chase_reply->rrsets[found]->rk.dname) == 0) {
+ /* remove from orig_msg */
+ val_reply_remove_auth(orig_reply, i);
+ break;
+ }
+ }
+ /* remove rrset from chase_reply */
+ val_reply_remove_auth(chase_reply, found);
+}
/**
* Given a "positive" response -- a response that contains an answer to the
@@ -1642,6 +1697,8 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
}
subtype = val_classify_response(qstate->query_flags, &qstate->qinfo,
&vq->qchase, vq->orig_msg->rep, vq->rrset_skip);
+ if(subtype != VAL_CLASS_REFERRAL)
+ remove_spurious_authority(vq->chase_reply, vq->orig_msg->rep);
/* check signatures in the message;
* answer and authority must be valid, additional is only checked. */
diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf
index 2f5cbca5c04f..ef3b8616fabc 100644
--- a/etc/defaults/rc.conf
+++ b/etc/defaults/rc.conf
@@ -648,7 +648,7 @@ devfs_system_ruleset="" # The name (NOT number) of a ruleset to apply to /dev
devfs_set_rulesets="" # A list of /mount/dev=ruleset_name settings to
# apply (must be mounted already, i.e. fstab(5))
devfs_load_rulesets="YES" # Enable to always load the default rulesets
-performance_cx_lowest="Cmax" # Online CPU idle state
+performance_cx_lowest="C2" # Online CPU idle state
performance_cpu_freq="NONE" # Online CPU frequency
economy_cx_lowest="Cmax" # Offline CPU idle state
economy_cpu_freq="NONE" # Offline CPU frequency
diff --git a/etc/mtree/BSD.tests.dist b/etc/mtree/BSD.tests.dist
index 35e1c062b1e9..c9c52a41b0fe 100644
--- a/etc/mtree/BSD.tests.dist
+++ b/etc/mtree/BSD.tests.dist
@@ -354,7 +354,19 @@
..
..
sys
+ aio
+ ..
+ fifo
+ ..
+ file
+ ..
kern
+ execve
+ ..
+ ..
+ kqueue
+ ..
+ mqueue
..
netinet
..
@@ -392,6 +404,8 @@
unlink
..
..
+ vm
+ ..
..
usr.bin
apply
diff --git a/etc/rc.d/Makefile b/etc/rc.d/Makefile
index 1e6e28ffbaa6..f1f6afe52b02 100644
--- a/etc/rc.d/Makefile
+++ b/etc/rc.d/Makefile
@@ -263,6 +263,10 @@ FILES+= routed
FILES+= sendmail
.endif
+.if ${MK_TESTS} != "no"
+SUBDIR+= tests
+.endif
+
.if ${MK_TIMED} != "no"
FILES+= timed
.endif
diff --git a/etc/rc.d/devd b/etc/rc.d/devd
index c7288e446292..53532cc8698d 100755
--- a/etc/rc.d/devd
+++ b/etc/rc.d/devd
@@ -4,7 +4,7 @@
#
# PROVIDE: devd
-# REQUIRE: netif
+# REQUIRE: netif ldconfig
# BEFORE: NETWORKING mountcritremote
# KEYWORD: nojail shutdown
diff --git a/etc/rc.d/hostid b/etc/rc.d/hostid
index c4545bd7916a..281b2417c9ea 100755
--- a/etc/rc.d/hostid
+++ b/etc/rc.d/hostid
@@ -1,6 +1,7 @@
#!/bin/sh
#
# Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
+# Copyright (c) 2015 Xin LI <delphij@FreeBSD.org>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -55,23 +56,66 @@ hostid_set()
${SYSCTL} kern.hostid=${id} >/dev/null
}
-hostid_hardware()
+valid_hostid()
{
- uuid=`kenv -q smbios.system.uuid`
+ uuid=$1
+
x="[0-9a-f]"
y=$x$x$x$x
+
+ # Check against a blacklist before
+ # accepting the UUID.
case "${uuid}" in
+ 00000000-0000-0000-0000-000000000000)
+ ;;
+ 00020003-0004-0005-0006-000700080009)
+ ;;
+ 03000200-0400-0500-0006-000700080009)
+ ;;
+ 07090201-0103-0301-0807-060504030201)
+ ;;
+ 11111111-1111-1111-1111-111111111111)
+ ;;
+ 11111111-2222-3333-4444-555555555555)
+ ;;
+ 4c4c4544-0000-2010-8020-80c04f202020)
+ ;;
+ 58585858-5858-5858-5858-585858585858)
+ ;;
+ 890e2d14-cacd-45d1-ae66-bc80e8bfeb0f)
+ ;;
+ 8e275844-178f-44a8-aceb-a7d7e5178c63)
+ ;;
+ dc698397-fa54-4cf2-82c8-b1b5307a6a7f)
+ ;;
+ fefefefe-fefe-fefe-fefe-fefefefefefe)
+ ;;
+ *-ffff-ffff-ffff-ffffffffffff)
+ ;;
$y$y-$y-$y-$y-$y$y$y)
- echo "${uuid}"
+ return 0
;;
esac
+
+ return 1
+}
+
+hostid_hardware()
+{
+ uuid=`kenv -q smbios.system.uuid`
+
+ if valid_hostid $uuid; then
+ echo "${uuid}"
+ fi
}
hostid_generate()
{
# First look for UUID in hardware.
uuid=`hostid_hardware`
- if [ -z ${uuid} ]; then
+ if [ -z "${uuid}" ]; then
+ warn "hostid: unable to figure out a UUID from DMI data, generating a new one"
+ sleep 2
# If not found, fall back to software-generated UUID.
uuid=`uuidgen`
fi
@@ -92,11 +136,15 @@ hostid_start()
{
# If ${hostid_file} already exists, we take UUID from there.
if [ -r ${hostid_file} ]; then
- hostid_set `cat ${hostid_file}`
- else
- # No hostid file, generate UUID.
- hostid_generate
+ read saved_hostid < ${hostid_file}
+ if valid_hostid ${saved_hostid}; then
+ hostid_set `cat ${hostid_file}`
+ exit 0
+ fi
fi
+
+ # No hostid file, generate UUID.
+ hostid_generate
}
load_rc_config $name
diff --git a/etc/tests/rc.d/Makefile b/etc/rc.d/tests/Makefile
index 368e8f4fc875..368e8f4fc875 100644
--- a/etc/tests/rc.d/Makefile
+++ b/etc/rc.d/tests/Makefile
diff --git a/etc/tests/rc.d/routing_test.sh b/etc/rc.d/tests/routing_test.sh
index 693af232ea39..693af232ea39 100755
--- a/etc/tests/rc.d/routing_test.sh
+++ b/etc/rc.d/tests/routing_test.sh
diff --git a/etc/tests/Makefile b/etc/tests/Makefile
index fd9efdaa566c..5aacd5b19e57 100644
--- a/etc/tests/Makefile
+++ b/etc/tests/Makefile
@@ -7,6 +7,4 @@ TESTSDIR= ${TESTSBASE}/etc
.PATH: ${.CURDIR:H:H}/tests
KYUAFILE= yes
-TESTS_SUBDIRS+= rc.d
-
.include <bsd.test.mk>
diff --git a/gnu/lib/libgomp/Makefile b/gnu/lib/libgomp/Makefile
index 237c14afb844..d428bd3f24c6 100644
--- a/gnu/lib/libgomp/Makefile
+++ b/gnu/lib/libgomp/Makefile
@@ -12,7 +12,7 @@ SHLIB_MAJOR= 1
SRCS= alloc.c barrier.c critical.c env.c \
error.c iter.c loop.c ordered.c parallel.c sections.c \
single.c team.c work.c lock.c mutex.c proc.c sem.c \
- bar.c time.c fortran.c
+ bar.c time.c fortran.c affinity.c
SRCS+= gstdint.h libgomp_f.h omp.h omp_lib.h
INCS+= omp.h
diff --git a/gnu/lib/libgomp/config.h b/gnu/lib/libgomp/config.h
index 6ef541be733a..547e6927db35 100644
--- a/gnu/lib/libgomp/config.h
+++ b/gnu/lib/libgomp/config.h
@@ -26,6 +26,9 @@
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
+/* Define if pthread_{,attr_}{g,s}etaffinity_np is supported. */
+#undef HAVE_PTHREAD_AFFINITY_NP
+
/* Define to 1 if you have the <semaphore.h> header file. */
#define HAVE_SEMAPHORE_H 1
@@ -52,6 +55,9 @@
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
+/* Define to 1 if you have the <sys/sysctl.h> header file. */
+#define HAVE_SYS_SYSCTL_H 1
+
/* Define to 1 if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1
diff --git a/gnu/usr.bin/cc/Makefile b/gnu/usr.bin/cc/Makefile
index abc987674844..65dc0871f3ee 100644
--- a/gnu/usr.bin/cc/Makefile
+++ b/gnu/usr.bin/cc/Makefile
@@ -12,7 +12,10 @@ SUBDIR+= cpp
.endif
.if ${MK_CXX} != "no"
-SUBDIR+= cc1plus c++ c++filt
+SUBDIR+= cc1plus c++
+.if ${MK_ELFTOOLCHAIN_TOOLS} == "no"
+SUBDIR+= c++filt
+.endif
.endif
.if ${MK_GCOV} != "no"
diff --git a/lib/libarchive/config_freebsd.h b/lib/libarchive/config_freebsd.h
index 0df3f917e92d..fbf429fec33c 100644
--- a/lib/libarchive/config_freebsd.h
+++ b/lib/libarchive/config_freebsd.h
@@ -25,6 +25,8 @@
* $FreeBSD$
*/
+#include <osreldate.h>
+
/* FreeBSD 5.0 and later have ACL and extattr support. */
#if __FreeBSD__ > 4
#define HAVE_ACL_CREATE_ENTRY 1
@@ -220,6 +222,11 @@
#define HAVE_ZLIB_H 1
#define TIME_WITH_SYS_TIME 1
+#if __FreeBSD_version >= 1100056
+#define HAVE_FUTIMENS 1
+#define HAVE_UTIMENSAT 1
+#endif
+
/* FreeBSD 4 and earlier lack intmax_t/uintmax_t */
#if __FreeBSD__ < 5
#define intmax_t int64_t
diff --git a/lib/libc/Makefile b/lib/libc/Makefile
index 8e0db62504cf..93ab138dba9f 100644
--- a/lib/libc/Makefile
+++ b/lib/libc/Makefile
@@ -157,7 +157,9 @@ libkern.${LIBC_ARCH}:: ${KMSRCS}
${CP} ${.ALLSRC} ${DESTDIR}/sys/libkern/${LIBC_ARCH}
.endif
-.include <bsd.arch.inc.mk>
+.if ${MK_TESTS} != "no"
+SUBDIR+= tests
+.endif
.include <bsd.lib.mk>
diff --git a/lib/libc/Makefile.amd64 b/lib/libc/Makefile.amd64
deleted file mode 100644
index dd0f5b0cfb2d..000000000000
--- a/lib/libc/Makefile.amd64
+++ /dev/null
@@ -1,6 +0,0 @@
-# $FreeBSD$
-
-.if ${MK_TESTS} != "no"
-SUBDIR+= tests
-.endif
-
diff --git a/lib/libc/Makefile.i386 b/lib/libc/Makefile.i386
deleted file mode 100644
index dd0f5b0cfb2d..000000000000
--- a/lib/libc/Makefile.i386
+++ /dev/null
@@ -1,6 +0,0 @@
-# $FreeBSD$
-
-.if ${MK_TESTS} != "no"
-SUBDIR+= tests
-.endif
-
diff --git a/lib/libc/gen/_once_stub.c b/lib/libc/gen/_once_stub.c
index d2acc29f32c2..c45565a79cbd 100644
--- a/lib/libc/gen/_once_stub.c
+++ b/lib/libc/gen/_once_stub.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2009 Advanced Computing Technologies LLC
+ * Copyright (c) 2009 Hudson River Trading LLC
* Written by: John H. Baldwin <jhb@FreeBSD.org>
* All rights reserved.
*
diff --git a/lib/libc/gen/getutxent.3 b/lib/libc/gen/getutxent.3
index 120f4a08b8e1..85c37b16e0fc 100644
--- a/lib/libc/gen/getutxent.3
+++ b/lib/libc/gen/getutxent.3
@@ -475,4 +475,4 @@ They replaced the
.In utmp.h
interface.
.Sh AUTHORS
-.An Ed Schouten Aq Mt ed@FreeBSD.org
+.An \&Ed Schouten Aq Mt ed@FreeBSD.org
diff --git a/lib/libc/gen/nice.3 b/lib/libc/gen/nice.3
index 8ce13af9d974..b04c8f4596b4 100644
--- a/lib/libc/gen/nice.3
+++ b/lib/libc/gen/nice.3
@@ -87,7 +87,7 @@ The
function conforms to
.St -p1003.1-2008
except for the return value.
-This implementation returns 0 upon successful completion but
+This implementation returns 0 upon successful completion but
the standard requires returning the new nice value,
which could be \-1.
.Sh HISTORY
diff --git a/lib/libc/gen/posix_spawn.3 b/lib/libc/gen/posix_spawn.3
index 52e81713660b..2c9131b5b8c4 100644
--- a/lib/libc/gen/posix_spawn.3
+++ b/lib/libc/gen/posix_spawn.3
@@ -457,4 +457,4 @@ and
functions first appeared in
.Fx 8.0 .
.Sh AUTHORS
-.An Ed Schouten Aq Mt ed@FreeBSD.org
+.An \&Ed Schouten Aq Mt ed@FreeBSD.org
diff --git a/lib/libc/gen/posix_spawn_file_actions_addopen.3 b/lib/libc/gen/posix_spawn_file_actions_addopen.3
index b28f3960ef6b..0b57999bf4be 100644
--- a/lib/libc/gen/posix_spawn_file_actions_addopen.3
+++ b/lib/libc/gen/posix_spawn_file_actions_addopen.3
@@ -200,4 +200,4 @@ and
functions first appeared in
.Fx 8.0 .
.Sh AUTHORS
-.An Ed Schouten Aq Mt ed@FreeBSD.org
+.An \&Ed Schouten Aq Mt ed@FreeBSD.org
diff --git a/lib/libc/gen/posix_spawn_file_actions_init.3 b/lib/libc/gen/posix_spawn_file_actions_init.3
index eda2a1daa1e9..380eed769003 100644
--- a/lib/libc/gen/posix_spawn_file_actions_init.3
+++ b/lib/libc/gen/posix_spawn_file_actions_init.3
@@ -101,4 +101,4 @@ and
functions first appeared in
.Fx 8.0 .
.Sh AUTHORS
-.An Ed Schouten Aq Mt ed@FreeBSD.org
+.An \&Ed Schouten Aq Mt ed@FreeBSD.org
diff --git a/lib/libc/gen/posix_spawnattr_getflags.3 b/lib/libc/gen/posix_spawnattr_getflags.3
index b5995cea4a82..2571f4ab307c 100644
--- a/lib/libc/gen/posix_spawnattr_getflags.3
+++ b/lib/libc/gen/posix_spawnattr_getflags.3
@@ -108,4 +108,4 @@ and
functions first appeared in
.Fx 8.0 .
.Sh AUTHORS
-.An Ed Schouten Aq Mt ed@FreeBSD.org
+.An \&Ed Schouten Aq Mt ed@FreeBSD.org
diff --git a/lib/libc/gen/posix_spawnattr_getpgroup.3 b/lib/libc/gen/posix_spawnattr_getpgroup.3
index 91b3e5cd3d18..cfc1b54ab633 100644
--- a/lib/libc/gen/posix_spawnattr_getpgroup.3
+++ b/lib/libc/gen/posix_spawnattr_getpgroup.3
@@ -93,4 +93,4 @@ and
functions first appeared in
.Fx 8.0 .
.Sh AUTHORS
-.An Ed Schouten Aq Mt ed@FreeBSD.org
+.An \&Ed Schouten Aq Mt ed@FreeBSD.org
diff --git a/lib/libc/gen/posix_spawnattr_getschedparam.3 b/lib/libc/gen/posix_spawnattr_getschedparam.3
index a137200bd6ae..5eef96ea825d 100644
--- a/lib/libc/gen/posix_spawnattr_getschedparam.3
+++ b/lib/libc/gen/posix_spawnattr_getschedparam.3
@@ -97,4 +97,4 @@ and
functions first appeared in
.Fx 8.0 .
.Sh AUTHORS
-.An Ed Schouten Aq Mt ed@FreeBSD.org
+.An \&Ed Schouten Aq Mt ed@FreeBSD.org
diff --git a/lib/libc/gen/posix_spawnattr_getschedpolicy.3 b/lib/libc/gen/posix_spawnattr_getschedpolicy.3
index 3e79d4b79582..5276de5a2f35 100644
--- a/lib/libc/gen/posix_spawnattr_getschedpolicy.3
+++ b/lib/libc/gen/posix_spawnattr_getschedpolicy.3
@@ -95,4 +95,4 @@ and
functions first appeared in
.Fx 8.0 .
.Sh AUTHORS
-.An Ed Schouten Aq Mt ed@FreeBSD.org
+.An \&Ed Schouten Aq Mt ed@FreeBSD.org
diff --git a/lib/libc/gen/posix_spawnattr_getsigdefault.3 b/lib/libc/gen/posix_spawnattr_getsigdefault.3
index 88783322ff97..a81c71417449 100644
--- a/lib/libc/gen/posix_spawnattr_getsigdefault.3
+++ b/lib/libc/gen/posix_spawnattr_getsigdefault.3
@@ -95,4 +95,4 @@ and
functions first appeared in
.Fx 8.0 .
.Sh AUTHORS
-.An Ed Schouten Aq Mt ed@FreeBSD.org
+.An \&Ed Schouten Aq Mt ed@FreeBSD.org
diff --git a/lib/libc/gen/posix_spawnattr_getsigmask.3 b/lib/libc/gen/posix_spawnattr_getsigmask.3
index 4f9c014853af..be15d9d47d82 100644
--- a/lib/libc/gen/posix_spawnattr_getsigmask.3
+++ b/lib/libc/gen/posix_spawnattr_getsigmask.3
@@ -95,4 +95,4 @@ and
functions first appeared in
.Fx 8.0 .
.Sh AUTHORS
-.An Ed Schouten Aq Mt ed@FreeBSD.org
+.An \&Ed Schouten Aq Mt ed@FreeBSD.org
diff --git a/lib/libc/gen/posix_spawnattr_init.3 b/lib/libc/gen/posix_spawnattr_init.3
index 388fe5a49ce9..b4ec52c30e25 100644
--- a/lib/libc/gen/posix_spawnattr_init.3
+++ b/lib/libc/gen/posix_spawnattr_init.3
@@ -120,4 +120,4 @@ and
functions first appeared in
.Fx 8.0 .
.Sh AUTHORS
-.An Ed Schouten Aq Mt ed@FreeBSD.org
+.An \&Ed Schouten Aq Mt ed@FreeBSD.org
diff --git a/lib/libc/include/compat.h b/lib/libc/include/compat.h
index 6ab17d7b137c..b20fac5ac600 100644
--- a/lib/libc/include/compat.h
+++ b/lib/libc/include/compat.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2009 Advanced Computing Technologies LLC
+ * Copyright (c) 2009 Hudson River Trading LLC
* Written by: John H. Baldwin <jhb@FreeBSD.org>
* All rights reserved.
*
diff --git a/lib/libc/locale/duplocale.3 b/lib/libc/locale/duplocale.3
index f2e82158ae0e..bc0c4bced812 100644
--- a/lib/libc/locale/duplocale.3
+++ b/lib/libc/locale/duplocale.3
@@ -36,7 +36,7 @@
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
-.In xlocale.h
+.In locale.h
.Ft locale_t
.Fn duplocale "locale_t locale"
.Sh DESCRIPTION
diff --git a/lib/libc/locale/freelocale.3 b/lib/libc/locale/freelocale.3
index 86f4809d6cac..0df80e7892cd 100644
--- a/lib/libc/locale/freelocale.3
+++ b/lib/libc/locale/freelocale.3
@@ -38,7 +38,7 @@ or
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
-.In xlocale.h
+.In locale.h
.Ft int
.Fn freelocale "locale_t locale"
.Sh DESCRIPTION
diff --git a/lib/libc/locale/newlocale.3 b/lib/libc/locale/newlocale.3
index a639c372a6c6..c7414be73d3a 100644
--- a/lib/libc/locale/newlocale.3
+++ b/lib/libc/locale/newlocale.3
@@ -35,7 +35,7 @@
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
-.In xlocale
+.In locale.h
.Ft locale_t
.Fn newlocale "int mask" "const char * locale" "locale_t base"
.Sh DESCRIPTION
diff --git a/lib/libc/locale/none.c b/lib/libc/locale/none.c
index 75adffaa96df..cacfd738e7c5 100644
--- a/lib/libc/locale/none.c
+++ b/lib/libc/locale/none.c
@@ -209,7 +209,7 @@ struct xlocale_ctype __xlocale_global_ctype = {
256 /* __mb_sb_limit */
};
-const struct xlocale_ctype __xlocale_C_ctype = {
+struct xlocale_ctype __xlocale_C_ctype = {
{{0}, "C"},
(_RuneLocale*)&_DefaultRuneLocale,
_none_mbrtowc,
diff --git a/lib/libc/locale/querylocale.3 b/lib/libc/locale/querylocale.3
index f90d626d1ac6..d1bb688ed907 100644
--- a/lib/libc/locale/querylocale.3
+++ b/lib/libc/locale/querylocale.3
@@ -36,7 +36,7 @@
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
-.In xlocale.h
+.In locale.h
.Ft const char *
.Fn querylocale "int mask" "locale_t locale"
.Sh DESCRIPTION
diff --git a/lib/libc/locale/uselocale.3 b/lib/libc/locale/uselocale.3
index df29a625e17e..96d0008f7837 100644
--- a/lib/libc/locale/uselocale.3
+++ b/lib/libc/locale/uselocale.3
@@ -36,7 +36,7 @@
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
-.In xlocale.h
+.In locale.h
.Ft locale_t
.Fn uselocale "locale_t locale"
.Sh DESCRIPTION
diff --git a/lib/libc/net/sctp_recvmsg.3 b/lib/libc/net/sctp_recvmsg.3
index bb1cf0671228..945797dc9e93 100644
--- a/lib/libc/net/sctp_recvmsg.3
+++ b/lib/libc/net/sctp_recvmsg.3
@@ -27,7 +27,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd August 13, 2007
+.Dd April 23, 2015
.Dt SCTP_RECVMSG 3
.Os
.Sh NAME
@@ -98,13 +98,13 @@ receive buffer, then the
argument will
.Em not
have the
-.Dv MSG_EOF
+.Dv MSG_EOR
flag applied.
If the message is a complete message then
the
.Fa flags
argument will have
-.Dv MSG_EOF
+.Dv MSG_EOR
set.
Locally detected errors are
indicated by a return value of -1 with
diff --git a/lib/libc/nls/catopen.3 b/lib/libc/nls/catopen.3
index 7a16ee50408a..7744b0bd864c 100644
--- a/lib/libc/nls/catopen.3
+++ b/lib/libc/nls/catopen.3
@@ -94,7 +94,7 @@ An empty string is substituted for undefined values.
Path names templates defined in
.Ev NLSPATH
are separated by colons
-.No ( Sq \&: ) .
+.Pq Sq \&: .
A leading or two adjacent colons
is equivalent to specifying %N.
.Pp
diff --git a/lib/libc/regex/re_format.7 b/lib/libc/regex/re_format.7
index 089316bb729e..b3f95611c9f8 100644
--- a/lib/libc/regex/re_format.7
+++ b/lib/libc/regex/re_format.7
@@ -392,10 +392,12 @@ and
.Ql ?\&
are ordinary characters, and their functionality
can be expressed using bounds
-.No ( Ql {1,}
+.Po
+.Ql {1,}
or
.Ql {0,1}
-respectively).
+respectively
+.Pc .
Also note that
.Ql x+
in modern REs is equivalent to
diff --git a/lib/libc/regex/regcomp.c b/lib/libc/regex/regcomp.c
index 2da50666b5d3..2f2d827ba836 100644
--- a/lib/libc/regex/regcomp.c
+++ b/lib/libc/regex/regcomp.c
@@ -1726,13 +1726,13 @@ computematchjumps(struct parse *p, struct re_guts *g)
if (p->error != 0)
return;
- pmatches = (int*) malloc(g->mlen * sizeof(unsigned int));
+ pmatches = (int*) malloc(g->mlen * sizeof(int));
if (pmatches == NULL) {
g->matchjump = NULL;
return;
}
- g->matchjump = (int*) malloc(g->mlen * sizeof(unsigned int));
+ g->matchjump = (int*) malloc(g->mlen * sizeof(int));
if (g->matchjump == NULL) { /* Not a fatal error */
free(pmatches);
return;
diff --git a/lib/libc/regex/regex.3 b/lib/libc/regex/regex.3
index ea1ba25a90b4..6df2f0981f56 100644
--- a/lib/libc/regex/regex.3
+++ b/lib/libc/regex/regex.3
@@ -420,10 +420,12 @@ it should have been the result from the most recent
using that
.Ft regex_t .
The
-.Fn ( regerror
+.Po
+.Fn regerror
may be able to supply a more detailed message using information
from the
-.Ft regex_t . )
+.Ft regex_t .
+.Pc
The
.Fn regerror
function
diff --git a/lib/libc/rpc/rpcbind.3 b/lib/libc/rpc/rpcbind.3
index 0b716ca7a2b6..3bf8be9ffa90 100644
--- a/lib/libc/rpc/rpcbind.3
+++ b/lib/libc/rpc/rpcbind.3
@@ -25,7 +25,7 @@
.Ft bool_t
.Fn rpcb_gettime "const char *host" "time_t * timep"
.Ft "enum clnt_stat"
-.Fn rpcb_rmtcall "const struct netconfig *netconf" "const char *host" "const rpcprog_t prognum, const rpcvers_t versnum" "const rpcproc_t procnum, const xdrproc_t inproc" "const caddr_t in" "const xdrproc_t outproc" "const caddr_t out" "const struct timeval tout, const struct netbuf *svcaddr"
+.Fn rpcb_rmtcall "const struct netconfig *netconf" "const char *host" "const rpcprog_t prognum" "const rpcvers_t versnum" "const rpcproc_t procnum" "const xdrproc_t inproc" "const caddr_t in" "const xdrproc_t outproc" "const caddr_t out" "const struct timeval tout" "const struct netbuf *svcaddr"
.Ft bool_t
.Fn rpcb_set "const rpcprog_t prognum" "const rpcvers_t versnum" "const struct netconfig *netconf" "const struct netbuf *svcaddr"
.Ft bool_t
diff --git a/lib/libc/stdio/open_memstream.3 b/lib/libc/stdio/open_memstream.3
index 117dcb270ee6..e01952bc4941 100644
--- a/lib/libc/stdio/open_memstream.3
+++ b/lib/libc/stdio/open_memstream.3
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2013 Advanced Computing Technologies LLC
+.\" Copyright (c) 2013 Hudson River Trading LLC
.\" Written by: John H. Baldwin <jhb@FreeBSD.org>
.\" All rights reserved.
.\"
diff --git a/lib/libc/stdio/open_memstream.c b/lib/libc/stdio/open_memstream.c
index aa50822b1522..baa71e4a72ef 100644
--- a/lib/libc/stdio/open_memstream.c
+++ b/lib/libc/stdio/open_memstream.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2013 Advanced Computing Technologies LLC
+ * Copyright (c) 2013 Hudson River Trading LLC
* Written by: John H. Baldwin <jhb@FreeBSD.org>
* All rights reserved.
*
diff --git a/lib/libc/stdio/open_wmemstream.c b/lib/libc/stdio/open_wmemstream.c
index cf2968ae626f..299e3d87940f 100644
--- a/lib/libc/stdio/open_wmemstream.c
+++ b/lib/libc/stdio/open_wmemstream.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2013 Advanced Computing Technologies LLC
+ * Copyright (c) 2013 Hudson River Trading LLC
* Written by: John H. Baldwin <jhb@FreeBSD.org>
* All rights reserved.
*
diff --git a/lib/libc/sys/closefrom.2 b/lib/libc/sys/closefrom.2
index ffaa0012bae9..a0b5fc218666 100644
--- a/lib/libc/sys/closefrom.2
+++ b/lib/libc/sys/closefrom.2
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2009 Advanced Computing Technologies LLC
+.\" Copyright (c) 2009 Hudson River Trading LLC
.\" Written by: John H. Baldwin <jhb@FreeBSD.org>
.\" All rights reserved.
.\"
diff --git a/lib/libc/sys/posix_openpt.2 b/lib/libc/sys/posix_openpt.2
index d34385fb93ee..b7e345c159f4 100644
--- a/lib/libc/sys/posix_openpt.2
+++ b/lib/libc/sys/posix_openpt.2
@@ -137,4 +137,4 @@ is included for compatibility; in
opening a terminal does not cause it to become a process's controlling
terminal.
.Sh AUTHORS
-.An Ed Schouten Aq Mt ed@FreeBSD.org
+.An \&Ed Schouten Aq Mt ed@FreeBSD.org
diff --git a/lib/libc/sys/procctl.2 b/lib/libc/sys/procctl.2
index 2c77901f1863..76a3cef1bfb4 100644
--- a/lib/libc/sys/procctl.2
+++ b/lib/libc/sys/procctl.2
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2013 Advanced Computing Technologies LLC
+.\" Copyright (c) 2013 Hudson River Trading LLC
.\" Written by: John H. Baldwin <jhb@FreeBSD.org>
.\" All rights reserved.
.\"
diff --git a/lib/libc/tests/db/Makefile b/lib/libc/tests/db/Makefile
index 323a9f07d4a6..ed1d6caadbf2 100644
--- a/lib/libc/tests/db/Makefile
+++ b/lib/libc/tests/db/Makefile
@@ -11,6 +11,7 @@ FILESDIR= ${TESTSDIR}
FILES= README
NETBSD_ATF_TESTS_SH+= db_test
+ATF_TESTS_SH_SED_db_test= -e 's,/bin/csh,/bin/cat,g'
.include "../Makefile.netbsd-tests"
diff --git a/lib/libc/tests/sys/Makefile b/lib/libc/tests/sys/Makefile
index 89431bced322..5e457fd35c9d 100644
--- a/lib/libc/tests/sys/Makefile
+++ b/lib/libc/tests/sys/Makefile
@@ -12,7 +12,9 @@ NETBSD_ATF_TESTS_C+= clock_gettime_test
NETBSD_ATF_TESTS_C+= connect_test
NETBSD_ATF_TESTS_C+= dup_test
NETBSD_ATF_TESTS_C+= fsync_test
+.if ${MACHINE} != "arm64" # ARM64TODO: Missing makecontext
NETBSD_ATF_TESTS_C+= getcontext_test
+.endif
NETBSD_ATF_TESTS_C+= getgroups_test
NETBSD_ATF_TESTS_C+= getitimer_test
NETBSD_ATF_TESTS_C+= getlogin_test
diff --git a/lib/libcapsicum/libcapsicum_dns.c b/lib/libcapsicum/libcapsicum_dns.c
index 113f8dc5a315..6f240bd65009 100644
--- a/lib/libcapsicum/libcapsicum_dns.c
+++ b/lib/libcapsicum/libcapsicum_dns.c
@@ -30,6 +30,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <assert.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
@@ -67,6 +68,8 @@ static struct hostent *
hostent_unpack(const nvlist_t *nvl, struct hostent *hp)
{
unsigned int ii, nitems;
+ char nvlname[64];
+ int n;
hostent_free(hp);
@@ -81,8 +84,10 @@ hostent_unpack(const nvlist_t *nvl, struct hostent *hp)
if (hp->h_aliases == NULL)
goto fail;
for (ii = 0; ii < nitems; ii++) {
+ n = snprintf(nvlname, sizeof(nvlname), "alias%u", ii);
+ assert(n > 0 && n < (int)sizeof(nvlname));
hp->h_aliases[ii] =
- strdup(nvlist_getf_string(nvl, "alias%u", ii));
+ strdup(nvlist_get_string(nvl, nvlname));
if (hp->h_aliases[ii] == NULL)
goto fail;
}
@@ -96,7 +101,9 @@ hostent_unpack(const nvlist_t *nvl, struct hostent *hp)
hp->h_addr_list[ii] = malloc(hp->h_length);
if (hp->h_addr_list[ii] == NULL)
goto fail;
- bcopy(nvlist_getf_binary(nvl, NULL, "addr%u", ii),
+ n = snprintf(nvlname, sizeof(nvlname), "addr%u", ii);
+ assert(n > 0 && n < (int)sizeof(nvlname));
+ bcopy(nvlist_get_binary(nvl, nvlname, NULL),
hp->h_addr_list[ii], hp->h_length);
}
hp->h_addr_list[ii] = NULL;
@@ -208,8 +215,9 @@ cap_getaddrinfo(cap_channel_t *chan, const char *hostname, const char *servname,
struct addrinfo *firstai, *prevai, *curai;
unsigned int ii;
const nvlist_t *nvlai;
+ char nvlname[64];
nvlist_t *nvl;
- int error;
+ int error, n;
nvl = nvlist_create(0);
nvlist_add_string(nvl, "cmd", "getaddrinfo");
@@ -237,9 +245,11 @@ cap_getaddrinfo(cap_channel_t *chan, const char *hostname, const char *servname,
nvlai = NULL;
firstai = prevai = curai = NULL;
for (ii = 0; ; ii++) {
- if (!nvlist_existsf_nvlist(nvl, "res%u", ii))
+ n = snprintf(nvlname, sizeof(nvlname), "res%u", ii);
+ assert(n > 0 && n < (int)sizeof(nvlname));
+ if (!nvlist_exists_nvlist(nvl, nvlname))
break;
- nvlai = nvlist_getf_nvlist(nvl, "res%u", ii);
+ nvlai = nvlist_get_nvlist(nvl, nvlname);
curai = addrinfo_unpack(nvlai);
if (curai == NULL)
break;
@@ -314,6 +324,8 @@ cap_dns_type_limit(cap_channel_t *chan, const char * const *types,
{
nvlist_t *limits;
unsigned int i;
+ char nvlname[64];
+ int n;
if (cap_limit_get(chan, &limits) < 0)
return (-1);
@@ -321,8 +333,11 @@ cap_dns_type_limit(cap_channel_t *chan, const char * const *types,
limits = nvlist_create(0);
else
limit_remove(limits, "type");
- for (i = 0; i < ntypes; i++)
- nvlist_addf_string(limits, types[i], "type%u", i);
+ for (i = 0; i < ntypes; i++) {
+ n = snprintf(nvlname, sizeof(nvlname), "type%u", i);
+ assert(n > 0 && n < (int)sizeof(nvlname));
+ nvlist_add_string(limits, nvlname, types[i]);
+ }
return (cap_limit_set(chan, limits));
}
@@ -332,6 +347,8 @@ cap_dns_family_limit(cap_channel_t *chan, const int *families,
{
nvlist_t *limits;
unsigned int i;
+ char nvlname[64];
+ int n;
if (cap_limit_get(chan, &limits) < 0)
return (-1);
@@ -340,8 +357,9 @@ cap_dns_family_limit(cap_channel_t *chan, const int *families,
else
limit_remove(limits, "family");
for (i = 0; i < nfamilies; i++) {
- nvlist_addf_number(limits, (uint64_t)families[i],
- "family%u", i);
+ n = snprintf(nvlname, sizeof(nvlname), "family%u", i);
+ assert(n > 0 && n < (int)sizeof(nvlname));
+ nvlist_add_number(limits, nvlname, (uint64_t)families[i]);
}
return (cap_limit_set(chan, limits));
}
diff --git a/lib/libcapsicum/libcapsicum_grp.c b/lib/libcapsicum/libcapsicum_grp.c
index c679ce9afbd8..adfbc95a4bd6 100644
--- a/lib/libcapsicum/libcapsicum_grp.c
+++ b/lib/libcapsicum/libcapsicum_grp.c
@@ -94,9 +94,10 @@ group_unpack_members(const nvlist_t *nvl, char ***fieldp, char **bufferp,
size_t *bufsizep)
{
const char *mem;
- char **outstrs, *str;
+ char **outstrs, *str, nvlname[64];
size_t nmem, datasize, strsize;
unsigned int ii;
+ int n;
if (!nvlist_exists_number(nvl, "gr_nmem")) {
datasize = _ALIGNBYTES + sizeof(char *);
@@ -113,7 +114,9 @@ group_unpack_members(const nvlist_t *nvl, char ***fieldp, char **bufferp,
nmem = (size_t)nvlist_get_number(nvl, "gr_nmem");
datasize = _ALIGNBYTES + sizeof(char *) * (nmem + 1);
for (ii = 0; ii < nmem; ii++) {
- mem = dnvlist_getf_string(nvl, NULL, "gr_mem[%u]", ii);
+ n = snprintf(nvlname, sizeof(nvlname), "gr_mem[%u]", ii);
+ assert(n > 0 && n < (int)sizeof(nvlname));
+ mem = dnvlist_get_string(nvl, nvlname, NULL);
if (mem == NULL)
return (EINVAL);
datasize += strlen(mem) + 1;
@@ -125,7 +128,9 @@ group_unpack_members(const nvlist_t *nvl, char ***fieldp, char **bufferp,
outstrs = (char **)_ALIGN(*bufferp);
str = (char *)outstrs + sizeof(char *) * (nmem + 1);
for (ii = 0; ii < nmem; ii++) {
- mem = nvlist_getf_string(nvl, "gr_mem[%u]", ii);
+ n = snprintf(nvlname, sizeof(nvlname), "gr_mem[%u]", ii);
+ assert(n > 0 && n < (int)sizeof(nvlname));
+ mem = nvlist_get_string(nvl, nvlname);
strsize = strlen(mem) + 1;
memcpy(str, mem, strsize);
outstrs[ii] = str;
@@ -407,6 +412,8 @@ cap_grp_limit_groups(cap_channel_t *chan, const char * const *names,
{
nvlist_t *limits, *groups;
unsigned int i;
+ char nvlname[64];
+ int n;
if (cap_limit_get(chan, &limits) < 0)
return (-1);
@@ -417,10 +424,16 @@ cap_grp_limit_groups(cap_channel_t *chan, const char * const *names,
nvlist_free_nvlist(limits, "groups");
}
groups = nvlist_create(0);
- for (i = 0; i < ngids; i++)
- nvlist_addf_number(groups, (uint64_t)gids[i], "gid%u", i);
- for (i = 0; i < nnames; i++)
- nvlist_addf_string(groups, names[i], "name%u", i);
+ for (i = 0; i < ngids; i++) {
+ n = snprintf(nvlname, sizeof(nvlname), "gid%u", i);
+ assert(n > 0 && n < (int)sizeof(nvlname));
+ nvlist_add_number(groups, nvlname, (uint64_t)gids[i]);
+ }
+ for (i = 0; i < nnames; i++) {
+ n = snprintf(nvlname, sizeof(nvlname), "gid%u", i);
+ assert(n > 0 && n < (int)sizeof(nvlname));
+ nvlist_add_string(groups, nvlname, names[i]);
+ }
nvlist_move_nvlist(limits, "groups", groups);
return (cap_limit_set(chan, limits));
}
diff --git a/lib/libcapsicum/libcapsicum_pwd.c b/lib/libcapsicum/libcapsicum_pwd.c
index 792fb6698128..4c1570337519 100644
--- a/lib/libcapsicum/libcapsicum_pwd.c
+++ b/lib/libcapsicum/libcapsicum_pwd.c
@@ -364,7 +364,9 @@ cap_pwd_limit_users(cap_channel_t *chan, const char * const *names,
size_t nnames, uid_t *uids, size_t nuids)
{
nvlist_t *limits, *users;
+ char nvlname[64];
unsigned int i;
+ int n;
if (cap_limit_get(chan, &limits) < 0)
return (-1);
@@ -375,10 +377,16 @@ cap_pwd_limit_users(cap_channel_t *chan, const char * const *names,
nvlist_free_nvlist(limits, "users");
}
users = nvlist_create(0);
- for (i = 0; i < nuids; i++)
- nvlist_addf_number(users, (uint64_t)uids[i], "uid%u", i);
- for (i = 0; i < nnames; i++)
- nvlist_addf_string(users, names[i], "name%u", i);
+ for (i = 0; i < nuids; i++) {
+ n = snprintf(nvlname, sizeof(nvlname), "uid%u", i);
+ assert(n > 0 && n < (int)sizeof(nvlname));
+ nvlist_add_number(users, nvlname, (uint64_t)uids[i]);
+ }
+ for (i = 0; i < nnames; i++) {
+ n = snprintf(nvlname, sizeof(nvlname), "name%u", i);
+ assert(n > 0 && n < (int)sizeof(nvlname));
+ nvlist_add_string(users, nvlname, names[i]);
+ }
nvlist_move_nvlist(limits, "users", users);
return (cap_limit_set(chan, limits));
}
diff --git a/lib/libedit/el.c b/lib/libedit/el.c
index beb961efc0f5..a0d70158193b 100644
--- a/lib/libedit/el.c
+++ b/lib/libedit/el.c
@@ -96,7 +96,7 @@ el_init_fd(const char *prog, FILE *fin, FILE *fout, FILE *ferr,
*/
el->el_flags = 0;
#ifdef WIDECHAR
- if (setlocale(LC_CTYPE, "") != NULL) {
+ if (setlocale(LC_CTYPE, NULL) != NULL) {
if (strcmp(nl_langinfo(CODESET), "UTF-8") == 0)
el->el_flags |= CHARSET_IS_UTF8;
}
diff --git a/lib/libgeom/geom_xml2tree.c b/lib/libgeom/geom_xml2tree.c
index d5d4f31fd858..2c23361b1666 100644
--- a/lib/libgeom/geom_xml2tree.c
+++ b/lib/libgeom/geom_xml2tree.c
@@ -257,6 +257,7 @@ EndElement(void *userData, const char *name)
if (!strcmp(name, "config")) {
mt->config = NULL;
+ free(p);
return;
}
diff --git a/lib/libmd/mdXhl.c b/lib/libmd/mdXhl.c
index e69e5e5fa24a..295454819637 100644
--- a/lib/libmd/mdXhl.c
+++ b/lib/libmd/mdXhl.c
@@ -74,7 +74,7 @@ MDXFileChunk(const char *filename, char *buf, off_t ofs, off_t len)
i = read(f, buffer, sizeof(buffer));
else
i = read(f, buffer, n);
- if (i < 0)
+ if (i <= 0)
break;
MDXUpdate(&ctx, buffer, i);
n -= i;
diff --git a/lib/libnv/Makefile b/lib/libnv/Makefile
index f7853b0d57a8..8b2fc7821d7a 100644
--- a/lib/libnv/Makefile
+++ b/lib/libnv/Makefile
@@ -22,147 +22,66 @@ MAN+= nv.3
MLINKS+=nv.3 libnv.3 \
nv.3 nvlist.3
-MLINKS+=nv.3 nvlist_create.3 \
- nv.3 nvlist_destroy.3 \
- nv.3 nvlist_error.3 \
- nv.3 nvlist_set_error.3 \
- nv.3 nvlist_empty.3 \
+MLINKS+=nv.3 nvlist_add_binary.3 \
+ nv.3 nvlist_add_bool.3 \
+ nv.3 nvlist_add_descriptor.3 \
+ nv.3 nvlist_add_null.3 \
+ nv.3 nvlist_add_number.3 \
+ nv.3 nvlist_add_nvlist.3 \
+ nv.3 nvlist_add_string.3 \
+ nv.3 nvlist_add_stringf.3 \
+ nv.3 nvlist_add_stringv.3 \
nv.3 nvlist_clone.3 \
+ nv.3 nvlist_create.3 \
+ nv.3 nvlist_destroy.3 \
nv.3 nvlist_dump.3 \
- nv.3 nvlist_fdump.3 \
- nv.3 nvlist_size.3 \
- nv.3 nvlist_pack.3 \
- nv.3 nvlist_unpack.3 \
- nv.3 nvlist_send.3 \
- nv.3 nvlist_recv.3 \
- nv.3 nvlist_xfer.3 \
- nv.3 nvlist_next.3 \
+ nv.3 nvlist_empty.3 \
+ nv.3 nvlist_error.3 \
nv.3 nvlist_exists.3 \
- nv.3 nvlist_exists_type.3 \
- nv.3 nvlist_exists_null.3 \
+ nv.3 nvlist_exists_binary.3 \
nv.3 nvlist_exists_bool.3 \
+ nv.3 nvlist_exists_descriptor.3 \
+ nv.3 nvlist_exists_null.3 \
nv.3 nvlist_exists_number.3 \
- nv.3 nvlist_exists_string.3 \
nv.3 nvlist_exists_nvlist.3 \
- nv.3 nvlist_exists_descriptor.3 \
- nv.3 nvlist_exists_binary.3 \
- nv.3 nvlist_add_null.3 \
- nv.3 nvlist_add_bool.3 \
- nv.3 nvlist_add_number.3 \
- nv.3 nvlist_add_string.3 \
- nv.3 nvlist_add_stringf.3 \
- nv.3 nvlist_add_stringv.3 \
- nv.3 nvlist_add_nvlist.3 \
- nv.3 nvlist_add_descriptor.3 \
- nv.3 nvlist_add_binary.3 \
- nv.3 nvlist_move_string.3 \
- nv.3 nvlist_move_nvlist.3 \
- nv.3 nvlist_move_descriptor.3 \
- nv.3 nvlist_move_binary.3 \
+ nv.3 nvlist_exists_string.3 \
+ nv.3 nvlist_exists_type.3 \
+ nv.3 nvlist_fdump.3 \
+ nv.3 nvlist_flags.3 \
+ nv.3 nvlist_free.3 \
+ nv.3 nvlist_free_binary.3 \
+ nv.3 nvlist_free_bool.3 \
+ nv.3 nvlist_free_descriptor.3 \
+ nv.3 nvlist_free_null.3 \
+ nv.3 nvlist_free_number.3 \
+ nv.3 nvlist_free_nvlist.3 \
+ nv.3 nvlist_free_string.3 \
+ nv.3 nvlist_free_type.3 \
+ nv.3 nvlist_get_binary.3 \
nv.3 nvlist_get_bool.3 \
+ nv.3 nvlist_get_descriptor.3 \
nv.3 nvlist_get_number.3 \
- nv.3 nvlist_get_string.3 \
nv.3 nvlist_get_nvlist.3 \
- nv.3 nvlist_get_descriptor.3 \
- nv.3 nvlist_get_binary.3 \
nv.3 nvlist_get_parent.3 \
+ nv.3 nvlist_get_string.3 \
+ nv.3 nvlist_move_binary.3 \
+ nv.3 nvlist_move_descriptor.3 \
+ nv.3 nvlist_move_nvlist.3 \
+ nv.3 nvlist_move_string.3 \
+ nv.3 nvlist_next.3 \
+ nv.3 nvlist_pack.3 \
+ nv.3 nvlist_recv.3 \
+ nv.3 nvlist_send.3 \
+ nv.3 nvlist_set_error.3 \
+ nv.3 nvlist_size.3 \
+ nv.3 nvlist_take_binary.3 \
nv.3 nvlist_take_bool.3 \
+ nv.3 nvlist_take_descriptor.3 \
nv.3 nvlist_take_number.3 \
- nv.3 nvlist_take_string.3 \
nv.3 nvlist_take_nvlist.3 \
- nv.3 nvlist_take_descriptor.3 \
- nv.3 nvlist_take_binary.3 \
- nv.3 nvlist_free.3 \
- nv.3 nvlist_free_type.3 \
- nv.3 nvlist_free_null.3 \
- nv.3 nvlist_free_bool.3 \
- nv.3 nvlist_free_number.3 \
- nv.3 nvlist_free_string.3 \
- nv.3 nvlist_free_nvlist.3 \
- nv.3 nvlist_free_descriptor.3 \
- nv.3 nvlist_free_binary.3
-MLINKS+=nv.3 nvlist_existsf.3 \
- nv.3 nvlist_existsf_type.3 \
- nv.3 nvlist_existsf_null.3 \
- nv.3 nvlist_existsf_bool.3 \
- nv.3 nvlist_existsf_number.3 \
- nv.3 nvlist_existsf_string.3 \
- nv.3 nvlist_existsf_nvlist.3 \
- nv.3 nvlist_existsf_descriptor.3 \
- nv.3 nvlist_existsf_binary.3 \
- nv.3 nvlist_addf_null.3 \
- nv.3 nvlist_addf_bool.3 \
- nv.3 nvlist_addf_number.3 \
- nv.3 nvlist_addf_string.3 \
- nv.3 nvlist_addf_nvlist.3 \
- nv.3 nvlist_addf_descriptor.3 \
- nv.3 nvlist_addf_binary.3 \
- nv.3 nvlist_movef_string.3 \
- nv.3 nvlist_movef_nvlist.3 \
- nv.3 nvlist_movef_descriptor.3 \
- nv.3 nvlist_movef_binary.3 \
- nv.3 nvlist_getf_bool.3 \
- nv.3 nvlist_getf_number.3 \
- nv.3 nvlist_getf_string.3 \
- nv.3 nvlist_getf_nvlist.3 \
- nv.3 nvlist_getf_descriptor.3 \
- nv.3 nvlist_getf_binary.3 \
- nv.3 nvlist_takef_bool.3 \
- nv.3 nvlist_takef_number.3 \
- nv.3 nvlist_takef_string.3 \
- nv.3 nvlist_takef_nvlist.3 \
- nv.3 nvlist_takef_descriptor.3 \
- nv.3 nvlist_takef_binary.3 \
- nv.3 nvlist_freef.3 \
- nv.3 nvlist_freef_type.3 \
- nv.3 nvlist_freef_null.3 \
- nv.3 nvlist_freef_bool.3 \
- nv.3 nvlist_freef_number.3 \
- nv.3 nvlist_freef_string.3 \
- nv.3 nvlist_freef_nvlist.3 \
- nv.3 nvlist_freef_descriptor.3 \
- nv.3 nvlist_freef_binary.3
-MLINKS+=nv.3 nvlist_existsv.3 \
- nv.3 nvlist_existsv_type.3 \
- nv.3 nvlist_existsv_null.3 \
- nv.3 nvlist_existsv_bool.3 \
- nv.3 nvlist_existsv_number.3 \
- nv.3 nvlist_existsv_string.3 \
- nv.3 nvlist_existsv_nvlist.3 \
- nv.3 nvlist_existsv_descriptor.3 \
- nv.3 nvlist_existsv_binary.3 \
- nv.3 nvlist_addv_null.3 \
- nv.3 nvlist_addv_bool.3 \
- nv.3 nvlist_addv_number.3 \
- nv.3 nvlist_addv_string.3 \
- nv.3 nvlist_addv_nvlist.3 \
- nv.3 nvlist_addv_descriptor.3 \
- nv.3 nvlist_addv_binary.3 \
- nv.3 nvlist_movev_string.3 \
- nv.3 nvlist_movev_nvlist.3 \
- nv.3 nvlist_movev_descriptor.3 \
- nv.3 nvlist_movev_binary.3 \
- nv.3 nvlist_getv_bool.3 \
- nv.3 nvlist_getv_number.3 \
- nv.3 nvlist_getv_string.3 \
- nv.3 nvlist_getv_nvlist.3 \
- nv.3 nvlist_getv_descriptor.3 \
- nv.3 nvlist_getv_binary.3 \
- nv.3 nvlist_takev_bool.3 \
- nv.3 nvlist_takev_number.3 \
- nv.3 nvlist_takev_string.3 \
- nv.3 nvlist_takev_nvlist.3 \
- nv.3 nvlist_takev_descriptor.3 \
- nv.3 nvlist_takev_binary.3 \
- nv.3 nvlist_freev.3 \
- nv.3 nvlist_freev_type.3 \
- nv.3 nvlist_freev_null.3 \
- nv.3 nvlist_freev_bool.3 \
- nv.3 nvlist_freev_number.3 \
- nv.3 nvlist_freev_string.3 \
- nv.3 nvlist_freev_nvlist.3 \
- nv.3 nvlist_freev_descriptor.3 \
- nv.3 nvlist_freev_binary.3
+ nv.3 nvlist_take_string.3 \
+ nv.3 nvlist_unpack.3 \
+ nv.3 nvlist_xfer.3
WARNS?= 6
diff --git a/lib/libnv/nv.3 b/lib/libnv/nv.3
index be6e0fe03a76..bbb7b031107c 100644
--- a/lib/libnv/nv.3
+++ b/lib/libnv/nv.3
@@ -28,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 30, 2015
+.Dd May 1, 2015
.Dt NV 3
.Os
.Sh NAME
@@ -37,6 +37,7 @@
.Nm nvlist_error ,
.Nm nvlist_set_error ,
.Nm nvlist_empty ,
+.Nm nvlist_flags ,
.Nm nvlist_exists ,
.Nm nvlist_free ,
.Nm nvlist_clone ,
@@ -68,6 +69,8 @@
.Fn nvlist_set_error "nvlist_t *nvl, int error"
.Ft bool
.Fn nvlist_empty "const nvlist_t *nvl"
+.Ft int
+.Fn nvlist_flags "const nvlist_t *nvl"
.\"
.Ft "nvlist_t *"
.Fn nvlist_clone "const nvlist_t *nvl"
@@ -269,6 +272,12 @@ otherwise.
The nvlist must not be in error state.
.Pp
The
+.Fn nvlist_flags
+function returns flags used to create the nvlist with the
+.Fn nvlist_create
+function.
+.Pp
+The
.Fn nvlist_clone
functions clones the given nvlist.
The clone shares no resources with its origin.
diff --git a/lib/libnv/tests/dnv_tests.cc b/lib/libnv/tests/dnv_tests.cc
index ad26f38bb073..2f92d9d866d9 100644
--- a/lib/libnv/tests/dnv_tests.cc
+++ b/lib/libnv/tests/dnv_tests.cc
@@ -45,7 +45,7 @@ ATF_TEST_CASE_BODY(dnvlist_get_bool__present)
nvlist_add_bool(nvl, key, value);
ATF_REQUIRE_EQ(dnvlist_get_bool(nvl, key, false), value);
- ATF_REQUIRE_EQ(dnvlist_getf_bool(nvl, false, "%c%s", 'n', "ame"), value);
+ ATF_REQUIRE_EQ(dnvlist_get_bool(nvl, "name", false), value);
nvlist_destroy(nvl);
}
@@ -60,12 +60,12 @@ ATF_TEST_CASE_BODY(dnvlist_get_bool__default_value)
nvl = nvlist_create(0);
ATF_REQUIRE_EQ(dnvlist_get_bool(nvl, key, false), false);
- ATF_REQUIRE_EQ(dnvlist_getf_bool(nvl, true, "%d", 123), true);
+ ATF_REQUIRE_EQ(dnvlist_get_bool(nvl, "123", true), true);
nvlist_add_bool(nvl, key, true);
ATF_REQUIRE_EQ(dnvlist_get_bool(nvl, "otherkey", true), true);
- ATF_REQUIRE_EQ(dnvlist_getf_bool(nvl, false, "%d%c", 12, 'c'), false);
+ ATF_REQUIRE_EQ(dnvlist_get_bool(nvl, "12c", false), false);
nvlist_destroy(nvl);
}
@@ -84,7 +84,7 @@ ATF_TEST_CASE_BODY(dnvlist_get_number__present)
nvlist_add_number(nvl, key, value);
ATF_REQUIRE_EQ(dnvlist_get_number(nvl, key, 19), value);
- ATF_REQUIRE_EQ(dnvlist_getf_number(nvl, 65, "key"), value);
+ ATF_REQUIRE_EQ(dnvlist_get_number(nvl, "key", 65), value);
nvlist_destroy(nvl);
}
@@ -99,12 +99,11 @@ ATF_TEST_CASE_BODY(dnvlist_get_number__default_value)
nvl = nvlist_create(0);
ATF_REQUIRE_EQ(dnvlist_get_number(nvl, key, 5), 5);
- ATF_REQUIRE_EQ(dnvlist_getf_number(nvl, 12, "%s", key), 12);
+ ATF_REQUIRE_EQ(dnvlist_get_number(nvl, "1234", 5), 5);
nvlist_add_number(nvl, key, 24841);
- ATF_REQUIRE_EQ(dnvlist_get_number(nvl, "hthth", 184), 184);
- ATF_REQUIRE_EQ(dnvlist_getf_number(nvl, 5641, "%d", 1234), 5641);
+ ATF_REQUIRE_EQ(dnvlist_get_number(nvl, "1234", 5641), 5641);
nvlist_destroy(nvl);
}
@@ -124,7 +123,7 @@ ATF_TEST_CASE_BODY(dnvlist_get_string__present)
ATF_REQUIRE_EQ(strcmp(dnvlist_get_string(nvl, key, "g"), value), 0);
- actual_value = dnvlist_getf_string(nvl, "rs", "%s", key);
+ actual_value = dnvlist_get_string(nvl, key, "rs");
ATF_REQUIRE_EQ(strcmp(actual_value, value), 0);
nvlist_destroy(nvl);
@@ -142,13 +141,13 @@ ATF_TEST_CASE_BODY(dnvlist_get_string__default_value)
ATF_REQUIRE_EQ(strcmp(dnvlist_get_string(nvl, key, "bar"), "bar"), 0);
- actual_value = dnvlist_getf_string(nvl, "d", "%s", key);
+ actual_value = dnvlist_get_string(nvl, key, "d");
ATF_REQUIRE_EQ(strcmp(actual_value, "d"), 0);
nvlist_add_string(nvl, key, "cxhweh");
ATF_REQUIRE_EQ(strcmp(dnvlist_get_string(nvl, "hthth", "fd"), "fd"), 0);
- actual_value = dnvlist_getf_string(nvl, "5", "%s", "5");
+ actual_value = dnvlist_get_string(nvl, "5", "5");
ATF_REQUIRE_EQ(strcmp("5", "5"), 0);
nvlist_destroy(nvl);
@@ -172,10 +171,6 @@ ATF_TEST_CASE_BODY(dnvlist_get_nvlist__present)
ATF_REQUIRE(actual_value != NULL);
ATF_REQUIRE(nvlist_empty(actual_value));
- actual_value = dnvlist_getf_nvlist(nvl, NULL, "%s", key);
- ATF_REQUIRE(actual_value != NULL);
- ATF_REQUIRE(nvlist_empty(actual_value));
-
nvlist_destroy(nvl);
}
@@ -191,11 +186,10 @@ ATF_TEST_CASE_BODY(dnvlist_get_nvlist__default_value)
dummy = nvlist_create(0);
ATF_REQUIRE_EQ(dnvlist_get_nvlist(nvl, key, dummy), dummy);
- ATF_REQUIRE_EQ(dnvlist_getf_nvlist(nvl, dummy, "%s", key), dummy);
nvlist_move_nvlist(nvl, key, nvlist_create(0));
ATF_REQUIRE_EQ(dnvlist_get_nvlist(nvl, "456", dummy), dummy);
- ATF_REQUIRE_EQ(dnvlist_getf_nvlist(nvl, dummy, "%s", "gh"), dummy);
+ ATF_REQUIRE_EQ(dnvlist_get_nvlist(nvl, "gh", dummy), dummy);
nvlist_destroy(nvl);
}
@@ -226,10 +220,6 @@ ATF_TEST_CASE_BODY(dnvlist_get_binary__present)
ATF_REQUIRE_EQ(value_size, actual_size);
ATF_REQUIRE_EQ(memcmp(actual_value, value, actual_size), 0);
- actual_value = dnvlist_getf_binary(nvl, &actual_size, "g", 1, "%s", k);
- ATF_REQUIRE_EQ(value_size, actual_size);
- ATF_REQUIRE_EQ(memcmp(actual_value, value, actual_size), 0);
-
nvlist_destroy(nvl);
}
@@ -251,8 +241,8 @@ ATF_TEST_CASE_BODY(dnvlist_get_binary__default_value)
ATF_REQUIRE_EQ(memcmp(actual_value, default_value, actual_size), 0);
set_const_binary_value(default_value, default_size, "atf");
- actual_value = dnvlist_getf_binary(nvl, &actual_size, default_value,
- default_size, "%s", key);
+ actual_value = dnvlist_get_binary(nvl, key, &actual_size, default_value,
+ default_size);
ATF_REQUIRE_EQ(default_size, actual_size);
ATF_REQUIRE_EQ(memcmp(actual_value, default_value, actual_size), 0);
@@ -266,8 +256,8 @@ ATF_TEST_CASE_BODY(dnvlist_get_binary__default_value)
set_const_binary_value(default_value, default_size,
"rrhgrythtyrtgbrhgrtdsvdfbtjlkul");
- actual_value = dnvlist_getf_binary(nvl, &actual_size, default_value,
- default_size, "s");
+ actual_value = dnvlist_get_binary(nvl, "s", &actual_size, default_value,
+ default_size);
ATF_REQUIRE_EQ(default_size, actual_size);
ATF_REQUIRE_EQ(memcmp(actual_value, default_value, actual_size), 0);
diff --git a/lib/libnv/tests/nv_tests.cc b/lib/libnv/tests/nv_tests.cc
index bfdc97231274..2d9fd97914d1 100644
--- a/lib/libnv/tests/nv_tests.cc
+++ b/lib/libnv/tests/nv_tests.cc
@@ -77,9 +77,8 @@ ATF_TEST_CASE_BODY(nvlist_add_null__single_insert)
ATF_REQUIRE(!nvlist_empty(nvl));
ATF_REQUIRE(nvlist_exists(nvl, key));
- ATF_REQUIRE(nvlist_existsf(nvl, "%s", key));
ATF_REQUIRE(nvlist_exists_null(nvl, key));
- ATF_REQUIRE(nvlist_existsf_null(nvl, "key"));
+ ATF_REQUIRE(nvlist_exists_null(nvl, "key"));
/* Iterate over the nvlist; ensure that it has only our one key. */
it = NULL;
@@ -108,11 +107,10 @@ ATF_TEST_CASE_BODY(nvlist_add_bool__single_insert)
ATF_REQUIRE(!nvlist_empty(nvl));
ATF_REQUIRE(nvlist_exists(nvl, key));
- ATF_REQUIRE(nvlist_existsf(nvl, "%s%s", "na", "me"));
+ ATF_REQUIRE(nvlist_exists(nvl, "name"));
ATF_REQUIRE(nvlist_exists_bool(nvl, key));
- ATF_REQUIRE(nvlist_existsf_bool(nvl, "%s%c", "nam", 'e'));
+ ATF_REQUIRE(nvlist_exists_bool(nvl, "name"));
ATF_REQUIRE_EQ(nvlist_get_bool(nvl, key), true);
- ATF_REQUIRE_EQ(nvlist_getf_bool(nvl, "%c%s", 'n', "ame"), true);
/* Iterate over the nvlist; ensure that it has only our one key. */
it = NULL;
@@ -143,11 +141,9 @@ ATF_TEST_CASE_BODY(nvlist_add_number__single_insert)
ATF_REQUIRE(!nvlist_empty(nvl));
ATF_REQUIRE(nvlist_exists(nvl, key));
- ATF_REQUIRE(nvlist_existsf(nvl, "%s%d", "foo", 123));
+ ATF_REQUIRE(nvlist_exists(nvl, "foo123"));
ATF_REQUIRE(nvlist_exists_number(nvl, key));
- ATF_REQUIRE(nvlist_existsf_number(nvl, "%s", key));
ATF_REQUIRE_EQ(nvlist_get_number(nvl, key), value);
- ATF_REQUIRE_EQ(nvlist_getf_number(nvl, "%s", key), value);
/* Iterate over the nvlist; ensure that it has only our one key. */
it = NULL;
@@ -178,11 +174,10 @@ ATF_TEST_CASE_BODY(nvlist_add_string__single_insert)
ATF_REQUIRE(!nvlist_empty(nvl));
ATF_REQUIRE(nvlist_exists(nvl, key));
- ATF_REQUIRE(nvlist_existsf(nvl, "%s", key));
+ ATF_REQUIRE(nvlist_exists(nvl, "test"));
ATF_REQUIRE(nvlist_exists_string(nvl, key));
- ATF_REQUIRE(nvlist_existsf_string(nvl, "%s", key));
+ ATF_REQUIRE(nvlist_exists_string(nvl, "test"));
ATF_REQUIRE_EQ(strcmp(nvlist_get_string(nvl, key), value), 0);
- ATF_REQUIRE_EQ(strcmp(nvlist_getf_string(nvl, "%s", key), value), 0);
/* nvlist_add_* is required to clone the value, so check for that. */
ATF_REQUIRE(nvlist_get_string(nvl, key) != value);
@@ -219,9 +214,9 @@ ATF_TEST_CASE_BODY(nvlist_add_nvlist__single_insert)
ATF_REQUIRE(!nvlist_empty(nvl));
ATF_REQUIRE(nvlist_exists(nvl, key));
- ATF_REQUIRE(nvlist_existsf(nvl, "%s", key));
+ ATF_REQUIRE(nvlist_exists(nvl, "test"));
ATF_REQUIRE(nvlist_exists_nvlist(nvl, key));
- ATF_REQUIRE(nvlist_existsf_nvlist(nvl, "%s", key));
+ ATF_REQUIRE(nvlist_exists_nvlist(nvl, "test"));
value = nvlist_get_nvlist(nvl, key);
ATF_REQUIRE(nvlist_exists_null(value, subkey));
@@ -229,10 +224,6 @@ ATF_TEST_CASE_BODY(nvlist_add_nvlist__single_insert)
/* nvlist_add_* is required to clone the value, so check for that. */
ATF_REQUIRE(sublist != value);
- value = nvlist_getf_nvlist(nvl, "%s", key);
- ATF_REQUIRE(nvlist_exists_null(value, subkey));
- ATF_REQUIRE(sublist != value);
-
/* Iterate over the nvlist; ensure that it has only our one key. */
it = NULL;
ATF_REQUIRE_EQ(strcmp(nvlist_next(nvl, &type, &it), key), 0);
@@ -283,9 +274,9 @@ ATF_TEST_CASE_BODY(nvlist_add_binary__single_insert)
ATF_REQUIRE(!nvlist_empty(nvl));
ATF_REQUIRE(nvlist_exists(nvl, key));
- ATF_REQUIRE(nvlist_existsf(nvl, "%s", key));
+ ATF_REQUIRE(nvlist_exists(nvl, "binary"));
ATF_REQUIRE(nvlist_exists_binary(nvl, key));
- ATF_REQUIRE(nvlist_existsf_binary(nvl, "%s", key));
+ ATF_REQUIRE(nvlist_exists_binary(nvl, "binary"));
ret_value = nvlist_get_binary(nvl, key, &ret_size);
ATF_REQUIRE_EQ(value_size, ret_size);
@@ -294,11 +285,6 @@ ATF_TEST_CASE_BODY(nvlist_add_binary__single_insert)
/* nvlist_add_* is required to clone the value, so check for that. */
ATF_REQUIRE(value != ret_value);
- ret_value = nvlist_getf_binary(nvl, &ret_size, "%s", key);
- ATF_REQUIRE_EQ(value_size, ret_size);
- ATF_REQUIRE_EQ(memcmp(value, ret_value, ret_size), 0);
- ATF_REQUIRE(value != ret_value);
-
/* Iterate over the nvlist; ensure that it has only our one key. */
it = NULL;
ATF_REQUIRE_EQ(strcmp(nvlist_next(nvl, &type, &it), key), 0);
diff --git a/lib/librt/Makefile b/lib/librt/Makefile
index 36296101a6f7..5696610a2b55 100644
--- a/lib/librt/Makefile
+++ b/lib/librt/Makefile
@@ -19,6 +19,8 @@ PRECIOUSLIB=
VERSION_MAP= ${.CURDIR}/Version.map
-.include <bsd.arch.inc.mk>
+.if ${MK_TESTS} != "no"
+SUBDIR+= tests
+.endif
.include <bsd.lib.mk>
diff --git a/lib/librt/Makefile.amd64 b/lib/librt/Makefile.amd64
deleted file mode 100644
index dd0f5b0cfb2d..000000000000
--- a/lib/librt/Makefile.amd64
+++ /dev/null
@@ -1,6 +0,0 @@
-# $FreeBSD$
-
-.if ${MK_TESTS} != "no"
-SUBDIR+= tests
-.endif
-
diff --git a/lib/librt/Makefile.i386 b/lib/librt/Makefile.i386
deleted file mode 100644
index dd0f5b0cfb2d..000000000000
--- a/lib/librt/Makefile.i386
+++ /dev/null
@@ -1,6 +0,0 @@
-# $FreeBSD$
-
-.if ${MK_TESTS} != "no"
-SUBDIR+= tests
-.endif
-
diff --git a/lib/libstand/Makefile b/lib/libstand/Makefile
index 7c6d718875e3..2ee29212f2cf 100644
--- a/lib/libstand/Makefile
+++ b/lib/libstand/Makefile
@@ -11,6 +11,9 @@ MK_SSP= no
.include <src.opts.mk>
+LIBSTAND_SRC= ${.CURDIR}
+LIBC_SRC= ${LIBSTAND_SRC}/../libc
+
LIB= stand
NO_PIC=
INCS= stand.h
@@ -19,7 +22,7 @@ MAN= libstand.3
WARNS?= 0
CFLAGS+= -ffreestanding -Wformat
-CFLAGS+= -I${.CURDIR}
+CFLAGS+= -I${LIBSTAND_SRC}
.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
CFLAGS+= -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -msoft-float
@@ -54,54 +57,54 @@ SRCS+= gzguts.h zutil.h __main.c assert.c bcd.c bswap.c environment.c getopt.c g
# private (pruned) versions of libc string functions
SRCS+= strcasecmp.c
-.PATH: ${.CURDIR}/../libc/net
+.PATH: ${LIBC_SRC}/net
SRCS+= ntoh.c
# string functions from libc
-.PATH: ${.CURDIR}/../libc/string
+.PATH: ${LIBC_SRC}/string
SRCS+= bcmp.c bcopy.c bzero.c ffs.c memccpy.c memchr.c memcmp.c memcpy.c \
memmove.c memset.c qdivrem.c strcat.c strchr.c strcmp.c strcpy.c \
strcspn.c strlen.c strncat.c strncmp.c strncpy.c strpbrk.c \
strrchr.c strsep.c strspn.c strstr.c strtok.c swab.c
.if ${MACHINE_CPUARCH} == "arm"
-.PATH: ${.CURDIR}/../libc/arm/gen
+.PATH: ${LIBC_SRC}/arm/gen
# Compiler support functions
-.PATH: ${.CURDIR}/../../contrib/compiler-rt/lib/builtins/
+.PATH: ${LIBSTAND_SRC}/../../contrib/compiler-rt/lib/builtins/
# __clzsi2 and ctzsi2 for various builtin functions
SRCS+= clzsi2.c ctzsi2.c
# Divide and modulus functions called by the compiler
SRCS+= divmoddi4.c divmodsi4.c divdi3.c divsi3.c moddi3.c modsi3.c
SRCS+= udivmoddi4.c udivmodsi4.c udivdi3.c udivsi3.c umoddi3.c umodsi3.c
-.PATH: ${.CURDIR}/../../contrib/compiler-rt/lib/builtins/arm/
+.PATH: ${LIBSTAND_SRC}/../../contrib/compiler-rt/lib/builtins/arm/
SRCS+= aeabi_idivmod.S aeabi_ldivmod.S aeabi_uidivmod.S aeabi_uldivmod.S
SRCS+= aeabi_memcmp.S aeabi_memcpy.S aeabi_memmove.S aeabi_memset.S
.endif
.if ${MACHINE_CPUARCH} == "aarch64"
-.PATH: ${.CURDIR}/../libc/aarch64/gen
+.PATH: ${LIBC_SRC}/aarch64/gen
.endif
.if ${MACHINE_CPUARCH} == "powerpc"
-.PATH: ${.CURDIR}/../libc/quad
+.PATH: ${LIBC_SRC}/quad
SRCS+= ashldi3.c ashrdi3.c
SRCS+= syncicache.c
.endif
# uuid functions from libc
-.PATH: ${.CURDIR}/../libc/uuid
+.PATH: ${LIBC_SRC}/uuid
SRCS+= uuid_equal.c uuid_is_nil.c
# _setjmp/_longjmp
-.PATH: ${.CURDIR}/${MACHINE_CPUARCH}
+.PATH: ${LIBSTAND_SRC}/${MACHINE_CPUARCH}
SRCS+= _setjmp.S
# decompression functionality from libbz2
# NOTE: to actually test this functionality after libbz2 upgrade compile
# loader(8) with LOADER_BZIP2_SUPPORT defined
-.PATH: ${.CURDIR}/../../contrib/bzip2
+.PATH: ${LIBSTAND_SRC}/../../contrib/bzip2
CFLAGS+= -DBZ_NO_STDIO -DBZ_NO_COMPRESS
SRCS+= libstand_bzlib_private.h
@@ -110,7 +113,8 @@ SRCS+= _${file}
CLEANFILES+= _${file}
_${file}: ${file}
- sed "s|bzlib_private\.h|libstand_bzlib_private.h|" ${.ALLSRC} > ${.TARGET}
+ sed "s|bzlib_private\.h|libstand_bzlib_private.h|" \
+ ${.ALLSRC} > ${.TARGET}
.endfor
CLEANFILES+= libstand_bzlib_private.h
@@ -119,8 +123,8 @@ libstand_bzlib_private.h: bzlib_private.h
${.ALLSRC} > ${.TARGET}
# decompression functionality from libz
-.PATH: ${.CURDIR}/../libz
-CFLAGS+=-DHAVE_MEMCPY -I${.CURDIR}/../libz
+.PATH: ${LIBSTAND_SRC}/../libz
+CFLAGS+=-DHAVE_MEMCPY -I${LIBSTAND_SRC}/../libz
SRCS+= adler32.c crc32.c libstand_zutil.h libstand_gzguts.h
.for file in infback.c inffast.c inflate.c inftrees.c zutil.c
@@ -165,4 +169,3 @@ SRCS+= nandfs.c
.endif
.include <bsd.lib.mk>
-
diff --git a/lib/libthr/Makefile b/lib/libthr/Makefile
index 0770d0625320..17176729b2e5 100644
--- a/lib/libthr/Makefile
+++ b/lib/libthr/Makefile
@@ -61,6 +61,8 @@ SYMLINKS+=lib${LIB}.so ${LIBDIR}/libpthread.so
SYMLINKS+=lib${LIB}_p.a ${LIBDIR}/libpthread_p.a
.endif
-.include <bsd.arch.inc.mk>
+.if ${MK_TESTS} != "no"
+SUBDIR+= tests
+.endif
.include <bsd.lib.mk>
diff --git a/lib/libthr/Makefile.amd64 b/lib/libthr/Makefile.amd64
deleted file mode 100644
index dd0f5b0cfb2d..000000000000
--- a/lib/libthr/Makefile.amd64
+++ /dev/null
@@ -1,6 +0,0 @@
-# $FreeBSD$
-
-.if ${MK_TESTS} != "no"
-SUBDIR+= tests
-.endif
-
diff --git a/lib/libthr/Makefile.i386 b/lib/libthr/Makefile.i386
deleted file mode 100644
index dd0f5b0cfb2d..000000000000
--- a/lib/libthr/Makefile.i386
+++ /dev/null
@@ -1,6 +0,0 @@
-# $FreeBSD$
-
-.if ${MK_TESTS} != "no"
-SUBDIR+= tests
-.endif
-
diff --git a/lib/libthr/tests/Makefile b/lib/libthr/tests/Makefile
index 50f07f07e008..11cf0e791e69 100644
--- a/lib/libthr/tests/Makefile
+++ b/lib/libthr/tests/Makefile
@@ -25,7 +25,9 @@ NETBSD_ATF_TESTS_C+= sigmask_test
NETBSD_ATF_TESTS_C+= sigsuspend_test
NETBSD_ATF_TESTS_C+= siglongjmp_test
NETBSD_ATF_TESTS_C+= sleep_test
+.if ${MACHINE} != "arm64" # ARM64TODO: Missing makecontext
NETBSD_ATF_TESTS_C+= swapcontext_test
+.endif
NETBSD_ATF_TESTS_SH= atexit_test
NETBSD_ATF_TESTS_SH+= cancel_test
diff --git a/lib/libthr/thread/thr_clean.c b/lib/libthr/thread/thr_clean.c
index dc5b0c7ee17d..f2007264a236 100644
--- a/lib/libthr/thread/thr_clean.c
+++ b/lib/libthr/thread/thr_clean.c
@@ -84,7 +84,7 @@ _pthread_cleanup_push(void (*routine) (void *), void *arg)
curthread->unwind_disabled = 1;
#endif
if ((newbuf = (struct pthread_cleanup *)
- malloc(sizeof(struct _pthread_cleanup_info))) != NULL) {
+ malloc(sizeof(struct pthread_cleanup))) != NULL) {
newbuf->routine = routine;
newbuf->routine_arg = arg;
newbuf->onheap = 1;
diff --git a/lib/libxo/Makefile b/lib/libxo/Makefile
index cc0e72aa4a91..62fface44dfa 100644
--- a/lib/libxo/Makefile
+++ b/lib/libxo/Makefile
@@ -26,6 +26,7 @@ MAN+= xo_attr.3 \
xo_flush.3 \
xo_no_setlocale.3 \
xo_open_container.3 \
+ xo_open_marker.3 \
xo_open_list.3 \
xo_parse_args.3 \
xo_set_allocator.3 \
@@ -33,6 +34,7 @@ MAN+= xo_attr.3 \
xo_set_info.3 \
xo_set_options.3 \
xo_set_style.3 \
+ xo_set_version.3 \
xo_set_writer.3
MAN+= xo_format.5
diff --git a/lib/msun/Makefile b/lib/msun/Makefile
index aee0f2d03315..5cb629213a7a 100644
--- a/lib/msun/Makefile
+++ b/lib/msun/Makefile
@@ -221,6 +221,8 @@ MLINKS+=trunc.3 truncf.3 trunc.3 truncl.3
.include <src.opts.mk>
-.include <bsd.arch.inc.mk>
+.if ${MK_TESTS} != "no"
+SUBDIR+= tests
+.endif
.include <bsd.lib.mk>
diff --git a/lib/msun/Makefile.amd64 b/lib/msun/Makefile.amd64
deleted file mode 100644
index dd0f5b0cfb2d..000000000000
--- a/lib/msun/Makefile.amd64
+++ /dev/null
@@ -1,6 +0,0 @@
-# $FreeBSD$
-
-.if ${MK_TESTS} != "no"
-SUBDIR+= tests
-.endif
-
diff --git a/lib/msun/Makefile.i386 b/lib/msun/Makefile.i386
deleted file mode 100644
index dd0f5b0cfb2d..000000000000
--- a/lib/msun/Makefile.i386
+++ /dev/null
@@ -1,6 +0,0 @@
-# $FreeBSD$
-
-.if ${MK_TESTS} != "no"
-SUBDIR+= tests
-.endif
-
diff --git a/lib/msun/man/j0.3 b/lib/msun/man/j0.3
index 7e1b79058e2e..587b72eaf394 100644
--- a/lib/msun/man/j0.3
+++ b/lib/msun/man/j0.3
@@ -98,7 +98,7 @@ The functions
.Fn y1 ,
and
.Fn y1f
-compute the linearly independent Bessel function of the second kind
+compute the linearly independent Bessel function of the second kind
of orders 0 and 1 for the positive
.Em real
value
@@ -135,12 +135,12 @@ is \*(Pm0, these routines
will generate a divide-by-zero exception and return -\*(If.
If
.Fa x
-is a sufficiently small positive number, then
+is a sufficiently small positive number, then
.Fn y1 ,
.Fn y1f ,
.Fn yn ,
and
-.Fn ynf
+.Fn ynf
will generate an overflow exception and return -\*(If.
.Sh SEE ALSO
.Xr math 3
diff --git a/lib/msun/man/lgamma.3 b/lib/msun/man/lgamma.3
index cb4b1607431a..c8a22a273165 100644
--- a/lib/msun/man/lgamma.3
+++ b/lib/msun/man/lgamma.3
@@ -124,7 +124,6 @@ are deprecated aliases for
and
.Fn lgammaf_r ,
respectively.
-
.Sh IDIOSYNCRASIES
Do not use the expression
.Dq Li signgam\(**exp(lgamma(x))
diff --git a/lib/msun/man/nextafter.3 b/lib/msun/man/nextafter.3
index c8c4aa34a5db..01c472d106a4 100644
--- a/lib/msun/man/nextafter.3
+++ b/lib/msun/man/nextafter.3
@@ -78,11 +78,11 @@ routines conform to
They implement the Nextafter function recommended by
.St -ieee754 ,
with the extension that
-.Fn nextafter +0.0, -0.0
+.Fn nextafter "+0.0" "-0.0"
returns
.Li -0.0 ,
and
-.Fn nextafter -0.0, +0.0
+.Fn nextafter "-0.0" "+0.0"
returns
.Li +0.0 .
.Sh HISTORY
diff --git a/lib/msun/tests/Makefile b/lib/msun/tests/Makefile
index cb06868958ab..0479cfb63801 100644
--- a/lib/msun/tests/Makefile
+++ b/lib/msun/tests/Makefile
@@ -6,13 +6,12 @@ TESTSRC= ${SRCTOP}/contrib/netbsd-tests/lib/libm
TESTSDIR= ${TESTSBASE}/lib/msun
-.if ${MACHINE} == "sparc" || ${MACHINE} == "i386" \
- || ${MACHINE} == "amd64" || ${MACHINE_CPU} == "arm" \
- || ${MACHINE} == "sparc64"
+# All architectures on FreeBSD have fenv.h
CFLAGS+= -DHAVE_FENV_H
-.endif
-.if ${MACHINE} == "amd64" || ${MACHINE} == "i386"
+# Not sure why this isn't defined for all architectures, since most
+# have long double.
+.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386"
CFLAGS+= -D__HAVE_LONG_DOUBLE
.endif
diff --git a/libexec/casper/dns/dns.c b/libexec/casper/dns/dns.c
index 6be022ab6566..f82801e42ddc 100644
--- a/libexec/casper/dns/dns.c
+++ b/libexec/casper/dns/dns.c
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/in.h>
+#include <assert.h>
#include <errno.h>
#include <netdb.h>
#include <stdlib.h>
@@ -103,6 +104,8 @@ static void
hostent_pack(const struct hostent *hp, nvlist_t *nvl)
{
unsigned int ii;
+ char nvlname[64];
+ int n;
nvlist_add_string(nvl, "name", hp->h_name);
nvlist_add_number(nvl, "addrtype", (uint64_t)hp->h_addrtype);
@@ -112,8 +115,9 @@ hostent_pack(const struct hostent *hp, nvlist_t *nvl)
nvlist_add_number(nvl, "naliases", 0);
} else {
for (ii = 0; hp->h_aliases[ii] != NULL; ii++) {
- nvlist_addf_string(nvl, hp->h_aliases[ii], "alias%u",
- ii);
+ n = snprintf(nvlname, sizeof(nvlname), "alias%u", ii);
+ assert(n > 0 && n < (int)sizeof(nvlname));
+ nvlist_add_string(nvl, nvlname, hp->h_aliases[ii]);
}
nvlist_add_number(nvl, "naliases", (uint64_t)ii);
}
@@ -122,8 +126,10 @@ hostent_pack(const struct hostent *hp, nvlist_t *nvl)
nvlist_add_number(nvl, "naddrs", 0);
} else {
for (ii = 0; hp->h_addr_list[ii] != NULL; ii++) {
- nvlist_addf_binary(nvl, hp->h_addr_list[ii],
- (size_t)hp->h_length, "addr%u", ii);
+ n = snprintf(nvlname, sizeof(nvlname), "addr%u", ii);
+ assert(n > 0 && n < (int)sizeof(nvlname));
+ nvlist_add_binary(nvl, nvlname, hp->h_addr_list[ii],
+ (size_t)hp->h_length);
}
nvlist_add_number(nvl, "naddrs", (uint64_t)ii);
}
@@ -228,8 +234,10 @@ dns_getnameinfo(const nvlist_t *limits, const nvlist_t *nvlin, nvlist_t *nvlout)
goto out;
}
- if (!dns_allowed_family(limits, (int)sast.ss_family))
- return (NO_RECOVERY);
+ if (!dns_allowed_family(limits, (int)sast.ss_family)) {
+ error = NO_RECOVERY;
+ goto out;
+ }
flags = (int)nvlist_get_number(nvlin, "flags");
@@ -269,9 +277,10 @@ dns_getaddrinfo(const nvlist_t *limits, const nvlist_t *nvlin, nvlist_t *nvlout)
{
struct addrinfo hints, *hintsp, *res, *cur;
const char *hostname, *servname;
+ char nvlname[64];
nvlist_t *elem;
unsigned int ii;
- int error, family;
+ int error, family, n;
if (!dns_allowed_type(limits, "ADDR"))
return (NO_RECOVERY);
@@ -308,7 +317,9 @@ dns_getaddrinfo(const nvlist_t *limits, const nvlist_t *nvlin, nvlist_t *nvlout)
for (cur = res, ii = 0; cur != NULL; cur = cur->ai_next, ii++) {
elem = addrinfo_pack(cur);
- nvlist_movef_nvlist(nvlout, elem, "res%u", ii);
+ n = snprintf(nvlname, sizeof(nvlname), "res%u", ii);
+ assert(n > 0 && n < (int)sizeof(nvlname));
+ nvlist_move_nvlist(nvlout, nvlname, elem);
}
freeaddrinfo(res);
diff --git a/libexec/casper/grp/grp.c b/libexec/casper/grp/grp.c
index ba22f62e59c7..ab28e1a933d8 100644
--- a/libexec/casper/grp/grp.c
+++ b/libexec/casper/grp/grp.c
@@ -30,6 +30,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <assert.h>
#include <errno.h>
#include <grp.h>
#include <stdlib.h>
@@ -184,6 +185,8 @@ grp_allowed_fields(const nvlist_t *oldlimits, const nvlist_t *newlimits)
static bool
grp_pack(const nvlist_t *limits, const struct group *grp, nvlist_t *nvl)
{
+ char nvlname[64];
+ int n;
if (grp == NULL)
return (true);
@@ -210,8 +213,10 @@ grp_pack(const nvlist_t *limits, const struct group *grp, nvlist_t *nvl)
unsigned int ngroups;
for (ngroups = 0; grp->gr_mem[ngroups] != NULL; ngroups++) {
- nvlist_addf_string(nvl, grp->gr_mem[ngroups],
- "gr_mem[%u]", ngroups);
+ n = snprintf(nvlname, sizeof(nvlname), "gr_mem[%u]",
+ ngroups);
+ assert(n > 0 && n < sizeof(nvlname));
+ nvlist_add_string(nvl, nvlname, grp->gr_mem[ngroups]);
}
nvlist_add_number(nvl, "gr_nmem", (uint64_t)ngroups);
}
diff --git a/libexec/getty/subr.c b/libexec/getty/subr.c
index 26d2173aa144..992280a5e8c0 100644
--- a/libexec/getty/subr.c
+++ b/libexec/getty/subr.c
@@ -38,9 +38,6 @@ static const char rcsid[] =
/*
* Melbourne getty.
*/
-#ifdef DEBUG
-#include <stdio.h>
-#endif
#include <stdlib.h>
#include <string.h>
#include <termios.h>
@@ -160,17 +157,6 @@ gettable(const char *name, char *buf)
fp->value = 1 ^ fp->invrt;
}
}
-
-#ifdef DEBUG
- printf("name=\"%s\", buf=\"%s\"\r\n", name, buf);
- for (sp = gettystrs; sp->field; sp++)
- printf("cgetstr: %s=%s\r\n", sp->field, sp->value);
- for (np = gettynums; np->field; np++)
- printf("cgetnum: %s=%d\r\n", np->field, np->value);
- for (fp = gettyflags; fp->field; fp++)
- printf("cgetflags: %s='%c' set='%c'\r\n", fp->field,
- fp->value + '0', fp->set + '0');
-#endif /* DEBUG */
}
void
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index b0704747ae7b..3ac446761992 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -148,8 +148,10 @@ static void unlink_object(Obj_Entry *);
static void unload_object(Obj_Entry *);
static void unref_dag(Obj_Entry *);
static void ref_dag(Obj_Entry *);
-static char *origin_subst_one(char *, const char *, const char *, bool);
-static char *origin_subst(char *, const char *);
+static char *origin_subst_one(Obj_Entry *, char *, const char *,
+ const char *, bool);
+static char *origin_subst(Obj_Entry *, char *);
+static bool obj_resolve_origin(Obj_Entry *obj);
static void preinit_main(void);
static int rtld_verify_versions(const Objlist *);
static int rtld_verify_object_versions(Obj_Entry *);
@@ -788,8 +790,8 @@ basename(const char *name)
static struct utsname uts;
static char *
-origin_subst_one(char *real, const char *kw, const char *subst,
- bool may_free)
+origin_subst_one(Obj_Entry *obj, char *real, const char *kw,
+ const char *subst, bool may_free)
{
char *p, *p1, *res, *resp;
int subst_len, kw_len, subst_count, old_len, new_len;
@@ -808,9 +810,15 @@ origin_subst_one(char *real, const char *kw, const char *subst,
/*
* If the keyword is not found, just return.
+ *
+ * Return non-substituted string if resolution failed. We
+ * cannot do anything more reasonable, the failure mode of the
+ * caller is unresolved library anyway.
*/
- if (subst_count == 0)
+ if (subst_count == 0 || (obj != NULL && !obj_resolve_origin(obj)))
return (may_free ? real : xstrdup(real));
+ if (obj != NULL)
+ subst = obj->origin_path;
/*
* There is indeed something to substitute. Calculate the
@@ -847,20 +855,22 @@ origin_subst_one(char *real, const char *kw, const char *subst,
}
static char *
-origin_subst(char *real, const char *origin_path)
+origin_subst(Obj_Entry *obj, char *real)
{
char *res1, *res2, *res3, *res4;
+ if (obj == NULL || !trust)
+ return (xstrdup(real));
if (uts.sysname[0] == '\0') {
if (uname(&uts) != 0) {
_rtld_error("utsname failed: %d", errno);
return (NULL);
}
}
- res1 = origin_subst_one(real, "$ORIGIN", origin_path, false);
- res2 = origin_subst_one(res1, "$OSNAME", uts.sysname, true);
- res3 = origin_subst_one(res2, "$OSREL", uts.release, true);
- res4 = origin_subst_one(res3, "$PLATFORM", uts.machine, true);
+ res1 = origin_subst_one(obj, real, "$ORIGIN", NULL, false);
+ res2 = origin_subst_one(NULL, res1, "$OSNAME", uts.sysname, true);
+ res3 = origin_subst_one(NULL, res2, "$OSREL", uts.release, true);
+ res4 = origin_subst_one(NULL, res3, "$PLATFORM", uts.machine, true);
return (res4);
}
@@ -1124,7 +1134,7 @@ digest_dynamic1(Obj_Entry *obj, int early, const Elf_Dyn **dyn_rpath,
#endif
case DT_FLAGS:
- if ((dynp->d_un.d_val & DF_ORIGIN) && trust)
+ if (dynp->d_un.d_val & DF_ORIGIN)
obj->z_origin = true;
if (dynp->d_un.d_val & DF_SYMBOLIC)
obj->symbolic = true;
@@ -1156,7 +1166,7 @@ digest_dynamic1(Obj_Entry *obj, int early, const Elf_Dyn **dyn_rpath,
case DT_FLAGS_1:
if (dynp->d_un.d_val & DF_1_NOOPEN)
obj->z_noopen = true;
- if ((dynp->d_un.d_val & DF_1_ORIGIN) && trust)
+ if (dynp->d_un.d_val & DF_1_ORIGIN)
obj->z_origin = true;
if (dynp->d_un.d_val & DF_1_GLOBAL)
obj->z_global = true;
@@ -1207,30 +1217,33 @@ digest_dynamic1(Obj_Entry *obj, int early, const Elf_Dyn **dyn_rpath,
}
}
+static bool
+obj_resolve_origin(Obj_Entry *obj)
+{
+
+ if (obj->origin_path != NULL)
+ return (true);
+ obj->origin_path = xmalloc(PATH_MAX);
+ return (rtld_dirname_abs(obj->path, obj->origin_path) != -1);
+}
+
static void
digest_dynamic2(Obj_Entry *obj, const Elf_Dyn *dyn_rpath,
const Elf_Dyn *dyn_soname, const Elf_Dyn *dyn_runpath)
{
- if (obj->z_origin && obj->origin_path == NULL) {
- obj->origin_path = xmalloc(PATH_MAX);
- if (rtld_dirname_abs(obj->path, obj->origin_path) == -1)
- rtld_die();
- }
-
- if (dyn_runpath != NULL) {
- obj->runpath = (char *)obj->strtab + dyn_runpath->d_un.d_val;
- if (obj->z_origin)
- obj->runpath = origin_subst(obj->runpath, obj->origin_path);
- }
- else if (dyn_rpath != NULL) {
- obj->rpath = (char *)obj->strtab + dyn_rpath->d_un.d_val;
- if (obj->z_origin)
- obj->rpath = origin_subst(obj->rpath, obj->origin_path);
- }
+ if (obj->z_origin && !obj_resolve_origin(obj))
+ rtld_die();
- if (dyn_soname != NULL)
- object_add_name(obj, obj->strtab + dyn_soname->d_un.d_val);
+ if (dyn_runpath != NULL) {
+ obj->runpath = (char *)obj->strtab + dyn_runpath->d_un.d_val;
+ obj->runpath = origin_subst(obj, obj->runpath);
+ } else if (dyn_rpath != NULL) {
+ obj->rpath = (char *)obj->strtab + dyn_rpath->d_un.d_val;
+ obj->rpath = origin_subst(obj, obj->rpath);
+ }
+ if (dyn_soname != NULL)
+ object_add_name(obj, obj->strtab + dyn_soname->d_un.d_val);
}
static void
@@ -1480,12 +1493,8 @@ find_library(const char *xname, const Obj_Entry *refobj, int *fdp)
xname);
return NULL;
}
- if (objgiven && refobj->z_origin) {
- return (origin_subst(__DECONST(char *, xname),
- refobj->origin_path));
- } else {
- return (xstrdup(xname));
- }
+ return (origin_subst(__DECONST(Obj_Entry *, refobj),
+ __DECONST(char *, xname)));
}
if (libmap_disable || !objgiven ||
diff --git a/release/Makefile.ec2 b/release/Makefile.ec2
index 869ebc15264e..f74d32027a7d 100644
--- a/release/Makefile.ec2
+++ b/release/Makefile.ec2
@@ -12,13 +12,17 @@ AMINAMESUFFIX!= date +-%Y-%m-%d
PUBLISH= --public
.endif
-ec2ami: cw-ec2
-.if !exists(/usr/local/bin/bsdec2-image-upload)
- @echo "--------------------------------------------------------------"
- @echo ">>> Creating EC2 AMIs requires bsdec2-image-upload"
- @echo "--------------------------------------------------------------"
- @false
+cw-ec2-portinstall:
+.if exists(${PORTSDIR}/net/bsdec2-image-upload/Makefile)
+ make -C ${PORTSDIR}/net/bsdec2-image-upload BATCH=1 all install clean
+.else
+. if !exists(/usr/local/sbin/pkg-static)
+ env ASSUME_ALWAYS_YES=yes pkg bootstrap -y
+. endif
+ env ASSUME_ALWAYS_YES=yes pkg install -y net/bsdec2-image-upload
.endif
+
+ec2ami: cw-ec2 cw-ec2-portinstall
.if !defined(AWSKEYFILE) || !exists(${AWSKEYFILE})
@echo "--------------------------------------------------------------"
@echo ">>> AWSKEYFILE must point at AWS keys for EC2 AMI creation"
diff --git a/release/arm/BEAGLEBONE.conf b/release/arm/BEAGLEBONE.conf
index 546af5ca2715..4efb61d20bec 100644
--- a/release/arm/BEAGLEBONE.conf
+++ b/release/arm/BEAGLEBONE.conf
@@ -33,5 +33,5 @@ load_target_env() {
export XDEV_FLAGS="${XDEV_FLAGS} MK_TESTS=no"
export KERNEL="BEAGLEBONE"
export CROCHETSRC="https://github.com/freebsd/crochet"
- export CROCHETBRANCH="trunk@r744"
+ export CROCHETBRANCH="trunk@rHEAD"
}
diff --git a/release/arm/PANDABOARD.conf b/release/arm/PANDABOARD.conf
index 9518914ef7bb..dc8952d333b4 100644
--- a/release/arm/PANDABOARD.conf
+++ b/release/arm/PANDABOARD.conf
@@ -33,5 +33,5 @@ load_target_env() {
export XDEV_FLAGS="${XDEV_FLAGS} MK_TESTS=no"
export KERNEL="PANDABOARD"
export CROCHETSRC="https://github.com/freebsd/crochet"
- export CROCHETBRANCH="trunk@r744"
+ export CROCHETBRANCH="trunk@rHEAD"
}
diff --git a/release/arm/RPI-B.conf b/release/arm/RPI-B.conf
index 19778f87536a..aae60c9831a9 100644
--- a/release/arm/RPI-B.conf
+++ b/release/arm/RPI-B.conf
@@ -33,7 +33,7 @@ load_target_env() {
export XDEV_FLAGS="${XDEV_FLAGS} MK_TESTS=no"
export KERNEL="RPI-B"
export CROCHETSRC="https://github.com/freebsd/crochet"
- export CROCHETBRANCH="trunk@r744"
+ export CROCHETBRANCH="trunk@rHEAD"
export UBOOTSRC="https://github.com/gonzoua/u-boot-pi"
export UBOOTBRANCH="trunk"
export UBOOTDIR="/tmp/crochet/u-boot-rpi"
diff --git a/release/arm/WANDBOARD-QUAD.conf b/release/arm/WANDBOARD-QUAD.conf
index 48aa63165a50..c3fff91694ae 100644
--- a/release/arm/WANDBOARD-QUAD.conf
+++ b/release/arm/WANDBOARD-QUAD.conf
@@ -33,5 +33,5 @@ load_target_env() {
export XDEV_FLAGS="${XDEV_FLAGS} MK_TESTS=no"
export KERNEL="WANDBOARD-QUAD"
export CROCHETSRC="https://github.com/freebsd/crochet"
- export CROCHETBRANCH="trunk@r744"
+ export CROCHETBRANCH="trunk@rHEAD"
}
diff --git a/release/arm/ZEDBOARD.conf b/release/arm/ZEDBOARD.conf
index 07c35ba21bad..4d0a4615ba6b 100644
--- a/release/arm/ZEDBOARD.conf
+++ b/release/arm/ZEDBOARD.conf
@@ -32,5 +32,5 @@ load_target_env() {
export XDEV_FLAGS="${XDEV_FLAGS} MK_TESTS=no"
export KERNEL="ZEDBOARD"
export CROCHETSRC="https://github.com/freebsd/crochet"
- export CROCHETBRANCH="trunk@r744"
+ export CROCHETBRANCH="trunk@rHEAD"
}
diff --git a/release/arm64/make-memstick.sh b/release/arm64/make-memstick.sh
index 09edfad3f057..27ebf275cd28 100755
--- a/release/arm64/make-memstick.sh
+++ b/release/arm64/make-memstick.sh
@@ -36,6 +36,6 @@ if [ $? -ne 0 ]; then
fi
rm ${1}/etc/fstab
-mkimg -s gpt -p efi:=${1}/boot/boot1.efifat -p freebsd-boot:=${1}/boot/gptboot -p freebsd-ufs:=${2}.part -p freebsd-swap::1M -o ${2}
+mkimg -s mbr -p efi:=${1}/boot/boot1.efifat -p freebsd:=${2}.part -o ${2}
rm ${2}.part
diff --git a/release/doc/en_US.ISO8859-1/relnotes/article.xml b/release/doc/en_US.ISO8859-1/relnotes/article.xml
index d3f82d78fed7..1528435f1aa5 100644
--- a/release/doc/en_US.ISO8859-1/relnotes/article.xml
+++ b/release/doc/en_US.ISO8859-1/relnotes/article.xml
@@ -22,7 +22,7 @@
<pubdate>$FreeBSD$</pubdate>
- <!-- Last rev: 278934 -->
+ <!-- Last rev: 282146 -->
<copyright>
<year>2015</year>
@@ -316,7 +316,24 @@
<para revision="279571" contrib="sponsor"
sponsor="&scaleengine;">The &man.freebsd-update.8; utility has
been updated to prevent fetching updated binary patches when
- a previous upgrade has not been throughly completed.</para>
+ a previous upgrade has not been thoroughly completed.</para>
+
+ <para revision="279122" contrib="sponsor"
+ sponsor="&juniper;">The &man.netstat.1; utility has been
+ updated to link against the &man.libxo.3; shared
+ library.</para>
+
+ <para revision="280870">A regression in the &man.libarchive.3;
+ library that would prevent a directory from being included in
+ the archive when <literal>--one-file-system</literal> is used
+ has been fixed.</para>
+
+ <para revision="281311" contrib="sponsor" sponsor="&ff;">The
+ &man.ar.1; utility has been updated to set
+ <literal>ARCHIVE_EXTRACT_SECURE_SYMLINKS</literal> and
+ <literal>ARCHIVE_EXTRACT_SECURE_NODOTDOT</literal> to disallow
+ directory traversal when extracting an archive, similar to
+ &man.tar.1;.</para>
</sect2>
<sect2 xml:id="userland-contrib">
@@ -335,9 +352,6 @@
<para revision="261071">&man.jemalloc.3; has been updated to
version 3.5.0.</para>
- <para revision="261212"><application>bmake</application> has
- been updated to version 20140101.</para>
-
<para revision="261283"><application>libc++</application> has
been updated to version 3.4.</para>
@@ -379,6 +393,7 @@
<application>addr2line</application>,
<application>elfcopy (strip)</application>,
<application>nm</application>,
+ <application>readelf</application>,
<application>size</application>, and
<application>strings</application> were switched to the
versions from the ELF Tool Chain project.</para>
@@ -388,17 +403,34 @@
adding <acronym>UTF-8</acronym> support to the &man.sh.1;
shell.</para>
- <para revision="277270"><application>OpenSSL</application> has
- been updated to version 1.0.1l.</para>
-
- <para revision="278433">The &man.xz.1; utility has been udpated
- to version 5.2.0.</para>
-
<para revision="278433">The &man.xz.1; utility has been updated
to support multi-threaded compression.</para>
- <para revision="278970">The &man.acpi.4; subsystem has been
- updated to version 20150204.</para>
+ <para revision="280297"><application>OpenSSL</application> has
+ been updated to version 1.0.1m.</para>
+
+ <para revision="280932" contrib="sponsor" sponsor="&ff;">The
+ <application>elftoolchain</application> utilities have been
+ updated to version 3179.</para>
+
+ <para revision="281316">The &man.xz.1; utility has been updated
+ to version 5.2.1.</para>
+
+ <para revision="281373">The &man.nvi.1; utility has been updated
+ to version 2.1.3.</para>
+
+ <para revision="281396">The &man.acpi.4; subsystem has been
+ updated to version 20150410.</para>
+
+ <para revision="281806">The &man.wpa.supplicant.8; and
+ &man.hostapd.8; utilties have been updated to version
+ 2.4.</para>
+
+ <para revision="281812"><application>bmake</application> has
+ been updated to version 20150418.</para>
+
+ <para revision="282089">The &man.unbound.8; utility has been
+ updated to version 1.5.3.</para>
</sect2>
<sect2 xml:id="userland-installer">
@@ -481,6 +513,10 @@
<acronym>ELF</acronym> object in the
<literal>dlpi_name</literal> structure member.</para>
+ <para revision="273562" contrib="sponsor"
+ sponsor="&juniper;">The &man.libxo.3; library has been
+ imported to the base system.</para>
+
<para revision="273806" contrib="sponsor" sponsor="&chelsio;">A
userland library for Chelsio Terminator 5 based iWARP cards
has been added, allowing userland <acronym>RDMA</acronym>
@@ -509,6 +545,15 @@
updated to be able to handle 32-bit aligned data on 64-bit
platforms, also providing a significant improvement in 32-bit
workloads.</para>
+
+ <para revision="281130">Several standard include headers have
+ been updated to use of <application>gcc</application>
+ attributes, such as <literal>__result_use_check()</literal>,
+ <literal>__alloc_size()</literal>, and
+ <literal>__nonnull()</literal>.</para>
+
+ <para revision="281845">Support for file verification in
+ <acronym>MAC</acronym> has been added.</para>
</sect2>
<sect2 xml:id="userland-abi">
@@ -547,6 +592,30 @@
<para revision="272089">A bug in &man.ipfw.4; that could
potentially lead to a kernel panic when using &man.dummynet.4;
at layer 2 has been fixed.</para>
+
+ <para revision="280930" contrib="sponsor" sponsor="&mitail;">The
+ kernel <acronym>RPC</acronym> has been updated to include
+ several enhancements:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The 45 MiB limit on requests queued for
+ &man.nfsd.8; threads has been removed.</para>
+ </listitem>
+
+ <listitem>
+ <para>Avoids unnecessary throttling by not deferring
+ accounting for completed requests.</para>
+ </listitem>
+
+ <listitem>
+ <para>Fixes an integer overflow and signedness bugs.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para revision="281261" arch="powerpc">Support for
+ &man.dtrace.1; has been added for the
+ Book-E&nbsp;&trade;.</para>
</sect2>
<sect2 xml:id="kernel-config">
@@ -604,6 +673,14 @@
<para revision="279361">The <literal>kern.osrelease</literal>
and <literal>kern.osreldate</literal> are now configurable
&man.jail.8; parameters.</para>
+
+ <para revision="280308,280949" contrib="sponsor"
+ sponsor="&ix;, &ff;">The &man.devfs.5; device filesystem has
+ been changed to update timestamps for read/write operations
+ using seconds precision. A new &man.sysctl.8;,
+ <literal>vfs.devfs.dotimes</literal> has been added, which
+ when set to a non-zero value, enables default precision
+ timestamps for these operations.</para>
</sect2>
</sect1>
@@ -642,6 +719,9 @@
<filename>/dev/hpet<replaceable>N</replaceable></filename>
device, providing access to <acronym>HPET</acronym> from
userspace.</para>
+
+ <para revision="280183">The <literal>drm</literal> code has
+ been updated to match &linux; version 3.8.13.</para>
</sect2>
<sect2 xml:id="drivers-storage">
@@ -676,6 +756,9 @@
<para revision="276526">The <literal>asr(4)</literal> driver has
been removed, and is no longer supported.</para>
+
+ <para revision="281387">The &man.hptnr.4; driver has been
+ updated to version 1.1.1.</para>
</sect2>
<sect2 xml:id="drivers-network">
@@ -768,6 +851,10 @@
driver has been updated to correct performance counter
sampling on G4 (MPC74xxx) and G5 class processors.</para>
+ <para revision="281713" arch="powerpc">The &man.hwpmc.4;
+ driver has been updated to support the Freescale e500
+ core.</para>
+
<para revision="275732" contrib="sponsor"
sponsor="&ff;,&netgate;">The
<application>OpenCrypto</application> framework has been
@@ -819,6 +906,14 @@
<para revision="273515">The &man.virtio.console.4; driver has
been added, which provides an interface to VirtIO console
devices through a &man.tty.4; device.</para>
+
+ <para revision="279957">The &man.bhyve.8; hypervisor has been
+ updated to support <literal>DSM TRIM</literal> commands for
+ virtual <acronym>AHCI</acronym> disks.</para>
+
+ <para revision="281439" arch="arm">Support for the
+ <application>QEMU</application> <literal>virt</literal> system
+ has been added.</para>
</sect2>
<sect2 xml:id="hardware-arm">
@@ -835,6 +930,10 @@
driver has been added, which supports <acronym>CPU</acronym>
frequency and voltage control on the Raspberry Pi
<acronym>SOC</acronym>.</para>
+
+ <para revision="280259" contrib="sponsor" sponsor="&ff;">Initial
+ support for the ARM AArch64 architecture has been
+ added.</para>
</sect2>
</sect1>
@@ -846,6 +945,7 @@
<sect2 xml:id="storage-general">
<title>General Storage</title>
+
<para revision="278037" contrib="sponsor" sponsor="&ix;">The
&man.ctl.4; <acronym>LUN</acronym> mapping has been rewritten,
replacing <acronym>iSCSI</acronym>-specific mapping mechanisms
@@ -907,6 +1007,12 @@
Alternatively, &man.syscons.4; can be enabled at boot time by
entering <literal>set kern.vty=sc</literal> at the
&man.loader.8; prompt.</para>
+
+ <para revision="281616">The boot loader has been updated to
+ support entering the <acronym>GELI</acronym> passphrase before
+ loading the kernel. To enable this behavior, add
+ <literal>geom_eli_passphrase_prompt="YES"</literal> to
+ &man.loader.conf.5;.</para>
</sect2>
<sect2 xml:id="boot-menu">
@@ -1002,6 +1108,13 @@
</tbody>
</tgroup>
</informaltable>
+
+ <para revision="280971" contrib="sponsor"
+ sponsor="&netflix;, &nginx;">Support for <acronym>IP</acronym>
+ identification for atomic datagrams (<acronym>RFC</acronym>
+ 6864) has been added. Support for this feature can be toggled
+ with the <literal>net.inet.ip.rfc6864</literal>
+ &man.sysctl.8;, which is enabled by default.</para>
</sect2>
</sect1>
diff --git a/release/doc/share/xml/release.ent b/release/doc/share/xml/release.ent
index e02a5f647b27..f72b4d0cc224 100644
--- a/release/doc/share/xml/release.ent
+++ b/release/doc/share/xml/release.ent
@@ -70,6 +70,7 @@
<!-- Architecture names -->
<!ENTITY arch.amd64 "amd64">
<!ENTITY arch.arm "arm">
+<!ENTITY arch.arm64 "aarch64">
<!ENTITY arch.i386 "i386">
<!ENTITY arch.mips "mips">
<!ENTITY arch.pc98 "pc98">
diff --git a/release/doc/share/xml/sponsor.ent b/release/doc/share/xml/sponsor.ent
index 6e77d0d0b4e9..91cfe65c1e26 100644
--- a/release/doc/share/xml/sponsor.ent
+++ b/release/doc/share/xml/sponsor.ent
@@ -23,12 +23,18 @@
<!ENTITY google "Google">
+<!ENTITY juniper "Juniper Networks, Inc.">
+
<!ENTITY ix "iXsystems">
<!ENTITY limelight "Limelight Networks">
<!ENTITY lsi "LSI">
+<!ENTITY mitail "MIT Computer Science &amp; Artificial Intelligence Laboratory">
+
+<!ENTITY netflix "Netflix">
<!ENTITY netgate "Netgate">
+<!ENTITY nginx "Nginx, Inc.">
<!ENTITY sandvine "Sandvine, Inc.">
<!ENTITY scaleengine "ScaleEngine, Inc.">
diff --git a/release/scripts/mk-vmimage.sh b/release/scripts/mk-vmimage.sh
index d5985ceb0d25..fd84216a99fe 100755
--- a/release/scripts/mk-vmimage.sh
+++ b/release/scripts/mk-vmimage.sh
@@ -93,6 +93,16 @@ main() {
. "${VMCONFIG}"
fi
+ case ${TARGET}:${TARGET_ARCH} in
+ arm64:aarch64)
+ ROOTLABEL="ufs"
+ NOSWAP=1
+ ;;
+ *)
+ ROOTLABEL="gpt"
+ ;;
+ esac
+
vm_create_base
vm_install_base
vm_extra_install_base
diff --git a/release/tools/vmimage.subr b/release/tools/vmimage.subr
index 1a295e55519b..d4cfc2d19e8b 100644
--- a/release/tools/vmimage.subr
+++ b/release/tools/vmimage.subr
@@ -30,10 +30,9 @@ write_partition_layout() {
-o ${VMIMAGE}
;;
arm64:aarch64)
- mkimg -s gpt \
- -p efi/efiboot:=${BOOTFILES}/efi/boot1/boot1.efifat \
- ${SWAPOPT} \
- -p freebsd-ufs/rootfs:=${VMBASE} \
+ mkimg -s mbr \
+ -p efi:=${BOOTFILES}/efi/boot1/boot1.efifat \
+ -p freebsd:=${VMBASE} \
-o ${VMIMAGE}
;;
powerpc:powerpc*)
@@ -77,7 +76,7 @@ vm_create_base() {
mkdir -p ${DESTDIR}
truncate -s ${VMSIZE} ${VMBASE}
mddev=$(mdconfig -f ${VMBASE})
- newfs /dev/${mddev}
+ newfs -L rootfs /dev/${mddev}
mount /dev/${mddev} ${DESTDIR}
return 0
@@ -97,7 +96,7 @@ vm_copy_base() {
truncate -s ${VMSIZE} ${VMBASE}.tmp
mkdir -p ${DESTDIR}/new
mdnew=$(mdconfig -f ${VMBASE}.tmp)
- newfs /dev/${mdnew}
+ newfs -L rootfs /dev/${mdnew}
mount /dev/${mdnew} ${DESTDIR}/new
tar -cf- -C ${DESTDIR}/old . | tar -xUf- -C ${DESTDIR}/new
@@ -123,7 +122,7 @@ vm_install_base() {
echo '# Custom /etc/fstab for FreeBSD VM images' \
> ${DESTDIR}/etc/fstab
- echo '/dev/gpt/rootfs / ufs rw 1 1' \
+ echo "/dev/${ROOTLABEL}/rootfs / ufs rw 1 1" \
>> ${DESTDIR}/etc/fstab
if [ -z "${NOSWAP}" ]; then
echo '/dev/gpt/swapfs none swap sw 0 0' \
@@ -182,8 +181,10 @@ vm_extra_install_ports() {
}
vm_extra_pre_umount() {
- # Prototype. When overridden, installs additional ports within the
- # virtual machine environment.
+ # Prototype. When overridden, performs additional tasks within the
+ # virtual machine environment prior to unmounting the filesystem.
+ # Note: When overriding this function, removing resolv.conf in the
+ # disk image must be included.
rm -f ${DESTDIR}/etc/resolv.conf
return 0
diff --git a/sbin/atm/atmconfig/atmconfig.8 b/sbin/atm/atmconfig/atmconfig.8
index c8a740cea59b..dc765ca3027a 100644
--- a/sbin/atm/atmconfig/atmconfig.8
+++ b/sbin/atm/atmconfig/atmconfig.8
@@ -90,7 +90,7 @@ To get a list of options and arguments for a command use:
.Pp
To get a list of common options use:
.D1 Nm Ic help Cm options
-.Ss The Ic diag Ss Command
+.Ss The Ic diag Command
The
.Ic diag
command allows the inspection of the ATM interfaces on the local host
@@ -201,7 +201,7 @@ Print traffic parameters: PCR, SCR, MBS, MCR.
.It Nm Ic diag Cm stats Ar device
Print driver specific statistics.
.El
-.Ss The Ic natm Ss Command
+.Ss The Ic natm Command
The
.Ic natm
command is used to change
diff --git a/sbin/camcontrol/camcontrol.8 b/sbin/camcontrol/camcontrol.8
index 97b897b55283..15e1862aebe8 100644
--- a/sbin/camcontrol/camcontrol.8
+++ b/sbin/camcontrol/camcontrol.8
@@ -529,7 +529,7 @@ on the system.
.It Ic defects
Send the
.Tn SCSI
-READ DEFECT DATA (10) command (0x37) or the
+READ DEFECT DATA (10) command (0x37) or the
.Tn SCSI
READ DEFECT DATA (12) command (0xB7) to the given device, and
print out any combination of: the total number of defects, the primary
@@ -563,19 +563,18 @@ drives.
.It longblock
Print out the list as logical blocks.
This option uses a 64-bit block size.
-.It bfi
+.It bfi
Print out the list in bytes from index format.
.It extbfi
Print out the list in extended bytes from index format.
The extended format allows for ranges of blocks to be printed.
-.It phys
+.It phys
Print out the list in physical sector format.
Most drives support this format.
.It extphys
Print out the list in extended physical sector format.
The extended format allows for ranges of blocks to be printed.
.El
-.Pp
.It Fl G
Print out the grown defect list.
This is a list of bad blocks that have
diff --git a/sbin/growfs/Makefile b/sbin/growfs/Makefile
index 1f7422e6d4a9..e7017a71f938 100644
--- a/sbin/growfs/Makefile
+++ b/sbin/growfs/Makefile
@@ -4,8 +4,6 @@
# $FreeBSD$
#
-#GFSDBG=
-
.include <src.opts.mk>
.PATH: ${.CURDIR}/../mount
@@ -16,7 +14,9 @@ MAN= growfs.8
CFLAGS+=-I${.CURDIR}/../mount
.if defined(GFSDBG)
-SRCS+= debug.c
+SRCS+= debug.c
+CFLAGS+= -DFS_DEBUG
+NO_WCAST_ALIGN= yes
.endif
LIBADD= util
diff --git a/sbin/growfs/growfs.c b/sbin/growfs/growfs.c
index 96897e2f8db9..7b85b25329b8 100644
--- a/sbin/growfs/growfs.c
+++ b/sbin/growfs/growfs.c
@@ -161,7 +161,7 @@ growfs(int fsi, int fso, unsigned int Nflag)
#ifdef FS_DEBUG
{
struct csum *dbg_csp;
- int dbg_csc;
+ u_int32_t dbg_csc;
char dbg_line[80];
dbg_csp = fscs;
@@ -242,7 +242,7 @@ growfs(int fsi, int fso, unsigned int Nflag)
#ifdef FS_DEBUG
{
struct csum *dbg_csp;
- int dbg_csc;
+ u_int32_t dbg_csc;
char dbg_line[80];
dbg_csp = fscs;
diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c
index 9a0bd9e5d7df..687d707195e6 100644
--- a/sbin/ipfw/ipfw2.c
+++ b/sbin/ipfw/ipfw2.c
@@ -375,6 +375,13 @@ static int ipfw_show_config(struct cmdline_opts *co, struct format_opts *fo,
ipfw_cfg_lheader *cfg, size_t sz, int ac, char **av);
static void ipfw_list_tifaces(void);
+struct tidx;
+static uint16_t pack_object(struct tidx *tstate, char *name, int otype);
+static uint16_t pack_table(struct tidx *tstate, char *name);
+
+static char *table_search_ctlv(ipfw_obj_ctlv *ctlv, uint16_t idx);
+static void object_sort_ctlv(ipfw_obj_ctlv *ctlv);
+
/*
* Simple string buffer API.
* Used to simplify buffer passing between function and for
@@ -2558,6 +2565,7 @@ ipfw_show_config(struct cmdline_opts *co, struct format_opts *fo,
if (cfg->flags & IPFW_CFG_GET_STATIC) {
/* We've requested static rules */
if (ctlv->head.type == IPFW_TLV_TBLNAME_LIST) {
+ object_sort_ctlv(ctlv);
fo->tstate = ctlv;
readsz += ctlv->head.length;
ctlv = (ipfw_obj_ctlv *)((caddr_t)ctlv +
@@ -2724,19 +2732,18 @@ struct tidx {
};
static uint16_t
-pack_table(struct tidx *tstate, char *name)
+pack_object(struct tidx *tstate, char *name, int otype)
{
int i;
ipfw_obj_ntlv *ntlv;
- if (table_check_name(name) != 0)
- return (0);
-
for (i = 0; i < tstate->count; i++) {
if (strcmp(tstate->idx[i].name, name) != 0)
continue;
if (tstate->idx[i].set != tstate->set)
continue;
+ if (tstate->idx[i].head.type != otype)
+ continue;
return (tstate->idx[i].idx);
}
@@ -2752,7 +2759,7 @@ pack_table(struct tidx *tstate, char *name)
ntlv = &tstate->idx[i];
memset(ntlv, 0, sizeof(ipfw_obj_ntlv));
strlcpy(ntlv->name, name, sizeof(ntlv->name));
- ntlv->head.type = IPFW_TLV_TBL_NAME;
+ ntlv->head.type = otype;
ntlv->head.length = sizeof(ipfw_obj_ntlv);
ntlv->set = tstate->set;
ntlv->idx = ++tstate->counter;
@@ -2761,6 +2768,16 @@ pack_table(struct tidx *tstate, char *name)
return (ntlv->idx);
}
+static uint16_t
+pack_table(struct tidx *tstate, char *name)
+{
+
+ if (table_check_name(name) != 0)
+ return (0);
+
+ return (pack_object(tstate, name, IPFW_TLV_TBL_NAME));
+}
+
static void
fill_table(ipfw_insn *cmd, char *av, uint8_t opcode, struct tidx *tstate)
{
@@ -3611,7 +3628,6 @@ compile_rule(char *av[], uint32_t *rbuf, int *rbufsize, struct tidx *tstate)
break;
} else
goto chkarg;
-
case TOK_QUEUE:
action->opcode = O_QUEUE;
goto chkarg;
@@ -4656,6 +4672,101 @@ done:
*rbufsize = (char *)dst - (char *)rule;
}
+static int
+compare_ntlv(const void *_a, const void *_b)
+{
+ ipfw_obj_ntlv *a, *b;
+
+ a = (ipfw_obj_ntlv *)_a;
+ b = (ipfw_obj_ntlv *)_b;
+
+ if (a->set < b->set)
+ return (-1);
+ else if (a->set > b->set)
+ return (1);
+
+ if (a->idx < b->idx)
+ return (-1);
+ else if (a->idx > b->idx)
+ return (1);
+
+ if (a->head.type < b->head.type)
+ return (-1);
+ else if (a->head.type > b->head.type)
+ return (1);
+
+ return (0);
+}
+
+/*
+ * Provide kernel with sorted list of referenced objects
+ */
+static void
+object_sort_ctlv(ipfw_obj_ctlv *ctlv)
+{
+
+ qsort(ctlv + 1, ctlv->count, ctlv->objsize, compare_ntlv);
+}
+
+struct object_kt {
+ uint16_t uidx;
+ uint16_t type;
+};
+static int
+compare_object_kntlv(const void *k, const void *v)
+{
+ ipfw_obj_ntlv *ntlv;
+ struct object_kt key;
+
+ key = *((struct object_kt *)k);
+ ntlv = (ipfw_obj_ntlv *)v;
+
+ if (key.uidx < ntlv->idx)
+ return (-1);
+ else if (key.uidx > ntlv->idx)
+ return (1);
+
+ if (key.type < ntlv->head.type)
+ return (-1);
+ else if (key.type > ntlv->head.type)
+ return (1);
+
+ return (0);
+}
+
+/*
+ * Finds object name in @ctlv by @idx and @type.
+ * Uses the following facts:
+ * 1) All TLVs are the same size
+ * 2) Kernel implementation provides already sorted list.
+ *
+ * Returns table name or NULL.
+ */
+static char *
+object_search_ctlv(ipfw_obj_ctlv *ctlv, uint16_t idx, uint16_t type)
+{
+ ipfw_obj_ntlv *ntlv;
+ struct object_kt key;
+
+ key.uidx = idx;
+ key.type = type;
+
+ ntlv = bsearch(&key, (ctlv + 1), ctlv->count, ctlv->objsize,
+ compare_object_kntlv);
+
+ if (ntlv != 0)
+ return (ntlv->name);
+
+ return (NULL);
+}
+
+static char *
+table_search_ctlv(ipfw_obj_ctlv *ctlv, uint16_t idx)
+{
+
+ return (object_search_ctlv(ctlv, idx, IPFW_TLV_TBL_NAME));
+}
+
/*
* Adds one or more rules to ipfw chain.
* Data layout:
@@ -4724,7 +4835,7 @@ ipfw_add(char *av[])
ctlv->count = ts.count;
ctlv->objsize = sizeof(ipfw_obj_ntlv);
memcpy(ctlv + 1, ts.idx, tlen);
- table_sort_ctlv(ctlv);
+ object_sort_ctlv(ctlv);
tstate = ctlv;
/* Rule next */
ctlv = (ipfw_obj_ctlv *)((caddr_t)ctlv + ctlv->head.length);
diff --git a/sbin/ipfw/ipfw2.h b/sbin/ipfw/ipfw2.h
index 80970ef0deee..5a083216d53b 100644
--- a/sbin/ipfw/ipfw2.h
+++ b/sbin/ipfw/ipfw2.h
@@ -344,8 +344,6 @@ int fill_ext6hdr(struct _ipfw_insn *cmd, char *av);
/* tables.c */
struct _ipfw_obj_ctlv;
-char *table_search_ctlv(struct _ipfw_obj_ctlv *ctlv, uint16_t idx);
-void table_sort_ctlv(struct _ipfw_obj_ctlv *ctlv);
int table_check_name(char *tablename);
void ipfw_list_ta(int ac, char *av[]);
void ipfw_list_values(int ac, char *av[]);
diff --git a/sbin/ipfw/tables.c b/sbin/ipfw/tables.c
index 4ea5b7b84fdb..08f47318e678 100644
--- a/sbin/ipfw/tables.c
+++ b/sbin/ipfw/tables.c
@@ -1937,73 +1937,6 @@ ipfw_list_values(int ac, char *av[])
}
int
-compare_ntlv(const void *_a, const void *_b)
-{
- ipfw_obj_ntlv *a, *b;
-
- a = (ipfw_obj_ntlv *)_a;
- b = (ipfw_obj_ntlv *)_b;
-
- if (a->set < b->set)
- return (-1);
- else if (a->set > b->set)
- return (1);
-
- if (a->idx < b->idx)
- return (-1);
- else if (a->idx > b->idx)
- return (1);
-
- return (0);
-}
-
-int
-compare_kntlv(const void *k, const void *v)
-{
- ipfw_obj_ntlv *ntlv;
- uint16_t key;
-
- key = *((uint16_t *)k);
- ntlv = (ipfw_obj_ntlv *)v;
-
- if (key < ntlv->idx)
- return (-1);
- else if (key > ntlv->idx)
- return (1);
-
- return (0);
-}
-
-/*
- * Finds table name in @ctlv by @idx.
- * Uses the following facts:
- * 1) All TLVs are the same size
- * 2) Kernel implementation provides already sorted list.
- *
- * Returns table name or NULL.
- */
-char *
-table_search_ctlv(ipfw_obj_ctlv *ctlv, uint16_t idx)
-{
- ipfw_obj_ntlv *ntlv;
-
- ntlv = bsearch(&idx, (ctlv + 1), ctlv->count, ctlv->objsize,
- compare_kntlv);
-
- if (ntlv != 0)
- return (ntlv->name);
-
- return (NULL);
-}
-
-void
-table_sort_ctlv(ipfw_obj_ctlv *ctlv)
-{
-
- qsort(ctlv + 1, ctlv->count, ctlv->objsize, compare_ntlv);
-}
-
-int
table_check_name(char *tablename)
{
int c, i, l;
diff --git a/share/doc/papers/Makefile b/share/doc/papers/Makefile
index 866fe20cd925..eaf097f56d38 100644
--- a/share/doc/papers/Makefile
+++ b/share/doc/papers/Makefile
@@ -6,7 +6,6 @@ SUBDIR= beyond4.3 \
devfs \
diskperf \
fsinterface \
- hwpmc \
jail \
kernmalloc \
kerntune \
diff --git a/share/doc/papers/bufbio/bio.ms b/share/doc/papers/bufbio/bio.ms
index 123f8e7699b7..32e29170903e 100644
--- a/share/doc/papers/bufbio/bio.ms
+++ b/share/doc/papers/bufbio/bio.ms
@@ -40,7 +40,7 @@ This paper contains the road-map for a stackable "BIO" system in
FreeBSD, which will support these facilities.
.AE
.NH
-The miseducation of \fCstruct buf\fP.
+The miseducation of \f(CW.)struct buf\fP.
.PP
To fully appreciate the topic, I include a little historic overview
of struct buf, it is a most enlightening case of not exactly bit-rot
@@ -51,7 +51,7 @@ memory is was introduced into UNIX, all disk I/O were done from or
to a struct buf. In the 6th edition sources, as printed in Lions
Book, struct buf looks like this:
.DS
-.ft C
+.ft CW
.ps -1
struct buf
{
@@ -95,7 +95,7 @@ aspect and only a few fields relate exclusively to the cache aspect.
If we step forward to the BSD 4.4-Lite-2 release, struct buf has grown
a bit here or there:
.DS
-.ft C
+.ft CW
.ps -1
struct buf {
LIST_ENTRY(buf) b_hash; /* Hash chain. */
@@ -144,7 +144,7 @@ aspect, link buffers to the VM system, provide hacks for file-systems
.PP
By the time we get to FreeBSD 3.0 more stuff has grown on struct buf:
.DS
-.ft C
+.ft CW
.ps -1
struct buf {
LIST_ENTRY(buf) b_hash; /* Hash chain. */
@@ -215,7 +215,7 @@ and Vinum. They all basically do the same: they map I/O requests from
a logical space to a physical space, and the mappings they perform
can be 1:1 or 1:N. \**
.FS
-It is interesting to note that Lions in his comments to the \fCrkaddr\fP
+It is interesting to note that Lions in his comments to the \f(CW.)rkaddr\fP
routine (p. 16-2) writes \fIThe code in this procedure incorporates
a special feature for files which extend over more than one disk
drive. This feature is described in the UPM Section "RK(IV)". Its
@@ -258,7 +258,7 @@ limited extent diskslice/label, which
need only the I/O aspect, not the vnode, caching or VM linkage.
.IP
.I
-The I/O aspect of struct buf should be put in a separate \fCstruct bio\fP.
+The I/O aspect of struct buf should be put in a separate \f(CW.)struct bio\fP.
.R
.NH 1
Implications for future struct buf improvements
@@ -296,7 +296,7 @@ Anything that could be added to or done with
the I/O aspect of struct buf can also be added to or done
with the I/O aspect if it lives in a new "struct bio".
.NH 1
-Implementing a \fCstruct bio\fP
+Implementing a \f(CW.)struct bio\fP
.PP
The first decision to be made was who got to use the name "struct buf",
and considering the fact that it is the I/O aspect which gets separated
@@ -344,7 +344,7 @@ Definition of struct bio
.PP
With the cleanup of b_flags in place, the definition of struct bio looks like this:
.DS
-.ft C
+.ft CW
.ps -1
struct bio {
u_int bio_cmd; /* I/O operation. */
@@ -375,7 +375,7 @@ Definition of struct buf
After adding a struct bio to struct buf and the fields aliased into it
struct buf looks like this:
.DS
-.ft C
+.ft CW
.ps -1
struct buf {
/* XXX: b_io must be the first element of struct buf for now /phk */
@@ -424,7 +424,7 @@ And can be found at http://phk.freebsd.dk/misc
.FE
and consists mainly of systematic substitutions like these
.DS
-.ft C
+.ft CW
s/struct buf/struct bio/
s/b_flags/bio_flags/
s/b_bcount/bio_bcount/
diff --git a/share/doc/papers/hwpmc/Makefile b/share/doc/papers/hwpmc/Makefile
deleted file mode 100644
index d24fe06d9d2d..000000000000
--- a/share/doc/papers/hwpmc/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# $FreeBSD$
-
-VOLUME= papers
-DOC= hwpmc
-SRCS= hwpmc.ms
-MACROS= -ms
-
-.include <bsd.doc.mk>
diff --git a/share/doc/papers/hwpmc/hwpmc.ms b/share/doc/papers/hwpmc/hwpmc.ms
deleted file mode 100644
index 9061bb7a69a3..000000000000
--- a/share/doc/papers/hwpmc/hwpmc.ms
+++ /dev/null
@@ -1,34 +0,0 @@
-.\" Copyright (c) 2004 Joseph Koshy.
-.\"
-.\" 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 JOSEPH KOSHY 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 JOSEPH KOSHY 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$
-.\"
-.OH '''Using Hardware Performance Monitoring Counters'
-.EH 'HWPMC'''
-.TL
-Using Hardware Performance Monitoring Counters in FreeBSD
-.sp
-\s-2FreeBSD 5.2.1\s+2
-.sp
-\fRJuly, 2004\fR
-.PP
diff --git a/share/doc/usd/06.bc/bc b/share/doc/usd/06.bc/bc
index c4e68c679a6b..4d87f2ce410a 100644
--- a/share/doc/usd/06.bc/bc
+++ b/share/doc/usd/06.bc/bc
@@ -36,12 +36,13 @@
.\" @(#)bc 6.2 (Berkeley) 4/17/91
.\"
.if n \{\
-.po 5n
-.ll 70n
+.nr PO 5n
+.nr LL 70n
.\}
.EH 'USD:6-%''BC \- An Arbitrary Precision Desk-Calculator Language'
.OH 'BC \- An Arbitrary Precision Desk-Calculator Language''USD:6-%'
.\".RP
+.ND
.TL
BC \- An Arbitrary Precision Desk-Calculator Language
.AU
diff --git a/share/doc/usd/10.exref/Makefile b/share/doc/usd/10.exref/Makefile
new file mode 100644
index 000000000000..8df4f7208726
--- /dev/null
+++ b/share/doc/usd/10.exref/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+SUBDIR= exref summary
+
+.include <bsd.subdir.mk>
+
diff --git a/share/doc/usd/10.exref/Makefile.inc b/share/doc/usd/10.exref/Makefile.inc
new file mode 100644
index 000000000000..9c637dc20250
--- /dev/null
+++ b/share/doc/usd/10.exref/Makefile.inc
@@ -0,0 +1,4 @@
+# $FreeBSD$
+
+VOLUME= usd/10.exref
+MACROS= -ms
diff --git a/share/doc/usd/10.exref/exref/Makefile b/share/doc/usd/10.exref/exref/Makefile
new file mode 100644
index 000000000000..7af18f93ef38
--- /dev/null
+++ b/share/doc/usd/10.exref/exref/Makefile
@@ -0,0 +1,5 @@
+# $FreeBSD$
+
+SRCS= ex.rm
+
+.include <bsd.doc.mk>
diff --git a/share/doc/usd/10.exref/exref/ex.rm b/share/doc/usd/10.exref/exref/ex.rm
new file mode 100644
index 000000000000..9adde179dade
--- /dev/null
+++ b/share/doc/usd/10.exref/exref/ex.rm
@@ -0,0 +1,2215 @@
+.\" Copyright (c) 1980, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)ex.rm 8.5 (Berkeley) 8/18/96
+.\" $FreeBSD$
+.\"
+.nr LL 6.5i
+.nr FL 6.5i
+.EH 'USD:12-%''Ex Reference Manual'
+.OH 'Ex Reference Manual''USD:12-%'
+.ND
+.nr )P 0
+.de ZP
+.nr pd \\n()P
+.nr )P 0
+.if \\n(.$=0 .IP
+.if \\n(.$=1 .IP "\\$1"
+.if \\n(.$>=2 .IP "\\$1" "\\$2"
+.nr )P \\n(pd
+.rm pd
+..
+.de LC
+.br
+.sp .1i
+.ne 4
+.LP
+.ta 4.0i
+..
+.bd S B 3
+.\".RP
+.TL
+Ex Reference Manual
+.br
+Version 3.7
+.AU
+William Joy
+.AU
+Mark Horton
+.AI
+Computer Science Division
+Department of Electrical Engineering and Computer Science
+University of California, Berkeley
+Berkeley, Ca. 94720
+.AB
+.I Ex
+a line oriented text editor, which supports both command and display
+oriented editing.
+This reference manual describes the command oriented part of
+.I ex;
+the display editing features of
+.I ex
+are described in
+.I "An Introduction to Display Editing with Vi."
+Other documents about the editor include the introduction
+.I "Edit: A tutorial",
+the
+.I "Ex/edit Command Summary",
+and a
+.I "Vi Quick Reference"
+card.
+.AE
+.NH 1
+Starting ex
+.PP
+.FS
+The financial support of an \s-2IBM\s0 Graduate Fellowship and the National
+Science Foundation under grants MCS74-07644-A03 and MCS78-07291 is gratefully
+acknowledged.
+.FE
+Each instance of the editor has a set of options,
+which can be set to tailor it to your liking.
+The command
+.I edit
+invokes a version of
+.I ex
+designed for more casual or beginning
+users by changing the default settings of some of these options.
+To simplify the description which follows we
+assume the default settings of the options.
+.PP
+When invoked,
+.I ex
+determines the terminal type from the \s-2TERM\s0 variable in the environment.
+It there is a \s-2TERMCAP\s0 variable in the environment, and the type
+of the terminal described there matches the \s-2TERM\s0 variable,
+then that description
+is used. Also if the \s-2TERMCAP\s0 variable contains a pathname (beginning
+with a \fB/\fR) then the editor will seek the description of the terminal
+in that file (rather than the default /etc/termcap).
+If there is a variable \s-2EXINIT\s0 in the environment, then the editor
+will execute the commands in that variable,
+otherwise if there is a file
+.I \&.exrc
+in your \s-2HOME\s0 directory
+.I ex
+reads commands from that file, simulating a
+.I source
+command.
+Option setting commands placed in
+\s-2EXINIT\s0 or
+.I \&.exrc
+will be executed before each editor session.
+.PP
+A command to enter
+.I ex
+has the following prototype:\(dg
+.FS
+\(dg Brackets `[' `]' surround optional parameters here.
+.FE
+.DS
+\fBex\fP [ \fB\-\fP ] [ \fB\-v\fP ] [ \fB\-t\fP \fItag\fP ] [ \fB\-r\fP ] [ \fB\-l\fP ] [ \fB\-w\fP\fIn\fP ] [ \fB\-x\fP ] [ \fB\-R\fP ] [ \fB+\fP\fIcommand\fP ] name ...
+.DE
+The most common case edits a single file with no options, i.e.:
+.DS
+\fBex\fR name
+.DE
+The
+.B \-
+command line option
+option suppresses all interactive-user feedback
+and is useful in processing editor scripts in command files.
+The
+.B \-v
+option is equivalent to using
+.I vi
+rather than
+.I ex.
+The
+.B \-t
+option is equivalent to an initial
+.I tag
+command, editing the file containing the
+.I tag
+and positioning the editor at its definition.
+The
+.B \-r
+option is used in recovering after an editor or system crash,
+retrieving the last saved version of the named file or,
+if no file is specified,
+typing a list of saved files.
+The
+.B \-l
+option sets up for editing \s-2LISP\s0, setting the
+.I showmatch
+and
+.I lisp
+options.
+The
+.B \-w
+option sets the default window size to
+.I n,
+and is useful on dialups to start in small windows.
+The
+.B \-x
+option causes
+.I ex
+to prompt for a
+.I key ,
+which is used to encrypt and decrypt the contents of the file,
+which should already be encrypted using the same key,
+see
+.I crypt (1).
+The
+.B \-R
+option sets the
+.I readonly
+option at the start.
+.I Name
+arguments indicate files to be edited.
+An argument of the form
+\fB+\fIcommand\fR
+indicates that the editor should begin by executing the specified command.
+If
+.I command
+is omitted, then it defaults to ``$'', positioning the editor at the last
+line of the first file initially. Other useful commands here are scanning
+patterns of the form ``/pat'' or line numbers, e.g. ``+100'' starting
+at line 100.
+.NH 1
+File manipulation
+.NH 2
+Current file
+.PP
+.I Ex
+is normally editing the contents of a single file,
+whose name is recorded in the
+.I current
+file name.
+.I Ex
+performs all editing actions in a buffer
+(actually a temporary file)
+into which the text of the file is initially read.
+Changes made to the buffer have no effect on the file being
+edited unless and until the buffer contents are written out to the
+file with a
+.I write
+command.
+After the buffer contents are written,
+the previous contents of the written file are no longer accessible.
+When a file is edited,
+its name becomes the current file name,
+and its contents are read into the buffer.
+.PP
+The current file is almost always considered to be
+.I edited.
+This means that the contents of the buffer are logically
+connected with the current file name,
+so that writing the current buffer contents onto that file,
+even if it exists,
+is a reasonable action.
+If the current file is not
+.I edited
+then
+.I ex
+will not normally write on it if it already exists.*
+.FS
+* The
+.I file
+command will say ``[Not edited]'' if the current file is not considered
+edited.
+.FE
+.NH 2
+Alternate file
+.PP
+Each time a new value is given to the current file name,
+the previous current file name is saved as the
+.I alternate
+file name.
+Similarly if a file is mentioned but does not become the current file,
+it is saved as the alternate file name.
+.NH 2
+Filename expansion
+.PP
+Filenames within the editor may be specified using the normal
+shell expansion conventions.
+In addition,
+the character `%' in filenames is replaced by the
+.I current
+file name and the character
+`#' by the
+.I alternate
+file name.\(dg
+.FS
+\(dg This makes it easy to deal alternately with
+two files and eliminates the need for retyping the
+name supplied on an
+.I edit
+command after a
+.I "No write since last change"
+diagnostic is received.
+.FE
+.NH 2
+Multiple files and named buffers
+.PP
+If more than one file is given on the command line,
+then the first file is edited as described above.
+The remaining arguments are placed with the first file in the
+.I "argument list."
+The current argument list may be displayed with the
+.I args
+command.
+The next file in the argument list may be edited with the
+.I next
+command.
+The argument list may also be respecified by specifying
+a list of names to the
+.I next
+command.
+These names are expanded,
+the resulting list of names becomes the new argument list,
+and
+.I ex
+edits the first file on the list.
+.PP
+For saving blocks of text while editing, and especially when editing
+more than one file,
+.I ex
+has a group of named buffers.
+These are similar to the normal buffer, except that only a limited number
+of operations are available on them.
+The buffers have names
+.I a
+through
+.I z.\(dd
+.FS
+\(dd It is also possible to refer to
+.I A
+through
+.I Z;
+the upper case buffers are the same as the lower but commands
+append to named buffers rather than replacing
+if upper case names are used.
+.FE
+.NH 2
+Read only
+.PP
+It is possible to use
+.I ex
+in
+.I "read only"
+mode to look at files that you have no intention of modifying.
+This mode protects you from accidently overwriting the file.
+Read only mode is on when the
+.I readonly
+option is set.
+It can be turned on with the
+.B \-R
+command line option,
+by the
+.I view
+command line invocation,
+or by setting the
+.I readonly
+option.
+It can be cleared by setting
+.I noreadonly .
+It is possible to write, even while in read only mode, by indicating
+that you really know what you are doing.
+You can write to a different file, or can use the ! form of write,
+even while in read only mode.
+.NH 1
+Exceptional Conditions
+.NH 2
+Errors and interrupts
+.PP
+When errors occur
+.I ex
+(optionally) rings the terminal bell and, in any case, prints an error
+diagnostic. If the primary input is from a file, editor processing
+will terminate. If an interrupt signal is received,
+.I ex
+prints ``Interrupt'' and returns to its command level. If the primary
+input is a file, then
+.I ex
+will exit when this occurs.
+.NH 2
+Recovering from hangups and crashes
+.PP
+If a hangup signal is received and the buffer has been modified since
+it was last written out, or if the system crashes, either the editor
+(in the first case) or the system (after it reboots in the second) will
+attempt to preserve the buffer. The next time you log in you should be
+able to recover the work you were doing, losing at most a few lines of
+changes from the last point before the hangup or editor crash. To
+recover a file you can use the
+.B \-r
+option. If you were editing the file
+.I resume,
+then you should change
+to the directory where you were when the crash occurred, giving the command
+.DS
+\fBex \-r\fP\fI resume\fP
+.DE
+After checking that the retrieved file is indeed ok, you can
+.I write
+it over the previous contents of that file.
+.PP
+You will normally get mail from the system telling you when a file has
+been saved after a crash. The command
+.DS
+\fBex\fP \-\fBr\fP
+.DE
+will print a list of the files which have been saved for you.
+(In the case of a hangup,
+the file will not appear in the list,
+although it can be recovered.)
+.NH 1
+Editing modes
+.PP
+.I Ex
+has five distinct modes. The primary mode is
+.I command
+mode. Commands are entered in command mode when a `:' prompt is
+present, and are executed each time a complete line is sent. In
+.I "text input"
+mode
+.I ex
+gathers input lines and places them in the file. The
+.I append,
+.I insert,
+and
+.I change
+commands use text input mode.
+No prompt is printed when you are in text input mode.
+This mode is left by typing a `.' alone at the beginning of a line, and
+.I command
+mode resumes.
+.PP
+The last three modes are
+.I open
+and
+.I visual
+modes, entered by the commands of the same name, and, within open and
+visual modes
+.I "text insertion"
+mode.
+.I Open
+and
+.I visual
+modes allow local editing operations to be performed on the text in the
+file. The
+.I open
+command displays one line at a time on any terminal while
+.I visual
+works on \s-2CRT\s0 terminals with random positioning cursors, using the
+screen as a (single) window for file editing changes.
+These modes are described (only) in
+.I "An Introduction to Display Editing with Vi."
+.NH
+Command structure
+.PP
+Most command names are English words,
+and initial prefixes of the words are acceptable abbreviations.
+The ambiguity of abbreviations is resolved in favor of the more commonly
+used commands.*
+.FS
+* As an example, the command
+.I substitute
+can be abbreviated `s'
+while the shortest available abbreviation for the
+.I set
+command is `se'.
+.FE
+.NH 2
+Command parameters
+.PP
+Most commands accept prefix addresses specifying the lines in the file
+upon which they are to have effect.
+The forms of these addresses will be discussed below.
+A number of commands also may take a trailing
+.I count
+specifying the number of lines to be involved in the command.\(dg
+.FS
+\(dg Counts are rounded down if necessary.
+.FE
+Thus the command ``10p'' will print the tenth line in the buffer while
+``delete 5'' will delete five lines from the buffer,
+starting with the current line.
+.PP
+Some commands take other information or parameters,
+this information always being given after the command name.\(dd
+.FS
+\(dd Examples would be option names in a
+.I set
+command i.e. ``set number'',
+a file name in an
+.I edit
+command,
+a regular expression in a
+.I substitute
+command,
+or a target address for a
+.I copy
+command, i.e. ``1,5 copy 25''.
+.FE
+.NH 2
+Command variants
+.PP
+A number of commands have two distinct variants.
+The variant form of the command is invoked by placing an
+`!' immediately after the command name.
+Some of the default variants may be controlled by options;
+in this case, the `!' serves to toggle the default.
+.NH 2
+Flags after commands
+.PP
+The characters `#', `p' and `l' may be placed after many commands.**
+.FS
+**
+A `p' or `l' must be preceded by a blank or tab
+except in the single special case `dp'.
+.FE
+In this case, the command abbreviated by these characters
+is executed after the command completes.
+Since
+.I ex
+normally prints the new current line after each change, `p' is rarely necessary.
+Any number of `+' or `\-' characters may also be given with these flags.
+If they appear, the specified offset is applied to the current line
+value before the printing command is executed.
+.NH 2
+Comments
+.PP
+It is possible to give editor commands which are ignored.
+This is useful when making complex editor scripts
+for which comments are desired.
+The comment character is the double quote: ".
+Any command line beginning with " is ignored.
+Comments beginning with " may also be placed at the ends
+of commands, except in cases where they could be confused as part
+of text (shell escapes and the substitute and map commands).
+.NH 2
+Multiple commands per line
+.PP
+More than one command may be placed on a line by separating each pair
+of commands by a `|' character.
+However the
+.I global
+commands,
+comments,
+and the shell escape `!'
+must be the last command on a line, as they are not terminated by a `|'.
+.NH 2
+Reporting large changes
+.PP
+Most commands which change the contents of the editor buffer give
+feedback if the scope of the change exceeds a threshold given by the
+.I report
+option.
+This feedback helps to detect undesirably large changes so that they may
+be quickly and easily reversed with an
+.I undo.
+After commands with more global effect such as
+.I global
+or
+.I visual,
+you will be informed if the net change in the number of lines
+in the buffer during this command exceeds this threshold.
+.NH 1
+Command addressing
+.NH 2
+Addressing primitives
+.IP \fB.\fR 20
+The current line.
+Most commands leave the current line as the last line which they affect.
+The default address for most commands is the current line,
+thus `\fB.\fR' is rarely used alone as an address.
+.IP \fIn\fR 20
+The \fIn\fRth line in the editor's buffer, lines being numbered
+sequentially from 1.
+.IP \fB$\fR 20
+The last line in the buffer.
+.IP \fB%\fR 20
+An abbreviation for ``1,$'', the entire buffer.
+.IP \fI+n\fR\ \fI\-n\fR 20
+An offset relative to the current buffer line.\(dg
+.FS
+\(dg
+The forms `.+3' `+3' and `+++' are all equivalent;
+if the current line is line 100 they all address line 103.
+.FE
+.IP \fB/\fIpat\fR\fB/\fR\ \fB?\fIpat\fR\fB?\fR 20
+Scan forward and backward respectively for a line containing \fIpat\fR, a
+regular expression (as defined below). The scans normally wrap around the end
+of the buffer.
+If all that is desired is to print the next line containing \fIpat\fR, then
+the trailing \fB/\fR or \fB?\fR may be omitted.
+If \fIpat\fP is omitted or explicitly empty, then the last
+regular expression specified is located.\(dd
+.FS
+\(dd The forms \fB\e/\fP and \fB\e?\fP scan
+using the last regular expression used in a scan; after a substitute
+\fB//\fP and \fB??\fP would scan using the substitute's regular expression.
+.FE
+.IP \fB\(aa\(aa\fP\ \fB\(aa\fP\fIx\fP 20
+Before each non-relative motion of the current line `\fB.\fP',
+the previous current line is marked with a tag, subsequently referred to as
+`\(aa\(aa'.
+This makes it easy to refer or return to this previous context.
+Marks may also be established by the
+.I mark
+command, using single lower case letters
+.I x
+and the marked lines referred to as
+`\(aa\fIx\fR'.
+.NH 2
+Combining addressing primitives
+.PP
+Addresses to commands consist of a series of addressing primitives,
+separated by `,' or `;'.
+Such address lists are evaluated left-to-right.
+When addresses are separated by `;' the current line `\fB.\fR'
+is set to the value of the previous addressing expression
+before the next address is interpreted.
+If more addresses are given than the command requires,
+then all but the last one or two are ignored.
+If the command takes two addresses, the first addressed line must
+precede the second in the buffer.\(dg
+.FS
+\(dg Null address specifications are permitted in a list of addresses,
+the default in this case is the current line `.';
+thus `,100' is equivalent to `\fB.\fR,100'.
+It is an error to give a prefix address to a command which expects none.
+.FE
+.NH 1
+Command descriptions
+.PP
+The following form is a prototype for all
+.I ex
+commands:
+.DS
+\fIaddress\fR \fBcommand\fR \fI! parameters count flags\fR
+.DE
+All parts are optional; the degenerate case is the empty command which prints
+the next line in the file. For sanity with use from within
+.I visual
+mode,
+.I ex
+ignores a ``:'' preceding any command.
+.PP
+In the following command descriptions, the
+default addresses are shown in parentheses,
+which are
+.I not,
+however,
+part of the command.
+.LC
+\fBabbreviate\fR \fIword rhs\fP abbr: \fBab\fP
+.ZP
+Add the named abbreviation to the current list.
+When in input mode in visual, if
+.I word
+is typed as a complete word, it will be changed to
+.I rhs .
+.LC
+( \fB.\fR ) \fBappend\fR abbr: \fBa\fR
+.br
+\fItext\fR
+.br
+\&\fB.\fR
+.ZP
+Reads the input text and places it after the specified line.
+After the command, `\fB.\fR'
+addresses the last line input or the
+specified line if no lines were input.
+If address `0' is given,
+text is placed at the beginning of the buffer.
+.LC
+\fBa!\fR
+.br
+\fItext\fR
+.br
+\&\fB.\fR
+.ZP
+The variant flag to
+.I append
+toggles the setting for the
+.I autoindent
+option during the input of
+.I text.
+.LC
+\fBargs\fR
+.ZP
+The members of the argument list are printed, with the current argument
+delimited by `[' and `]'.
+.ig
+.PP
+\fBcd\fR \fIdirectory\fR
+.ZP
+The
+.I cd
+command is a synonym for
+.I chdir.
+..
+.LC
+( \fB.\fP , \fB.\fP ) \fBchange\fP \fIcount\fP abbr: \fBc\fP
+.br
+\fItext\fP
+.br
+\&\fB.\fP
+.ZP
+Replaces the specified lines with the input \fItext\fP.
+The current line becomes the last line input;
+if no lines were input it is left as for a
+\fIdelete\fP.
+.LC
+\fBc!\fP
+.br
+\fItext\fP
+.br
+\&\fB.\fP
+.ZP
+The variant toggles
+.I autoindent
+during the
+.I change.
+.ig
+.LC
+\fBchdir\fR \fIdirectory\fR
+.ZP
+The specified \fIdirectory\fR becomes the current directory.
+If no directory is specified, the current value of the
+.I home
+option is used as the target directory.
+After a
+.I chdir
+the current file is not considered to have been
+edited so that write restrictions on pre-existing files apply.
+..
+.LC
+( \fB.\fP , \fB.\fP )\|\fBcopy\fP \fIaddr\fP \fIflags\fP abbr: \fBco\fP
+.ZP
+A
+.I copy
+of the specified lines is placed after
+.I addr,
+which may be `0'.
+The current line
+`\fB.\fR'
+addresses the last line of the copy.
+The command
+.I t
+is a synonym for
+.I copy.
+.LC
+( \fB.\fR , \fB.\fR )\|\fBdelete\fR \fIbuffer\fR \fIcount\fR \fIflags\fR abbr: \fBd\fR
+.ZP
+Removes the specified lines from the buffer.
+The line after the last line deleted becomes the current line;
+if the lines deleted were originally at the end,
+the new last line becomes the current line.
+If a named
+.I buffer
+is specified by giving a letter,
+then the specified lines are saved in that buffer,
+or appended to it if an upper case letter is used.
+.LC
+\fBedit\fR \fIfile\fR abbr: \fBe\fR
+.br
+\fBex\fR \fIfile\fR
+.ZP
+Used to begin an editing session on a new file.
+The editor
+first checks to see if the buffer has been modified since the last
+.I write
+command was issued.
+If it has been,
+a warning is issued and the
+command is aborted.
+The
+command otherwise deletes the entire contents of the editor buffer,
+makes the named file the current file and prints the new filename.
+After insuring that this file is sensible\(dg
+.FS
+\(dg I.e., that it is not a binary file such as a directory,
+a block or character special file other than
+.I /dev/tty,
+a terminal,
+or a binary or executable file
+(as indicated by the first word).
+.FE
+the editor reads the file into its buffer.
+.IP
+If the read of the file completes without error,
+the number of lines and characters read is typed.
+If there were any non-\s-2ASCII\s0 characters
+in the file they are stripped of their non-\s-2ASCII\s0
+high bits,
+and any null characters in the file are discarded.
+If none of these errors occurred, the file is considered
+.I edited.
+If the last line of the input file is missing the trailing
+newline character, it will be supplied and a complaint will be issued.
+This command leaves the current line `\fB.\fR' at the last line read.\(dd
+.FS
+\(dd If executed from within
+.I open
+or
+.I visual,
+the current line is initially the first line of the file.
+.FE
+.LC
+\fBe!\fR \fIfile\fR
+.ZP
+The variant form suppresses the complaint about modifications having
+been made and not written from the editor buffer, thus
+discarding all changes which have been made before editing the new file.
+.LC
+\fBe\fR \fB+\fIn\fR \fIfile\fR
+.ZP
+Causes the editor to begin at line
+.I n
+rather than at the last line;
+\fIn\fR may also be an editor command containing no spaces, e.g.: ``+/pat''.
+.LC
+\fBfile\fR abbr: \fBf\fR
+.ZP
+Prints the current file name,
+whether it has been `[Modified]' since the last
+.I write
+command,
+whether it is
+.I "read only" ,
+the current line,
+the number of lines in the buffer,
+and the percentage of the way through the buffer of the current line.*
+.FS
+* In the rare case that the current file is `[Not edited]' this is
+noted also; in this case you have to use the form \fBw!\fR to write to
+the file, since the editor is not sure that a \fBwrite\fR will not
+destroy a file unrelated to the current contents of the buffer.
+.FE
+.LC
+\fBfile\fR \fIfile\fR
+.ZP
+The current file name is changed to
+.I file
+which is considered
+`[Not edited]'.
+.LC
+( 1 , $ ) \fBglobal\fR /\fIpat\|\fR/ \fIcmds\fR abbr: \fBg\fR
+.ZP
+First marks each line among those specified which matches
+the given regular expression.
+Then the given command list is executed with `\fB.\fR' initially
+set to each marked line.
+.IP
+The command list consists of the remaining commands on the current
+input line and may continue to multiple lines by ending all but the
+last such line with a `\e'.
+If
+.I cmds
+(and possibly the trailing \fB/\fR delimiter) is omitted, each line matching
+.I pat
+is printed.
+.I Append,
+.I insert,
+and
+.I change
+commands and associated input are permitted;
+the `\fB.\fR' terminating input may be omitted if it would be on the
+last line of the command list.
+.I Open
+and
+.I visual
+commands are permitted in the command list and take input from the terminal.
+.IP
+The
+.I global
+command itself may not appear in
+.I cmds.
+The
+.I undo
+command is also not permitted there,
+as
+.I undo
+instead can be used to reverse the entire
+.I global
+command.
+The options
+.I autoprint
+and
+.I autoindent
+are inhibited during a
+.I global,
+(and possibly the trailing \fB/\fR delimiter) and the value of the
+.I report
+option is temporarily infinite,
+in deference to a \fIreport\fR for the entire global.
+Finally, the context mark `\'\'' is set to the value of
+`.' before the global command begins and is not changed during a global
+command,
+except perhaps by an
+.I open
+or
+.I visual
+within the
+.I global.
+.LC
+\fBg!\fR \fB/\fIpat\fB/\fR \fIcmds\fR abbr: \fBv\fR
+.IP
+The variant form of \fIglobal\fR runs \fIcmds\fR at each line not matching
+\fIpat\fR.
+.LC
+( \fB.\fR )\|\fBinsert\fR abbr: \fBi\fR
+.br
+\fItext\fR
+.br
+\&\fB.\fR
+.ZP
+Places the given text before the specified line.
+The current line is left at the last line input;
+if there were none input it is left at the line before the addressed line.
+This command differs from
+.I append
+only in the placement of text.
+.KS
+.LC
+\fBi!\fR
+.br
+\fItext\fR
+.br
+\&\fB.\fR
+.ZP
+The variant toggles
+.I autoindent
+during the
+.I insert.
+.KE
+.LC
+( \fB.\fR , \fB.\fR+1 ) \fBjoin\fR \fIcount\fR \fIflags\fR abbr: \fBj\fR
+.ZP
+Places the text from a specified range of lines
+together on one line.
+White space is adjusted at each junction to provide at least
+one blank character, two if there was a `\fB.\fR' at the end of the line,
+or none if the first following character is a `)'.
+If there is already white space at the end of the line,
+then the white space at the start of the next line will be discarded.
+.LC
+\fBj!\fR
+.ZP
+The variant causes a simpler
+.I join
+with no white space processing; the characters in the lines are simply
+concatenated.
+.LC
+( \fB.\fR ) \fBk\fR \fIx\fR
+.ZP
+The
+.I k
+command is a synonym for
+.I mark.
+It does not require a blank or tab before the following letter.
+.LC
+( \fB.\fR , \fB.\fR ) \fBlist\fR \fIcount\fR \fIflags\fR
+.ZP
+Prints the specified lines in a more unambiguous way:
+tabs are printed as `^I'
+and the end of each line is marked with a trailing `$'.
+The current line is left at the last line printed.
+.LC
+\fBmap\fR \fIlhs\fR \fIrhs\fR
+.ZP
+The
+.I map
+command is used to define macros for use in
+.I visual
+mode.
+.I Lhs
+should be a single character, or the sequence ``#n'', for n a digit,
+referring to function key \fIn\fR. When this character or function key
+is typed in
+.I visual
+mode, it will be as though the corresponding \fIrhs\fR had been typed.
+On terminals without function keys, you can type ``#n''.
+See section 6.9 of the ``Introduction to Display Editing with Vi''
+for more details.
+.LC
+( \fB.\fR ) \fBmark\fR \fIx\fR
+.ZP
+Gives the specified line mark
+.I x,
+a single lower case letter.
+The
+.I x
+must be preceded by a blank or a tab.
+The addressing form `\'x' then addresses this line.
+The current line is not affected by this command.
+.LC
+( \fB.\fR , \fB.\fR ) \fBmove\fR \fIaddr\fR abbr: \fBm\fR
+.ZP
+The
+.I move
+command repositions the specified lines to be after
+.I addr .
+The first of the moved lines becomes the current line.
+.LC
+\fBnext\fR abbr: \fBn\fR
+.ZP
+The next file from the command line argument list is edited.
+.LC
+\fBn!\fR
+.ZP
+The variant suppresses warnings about the modifications to the buffer not
+having been written out, discarding (irretrievably) any changes which may
+have been made.
+.LC
+\fBn\fR \fIfilelist\fR
+.br
+\fBn\fR \fB+\fIcommand\fR \fIfilelist\fR
+.ZP
+The specified
+.I filelist
+is expanded and the resulting list replaces the
+current argument list;
+the first file in the new list is then edited.
+If
+.I command
+is given (it must contain no spaces), then it is executed after editing the first such file.
+.LC
+( \fB.\fR , \fB.\fR ) \fBnumber\fR \fIcount\fR \fIflags\fR abbr: \fB#\fR or \fBnu\fR
+.ZP
+Prints each specified line preceded by its buffer line
+number.
+The current line is left at the last line printed.
+.KS
+.LC
+( \fB.\fR ) \fBopen\fR \fIflags\fR abbr: \fBo\fR
+.br
+( \fB.\fR ) \fBopen\fR /\fIpat\|\fR/ \fIflags\fR
+.ZP
+Enters intraline editing \fIopen\fR mode at each addressed line.
+If
+.I pat
+is given,
+then the cursor will be placed initially at the beginning of the
+string matched by the pattern.
+To exit this mode use Q.
+See
+.I "An Introduction to Display Editing with Vi"
+for more details.
+.KE
+.LC
+\fBpreserve\fR
+.ZP
+The current editor buffer is saved as though the system had just crashed.
+This command is for use only in emergencies when a
+.I write
+command has resulted in an error and you don't know how to save your work.
+After a
+.I preserve
+you should seek help.
+.LC
+( \fB.\fR , \fB.\fR )\|\fBprint\fR \fIcount\fR abbr: \fBp\fR or \fBP\fR
+.ZP
+Prints the specified lines
+with non-printing characters printed as control characters `^\fIx\fR\|';
+delete (octal 177) is represented as `^?'.
+The current line is left at the last line printed.
+.LC
+( \fB.\fR )\|\fBput\fR \fIbuffer\fR abbr: \fBpu\fR
+.ZP
+Puts back
+previously
+.I deleted
+or
+.I yanked
+lines.
+Normally used with
+.I delete
+to effect movement of lines,
+or with
+.I yank
+to effect duplication of lines.
+If no
+.I buffer
+is specified, then the last
+.I deleted
+or
+.I yanked
+text is restored.*
+.FS
+* But no modifying commands may intervene between the
+.I delete
+or
+.I yank
+and the
+.I put,
+nor may lines be moved between files without using a named buffer.
+.FE
+By using a named buffer, text may be restored that was saved there at any
+previous time.
+.LC
+\fBquit\fR abbr: \fBq\fR
+.ZP
+Causes
+.I ex
+to terminate.
+No automatic write of the editor buffer to a file is performed.
+However,
+.I ex
+issues a warning message if the file has changed
+since the last
+.I write
+command was issued, and does not
+.I quit.\(dg
+.FS
+\(dg \fIEx\fR
+will also issue a diagnostic if there are more files in the argument
+list.
+.FE
+Normally, you will wish to save your changes, and you
+should give a \fIwrite\fR command;
+if you wish to discard them, use the \fBq!\fR command variant.
+.LC
+\fBq!\fR
+.ZP
+Quits from the editor, discarding changes to the buffer without complaint.
+.LC
+( \fB.\fR ) \fBread\fR \fIfile\fR abbr: \fBr\fR
+.ZP
+Places a copy of the text of the given file in the
+editing buffer after the specified line.
+If no
+.I file
+is given the current file name is used.
+The current file name is not changed unless there is none in which
+case
+.I file
+becomes the current name.
+The sensibility restrictions for the
+.I edit
+command apply here also.
+If the file buffer is empty and there is no current name then
+.I ex
+treats this as an
+.I edit
+command.
+.IP
+Address `0' is legal for this command and causes the file to be read at
+the beginning of the buffer.
+Statistics are given as for the
+.I edit
+command when the
+.I read
+successfully terminates.
+After a
+.I read
+the current line is the last line read.\(dd
+.FS
+\(dd Within
+.I open
+and
+.I visual
+the current line is set to the first line read rather than the last.
+.FE
+.LC
+( \fB.\fR ) \fBread\fR \fB!\fR\fIcommand\fR
+.ZP
+Reads the output of the command
+.I command
+into the buffer after the specified line.
+This is not a variant form of the command, rather a read
+specifying a
+.I command
+rather than a
+.I filename;
+a blank or tab before the \fB!\fR is mandatory.
+.LC
+\fBrecover \fIfile\fR
+.ZP
+Recovers
+.I file
+from the system save area.
+Used after a accidental hangup of the phone**
+.FS
+** The system saves a copy of the file you were editing only if you
+have made changes to the file.
+.FE
+or a system crash** or
+.I preserve
+command.
+Except when you use
+.I preserve
+you will be notified by mail when a file is saved.
+.LC
+\fBrewind\fR abbr: \fBrew\fR
+.ZP
+The argument list is rewound, and the first file in the list is edited.
+.LC
+\fBrew!\fR
+.ZP
+Rewinds the argument list discarding any changes made to the current buffer.
+.LC
+\fBset\fR \fIparameter\fR
+.ZP
+With no arguments, prints those options whose values have been
+changed from their defaults;
+with parameter
+.I all
+it prints all of the option values.
+.IP
+Giving an option name followed by a `?'
+causes the current value of that option to be printed.
+The `?' is unnecessary unless the option is Boolean valued.
+Boolean options are given values either by the form
+`set \fIoption\fR' to turn them on or
+`set no\fIoption\fR' to turn them off;
+string and numeric options are assigned via the form
+`set \fIoption\fR=value'.
+.IP
+More than one parameter may be given to
+.I set \|;
+they are interpreted left-to-right.
+.LC
+\fBshell\fR abbr: \fBsh\fR
+.IP
+A new shell is created.
+When it terminates, editing resumes.
+.LC
+\fBsource\fR \fIfile\fR abbr: \fBso\fR
+.IP
+Reads and executes commands from the specified file.
+.I Source
+commands may be nested.
+.LC
+( \fB.\fR , \fB.\fR ) \fBsubstitute\fR /\fIpat\fR\|/\fIrepl\fR\|/ \fIoptions\fR \fIcount\fR \fIflags\fR abbr: \fBs\fR
+.IP
+On each specified line, the first instance of pattern
+.I pat
+is replaced by replacement pattern
+.I repl.
+If the
+.I global
+indicator option character `g'
+appears, then all instances are substituted;
+if the
+.I confirm
+indication character `c' appears,
+then before each substitution the line to be substituted
+is typed with the string to be substituted marked
+with `\(ua' characters.
+By typing an `y' one can cause the substitution to be performed,
+any other input causes no change to take place.
+After a
+.I substitute
+the current line is the last line substituted.
+.IP
+Lines may be split by substituting
+new-line characters into them.
+The newline in
+.I repl
+must be escaped by preceding it with a `\e'.
+Other metacharacters available in
+.I pat
+and
+.I repl
+are described below.
+.LC
+.B stop
+.ZP
+Suspends the editor, returning control to the top level shell.
+If
+.I autowrite
+is set and there are unsaved changes,
+a write is done first unless the form
+.B stop !
+is used.
+This commands is only available where supported by the teletype driver
+and operating system.
+.LC
+( \fB.\fR , \fB.\fR ) \fBsubstitute\fR \fIoptions\fR \fIcount\fR \fIflags\fR abbr: \fBs\fR
+.ZP
+If
+.I pat
+and
+.I repl
+are omitted, then the last substitution is repeated.
+This is a synonym for the
+.B &
+command.
+.LC
+( \fB.\fR , \fB.\fR ) \fBt\fR \fIaddr\fR \fIflags\fR
+.ZP
+The
+.I t
+command is a synonym for
+.I copy .
+.LC
+\fBta\fR \fItag\fR
+.ZP
+The focus of editing switches to the location of
+.I tag,
+switching to a different line in the current file where it is defined,
+or if necessary to another file.\(dd
+.FS
+\(dd If you have modified the current file before giving a
+.I tag
+command, you must write it out; giving another
+.I tag
+command, specifying no
+.I tag
+will reuse the previous tag.
+.FE
+.IP
+The tags file is normally created by a program such as
+.I ctags,
+and consists of a number of lines with three fields separated by blanks
+or tabs. The first field gives the name of the tag,
+the second the name of the file where the tag resides, and the third
+gives an addressing form which can be used by the editor to find the tag;
+this field is usually a contextual scan using `/\fIpat\fR/' to be immune
+to minor changes in the file. Such scans are always performed as if
+.I nomagic
+was set.
+.PP
+The tag names in the tags file must be sorted alphabetically.
+.LC
+\fBunabbreviate\fR \fIword\fP abbr: \fBuna\fP
+.ZP
+Delete
+.I word
+from the list of abbreviations.
+.LC
+\fBundo\fR abbr: \fBu\fR
+.ZP
+Reverses the changes made in the buffer by the last
+buffer editing command.
+Note that
+.I global
+commands are considered a single command for the purpose of
+.I undo
+(as are
+.I open
+and
+.I visual.)
+Also, the commands
+.I write
+and
+.I edit
+which interact with the
+file system cannot be undone.
+.I Undo
+is its own inverse.
+.IP
+.I Undo
+always marks the previous value of the current line `\fB.\fR'
+as `\'\''.
+After an
+.I undo
+the current line is the first line restored
+or the line before the first line deleted if no lines were restored.
+For commands with more global effect
+such as
+.I global
+and
+.I visual
+the current line regains it's pre-command value after an
+.I undo.
+.LC
+\fBunmap\fR \fIlhs\fR
+.ZP
+The macro expansion associated by
+.I map
+for
+.I lhs
+is removed.
+.LC
+( 1 , $ ) \fBv\fR /\fIpat\fR\|/ \fIcmds\fR
+.ZP
+A synonym for the
+.I global
+command variant \fBg!\fR, running the specified \fIcmds\fR on each
+line which does not match \fIpat\fR.
+.LC
+\fBversion\fR abbr: \fBve\fR
+.ZP
+Prints the current version number of the editor
+as well as the date the editor was last changed.
+.LC
+( \fB.\fR ) \fBvisual\fR \fItype\fR \fIcount\fR \fIflags\fR abbr: \fBvi\fR
+.ZP
+Enters visual mode at the specified line.
+.I Type
+is optional and may be `\-' , `\(ua' or `\fB.\fR'
+as in the
+.I z
+command to specify the placement of the specified line on the screen.
+By default, if
+.I type
+is omitted, the specified line is placed as the first on the screen.
+A
+.I count
+specifies an initial window size; the default is the value of the option
+.I window.
+See the document
+.I "An Introduction to Display Editing with Vi"
+for more details.
+To exit this mode, type Q.
+.LC
+\fBvisual\fP file
+.br
+\fBvisual\fP +\fIn\fP file
+.ZP
+From visual mode,
+this command is the same as edit.
+.LC
+( 1 , $ ) \fBwrite\fR \fIfile\fR abbr: \fBw\fR
+.ZP
+Writes changes made back to \fIfile\fR, printing the number of lines and
+characters written.
+Normally \fIfile\fR is omitted and the text goes back where it came from.
+If a \fIfile\fR is specified, then text will be written to that file.*
+.FS
+* The editor writes to a file only if it is
+the current file and is
+.I edited ,
+if the file does not exist,
+or if the file is actually a teletype,
+.I /dev/tty,
+.I /dev/null.
+Otherwise, you must give the variant form \fBw!\fR to force the write.
+.FE
+If the file does not exist it is created.
+The current file name is changed only if there is no current file
+name; the current line is never changed.
+.IP
+If an error occurs while writing the current and
+.I edited
+file, the editor
+considers that there has been ``No write since last change''
+even if the buffer had not previously been modified.
+.LC
+( 1 , $ ) \fBwrite>>\fR \fIfile\fR abbr: \fBw>>\fR
+.ZP
+Writes the buffer contents at the end of
+an existing file.
+.IP
+.LC
+\fBw!\fR \fIname\fR
+.ZP
+Overrides the checking of the normal \fIwrite\fR command,
+and will write to any file which the system permits.
+.LC
+( 1 , $ ) \fBw\fR \fB!\fR\fIcommand\fR
+.ZP
+Writes the specified lines into
+.I command.
+Note the difference between \fBw!\fR which overrides checks and
+\fBw\ \ !\fR which writes to a command.
+.LC
+\fBwq\fR \fIname\fR
+.ZP
+Like a \fIwrite\fR and then a \fIquit\fR command.
+.LC
+\fBwq!\fR \fIname\fR
+.ZP
+The variant overrides checking on the sensibility of the
+.I write
+command, as \fBw!\fR does.
+.LC
+\fBxit\fP \fIname\fR
+.ZP
+If any changes have been made and not written, writes the buffer out.
+Then, in any case, quits.
+.LC
+( \fB.\fR , \fB.\fR )\|\fByank\fR \fIbuffer\fR \fIcount\fR abbr: \fBya\fR
+.ZP
+Places the specified lines in the named
+.I buffer,
+for later retrieval via
+.I put.
+If no buffer name is specified, the lines go to a more volatile place;
+see the \fIput\fR command description.
+.LC
+( \fB.+1\fR ) \fBz\fR \fIcount\fR
+.ZP
+Print the next \fIcount\fR lines, default \fIwindow\fR.
+.LC
+( \fB.\fR ) \fBz\fR \fItype\fR \fIcount\fR
+.ZP
+Prints a window of text with the specified line at the top.
+If \fItype\fR is `\-' the line is placed at the bottom; a `\fB.\fR' causes
+the line to be placed in the center.*
+A count gives the number of lines to be displayed rather than
+double the number specified by the \fIscroll\fR option.
+On a \s-2CRT\s0 the screen is cleared before display begins unless a
+count which is less than the screen size is given.
+The current line is left at the last line printed.
+.FS
+* Forms `z=' and `z\(ua' also exist; `z=' places the current line in the
+center, surrounds it with lines of `\-' characters and leaves the current
+line at this line. The form `z\(ua' prints the window before `z\-'
+would. The characters `+', `\(ua' and `\-' may be repeated for cumulative
+effect.
+On some v2 editors, no
+.I type
+may be given.
+.FE
+.LC
+\fB!\fR \fIcommand\fR\fR
+.ZP
+The remainder of the line after the `!' character is sent to a shell
+to be executed.
+Within the text of
+.I command
+the characters
+`%' and `#' are expanded as in filenames and the character
+`!' is replaced with the text of the previous command.
+Thus, in particular,
+`!!' repeats the last such shell escape.
+If any such expansion is performed, the expanded line will be echoed.
+The current line is unchanged by this command.
+.IP
+If there has been ``[No\ write]'' of the buffer contents since the last
+change to the editing buffer, then a diagnostic will be printed
+before the command is executed as a warning.
+A single `!' is printed when the command completes.
+.LC
+( \fIaddr\fR , \fIaddr\fR ) \fB!\fR \fIcommand\fR\fR
+.ZP
+Takes the specified address range and supplies it as
+standard input to
+.I command;
+the resulting output then replaces the input lines.
+.LC
+( $ ) \fB=\fR
+.ZP
+Prints the line number of the
+addressed line.
+The current line is unchanged.
+.KS
+.LC
+( \fB.\fR , \fB.\fR ) \fB>\fR \fIcount\fR \fIflags\fR
+.br
+( \fB.\fR , \fB.\fR ) \fB<\fR \fIcount\fR \fIflags\fR
+.IP
+Perform intelligent shifting on the specified lines;
+\fB<\fR shifts left and \fB>\fR shift right.
+The quantity of shift is determined by the
+.I shiftwidth
+option and the repetition of the specification character.
+Only white space (blanks and tabs) is shifted;
+no non-white characters are discarded in a left-shift.
+The current line becomes the last line which changed due to the
+shifting.
+.KE
+.LC
+\fB^D\fR
+.ZP
+An end-of-file from a terminal input scrolls through the file.
+The
+.I scroll
+option specifies the size of the scroll, normally a half screen of text.
+.LC
+( \fB.\fR+1 , \fB.\fR+1 )
+.br
+( \fB.\fR+1 , \fB.\fR+1 ) |
+.ZP
+An address alone causes the addressed lines to be printed.
+A blank line prints the next line in the file.
+.LC
+( \fB.\fR , \fB.\fR ) \fB&\fR \fIoptions\fR \fIcount\fR \fIflags\fR
+.ZP
+Repeats the previous
+.I substitute
+command.
+.LC
+( \fB.\fR , \fB.\fR ) \fB\s+2~\s0\fR \fIoptions\fR \fIcount\fR \fIflags\fR
+.ZP
+Replaces the previous regular expression with the previous
+replacement pattern from a substitution.
+.NH 1
+Regular expressions and substitute replacement patterns
+.NH 2
+Regular expressions
+.PP
+A regular expression specifies a set of strings of characters.
+A member of this set of strings is said to be
+.I matched
+by the regular expression.
+.I Ex
+remembers two previous regular expressions:
+the previous regular expression used in a
+.I substitute
+command
+and the previous regular expression used elsewhere
+(referred to as the previous \fIscanning\fR regular expression.)
+The previous regular expression
+can always be referred to by a null \fIre\fR, e.g. `//' or `??'.
+.NH 2
+Magic and nomagic
+.PP
+The regular expressions allowed by
+.I ex
+are constructed in one of two ways depending on the setting of
+the
+.I magic
+option.
+The
+.I ex
+and
+.I vi
+default setting of
+.I magic
+gives quick access to a powerful set of regular expression
+metacharacters.
+The disadvantage of
+.I magic
+is that the user must remember that these metacharacters are
+.I magic
+and precede them with the character `\e'
+to use them as ``ordinary'' characters.
+With
+.I nomagic,
+the default for
+.I edit,
+regular expressions are much simpler,
+there being only two metacharacters.
+The power of the other metacharacters is still available by preceding
+the (now) ordinary character with a `\e'.
+Note that `\e' is thus always a metacharacter.
+.PP
+The remainder of the discussion of regular expressions assumes
+that
+that the setting of this option is
+.I magic.\(dg
+.FS
+\(dg To discern what is true with
+.I nomagic
+it suffices to remember that the only
+special characters in this case will be `\(ua' at the beginning
+of a regular expression,
+`$' at the end of a regular expression,
+and `\e'.
+With
+.I nomagic
+the characters `\s+2~\s0' and `&' also lose their special meanings
+related to the replacement pattern of a substitute.
+.FE
+.NH 2
+Basic regular expression summary
+.PP
+The following basic constructs are used to construct
+.I magic
+mode regular expressions.
+.IP \fIchar\fR 15
+An ordinary character matches itself.
+The characters `\(ua' at the beginning of a line,
+`$' at the end of line,
+`*' as any character other than the first,
+`.', `\e', `[', and `\s+2~\s0' are not ordinary characters and
+must be escaped (preceded) by `\e' to be treated as such.
+.IP \fB\(ua\fR
+At the beginning of a pattern
+forces the match to succeed only at the beginning of a line.
+.IP \fB$\fR
+At the end of a regular expression forces the match to
+succeed only at the end of the line.
+.IP \&\fB.\fR
+Matches any single character except
+the new-line character.
+.IP \fB\e<\fR
+Forces the match
+to occur only at the beginning of a ``variable'' or ``word'';
+that is, either at the beginning of a line, or just before
+a letter, digit, or underline and after a character not one of
+these.
+.IP \fB\e>\fR
+Similar to `\e<', but matching the end of a ``variable''
+or ``word'', i.e. either the end of the line or before character
+which is neither a letter, nor a digit, nor the underline character.
+.IP \fB[\fIstring\fR]\fR
+Matches any (single) character in the class defined by
+.I string.
+Most characters in
+.I string
+define themselves.
+A pair of characters separated by `\-' in
+.I string
+defines the set of characters collating between the specified lower and upper
+bounds, thus `[a\-z]' as a regular expression matches
+any (single) lower-case letter.
+If the first character of
+.I string
+is an `\(ua' then the construct
+matches those characters which it otherwise would not;
+thus `[\(uaa\-z]' matches anything but a lower-case letter (and of course a
+newline).
+To place any of the characters
+`\(ua', `[', or `\-' in
+.I string
+you must escape them with a preceding `\e'.
+.NH 2
+Combining regular expression primitives
+.PP
+The concatenation of two regular expressions matches the leftmost and
+then longest string
+which can be divided with the first piece matching the first regular
+expression and the second piece matching the second.
+Any of the (single character matching) regular expressions mentioned
+above may be followed by the character `*' to form a regular expression
+which matches any number of adjacent occurrences (including 0) of characters
+matched by the regular expression it follows.
+.PP
+The character `\s+2~\s0' may be used in a regular expression,
+and matches the text which defined the replacement part
+of the last
+.I substitute
+command.
+A regular expression may be enclosed between the sequences
+`\e(' and `\e)' with side effects in the
+.I substitute
+replacement patterns.
+.NH 2
+Substitute replacement patterns
+.PP
+The basic metacharacters for the replacement pattern are
+`&' and `~'; these are
+given as `\e&' and `\e~' when
+.I nomagic
+is set.
+Each instance of `&' is replaced by the characters
+which the regular expression matched.
+The metacharacter `~' stands, in the replacement pattern,
+for the defining text of the previous replacement pattern.
+.PP
+Other metasequences possible in the replacement pattern
+are always introduced by the escaping character `\e'.
+The sequence `\e\fIn\fR' is replaced by the text matched
+by the \fIn\fR-th regular subexpression enclosed between
+`\e(' and `\e)'.\(dg
+.FS
+\(dg When nested, parenthesized subexpressions are present,
+\fIn\fR is determined by counting occurrences of `\e(' starting from the left.
+.FE
+The sequences `\eu' and `\el' cause the immediately following character in
+the replacement to be converted to upper- or lower-case respectively
+if this character is a letter.
+The sequences `\eU' and `\eL' turn such conversion on, either until
+`\eE' or `\ee' is encountered, or until the end of the replacement pattern.
+.de LC
+.br
+.sp .1i
+.ne 4
+.LP
+.ta 3i
+..
+.NH 1
+Option descriptions
+.PP
+.LC
+\fBautoindent\fR, \fBai\fR default: noai
+.ZP
+Can be used to ease the preparation of structured program text.
+At the beginning of each
+.I append ,
+.I change
+or
+.I insert
+command
+or when a new line is
+.I opened
+or created by an
+.I append ,
+.I change ,
+.I insert ,
+or
+.I substitute
+operation within
+.I open
+or
+.I visual
+mode,
+.I ex
+looks at the line being appended after,
+the first line changed
+or the line inserted before and calculates the amount of white space
+at the start of the line.
+It then aligns the cursor at the level of indentation so determined.
+.IP
+If the user then types lines of text in,
+they will continue to be justified at the displayed indenting level.
+If more white space is typed at the beginning of a line,
+the following line will start aligned with the first non-white character
+of the previous line.
+To back the cursor up to the preceding tab stop one can hit
+\fB^D\fR.
+The tab stops going backwards are defined at multiples of the
+.I shiftwidth
+option.
+You
+.I cannot
+backspace over the indent,
+except by sending an end-of-file with a \fB^D\fR.
+.IP
+Specially processed in this mode is a line with no characters added
+to it, which turns into a completely blank line (the white
+space provided for the
+.I autoindent
+is discarded.)
+Also specially processed in this mode are lines beginning with
+an `\(ua' and immediately followed by a \fB^D\fR.
+This causes the input to be repositioned at the beginning of the line,
+but retaining the previous indent for the next line.
+Similarly, a `0' followed by a \fB^D\fR
+repositions at the beginning but without
+retaining the previous indent.
+.IP
+.I Autoindent
+doesn't happen in
+.I global
+commands or when the input is not a terminal.
+.LC
+\fBautoprint\fR, \fBap\fR default: ap
+.ZP
+Causes the current line to be printed after each
+.I delete ,
+.I copy ,
+.I join ,
+.I move ,
+.I substitute ,
+.I t ,
+.I undo
+or
+shift command.
+This has the same effect as supplying a trailing `p'
+to each such command.
+.I Autoprint
+is suppressed in globals,
+and only applies to the last of many commands on a line.
+.LC
+\fBautowrite\fR, \fBaw\fR default: noaw
+.ZP
+Causes the contents of the buffer to be written to the current file
+if you have modified it and give a
+.I next,
+.I rewind,
+.I stop,
+.I tag,
+or
+.I !
+command, or a \fB^\(ua\fR (switch files) or \fB^]\fR (tag goto) command
+in
+.I visual.
+Note, that the
+.I edit
+and
+.I ex
+commands do
+.B not
+autowrite.
+In each case, there is an equivalent way of switching when autowrite
+is set to avoid the
+.I autowrite
+(\fIedit\fR
+for
+.I next ,
+.I rewind!
+for .I rewind ,
+.I stop!
+for
+.I stop ,
+.I tag!
+for
+.I tag ,
+.I shell
+for
+.I ! ,
+and
+\fB:e\ #\fR and a \fB:ta!\fR command from within
+.I visual).
+.LC
+\fBbeautify\fR, \fBbf\fR default: nobeautify
+.ZP
+Causes all control characters except tab, newline and form-feed
+to be discarded from the input.
+A complaint is registered the first time a
+backspace character is discarded.
+.I Beautify
+does not apply to command input.
+.LC
+\fBdirectory\fR, \fBdir\fR default: dir=/tmp
+.ZP
+Specifies the directory in which
+.I ex
+places its buffer file.
+If this directory in not
+writable, then the editor will exit abruptly when it fails to be
+able to create its buffer there.
+.LC
+\fBedcompatible\fR default: noedcompatible
+.ZP
+Causes the presence of absence of
+.B g
+and
+.B c
+suffixes on substitute commands to be remembered, and to be toggled
+by repeating the suffices. The suffix
+.B r
+makes the substitution be as in the
+.I ~
+command, instead of like
+.I &.
+.LC
+\fBerrorbells\fR, \fBeb\fR default: noeb
+.ZP
+Error messages are preceded by a bell.*
+.FS
+* Bell ringing in
+.I open
+and
+.I visual
+on errors is not suppressed by setting
+.I noeb.
+.FE
+If possible the editor always places the error message in a standout mode of the
+terminal (such as inverse video) instead of ringing the bell.
+.LC
+\fBhardtabs\fR, \fBht\fR default: ht=8
+.ZP
+Gives the boundaries on which terminal hardware tabs are set (or
+on which the system expands tabs).
+.LC
+\fBignorecase\fR, \fBic\fR default: noic
+.ZP
+All upper case characters in the text are mapped to lower case in regular
+expression matching.
+In addition, all upper case characters in regular expressions are mapped
+to lower case except in character class specifications.
+.LC
+\fBlisp\fR default: nolisp
+.ZP
+\fIAutoindent\fR indents appropriately for
+.I lisp
+code, and the \fB( ) { } [[\fR and \fB]]\fR commands in
+.I open
+and
+.I visual
+are modified to have meaning for \fIlisp\fR.
+.LC
+\fBlist\fR default: nolist
+.ZP
+All printed lines will be displayed (more) unambiguously,
+showing tabs and end-of-lines as in the
+.I list
+command.
+.LC
+\fBmagic\fR default: magic for \fIex\fR and \fIvi\fR\(dg
+.FS
+\(dg \fINomagic\fR for \fIedit\fR.
+.FE
+.ZP
+If
+.I nomagic
+is set, the number of regular expression metacharacters is greatly reduced,
+with only `\(ua' and `$' having special effects.
+In addition the metacharacters
+`~'
+and
+`&'
+of the replacement pattern are treated as normal characters.
+All the normal metacharacters may be made
+.I magic
+when
+.I nomagic
+is set by preceding them with a `\e'.
+.LC
+\fBmesg\fR default: mesg
+.ZP
+Causes write permission to be turned off to the terminal
+while you are in visual mode, if
+.I nomesg
+is set.
+.LC
+\fBmodeline\fR default: nomodeline
+.ZP
+If
+.I modeline
+is set, then the first 5 lines and the last five lines of the file
+will be checked for ex command lines and the comands issued.
+To be recognized as a command line, the line must have the string
+.B ex:
+or
+.B vi:
+preceeded by a tab or a space. This string may be anywhere in the
+line and anything after the
+.I :
+is interpeted as editor commands. This option defaults to off because
+of unexpected behavior when editting files such as
+.I /etc/passwd.
+.LC
+\fBnumber, nu\fR default: nonumber
+.ZP
+Causes all output lines to be printed with their
+line numbers.
+In addition each input line will be prompted for by supplying the line number
+it will have.
+.LC
+\fBopen\fR default: open
+.ZP
+If \fInoopen\fR, the commands
+.I open
+and
+.I visual
+are not permitted.
+This is set for
+.I edit
+to prevent confusion resulting from accidental entry to
+open or visual mode.
+.LC
+\fBoptimize, opt\fR default: optimize
+.ZP
+Throughput of text is expedited by setting the terminal
+to not do automatic carriage returns
+when printing more than one (logical) line of output,
+greatly speeding output on terminals without addressable
+cursors when text with leading white space is printed.
+.LC
+\fBparagraphs,\ para\fR default: para=IPLPPPQPP\0LIbp
+.ZP
+Specifies the paragraphs for the \fB{\fR and \fB}\fR operations in
+.I open
+and
+.I visual.
+The pairs of characters in the option's value are the names
+of the macros which start paragraphs.
+.LC
+\fBprompt\fR default: prompt
+.ZP
+Command mode input is prompted for with a `:'.
+.LC
+\fBredraw\fR default: noredraw
+.ZP
+The editor simulates (using great amounts of output), an intelligent
+terminal on a dumb terminal (e.g. during insertions in
+.I visual
+the characters to the right of the cursor position are refreshed
+as each input character is typed.)
+Useful only at very high speed.
+.LC
+\fBremap\fP default: remap
+.ZP
+If on, macros are repeatedly tried until they are unchanged.
+For example, if
+.B o
+is mapped to
+.B O ,
+and
+.B O
+is mapped to
+.B I ,
+then if
+.I remap
+is set,
+.B o
+will map to
+.B I ,
+but if
+.I noremap
+is set, it will map to
+.B O .
+.LC
+\fBreport\fR default: report=5\(dg
+.FS
+\(dg 2 for \fIedit\fR.
+.FE
+.ZP
+Specifies a threshold for feedback from commands.
+Any command which modifies more than the specified number of lines
+will provide feedback as to the scope of its changes.
+For commands such as
+.I global ,
+.I open ,
+.I undo ,
+and
+.I visual
+which have potentially more far reaching scope,
+the net change in the number of lines in the buffer is
+presented at the end of the command, subject to this same threshold.
+Thus notification is suppressed during a
+.I global
+command on the individual commands performed.
+.LC
+\fBscroll\fR default: scroll=\(12 window
+.ZP
+Determines the number of logical lines scrolled when an end-of-file
+is received from a terminal input in command mode,
+and the number of lines printed by a command mode
+.I z
+command (double the value of
+.I scroll ).
+.LC
+\fBsections\fR default: sections=SHNHH\0HU
+.ZP
+Specifies the section macros for the \fB[[\fR and \fB]]\fR operations
+in
+.I open
+and
+.I visual.
+The pairs of characters in the options's value are the names
+of the macros which start paragraphs.
+.LC
+\fBshell\fR, \fBsh\fR default: sh=/bin/sh
+.ZP
+Gives the path name of the shell forked for
+the shell escape command `!', and by the
+.I shell
+command.
+The default is taken from SHELL in the environment, if present.
+.LC
+\fBshiftwidth\fR, \fBsw\fR default: sw=8
+.ZP
+Gives the width a software tab stop,
+used in reverse tabbing with \fB^D\fR when using
+.I autoindent
+to append text,
+and by the shift commands.
+.LC
+\fBshowmatch, sm\fR default: nosm
+.ZP
+In
+.I open
+and
+.I visual
+mode, when a \fB)\fR or \fB}\fR is typed, move the cursor to the matching
+\fB(\fR or \fB{\fR for one second if this matching character is on the
+screen. Extremely useful with
+.I lisp.
+.LC
+\fBslowopen, slow\fR terminal dependent
+.ZP
+Affects the display algorithm used in
+.I visual
+mode, holding off display updating during input of new text to improve
+throughput when the terminal in use is both slow and unintelligent.
+See
+.I "An Introduction to Display Editing with Vi"
+for more details.
+.LC
+\fBtabstop,\ ts\fR default: ts=8
+.ZP
+The editor expands tabs in the input file to be on
+.I tabstop
+boundaries for the purposes of display.
+.LC
+\fBtaglength,\ tl\fR default: tl=0
+.ZP
+Tags are not significant beyond this many characters.
+A value of zero (the default) means that all characters are significant.
+.LC
+\fBtags\fR default: tags=tags /usr/lib/tags
+.ZP
+A path of files to be used as tag files for the
+.I tag
+command.
+A requested tag is searched for in the specified files, sequentially.
+By default, files called
+.B tags
+are searched for in the current directory and in /usr/lib
+(a master file for the entire system).
+.LC
+\fBterm\fR from environment TERM
+.ZP
+The terminal type of the output device.
+.LC
+\fBterse\fR default: noterse
+.ZP
+Shorter error diagnostics are produced for the experienced user.
+.LC
+\fBwarn\fR default: warn
+.ZP
+Warn if there has been `[No write since last change]' before a `!'
+command escape.
+.LC
+\fBwindow\fR default: window=speed dependent
+.ZP
+The number of lines in a text window in the
+.I visual
+command.
+The default is 8 at slow speeds (600 baud or less),
+16 at medium speed (1200 baud),
+and the full screen (minus one line) at higher speeds.
+.LC
+\fBw300,\ w1200\, w9600\fR
+.ZP
+These are not true options but set
+.B window
+only if the speed is slow (300), medium (1200), or high (9600),
+respectively.
+They are suitable for an EXINIT
+and make it easy to change the 8/16/full screen rule.
+.LC
+\fBwrapscan\fR, \fBws\fR default: ws
+.ZP
+Searches using the regular expressions in addressing
+will wrap around past the end of the file.
+.LC
+\fBwrapmargin\fR, \fBwm\fR default: wm=0
+.ZP
+Defines a margin for automatic wrapover of text during input in
+.I open
+and
+.I visual
+modes. See
+.I "An Introduction to Text Editing with Vi"
+for details.
+.LC
+\fBwriteany\fR, \fBwa\fR default: nowa
+.IP
+Inhibit the checks normally made before
+.I write
+commands, allowing a write to any file which the system protection
+mechanism will allow.
+.NH 1
+Acknowledgements
+.PP
+Chuck Haley contributed greatly to the early development of
+.I ex.
+Bruce Englar encouraged the redesign which led to
+.I ex
+version 1.
+Bill Joy wrote versions 1 and 2.0 through 2.7,
+and created the framework that users see in the present editor.
+Mark Horton added macros and other features and made the
+editor work on a large number of terminals and Unix systems.
diff --git a/share/doc/usd/10.exref/summary/Makefile b/share/doc/usd/10.exref/summary/Makefile
new file mode 100644
index 000000000000..143333f6ea2c
--- /dev/null
+++ b/share/doc/usd/10.exref/summary/Makefile
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+DOC= summary
+SRCS= ex.summary
+USE_TBL=
+
+.include <bsd.doc.mk>
diff --git a/share/doc/usd/10.exref/summary/ex.summary b/share/doc/usd/10.exref/summary/ex.summary
new file mode 100644
index 000000000000..83084a368ed8
--- /dev/null
+++ b/share/doc/usd/10.exref/summary/ex.summary
@@ -0,0 +1,730 @@
+.\" Copyright (c) 1980, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)ex.summary 8.3 (Berkeley) 8/18/96
+.\"
+.ds p \v'-0.2'.\v'+0.2'
+.ds U \s-2UNIX\s+2
+.ds c \v'-0.2':\v'+0.2'
+.nr LL 6.5i
+.lt 6.5i
+.ll 6.5i
+.ds CH
+.ds LF Computing Services, U.C. Berkeley
+.ds RF April 3, 1979
+.de SP
+.sp 1v
+..
+.nr PI 3n
+.nr PD 0
+.ND
+.ps 12
+.ft B
+.ce 1
+Ex/Edit Command Summary (Version 2.0)
+.sp 1
+.ft R
+.nr VS 11
+.nr PS 9
+.2C
+.PP
+.I Ex
+and
+.I edit
+are text editors, used for creating
+and modifying files of text on the \*U
+computer system.
+.I Edit
+is a variant of
+.I ex
+with features designed to
+make it less complicated
+to learn and use.
+In terms of command syntax and effect
+the editors are essentially identical,
+and this command summary applies to both.
+.PP
+The summary is meant as a quick reference
+for users already acquainted
+with
+.I edit
+or \fIex\fP.
+Fuller explanations of the editors are available
+in the documents
+.I
+Edit: A Tutorial
+.R
+(a self-teaching introduction) and the
+.I
+Ex Reference Manual
+.R
+(the comprehensive reference source for
+both \fIedit\fP and \fIex\fP).
+Both of these writeups are available in the
+Computing Services Library.
+.PP
+In the examples included with the
+summary, commands and text entered by
+the user are printed in \fBboldface\fR to
+distinguish them from responses printed
+by the computer.
+.sp 0.45v
+.LP
+.B
+The Editor Buffer
+.PP
+In order to perform its tasks
+the editor sets aside a temporary
+work space,
+called a \fIbuffer\fR,
+separate from the user's permanent
+file.
+Before starting to work on an existing
+file the editor makes a copy of it in the
+buffer, leaving the original untouched.
+All editing changes are made to the
+buffer copy, which must then
+be written back to the permanent
+file in order to update the
+old version.
+The buffer disappears
+at the end of the editing session.
+.sp 0.45v
+.LP
+.B
+Editing: Command and Text Input Modes
+.PP
+.R
+During an editing session there are
+two usual modes of operation:
+\fIcommand\fP mode and \fItext input\fP
+mode.
+(This disregards, for the moment,
+.I open
+and
+.I visual
+modes, discussed below.)
+In command mode, the editor issues a
+colon prompt (:)
+to show that it is ready to
+accept and execute a command.
+In text input mode, on the other hand, there is
+no prompt and the editor merely accepts text to
+be added to the buffer.
+Text input mode is initiated by the commands
+\fIappend\fP, \fIinsert\fP, and \fIchange\fP,
+and is terminated by typing a period as the
+first and only character on a line.
+.sp 0.45v
+.LP
+.B
+Line Numbers and Command Syntax
+.PP
+.R
+The editor keeps track of lines of text
+in the buffer by numbering them consecutively
+starting with 1 and renumbering
+as lines are added or deleted.
+At any given time the editor is positioned
+at one of these lines; this position is
+called the \fIcurrent line\fP.
+Generally, commands that change the
+contents of the buffer print the
+new current line at the end of their
+execution.
+.PP
+Most commands can be preceded by one or two
+line-number addresses which indicate the lines
+to be affected.
+If one number is given the command operates on
+that line only; if two, on an inclusive range
+of lines.
+Commands that can take line-number prefixes also
+assume default prefixes if none are given.
+The default assumed by each command is designed
+to make it convenient to use in many instances
+without any line-number prefix.
+For the most part, a command used without a
+prefix operates on the current line,
+though exceptions to this rule should be noted.
+The \fIprint\fP command
+by itself, for instance, causes
+one line, the current line, to be
+printed at the terminal.
+.PP
+The summary shows the number of line addresses
+that can be
+prefixed to each command as well as
+the defaults assumed if they are omitted.
+For example,
+.I (.,.)
+means that up to 2 line-numbers may be given,
+and that if none is given the
+command operates on the current line.
+(In the address prefix notation, ``.'' stands
+for the current line and ``$'' stands for
+the last line of the buffer.)
+If no such notation appears, no
+line-number prefix may be used.
+.PP
+Some commands take trailing
+information;
+only
+the more important instances of this
+are mentioned in the summary.
+.sp 0.25v
+.LP
+.B
+Open and Visual Modes
+.PP
+.R
+Besides command and text input modes,
+.I ex
+and
+.I edit
+provide on some CRT terminals other modes of editing,
+.I open
+and
+.I visual .
+In these modes the cursor can
+be moved to individual words
+or characters in a line.
+The commands then given are very different
+from the standard editor commands; most do not appear on the screen when
+typed.
+.I
+An Introduction to Display Editing with Vi
+.R
+provides a full discussion.
+.sp 0.25v
+.LP
+.B
+Special Characters
+.PP
+.R
+.fi
+Some characters take on special meanings
+when used in context searches
+and in patterns given to the \fIsubstitute\fP command.
+For \fIedit\fR, these are ``^'' and ``$'',
+meaning the beginning and end of a line,
+respectively.
+.I Ex
+has the following additional special characters:
+.B
+.ce 1
+\&. & * [ ] ~
+.R
+To use one of the special characters as its
+simple graphic representation
+rather than with its special meaning,
+precede it by a backslash (\\).
+The backslash always has a special meaning.
+.1C
+.TS
+cp10 cp10 cp10 cp10
+ltw(1.0i) lt2w(0.40i)fB ltw(3.0i) ltw(1.8i).
+Name Abbr Description Examples
+.sp 1.75
+(.)\fBappend a T{
+Begins text input mode,
+adding lines to the buffer after
+the line specified. Appending continues
+until ``.'' is typed alone at the
+beginning of a new line, followed by
+a carriage return. \fI0a\fR places
+lines at the beginning of the buffer.
+T} T{
+.nf
+\fR:\fBa
+Three lines of text
+are added to the buffer
+after the current line.
+\*p
+.R
+\*c
+.fi
+T}
+.SP
+\fR(.,.)\fBchange c T{
+Deletes indicated line(s) and
+initiates text input mode to
+replace them with new text which follows.
+New text is terminated the same way
+as with \fIappend\fR.
+T} T{
+.nf
+:\fB5,6c
+Lines 5 and 6 are
+deleted and replaced by
+these three lines.
+\*p
+.R
+\*c
+.fi
+T}
+.SP
+\fR(.,.)\fBcopy \fIaddr co T{
+Places a copy of the specified lines
+after the line indicated by \fIaddr\fR.
+The example places a copy of lines 8 through
+12, inclusive, after line 25.
+T} T{
+.nf
+\fR:\fB8,12co 25
+\fRLast line copied is printed
+\fR\*c
+.fi
+T}
+.SP
+\fR(.,.)\fBdelete d T{
+Removes lines from the buffer
+and prints the current line after the deletion.
+T} T{
+.nf
+\fR:\fB13,15d
+\fRNew current line is printed
+\*c
+.fi
+T}
+.TE
+.sp 0.5v
+.TS
+ltw(1.0i) lt2w(0.40i)fB ltw(3.0i) ltw(1.8i).
+T{
+\fBedit \fIfile\fP
+.br
+\fBedit! \fIfile\fP
+T} T{
+e
+.br
+e!
+T} T{
+.fi
+\fRClears the editor buffer and then
+copies into it the named \fIfile\fR,
+which becomes the current file.
+This is a way of shifting to a different
+file
+without leaving the editor.
+The editor issues a warning
+message if this command is used before
+saving changes
+made to the file already in the buffer;
+using the form \fBe!\fR overrides this protective mechanism.
+T} T{
+.nf
+\fR:\fBe ch10\fR
+No write since last change
+:\fBe! ch10\fR
+"ch10" 3 lines, 62 characters
+\*c
+.fi
+T}
+.SP
+\fBfile \fIname\fR f T{
+\fRIf followed by a \fIname\fR, renames
+the current file to \fIname\fR.
+If used without \fIname\fR, prints
+the name of the current file.
+T} T{
+.nf
+\fR:\fBf ch9
+\fR"ch9" [Modified] 3 lines ...
+:\fBf
+\fR"ch9" [Modified] 3 lines ...
+\*c
+.fi
+T}
+.SP
+(1,$)\fBglobal g \fBglobal/\fIpattern\fB/\fIcommands T{
+.nf
+:\fBg/nonsense/d
+\fR\*c
+.fi
+T}
+\fR(1,$)\fBglobal! g!\fR or \fBv T{
+Searches the entire buffer (unless a smaller
+range is specified by line-number prefixes) and
+executes \fIcommands\fR on every line with
+an expression matching \fIpattern\fR.
+The second form, abbreviated
+either \fBg!\fR or \fBv\fR,
+executes \fIcommands\fR on lines that \fIdo
+not\fR contain the expression \fIpattern\fR.
+T} \^
+.SP
+\fR(.)\fBinsert i T{
+Inserts new lines of text immediately before the specified line.
+Differs from
+.I append
+only in that text is placed before, rather than after, the indicated line.
+In other words, \fB1i\fR has the same effect as \fB0a\fR.
+T} T{
+.nf
+:\fB1i
+These lines of text will
+be added prior to line 1.
+\&.
+\fR:
+.fi
+T}
+.SP
+\fR(.,.+1)\fBjoin j T{
+Join lines together, adjusting white space (spaces
+and tabs) as necessary.
+T} T{
+.nf
+:\fB2,5j\fR
+Resulting line is printed
+:
+.fi
+T}
+.TE
+.bp
+.TS
+cp10 cp10 cp10 cp10
+ltw(1.0i) lt2w(0.40i)fB ltw(3.0i) ltw(1.8i).
+Name Abbr Description Examples
+.sp 1.75
+\fR(.,.)\fBlist l T{
+\fRPrints lines in a more
+unambiguous way than the \fIprint\fR
+command does. The end of a line,
+for example, is marked with a ``$'',
+and tabs printed as ``^I''.
+T} T{
+.nf
+:\fB9l
+\fRThis is line 9$
+\*c
+.fi
+T}
+.TE
+.sp 0.5v
+.TS
+ltw(1.0i) lt2w(0.40i)fB ltw(3.0i) ltw(1.8i).
+\fR(.,.)\fBmove \fIaddr\fB m T{
+\fRMoves the specified lines
+to a position after the line
+indicated by \fIaddr\fR.
+T} T{
+.nf
+\fR:\fB12,15m 25\fR
+New current line is printed
+\*c
+.fi
+T}
+.SP
+\fR(.,.)\fBnumber nu T{
+Prints each line preceded
+by its buffer line number.
+T} T{
+.nf
+\fR:\fBnu
+\0\0\fR10\0 This is line 10
+\*c
+.fi
+T}
+.SP
+\fR(.)\fBopen o T{
+Too involved to discuss here,
+but if you enter open mode
+accidentally, press
+the \s-2ESC\s0 key followed by
+\fBq\fR to
+get back into normal editor
+command mode.
+\fIEdit\fP is designed to
+prevent accidental use of
+the open command.
+T}
+.SP
+\fBpreserve pre T{
+Saves a copy of the current buffer contents as though the system had
+just crashed. This is for use in an emergency when a
+.I write
+command has failed and you don't know how else to save your work.\(dg
+T} T{
+.nf
+:\fBpreserve\fR
+File preserved.
+:
+.fi
+T}
+.SP
+\fR(.,.)\fBprint p Prints the text of line(s). T{
+.nf
+:\fB+2,+3p\fR
+The second and third lines
+after the current line
+:
+.fi
+T}
+.TE
+.FS
+.ll 6.5i
+\(dg You should seek assistance from a system administrator as soon as
+possible after saving a file with the
+.I preserve
+command, because the preserved copy of the file is saved in a
+directory used to store temporary files, and thus, the preserved
+copy may only be available for a short period of time.
+.FE
+.SP
+.nf
+.TS
+ltw(1.0i) lt2w(0.40i)fB ltw(3.0i) ltw(1.8i).
+T{
+.nf
+\fBquit
+quit!
+.fi
+T} T{
+.nf
+q
+q!
+T} T{
+.fi
+\fREnds the editing session.
+You will receive a
+warning if you have changed the buffer
+since last writing its contents
+to the file. In this event you
+must either type \fBw\fR to write,
+or type \fBq!\fR to exit from
+the editor without saving your changes.
+T} T{
+.nf
+\fR:\fBq
+\fRNo write since last change
+:\fBq!
+\fR%
+.fi
+T}
+.SP
+\fR(.)\fBread \fIfile\fP r T{
+.fi
+\fRPlaces a copy of \fIfile\fR in the
+buffer after the specified line.
+Address 0 is permissible and causes
+the copy of \fIfile\fR to be placed
+at the beginning of the buffer.
+The \fIread\fP command does not
+erase any text already in the buffer.
+If no line number is specified,
+\fIfile\fR is placed after the
+current line.
+T} T{
+.nf
+\fR:\fB0r newfile
+\fR"newfile" 5 lines, 86 characters
+\*c
+.fi
+T}
+.SP
+\fBrecover \fIfile\fP rec T{
+.fi
+Retrieves a copy of the editor buffer
+after a system crash, editor crash,
+phone line disconnection, or
+\fIpreserve\fR command.
+T}
+.SP
+\fR(.,.)\fBsubstitute s T{
+.nf
+\fBsubstitute/\fIpattern\fB/\fIreplacement\fB/
+substitute/\fIpattern\fB/\fIreplacement\fB/gc
+.fi
+\fRReplaces the first occurrence of \fIpattern\fR
+on a line
+with \fIreplacement\fP.
+Including a \fBg\fR after the command
+changes all occurrences of \fIpattern\fP
+on the line.
+The \fBc\fR option allows the user to
+confirm each substitution before it is
+made; see the manual for details.
+T} T{
+.nf
+:\fB3p
+\fRLine 3 contains a misstake
+:\fBs/misstake/mistake/
+\fRLine 3 contains a mistake
+\*c
+.fi
+T}
+.TE
+.bp
+.TS
+cp10 cp10 cp10 cp10
+ltw(1.0i) lt2w(0.40i)fB ltw(3.0i) ltw(1.8i).
+Name Abbr Description Examples
+.sp 1.75
+\fBundo u T{
+.fi
+\fRReverses the changes made in
+the buffer by the last buffer-editing
+command.
+Note that this example contains
+a notification about the number of
+lines affected.
+T} T{
+.nf
+\fR:\fB1,15d
+\fR15 lines deleted
+new line number 1 is printed
+:\fBu
+\fR15 more lines in file ...
+old line number 1 is printed
+\*c
+.fi
+T}
+.SP
+\fR(1,$)\fBwrite \fIfile\fR w T{
+.fi
+\fRCopies data from the buffer onto
+a permanent file. If no \fIfile\fR
+is named, the current filename
+is used.
+The file is automatically created
+if it does not yet exist.
+A response containing the number of
+lines and characters in the file
+indicates that the write
+has been completed successfully.
+The editor's built-in protections
+against overwriting existing files
+will in some circumstances
+inhibit a write.
+The form \fBw!\fR forces the
+write, confirming that
+an existing file is to be overwritten.
+T} T{
+.nf
+\fR:\fBw
+\fR"file7" 64 lines, 1122 characters
+:\fBw file8
+\fR"file8" File exists ...
+:\fBw! file8
+\fR"file8" 64 lines, 1122 characters
+\*c
+.fi
+T}
+\fR(1,$)\fBwrite! \fIfile\fP w! \^ \^
+.TE
+.sp 0.5v
+.TS
+ltw(1.0i) lt2w(0.40i)fB ltw(3.0i) ltw(1.8i).
+\fR(.)\fBz \fIcount\fP z T{
+.fi
+\fRPrints a screen full of text starting
+with the line indicated;
+or, if \fIcount\fR is specified,
+prints that number of lines.
+Variants of the \fIz\fR command
+are described in the manual.
+T}
+.SP
+\fB!\fIcommand T{
+.fi
+Executes the remainder of the line
+after \fB!\fR as a \*U command.
+The buffer is unchanged by this, and
+control is returned to the editor when
+the execution of \fIcommand\fR is complete.
+T} T{
+.nf
+\fR:\fB!date
+\fRFri Jun 9 12:15:11 PDT 1978
+!
+\*c
+.fi
+T}
+.SP
+\fRcontrol-d T{
+.fi
+Prints the next \fIscroll\fR of text,
+normally half of a screen. See the
+manual for details of the \fIscroll\fR
+option.
+T}
+.SP
+\fR(.+1)<cr> T{
+.fi
+An address alone followed by a carriage
+return causes the line to be printed.
+A carriage return by itself prints the
+line following the current line.
+T} T{
+.nf
+:\fR<cr>
+the line after the current line
+\*c
+.fi
+T}
+.TE
+.sp 0.5v
+.TS
+ltw(1.0i) lt2w(0.40i)fB ltw(3.0i) ltw(1.8i).
+\fB/\fIpattern\fB/ T{
+.fi
+\fRSearches for the next line in which
+\fIpattern\fR occurs and prints it.
+T} T{
+.nf
+\fR:\fB/This pattern/
+\fRThis pattern next occurs here.
+\*c
+.fi
+T}
+.SP
+\fB// T{
+Repeats the most recent search.
+T} T{
+.nf
+\fR:\fB//
+\fRThis pattern also occurs here.
+\*c
+.fi
+T}
+.SP
+\fB?\fIpattern\fB? T{
+Searches in the reverse direction
+for \fIpattern\fP.
+T}
+.SP
+\fB?? T{
+Repeats the most recent search,
+moving in the reverse direction
+through the buffer.
+T}
+.TE
diff --git a/share/doc/usd/11.vitut/Makefile b/share/doc/usd/11.vitut/Makefile
new file mode 100644
index 000000000000..5fbe9db441a1
--- /dev/null
+++ b/share/doc/usd/11.vitut/Makefile
@@ -0,0 +1,17 @@
+# From: @(#)Makefile 8.1 (Berkeley) 6/8/93
+# $FreeBSD$
+
+VOLUME= usd/11.edit
+SRCS= edittut.ms
+MACROS= -ms
+USE_TBL=
+
+# index for versatec is different from the one in edit.tut
+# because the fonts are different and entries reference page
+# rather than section numbers. if you have a typesetter
+# you should just use the index in edit.tut, and ignore editvindex.
+
+#editvindex:
+# ${TROFF} ${MACROS} -n22 edit.vindex
+
+.include <bsd.doc.mk>
diff --git a/share/doc/usd/11.vitut/edittut.ms b/share/doc/usd/11.vitut/edittut.ms
new file mode 100644
index 000000000000..8a9d66ede2e6
--- /dev/null
+++ b/share/doc/usd/11.vitut/edittut.ms
@@ -0,0 +1,2280 @@
+.\" Copyright (c) 1980, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)edittut.ms 8.3 (Berkeley) 8/18/96
+.\"
+.ll 6.5i
+.nr LL 6.5i
+.EH 'USD:11-%''Edit: A Tutorial'
+.OH 'Edit: A Tutorial''USD:11-%'
+.LP
+.ds u \s-2UNIX\s0
+.ND
+.sp 4
+.ce
+\f3\s+2Edit: A Tutorial\s0\f1
+.sp
+.ce 3
+.I
+Ricki Blau
+.sp
+James Joyce
+.R
+.sp
+.ce 3
+Computing Services
+University of California
+Berkeley, California 94720
+.sp 3
+.ce
+.I
+ABSTRACT
+.R
+.sp
+.LP
+This narrative introduction to the use of the text editor
+.I edit
+assumes no prior familiarity with computers or with text editing.
+Its aim is to lead the beginning \s-2UNIX\(dg\s+2 user through the
+.FS
+\(dgUNIX is a trademark of Bell Laboratories.
+.FE
+fundamental steps of writing and revising a file of text.
+Edit,
+a version of the text editor
+.I ex,
+was designed to provide an informative environment
+for new and casual users.
+.PP
+We welcome comments and suggestions about this tutorial
+and the \s-2UNIX\s+2 documentation in general.
+.sp .5v
+September 1981
+.bp
+.ll 6.5i
+.nr LL 6.5i
+.nr LT 6.5i
+.ds u \s-2UNIX\s0
+.ce
+\s+2\f3Contents\f1\s0
+.LP
+.nf
+Introduction\ \ \ 3
+.sp
+Session 1\ \ 4
+.in +.5i
+Making contact with \s-2UNIX\s+2\ \ \ 4
+Logging in\ \ 4
+Asking for \fIedit\fR\ \ \ 4
+The ``Command not found'' message\ \ \ 5
+A summary\ \ 5
+Entering text\ \ \ 5
+Messages from \fIedit\fR\ \ \ 5
+Text input mode\ \ \ 6
+Making corrections\ \ \ 6
+Writing text to disk\ \ \ 7
+Signing off\ \ 7
+.in -.5i
+.sp
+Session 2\ \ \ 8
+.in +.5i
+Adding more text to the file\ \ \ 8
+Interrupt\ \ \ 8
+Making corrections\ \ \ 8
+Listing what's in the buffer (p)\ \ \ 9
+Finding things in the buffer\ \ \ 9
+The current line\ \ \ 10
+Numbering lines (nu)\ \ \ 10
+Substitute command (s)\ \ \ 10
+Another way to list what's in the buffer (z)\ \ \ 11
+Saving the modified text\ \ \ 12
+.in -.5i
+.sp
+Session 3\ \ \ 13
+.in +.5i
+Bringing text into the buffer (e)\ \ \ 13
+Moving text in the buffer (m)\ \ \ 13
+Copying lines (copy)\ \ \ 14
+Deleting lines (d)\ \ \ 14
+A word or two of caution\ \ \ 15
+Undo (u) to the rescue\ \ \ 15
+More about the dot (.) and buffer end ($)\ \ \ 16
+Moving around in the buffer (+ and \-)\ \ \ 16
+Changing lines (c)\ \ \ 17
+.in -.5i
+.sp
+Session 4\ \ \ 18
+.in +.5i
+Making commands global (g)\ \ \ 18
+More about searching and substituting\ \ \ 19
+Special characters\ \ \ 19
+Issuing \s-2UNIX\s+2 commands from the editor\ \ \ 20
+Filenames and file manipulation\ \ \ 20
+The file (f) command\ \ \ 20
+Reading additional files (r)\ \ \ 21
+Writing parts of the buffer\ \ \ 21
+Recovering files\ \ \ 21
+Other recovery techniques\ \ \ 21
+Further reading and other information\ \ \ 22
+Using \fIex\fR\ \ \ 22
+.in -.5i
+.sp
+Index\ \ \ 23
+.bp
+.SH
+.ce
+\s+2Introduction\s0
+.PP
+Text editing using a terminal connected to a computer
+allows you to create, modify, and print text
+easily.
+A
+.I
+text editor
+.R
+is a program
+that assists you
+as you create and modify text.
+The text editor you will learn here is named
+.I edit.
+Creating text using edit is as easy as typing it
+on an electric typewriter.
+Modifying text involves telling the text editor
+what you want to add, change, or delete.
+You can review your text
+by typing a command
+to print the file contents
+as they are currently.
+Another program (which we do not discuss in this
+document), a text formatter,
+rearranges your text
+for you into ``finished form.''
+.PP
+These lessons assume no prior familiarity with computers
+or with text editing.
+They consist of a series of text editing sessions
+which lead you through the fundamental steps
+of creating and revising text.
+After scanning each lesson and before beginning the next,
+you should try the examples at a terminal to get a feeling
+for the actual process of text editing.
+If you set aside some time for experimentation,
+you will soon become familiar with using the
+computer to write and modify text.
+In addition to the actual use of the text editor,
+other features of \s-2UNIX\s0 will be very important to your work.
+You can begin to
+learn about these other features by
+reading one of the other tutorials
+that provide a general introduction to the system.
+You will be ready to proceed with this lesson as soon as
+you are familiar with (1) your terminal and its special keys,
+(2) how to login,
+(3) and the ways of correcting typing errors.
+Let's first define some terms:
+.sp .5
+.IP program 12
+A set of instructions, given to the computer,
+describing the sequence of steps the computer performs
+in order to accomplish a specific task.
+The task must be specific,
+such as balancing your checkbook
+or editing your text.
+A general task,
+such as working for world peace,
+is something we can all do,
+but not something we can currently write programs to do.
+.IP UNIX
+\s-2UNIX\s0 is a special type of program,
+called an operating system, that supervises the machinery
+and all other programs comprising the total
+computer system.
+.IP edit
+.I edit
+is the name of the \s-2UNIX\s0 text editor you will be learning to use,
+and is a program that aids you in writing or revising text.
+Edit was designed for beginning users,
+and is a simplified version of an editor named
+.I ex.
+.IP file
+Each \s-2UNIX\s0 account is allotted
+space for the permanent storage of information,
+such as programs, data or text.
+A file is a logical unit of data,
+for example, an essay, a program,
+or a chapter from a book,
+which is stored on a computer system.
+Once you create a file,
+it is kept until you instruct the system to remove it.
+You may create a file during one \s-2UNIX\s0 session,
+end the session,
+and return to use it at a later time.
+Files contain anything you choose to write and store in them.
+The sizes of files vary to suit your needs;
+one file might hold only a single number,
+yet another might contain
+a very long document or program.
+The only way to save
+information from one session to the next is to store it in a file,
+which you will learn in Session 1.
+.IP filename
+Filenames are used to distinguish one file from another,
+serving the same purpose as the labels of manila
+folders in a file cabinet.
+In order to write or access information in a file,
+you use the name of that file in a \s-2UNIX\s0 command,
+and the system will automatically locate the file.
+.IP disk
+Files are stored on an input/output device called a disk,
+which looks something like a stack of phonograph records.
+Each surface is coated with a material similar to that
+on magnetic recording tape,
+and information is recorded on it.
+.IP buffer
+A temporary work space, made available to the user
+for the duration of a session of text editing
+and used for creating and modifying
+the text file.
+We can think of the buffer as a blackboard that is
+erased after each class, where each session with the editor
+is a class.
+.bp
+.SH
+.ce 1
+\s+2Session 1\s0
+.sp 1
+.SH
+Making contact with \s-1UNIX\s0
+.PP
+To use the editor you must first make contact with the computer
+by logging in to \s-2UNIX\s0.
+We'll quickly review the standard \s-2UNIX\s0 login procedure
+for the two ways you can make contact:
+on a terminal that is directly linked to the computer,
+or over a telephone line where the computer answers your call.
+.SH
+Directly-linked terminals
+.PP
+Turn on your terminal and press the \s-1RETURN\s0 key.
+You are now ready to login.
+.SH
+Dial-up terminals
+.PP
+If your terminal connects with the computer over a telephone line,
+turn on the terminal, dial the system access number,
+and, when you hear a high-pitched tone, place the
+telephone handset in the acoustic coupler, if you are using one.
+You are now ready to login.
+.SH
+Logging in
+.PP
+The message inviting you to login is:
+.DS I 1i
+login:
+.DE
+.LP
+Type your login name, which identifies you to \s-2UNIX\s0,
+on the same line as the login message,
+and press \s-2RETURN\s+2.
+If the terminal you are using
+has both upper and lower case,
+.B
+be sure you enter your login name in lower case;
+.R
+otherwise \s-2UNIX\s0 assumes your terminal
+has only upper case and will not recognize lower case
+letters you may type.
+\s-2UNIX\s0 types ``login:'' and you reply
+with your login name, for example ``susan'':
+.DS I 1i
+login: \fBsusan\fR \fI(and press the \s-2RETURN\s0 key)\fR
+.DE
+(In the examples, input you would type appears in
+.B "bold face"
+to distinguish it from the responses from \s-2UNIX\s0.)
+.PP
+\s-2UNIX\s0 will next respond with a request for a password
+as an additional precaution to prevent
+unauthorized people from using your account.
+The password will not appear when you type it,
+to prevent others from seeing it.
+The message is:
+.DS I 1i
+Password: \fI(type your password and press \s-2RETURN\s+2)\fR
+.DE
+If any of the information you gave during the login
+sequence was mistyped or incorrect,
+\s-2UNIX\s0 will respond with
+.DS I 1i
+Login incorrect.
+.if t .sp .2v
+.if n .sp 1
+login:
+.DE
+in which case you should start the login process anew.
+Assuming that you have successfully
+logged in, \s-2UNIX\s0
+will print the message of the day and eventually will present
+you with a % at the beginning of a fresh line.
+The % is the \s-2UNIX\s0 prompt symbol
+which tells you that \s-2UNIX\s0 is ready to accept a command.
+.bd I 3
+.SH
+Asking for \fIedit\fP
+.fl
+.bd I
+.PP
+You are ready to tell \s-2UNIX\s0 that you
+want to work with edit, the text editor.
+Now is a convenient time to choose
+a name for the file of text you are about to create.
+To begin your editing session,
+type
+.B edit
+followed by a space and then the filename
+you have selected; for example, ``text''.
+After that,
+press the \s-2RETURN\s0 key and wait for edit's response:
+.DS I 1i
+% \fBedit text\fP \fI(followed by a \s-2RETURN\s+2)\fR
+"text" No such file or directory
+:
+.DE
+If you typed the command correctly,
+you will now be in communication with edit.
+Edit has set aside a buffer for use as
+a temporary working space during your current editing session.
+Since ``text'' is a new file we are about to create
+the editor was unable to find that file, which it
+confirms by saying:
+.DS I 1i
+"text" No such file or directory
+.DE
+On the next line appears edit's prompt ``:'',
+announcing that you are in \f2command mode\f1 and
+edit expects a command from you.
+You may now begin to create the new file.
+.SH
+The ``Command not found'' message
+.PP
+If you misspelled edit by typing, say, ``editor'',
+this might appear:
+.DS I 1i
+% \fBeditor\fP
+editor: Command not found
+%
+.DE
+Your mistake in calling edit ``editor'' was
+treated by \s-2UNIX\s0 as a request
+for a program named ``editor''.
+Since there is no program
+named ``editor'',
+\s-2UNIX\s0 reported that the program was ``not found''.
+A new % indicates that \s-2UNIX\s0 is ready for another command,
+and you may then enter the correct command.
+.SH
+A summary
+.PP
+Your exchange with \s-2UNIX\s0 as you logged in and made contact with edit
+should look something like this:
+.DS I 1i
+login: \fBsusan\fP
+Password:
+\&... A Message of General Interest ...
+% \fBedit text\fP
+"text" No such file or directory
+:
+.DE
+.SH
+Entering text
+.PP
+You may now begin entering text into the buffer.
+This is done by \fIappending\fP (or adding) text to whatever
+is currently in the buffer.
+Since there is nothing in the buffer at the moment,
+you are appending text to nothing;
+in effect,
+since you are adding text to nothing
+you are creating text.
+Most edit commands have two equivalent forms:
+a word that suggests what the command does,
+and a shorter abbreviation of that word.
+Many beginners find the full command names
+easier to remember at first,
+but once you are familiar with editing you may
+prefer to type the shorter abbreviations.
+The command to input text is ``append''.
+(It may be abbreviated ``a''.)
+Type
+.B append
+and press the \s-2RETURN\s0 key.
+.DS I 1i
+% \fBedit text
+\fR:\|\fBappend
+.R
+.DE
+.SH
+.bd I 3
+Messages from
+.I edit
+.fl
+.bd I
+.PP
+If you make a mistake in entering a command and
+type something that edit does not recognize,
+edit will respond with a message
+intended to help you diagnose your error.
+For example, if you misspell the command to input text by typing,
+perhaps, ``add'' instead of ``append'' or ``a'',
+you will receive this message:
+.DS I 1i
+:\|\fBadd\fR
+add: Not an editor command
+:
+.DE
+When you receive a diagnostic message,
+check what you typed in order to determine what
+part of your command confused edit.
+The message above means that edit
+was unable to recognize your mistyped command
+and, therefore, did not execute it.
+Instead, a new ``:''
+appeared to let you know that
+edit is again ready to execute a command.
+.SH
+Text input mode
+.PP
+By giving the command ``append'' (or using the abbreviation ``a''),
+you entered
+.I
+text input mode,
+.R
+also known as
+.I
+append mode.
+.R
+When you enter text input mode,
+edit stops sending you a prompt.
+You will not receive any prompts
+or error messages
+while in text input mode.
+You can enter
+pretty much anything you want on the lines.
+The lines are transmitted one by one to the buffer
+and held there during the editing session.
+You may append as much text as you want, and
+.I
+when you wish to stop entering text lines you should
+type a period as the only character on the line
+and press the \s-2RETURN\s0 key.
+.R
+When you type the period and press \s-2RETURN\s0,
+you signal that you want to stop appending text,
+and edit responds by allowing
+you to exit text input mode and reenter command mode.
+Edit will again
+prompt you for a command by printing ``:''.
+.PP
+Leaving append mode does not destroy the text in
+the buffer.
+You have to leave append
+mode to do any of the other kinds of editing,
+such as changing, adding, or printing text.
+If you type a period as the first character and
+type any other character on the same line,
+edit will believe you want to remain in append mode
+and will not let you out.
+As this can be very frustrating,
+be sure to type
+.B only
+the period and the \s-2RETURN\s0 key.
+.PP
+This is a good place to learn an important
+lesson about computers and text: a blank space is
+a character as far as a computer is concerned.
+If you so much as type a period followed by a blank
+(that is, type a period and then the space bar on the keyboard),
+you will remain in append mode with the last line of text
+being:
+.DS I 1i
+.B
+.ps +2
+\&.
+.ps -2
+.R
+.DE
+Let's say that you enter the lines
+(try to type
+.B exactly
+what you see, including ``thiss''):
+.DS I 1i
+.B
+This is some sample text.
+And thiss is some more text.
+Text editing is strange, but nice.
+\&.
+.R
+.DE
+The last line is the period followed by a \s-2RETURN\s0
+that gets you out of append mode.
+.SH
+Making corrections
+.PP
+If you have read a general introduction to \s-2UNIX\s0,
+you will recall that it is possible to erase individual
+letters that you have typed.
+This is done by typing the designated erase character
+as many times as there are characters
+you want to erase.
+.PP
+The usual erase character varies from place to place and
+user to user. Often it
+is the backspace (control-H),
+so you can correct typing errors
+in the line you are typing
+by holding down the \s-1CTRL\s+1 key
+and typing the ``H'' key. (Sometimes it is the DEL key.)
+If you type the erase character
+you will notice
+that the terminal backspaces in the line you are on.
+You can backspace over your error,
+and then type what you want to be the rest of the line.
+.PP
+If you make a bad start
+in a line
+and would like to begin again,
+you can either backspace to the beginning of the line
+or you can use the at-sign ``@'' to erase everything on the line:
+.DS I 1i
+.B
+Text edtiing is strange, but@
+Text editing is strange, but nice.
+.R
+.fl
+.bd S
+.DE
+When you type the at-sign (@), you erase
+the entire line typed so far
+and are given a fresh line to type on.
+You may immediately begin to retype the line.
+This, unfortunately, does not work after you type the
+line and press \s-2RETURN\s+2.
+To make corrections in lines that have been completed,
+it is necessary to use the editing commands
+covered in the next sessions.
+.SH
+Writing text to disk
+.PP
+You are now ready to edit the text. One common operation
+is to write the text to disk as a file for safekeeping
+after the session is over.
+This is the only way to save information from one session to the next,
+since the editor's buffer is temporary and will last only until the
+end of the editing session.
+Learning how to write a file to disk is second in
+importance only to entering the text.
+To write the contents of the buffer to a disk
+file, use the command ``write''
+(or its abbreviation ``w''):
+.DS I 1i
+:\|\fBwrite
+.R
+.DE
+Edit will copy the contents of the buffer to a disk file.
+If the file does not yet exist,
+a new file will be created automatically
+and the presence of a ``[New file]'' will be noted.
+The newly-created file will be given the name specified when
+you entered the editor, in this case ``text''.
+To confirm that the disk file has been successfully written,
+edit will repeat the filename and give
+the number of lines and the total
+number of characters in the file.
+The buffer remains unchanged by the ``write'' command.
+All of the lines that were written to disk will still be
+in the buffer,
+should you want to modify or add to them.
+.PP
+Edit must have a name for the file to be written.
+If you forgot to indicate the name of the file
+when you began to edit,
+edit will print in response to your write command:
+.DS I 1i
+No current filename
+.DE
+If this happens, you can specify the filename in a new write command:
+.DS I 1i
+:\|\fBwrite text
+.R
+.DE
+After the ``write'' (or ``w''), type a space and then the name of the file.
+.SH
+Signing off
+.PP
+We have done enough for this first lesson on using the
+\s-2UNIX\s0 text editor, and are ready to quit the session with edit.
+To do this we type ``quit'' (or ``q'') and press \s-2RETURN\s+2:
+.DS I 1i
+:\|\fBwrite
+.R
+"text" [New file] 3 lines, 90 characters
+:\|\fBquit\fR
+%
+.DE
+The % is from \s-2UNIX\s0 to tell you that your session with edit is
+over and you may command \s-2UNIX\s0 further.
+Since we want
+to end the entire session at the terminal, we also need to
+exit from \s-2UNIX\s0.
+In response to the \s-2UNIX\s0 prompt of ``\|%\|''
+type the command
+.DS I 1i
+%\|\fBlogout\fR
+.DE
+This will end your session with \s-2UNIX\s0, and will ready the
+terminal for the next user.
+It is always important to type \fBlogout\fR at the end of a session
+to make absolutely sure no one
+could accidentally stumble into your abandoned
+session and thus gain access to your files,
+tempting even the most honest of souls.
+.sp 1
+.PP
+This is the end of the first session on \s-2UNIX\s0 text editing.
+.bp
+.TL
+Session 2
+.sp
+.PP
+Login with \s-2UNIX\s0 as in the first session:
+.DS I 1i
+login: \fBsusan\fP \fI(carriage return)\fR
+Password: \fI(give password and carriage return)\fR
+.if t .sp .2v
+.if n .sp 1
+\&... A Message of General Interest ...
+%
+.DE
+When you indicate you want to edit,
+you can specify the name of the file you worked on last time.
+This will
+start edit working, and it will fetch the contents of the
+file into the buffer, so that you can resume editing the same file.
+When edit has copied the file into the buffer, it
+will repeat its name and tell
+you the number of lines and characters it contains.
+Thus,
+.DS I 1i
+.B
+% edit text
+.R
+"text" 3 lines, 90 characters
+:
+.DE
+means you asked edit to fetch
+the file named ``text'' for editing,
+causing it to copy the
+90 characters of text into the buffer.
+Edit awaits
+your further instructions,
+and indicates this by its prompt character, the colon (:).
+In this session, we will append more text to our file,
+print the contents of the buffer, and learn to change the text of a line.
+.SH
+Adding more text to the file
+.PP
+If you want to add more to the end of your
+text you may do so by using the append command to enter text input mode.
+When ``append'' is the first command
+of your editing session,
+the lines you enter
+are placed at the end of the buffer.
+Here we'll use the abbreviation for the append command, ``a'':
+.DS I 1i
+:\|\fBa
+This is text added in Session 2.
+It doesn't mean much here, but
+it does illustrate the editor.
+\|\fB\s+2\&.\s-2
+.R
+.DE
+You may recall that once you enter append mode
+using the ``a'' (or ``append'') command,
+you need to type a line containing only a period (.)
+to exit append mode.
+.SH
+Interrupt
+.PP
+Should you press the \s-2RUB\s+2 key (sometimes labelled \s-2DELETE\s+2)
+while working with edit,
+it will send this message to you:
+.DS I 1i
+Interrupt
+:
+.DE
+Any command that edit might be executing
+is terminated by rub or delete,
+causing edit to prompt you for a new command.
+If you are appending text at the time,
+you will exit from append mode
+and be expected to give another command.
+The line of text you were typing
+when the append command was interrupted
+will not be entered into the buffer.
+.SH
+Making corrections
+.PP
+If while typing the line you hit an incorrect key,
+recall that
+you may delete the incorrect character
+or cancel the entire line of input by erasing in the usual way.
+Refer either
+to the last few pages of Session 1
+if you need to review
+the procedures for making a correction.
+The most important idea to remember is that
+erasing a character or cancelling a line must be done
+before you press the \s-2RETURN\s+2 key.
+.SH
+Listing what's in the buffer (p)
+.PP
+Having appended text to what you wrote in Session 1,
+you might want to see all the lines in the buffer.
+To print the contents of the buffer, type the command:
+.DS I 1i
+:\|\fB1,$p
+.R
+.DE
+The ``1''\(dg
+.FS
+\(dgThe numeral ``one'' is the top left-most key,
+and should not be confused with the letter ``el''.
+.FE
+stands for line 1 of the buffer,
+the ``$'' is a special symbol designating the last line
+of the buffer,
+and ``p'' (or \fBprint\fR) is the command to print from line 1
+to the end of the buffer.
+The command ``1,$p'' gives you:
+.DS I 1i
+This is some sample text.
+And thiss is some more text.
+Text editing is strange, but nice.
+This is text added in Session 2.
+It doesn't mean much here, but
+it does illustrate the editor.
+.DE
+Occasionally, you may accidentally
+type a character that can't be printed,
+which can be done by striking a key
+while the \s-2CTRL\s0 key is pressed.
+In printing lines, edit uses a special notation to
+show the existence of non-printing characters.
+Suppose you had introduced the non-printing character ``control-A''
+into the word ``illustrate''
+by accidently pressing the \s-2CTRL\s0 key while
+typing ``a''.
+This can happen on many terminals
+because the \s-2CTRL\s+2 key and the ``A'' key
+are beside each other.
+If your finger presses between the two keys,
+control-A results.
+When asked to print the contents of the buffer,
+edit would display
+.DS I 1i
+it does illustr^Ate the editor.
+.DE
+To represent the control-A, edit shows ``^A''.
+The sequence ``^'' followed by a capital
+letter stands for the one character
+entered by holding down the \s-2CTRL\s0 key and typing the letter
+which appears after the ``^''.
+We'll soon discuss the commands that can be used
+to correct this typing error.
+.PP
+In looking over the text we see that
+``this'' is typed as ``thiss'' in the second line,
+a deliberate error so we can learn to make corrections.
+Let's correct the spelling.
+.SH
+Finding things in the buffer
+.PP
+In order to change something in the buffer we first need to
+find it.
+We can find ``thiss'' in the text we have
+entered by looking at a listing
+of the lines.
+Physically speaking, we search the lines
+of text looking for ``thiss'' and stop searching when
+we have found it.
+The way to tell edit to search for something
+is to type it inside slash marks:
+.DS I 1i
+:\|\fB/thiss/
+.R
+.DE
+By typing
+.B /thiss/
+and pressing \s-1RETURN\s0,
+you instruct edit to search for ``thiss''.
+If you ask edit to look for a pattern of characters
+which it cannot find in the buffer,
+it will respond ``Pattern not found''.
+When edit finds
+the characters ``thiss'', it will print the line of text
+for your inspection:
+.DS I 1i
+And thiss is some more text.
+.DE
+Edit is now positioned in the buffer at the
+line it just printed,
+ready to make a change in the line.
+.bp
+.SH
+The current line
+.PP
+Edit keeps track of the line in the buffer where it is located
+at all times during an editing session.
+In general, the line that has been most recently
+printed, entered, or changed
+is the current location in the buffer.
+The editor is prepared to make changes
+at the current location in the buffer,
+unless you direct it to another location.
+.PP
+In particular,
+when you bring a file into the buffer,
+you will be located at the last line in the file,
+where the editor left off copying the lines
+from the file to the buffer.
+If your first editing command is ``append'',
+the lines you enter are added
+to the end of the file,
+after the current line \(em
+the last line in the file.
+.PP
+You can refer to your current location in the buffer by the
+symbol
+period (.) usually known by the name ``dot''.
+If you type ``.'' and carriage
+return you will be instructing edit to print the current line:
+.DS I 1i
+:\|\fB\s+2\&.\s-2
+.R
+And thiss is some more text.
+.DE
+.PP
+If you want to know the number of the current line,
+you can type
+.B \&.=
+and press \s-2RETURN\s+2,
+and edit will respond with the line number:
+.DS I 1i
+:\|\fB\s+2.\s-2=
+.R
+2
+.DE
+If you type the number of any line and press \s-2RETURN\s+2,
+edit will position you at that line and
+print its contents:
+.DS I 1i
+:\|\fB2
+.R
+And thiss is some more text.
+.DE
+You should experiment with these commands
+to gain experience in using them to make changes.
+.SH
+Numbering lines (nu)
+.PP
+The
+.B
+number (nu)
+.R
+command is similar to print,
+giving both the number and the text of each printed line.
+To see the number and the text of the current line type
+.DS I 1i
+:\|\fBnu
+.R
+\0\0\0\0\02\0\0And thiss is some more text.
+.DE
+Note that the shortest abbreviation for the number command is
+``nu'' (and not ``n'', which is used for a different command).
+You may specify a range of lines
+to be listed by the number command in the same way that lines
+are specified for print.
+For example, \f31,$nu\f1 lists all lines in the buffer with their
+corresponding line numbers.
+.SH
+Substitute command (s)
+.PP
+Now that you have found the misspelled word,
+you can change it from ``thiss'' to ``this''.
+As far as edit is concerned,
+changing things is a matter of
+substituting one thing for another.
+As
+.I a
+stood for
+.I append,
+so
+.I s
+stands for
+.I substitute.
+We will use the abbreviation ``s'' to reduce the chance
+of mistyping the substitute command.
+This command will instruct edit to make the change:
+.DS I 1i
+\f32s/thiss/this/\f1
+.DE
+We first indicate the line to be changed, line 2,
+and then
+type an ``s'' to indicate we want
+edit to make a substitution.
+Inside the first set of slashes
+are the characters that we want to change,
+followed by the characters to replace them,
+and then a closing slash mark.
+To summarize:
+.DS I 1i
+2s/ \fIwhat is to be changed\fR / \fIwhat to change it to \fR/
+.DE
+If edit finds an exact match of the characters to be
+changed it will make the change
+.B only
+in the first occurrence of the characters.
+If it does not find the characters
+to be changed, it will respond:
+.DS I 1i
+Substitute pattern match failed
+.DE
+indicating that your instructions could not be carried out.
+When edit does find the characters that you want to change,
+it will make the substitution and automatically print
+the changed line, so that you can check that the correct substitution
+was made.
+In the example,
+.DS I 1i
+:\|\fB2s/thiss/this/
+.R
+And this is some more text.
+.DE
+line 2 (and line 2 only) will be searched for the characters
+``thiss'', and when the first exact match is found, ``thiss''
+will be changed to ``this''.
+Strictly speaking, it was not necessary above to
+specify the number of the line to be changed.
+In
+.DS I 1i
+:\|\fBs/thiss/this/
+.R
+.DE
+edit will assume that we mean to change
+the line where we are currently located (``.'').
+In this case,
+the command without a line number would have produced the same result
+because we were already located
+at the line we wished to change.
+.PP
+For another illustration of the substitute command,
+let us choose the line:
+.DS I 1i
+Text editing is strange, but nice.
+.DE
+You can make this line a bit more positive
+by taking out the characters ``strange, but\ '' so the line
+reads:
+.DS I 1i
+Text editing is nice.
+.DE
+A command that will first position edit at the desired line
+and then make the substitution is:
+.DS I 1i
+:\|\fB/strange/s/strange, but //
+.R
+.DE
+.LP
+What we have done here is combine our search with
+our substitution.
+Such combinations are perfectly legal,
+and speed up editing quite a bit
+once you get used to them.
+That is, you do not necessarily have to use
+line numbers to identify a line to edit.
+Instead, you may identify the line you want to change
+by asking edit to search for a specified pattern of letters
+that occurs in that line.
+The parts of the above command are:
+.in +1i
+.TS
+l l.
+\fB/strange/\fP tells edit to find the characters ``strange'' in the text
+\fBs\fP tells edit to make a substitution
+\fB/strange, but //\fP substitutes nothing at all for the characters ``strange, but ''
+.TE
+.in -1i
+.PP
+You should note the space after ``but'' in ``/strange, but /''.
+If you do not indicate that the space is to be taken out,
+your line will read:
+.DS I 1i
+.if t Text editing is nice.
+.if n Text editing is nice.
+.DE
+which looks a little funny
+because of the extra space between ``is'' and ``nice''.
+Again, we realize from this that a blank space
+is a real character to a computer, and in editing text
+we need to be aware of spaces
+within a line just as we would be aware of an ``a'' or
+a ``4''.
+.SH
+Another way to list what's in the buffer (z)
+.PP
+Although the print command is useful for looking at specific lines
+in the buffer,
+other commands may be more convenient for
+viewing large sections of text.
+You can ask to see a screen full of text at a time
+by using the command
+.B z.
+If you type
+.DS I 1i
+:\|\fB1z
+.R
+.DE
+edit will start with line 1 and continue printing lines,
+stopping either when the screen of
+your terminal is full
+or when the last line in the buffer has been printed.
+If you want to read the next segment of text, type the command
+.DS I 1i
+:\|\fBz
+.DE
+If no starting line number is given for the z command,
+printing will start at the ``current'' line, in this case the
+last line printed.
+Viewing lines in the buffer one screen full at a time
+is known as \fIpaging\fR.
+Paging can also be used to print
+a section of text on a hard-copy terminal.
+.SH
+Saving the modified text
+.PP
+This seems to be a good place to pause in our work,
+and so we should end the second session.
+If you (in haste) type ``q'' to quit the session
+your dialogue with edit will be:
+.DS I 1i
+:\|\fBq
+.R
+No write since last change (:quit! overrides)
+:
+.DE
+This is edit's warning that you have not written
+the modified contents of the buffer to disk.
+You run the risk of losing the work you did
+during the editing session since you typed the latest write
+command.
+Because in this lesson we have not written
+to disk at all, everything we have done
+would have been lost
+if edit had obeyed the \fBq\fR command.
+If you did not want to save the work done during
+this editing session, you would have to type ``q!''
+or (``quit!'')
+to confirm that you indeed wanted to end the session
+immediately,
+leaving the file as it was
+after the most recent ``write'' command.
+However,
+since you want to save what
+you have edited, you need to type:
+.DS I 1i
+:\|\fBw
+.R
+"text" 6 lines, 171 characters
+.DE
+and then follow with the commands to quit and logout:
+.DS I 1i
+:\|\fBq
+% \fBlogout\fR
+.DE
+and hang up the phone or turn off the terminal when
+\s-2UNIX\s0 asks for a name.
+Terminals connected to the port selector
+will stop after the logout command,
+and pressing keys on the keyboard will do nothing.
+.sp 1
+.PP
+This is the end of the second session on \s-2UNIX\s0 text editing.
+.bp
+.TL
+Session 3
+.SH
+Bringing text into the buffer (e)
+.PP
+Login to \s-2UNIX\s0 and make contact with edit.
+You should try to login without
+looking at the notes, but if you must
+then by all means do.
+.PP
+Did you remember to give the name of the file
+you wanted to edit?
+That is, did you type
+.DS I 1i
+% \fBedit text\fR
+.DE
+or simply
+.DS I 1i
+% \fBedit\fR
+.DE
+Both ways get you in contact with edit, but the first way
+will bring a copy of the file named ``text'' into
+the buffer.
+If you did forget to tell edit the name of your file,
+you can get it into the buffer by
+typing:
+.DS I 1i
+:\|\fBe text
+.R
+"text" 6 lines, 171 characters
+.DE
+The command
+.B edit,
+which may be abbreviated \fBe\fR,
+tells edit that you want
+to erase anything that might already be in
+the buffer and bring a copy of the file ``text'' into the buffer
+for editing.
+You may also use the edit (e) command to change files in
+the middle of an editing session,
+or to give edit the name of a new file that you want to create.
+Because the edit command clears the buffer,
+you will receive a warning if you try to edit a new file without
+having saved a copy of the old file.
+This gives you a chance to write the contents of the buffer to disk
+before editing the next file.
+.SH
+Moving text in the buffer (m)
+.PP
+Edit allows you to move lines of text
+from one location in the buffer to another
+by means of the
+.B move
+(\fBm\fR) command.
+The first two examples are for illustration only,
+though after you have read this Session
+you are welcome to return to them for practice.
+The command
+.DS I 1i
+:\|\fB2,4m$
+.R
+.DE
+directs edit to move lines 2, 3, and 4
+to the end of the buffer ($).
+The format for the move command is that you specify
+the first line to be moved, the last line to be moved,
+the move command ``m'', and the line after which
+the moved text is to be placed.
+So,
+.DS I 1i
+:\|\fB1,3m6
+.R
+.DE
+would instruct edit to move lines 1 through 3 (inclusive)
+to a location after line 6 in the buffer.
+To move only one line, say, line 4,
+to a location in the buffer after line 5,
+the command would be ``4m5''.
+.PP
+Let's move some text using the command:
+.DS I 1i
+:\|\fB5,$m1
+.R
+2 lines moved
+it does illustrate the editor.
+.DE
+After executing a command that moves more than one line of the buffer,
+edit tells how many lines were affected by the move
+and prints the last moved line for your inspection.
+If you want to see more than just the last line,
+you can then
+use the print (p), z, or number (nu) command to view more text.
+The buffer should now contain:
+.DS I 1i
+This is some sample text.
+It doesn't mean much here, but
+it does illustrate the editor.
+And this is some more text.
+Text editing is nice.
+This is text added in Session 2.
+.DE
+You can restore the original order by typing:
+.DS I 1i
+:\|\fB4,$m1
+.R
+.DE
+or, combining context searching and the move command:
+.DS I 1i
+:\|\fB/And this is some/,/This is text/m/This is some sample/
+.R
+.DE
+(Do not type both examples here!)
+The problem with combining context searching
+with the move command
+is that your chance of making a typing error
+in such a long command is greater than
+if you type line numbers.
+.SH
+Copying lines (copy)
+.PP
+The
+.B copy
+command
+is used to make a second copy of specified lines,
+leaving the original lines where they were.
+Copy
+has the same format as the move command, for example:
+.DS I 1i
+:\|\fB2,5copy $
+.R
+.DE
+makes a copy of lines 2 through 5,
+placing the added lines after the buffer's end ($).
+Experiment with the copy command
+so that you can become familiar with how it works.
+Note that the shortest abbreviation for copy is
+\f3co\f1 (and
+not the letter ``c'', which has another meaning).
+.SH
+Deleting lines (d)
+.PP
+Suppose you want to delete
+the line
+.DS I 1i
+This is text added in Session 2.
+.DE
+from the buffer.
+If you know the number of the line to be deleted,
+you can type
+that number followed by
+\fBdelete\fR or \fBd\fR.
+This example deletes line 4,
+which is ``This is text added in Session 2.''
+if you typed the commands
+suggested so far.
+.DS I 1i
+:\|\fB4d
+.R
+It doesn't mean much here, but
+.DE
+Here ``4'' is the number of the line to be deleted,
+and ``delete'' or ``d'' is the command to delete the line.
+After executing the delete command,
+edit prints the line that has become the current line (``.'').
+.PP
+If you do not happen to know the line number
+you can search for the line and then delete it using this
+sequence of commands:
+.DS I 1i
+:\|\fB/added in Session 2./
+.R
+This is text added in Session 2.
+:\|\fBd
+.R
+It doesn't mean much here, but
+.DE
+The ``/added in Session 2./''
+asks edit to locate and print
+the line containing the indicated text,
+starting its search at the current line
+and moving line by line
+until it finds the text.
+Once you are sure that you have correctly specified the line
+you want to delete,
+you can enter the delete (d) command.
+In this case it is not necessary to
+specify a line number before the ``d''.
+If no line number is given,
+edit deletes the current line (``.''),
+that is, the line found by our search.
+After the deletion, your buffer should contain:
+.DS I 1i
+This is some sample text.
+And this is some more text.
+Text editing is nice.
+It doesn't mean much here, but
+it does illustrate the editor.
+And this is some more text.
+Text editing is nice.
+This is text added in Session 2.
+It doesn't mean much here, but
+.DE
+To delete both lines 2 and 3:
+.DS I 1i
+And this is some more text.
+Text editing is nice.
+.DE
+you type
+.DS I 1i
+:\|\f32,3d\f1
+2 lines deleted
+.DE
+which specifies the range of lines from 2 to 3,
+and the operation on those lines \(em ``d'' for delete.
+If you delete more than one line
+you will receive a message
+telling you the number of lines deleted,
+as indicated in the example above.
+.PP
+The previous example assumes that you know the line numbers for
+the lines to be deleted.
+If you do not you might combine the search command
+with the delete command:
+.DS I 1i
+:\|\fB/And this is some/,/Text editing is nice./d
+.R
+.DE
+.SH
+A word or two of caution
+.PP
+In using the search function to locate lines to
+be deleted you should be
+.B
+absolutely sure
+.R
+the characters you give as the basis for the search
+will take edit to the line you want deleted.
+Edit will search for the first
+occurrence of the characters starting from where
+you last edited \-
+that is, from the line you see printed if you type dot (.).
+.PP
+A search based on too few
+characters may result in the wrong lines being deleted,
+which edit will do as easily as if you had meant it.
+For this reason, it is usually safer
+to specify the search and then delete in two separate steps,
+at least until you become familiar enough with using the editor
+that you understand how best to specify searches.
+For a beginner it is not a bad idea to double-check
+each command before pressing \s-2RETURN\s+2 to send the command on its way.
+.SH
+Undo (u) to the rescue
+.PP
+The
+.B
+undo (u)
+.R
+command has the ability to
+reverse the effects of the last command that changed the buffer.
+To undo the previous command, type
+``u'' or ``undo''.
+Undo can rescue
+the contents of the buffer from many an unfortunate mistake.
+However, its powers are not unlimited,
+so it is still wise to be reasonably
+careful about the commands you give.
+.PP
+It is possible to undo only commands which
+have the power to change the buffer \(em for example,
+delete, append, move, copy, substitute, and even undo itself.
+The commands write (w) and edit (e), which interact with disk files,
+cannot be undone, nor can commands that do not change
+the buffer, such as print.
+Most importantly,
+the
+.B only
+command that can be reversed by undo
+is the
+last ``undo-able'' command you typed.
+You can use control-H and @ to change
+commands while you are typing them,
+and undo to reverse the effect of the commands
+after you have typed them and pressed \s-2RETURN\s+2.
+.PP
+To illustrate,
+let's issue an undo command.
+Recall that the last buffer-changing command we gave deleted
+the lines formerly numbered 2 and 3.
+Typing undo at this moment will reverse the effects
+of the deletion, causing those two lines to be
+replaced in the buffer.
+.DS I 1i
+:\|\fBu
+.R
+2 more lines in file after undo
+And this is some more text.
+.DE
+Here again, edit informs you if the command affects more
+than one line,
+and prints
+the text of the line which is now ``dot'' (the current line).
+.SH
+More about the dot (.) and buffer end ($)
+.PP
+The function assumed by the symbol dot depends on its context.
+It can be used:
+.IP
+1. to exit from append mode; we type dot (and only a dot) on
+a line and press \s-2RETURN\s+2;
+.IP
+2. to refer to the line we are at in the buffer.
+.LP
+Dot can also be combined with the equal sign to get
+the number of the line currently being edited:
+.DS I 1i
+:\|\fB\&.=
+.R
+.DE
+If we type ``\fB.\fR='' we are asking for the number of the line,
+and if we type ``\fB.\fR'' we are asking for the text of the line.
+.PP
+In this editing session and the last, we used the dollar
+sign to indicate the end of the buffer
+in commands such as print, copy, and move.
+The dollar sign as a command asks edit to print the last
+line in the buffer.
+If the dollar sign is combined with the equal sign (\f3$=\f1)
+edit will print the line number corresponding to the
+last line in the buffer.
+.PP
+``\fB.\fR'' and ``$'', then, represent line numbers.
+Whenever appropriate, these symbols can be used in
+place of line numbers in commands.
+For example
+.DS I 1i
+:\|\fB\s+2.\s-2,$d
+.R
+.DE
+instructs edit to delete all lines from the current line (\fB.\fR)
+to the end of the buffer.
+.SH
+Moving around in the buffer (+ and \-)
+.PP
+When you are editing
+you often want
+to go back and re-read a previous line.
+You could specify a context search for a line you want to
+read if you remember some of its text,
+but if you simply want to see what was written a few, say 3, lines
+ago, you can type
+.DS I 1i
+\-3p
+.DE
+This tells edit to move back to a position 3 lines
+before the current line (.)
+and print that line.
+You can move forward in the buffer similarly:
+.DS I 1i
++2p
+.DE
+instructs edit to print the line that is 2
+ahead of your current position.
+.PP
+You may use ``+'' and ``\-'' in any command where edit
+accepts line numbers.
+Line numbers specified with ``+'' or ``\-''
+can be combined to print a range of lines.
+The command
+.DS I 1i
+:\|\fB\-1,+2copy$
+.R
+.DE
+makes a copy of 4 lines: the current line, the line before it,
+and the two after it.
+The copied lines will be placed after the last line
+in the buffer ($),
+and the original lines referred to by ``\-1'' and ``+2''
+remain where they are.
+.PP
+Try typing only ``\-''; you will move back one line just as
+if you had typed ``\-1p''.
+Typing the command ``+'' works similarly.
+You might also try typing a few plus or minus signs in a row
+(such as ``+++'') to see edit's response.
+Typing \s-2RETURN\s+2 alone on a line is the equivalent
+of typing ``+1p''; it will move you one line ahead in the buffer
+and print that line.
+.PP
+If you are at the last line of the buffer and try
+to move further ahead, perhaps by typing a ``+'' or
+a carriage return alone on the line,
+edit will remind you that you are at the end of the buffer:
+.sp
+.nf
+.ti 1i
+At end-of-file
+.br
+or
+.ti 1i
+Not that many lines in buffer
+.fi
+.LP
+Similarly, if you try to move to a position before the first line,
+edit will print one of these messages:
+.sp
+.nf
+.ti 1i
+Nonzero address required on this command
+.br
+or
+.ti 1i
+Negative address \- first buffer line is 1
+.fi
+.LP
+The number associated with a buffer line is the line's ``address'',
+in that it can be used to locate the line.
+.SH
+Changing lines (c)
+.PP
+You can also delete certain lines and
+insert new text in their place.
+This can be accomplished easily with the
+.B "change (c)"
+command.
+The change command instructs edit to delete specified lines
+and then switch to text input mode to
+accept the text that will replace them.
+Let's say you want to change the first two lines in the buffer:
+.DS I 1i
+This is some sample text.
+And this is some more text.
+.DE
+to read
+.DS I 1i
+This text was created with the \s-2UNIX\s0 text editor.
+.DE
+To do so, you type:
+.DS I 1i
+:\|\fB1,2c
+.R
+2 lines changed
+.B
+This text was created with the \s-2UNIX\s0 text editor.
+\s+2\&.\s-2
+.R
+:
+.DE
+In the command
+.B 1,2c
+we specify that we want to change
+the range of lines beginning with 1 and ending with 2
+by giving line numbers as with the print command.
+These lines will be deleted.
+After you type \s-2RETURN\s+2 to end the change command,
+edit notifies you if more than one line will be changed
+and places you in text input mode.
+Any text typed on the following lines will be inserted into
+the position where lines were deleted by the change command.
+.B
+You will remain in text input mode until you exit in the usual way,
+by typing a period alone on a line.
+.R
+Note that the number of lines added to the buffer need not be
+the same as the number of lines deleted.
+.sp 1
+.PP
+This is the end of the third session on text editing with \s-2UNIX\s0.
+.bp
+.SH
+.ce 1
+\s+2Session 4\s0
+.sp
+.PP
+This lesson covers several topics, starting with
+commands that apply throughout the buffer,
+characters with special meanings,
+and how to issue \s-2UNIX\s0 commands while in the editor.
+The next topics deal with files:
+more on reading and writing,
+and methods of recovering files lost in a crash.
+The final section suggests sources of further information.
+.SH
+Making commands global (g)
+.PP
+One disadvantage to the commands we have used for
+searching or substituting is that if you
+have a number of instances of a word to change
+it appears that you have to type the command
+repeatedly, once for
+each time the change needs to be made.
+Edit, however, provides a way to make commands
+apply to the entire contents of the buffer \-
+the
+.B
+global (g)
+.R
+command.
+.PP
+To print all lines
+containing a certain sequence of characters
+(say, ``text'')
+the command is:
+.DS I 1i
+:\|\fBg/text/p
+.R
+.DE
+The ``g'' instructs edit to
+make a global search for all lines
+in the buffer containing the characters ``text''.
+The ``p'' prints the lines found.
+.PP
+To issue a global command, start by typing a ``g'' and then a search
+pattern identifying
+the lines to be affected.
+Then, on the same line, type the command to be
+executed for the identified lines.
+Global substitutions are frequently useful.
+For example,
+to change all instances of the word ``text'' to the word ``material''
+the command would be a combination of the global search and the
+substitute command:
+.DS I 1i
+:\|\fBg/text/s/text/material/g
+.R
+.DE
+Note the ``g'' at the end of the global command,
+which instructs edit to change
+each and every instance of ``text'' to ``material''.
+If you do not type the ``g'' at the end of the command
+only the
+.I first
+instance of ``text'' \fIin each line\fR will be changed
+(the normal result of the substitute command).
+The ``g'' at the end of the command is independent of the ``g''
+at the beginning.
+You may give a command such as:
+.DS I 1i
+:\|\fB5s/text/material/g
+.R
+.DE
+to change every instance of ``text'' in line 5 alone.
+Further, neither command will change ``text'' to ``material''
+if ``Text'' begins with a capital rather than a lower-case
+.I t.
+.PP
+Edit does not automatically print the lines modified by a
+global command.
+If you want the lines to be printed, type a ``p''
+at the end of the global command:
+.DS I 1i
+:\|\fBg/text/s/text/material/gp
+.R
+.DE
+You should be careful
+about using the global command in combination with any other \-
+in essence, be sure of what you are telling edit to do
+to the entire buffer.
+For example,
+.DS I 1i
+:\|\fBg/ /d
+.R
+72 less lines in file after global
+.DE
+will delete every line containing a blank anywhere in it.
+This could adversely affect
+your document, since most lines have spaces between words
+and thus would be deleted.
+After executing the global command,
+edit will print a warning if the command added or deleted more than one line.
+Fortunately, the undo command can reverse
+the effects of a global command.
+You should experiment with the global command
+on a small file of text to see what it can do for you.
+.SH
+More about searching and substituting
+.PP
+In using slashes to identify a character string
+that we want to search for or change,
+we have always specified the exact characters.
+There is a less tedious way to
+repeat the same string of characters.
+To change ``text'' to ``texts'' we may type either
+.DS I 1i
+:\|\fB/text/s/text/texts/
+.R
+.DE
+as we have done in the past,
+or a somewhat abbreviated command:
+.DS I 1i
+:\|\fB/text/s//texts/
+.R
+.DE
+In this example, the characters to be changed
+are not specified \-
+there are no characters, not even a space,
+between the two slash marks
+that indicate what is to be changed.
+This lack of characters between the slashes
+is taken by the editor to mean
+``use the characters we last searched for as the characters to be changed.''
+.PP
+Similarly, the last context search may be repeated
+by typing a pair of slashes with nothing between them:
+.DS I 1i
+:\|\fB/does/
+.R
+It doesn't mean much here, but
+:\|\fB//
+.R
+it does illustrate the editor.
+.DE
+(You should note that the search command found the characters ``does''
+in the word ``doesn't'' in the first search request.)
+Because no characters are specified for the second search,
+the editor scans the buffer for the next occurrence of the
+characters ``does''.
+.PP
+Edit normally searches forward through the buffer,
+wrapping around from the end of the buffer to the beginning,
+until the specified character string is found.
+If you want to search in the reverse direction,
+use question marks (?) instead of slashes
+to surround the characters you are searching for.
+.PP
+It is also possible
+to repeat the last substitution
+without having to retype the entire command.
+An ampersand (&) used as a command
+repeats the most recent substitute command,
+using the same search and replacement patterns.
+After altering the current line by typing
+.DS I 1i
+:\|\fBs/text/texts/
+.R
+.DE
+you type
+.DS I 1i
+:\|\fB/text/&
+.R
+.DE
+or simply
+.DS I 1i
+:\|\fB//&
+.R
+.DE
+to make the same change on the next line in the buffer
+containing the characters ``text''.
+.SH
+Special characters
+.PP
+Two characters have special meanings when
+used in specifying searches: ``$'' and ``^''.
+``$'' is taken by the editor to mean ``end of the line''
+and is used to identify strings
+that occur at the end of a line.
+.DS I 1i
+:\|\fBg/text.$/s//material./p
+.R
+.DE
+tells the editor to search for all lines ending in ``text.''
+(and nothing else, not even a blank space),
+to change each final ``text.'' to ``material.'',
+and print the changed lines.
+.PP
+The symbol ``^'' indicates the beginning of a line.
+Thus,
+.DS I 1i
+:\|\fBs/^/1. /
+.R
+.DE
+instructs the editor to insert ``1.'' and a space at the beginning
+of the current line.
+.PP
+The characters ``$'' and ``^'' have special meanings only in the context
+of searching.
+At other times, they are ordinary characters.
+If you ever need to search for a character that has a special meaning,
+you must indicate that the
+character is to lose temporarily
+its special significance by typing another special character,
+the backslash (\\), before it.
+.DS I 1i
+:\|\fBs/\\\\\&$/dollar/
+.R
+.DE
+looks for the character ``$'' in the current
+line and replaces it by the word ``dollar''.
+Were it not for the backslash, the ``$'' would have represented
+``the end of the line'' in your search
+rather than the character ``$''.
+The backslash retains its special significance
+unless it is preceded by another backslash.
+.SH
+Issuing \s-2UNIX\s0 commands from the editor
+.PP
+After creating several files with the editor,
+you may want to delete files
+no longer useful to you or ask for a list of your files.
+Removing and listing files are not functions of the editor,
+and so they require the use of \s-2UNIX\s0 system commands
+(also referred to as ``shell'' commands, as
+``shell'' is the name of the program that processes \s-2UNIX\s0 commands).
+You do not need to quit the editor to execute a \s-2UNIX\s0 command
+as long as you indicate that it
+is to be sent to the shell for execution.
+To use the \s-2UNIX\s0 command
+.B rm
+to remove the file named ``junk'' type:
+.DS I 1i
+:\|\fB!rm junk
+.R
+!
+:
+.DE
+The exclamation mark (!)
+indicates that the rest of the line is to be processed as a shell command.
+If the buffer contents have not been written since the last change,
+a warning will be printed before the command is executed:
+.DS I 1i
+[No write since last change]
+.DE
+The editor prints a ``!'' when the command is completed.
+Other tutorials describe useful features of the system,
+of which an editor is only one part.
+.SH
+Filenames and file manipulation
+.PP
+Throughout each editing session,
+edit keeps track of the name of the file being edited as the
+.I "current filename."
+Edit remembers as the current filename the name given
+when you entered the editor.
+The current filename changes whenever the edit (e) command
+is used to specify a new file.
+Once edit has recorded a current filename,
+it inserts that name into any command where a filename has been omitted.
+If a write command does not specify a file,
+edit, as we have seen, supplies the current filename.
+If you are editing a file named ``draft3'' having 283 lines in it,
+you can have the editor write onto a different file
+by including its name in the write command:
+.DS I 1i
+:\fB\|w chapter3
+.R
+"chapter3" [new file] 283 lines, 8698 characters
+.DE
+The current filename remembered by the editor
+.I
+will not be changed as a result of the write command.
+.R
+Thus, if the next write command
+does not specify a name,
+edit will write onto the current file (``draft3'')
+and not onto the file ``chapter3''.
+.SH
+The file (f) command
+.PP
+To ask for the current filename, type
+.B file
+(or
+.B f ).
+In response, the editor provides current information about the buffer,
+including the filename, your current position, the number of
+lines in the buffer,
+and the percent of the distance through the file
+your current location is.
+.DS I 1i
+:\|\fBf
+.R
+"text" [Modified] line 3 of 4 --75%--
+.DE
+.\"The expression ``[Edited]'' indicates that the buffer contains
+.\"either the editor's copy of the existing file ``text''
+.\"or a file which you are just now creating.
+If the contents of the buffer have changed
+since the last time the file was written,
+the editor will tell you that the file has been ``[Modified]''.
+After you save the changes by writing onto a disk file,
+the buffer will no longer be considered modified:
+.DS I 1i
+:\|\fBw
+.R
+"text" 4 lines, 88 characters
+:\|\fBf
+.R
+"text" line 3 of 4 --75%--
+.DE
+.SH
+Reading additional files (r)
+.PP
+The
+\f3read (r)\f1 command allows you to add the contents of a file
+to the buffer
+at a specified location,
+essentially copying new lines
+between two existing lines.
+To use it, specify the line after which the new text will be placed,
+the \f3read (r)\f1 command,
+and then the name of the file.
+If you have a file named ``example'', the command
+.DS I 1i
+:\|\fB$r example
+.R
+"example" 18 lines, 473 characters
+.DE
+reads the file ``example''
+and adds it to the buffer after the last line.
+The current filename is not changed by the read command.
+.SH
+Writing parts of the buffer
+.PP
+The
+.B
+write (w)
+.R
+command can write all or part of the buffer
+to a file you specify.
+We are already familiar with
+writing the entire contents of the
+buffer to a disk file.
+To write only part of the buffer onto a file,
+indicate the beginning and ending lines before the write command,
+for example
+.DS I 1i
+:\|\fB45,$w ending
+.R
+.DE
+Here all lines from 45 through the end of the buffer
+are written onto the file named
+.I ending.
+The lines remain in the buffer
+as part of the document you are editing,
+and you may continue to edit the entire buffer.
+Your original file is unaffected
+by your command to write part of the buffer
+to another file.
+Edit still remembers whether you have saved changes to the buffer
+in your original file or not.
+.SH
+Recovering files
+.PP
+Although it does not happen very often,
+there are times \s-2UNIX\s+2 stops working
+because of some malfunction.
+This situation is known as a \fIcrash\fR.
+Under most circumstances,
+edit's crash recovery feature
+is able to save work to within a few lines of changes
+before a crash (or an accidental phone hang up).
+If you lose the contents of an editing buffer in a system crash,
+you will normally receive mail when you login that gives
+the name of the recovered file.
+To recover the file,
+enter the editor and type the command
+.B recover
+(\fBrec\fR),
+followed by the name of the lost file.
+For example,
+to recover the buffer for an edit session
+involving the file ``chap6'', the command is:
+.DS I 1i
+.R
+:\|\fBrecover chap6
+.R
+.DE
+Recover is sometimes unable to save the entire buffer successfully,
+so always check the contents of the saved buffer carefully
+before writing it back onto the original file.
+For best results,
+write the buffer to a new file temporarily
+so you can examine it without risk to the original file.
+Unfortunately,
+you cannot use the recover command
+to retrieve a file you removed
+using the shell command \f3rm\f1.
+.SH
+Other recovery techniques
+.PP
+If something goes wrong when you are using the editor,
+it may be possible to save your work by using the command
+.B preserve
+(\fBpre\fR),
+which saves the buffer as if the system had crashed.
+If you are writing a file and you get the message
+``Quota exceeded'', you have tried to use more disk storage
+than is allotted to your account.
+.I
+Proceed with caution
+.R
+because it is likely that only a part
+of the editor's buffer is now present in the file you tried to write.
+In this case you should use the shell escape from the editor (!)
+to remove some files you don't need and try to write
+the file again.
+If this is not possible and you cannot find someone to help you,
+enter the command
+.DS I 1i
+:\|\fBpreserve
+.R
+.DE
+and wait for the reply,
+.DS I 1i
+File preserved.
+.DE
+If you do not receive this reply,
+seek help immediately.
+Do not simply leave the editor.
+If you do, the buffer will be lost,
+and you may not be able to save your file.
+If the reply is ``File preserved.''
+you can leave the editor
+(or logout)
+to remedy the situation.
+After a preserve, you can use the recover command
+once the problem has been corrected,
+or the \fB\-r\fR option of the edit command
+if you leave the editor and want to return.
+.PP
+If you make an undesirable change to the buffer
+and type a write command before discovering your mistake,
+the modified version will replace any previous version of the file.
+Should you ever lose a good version of a document in this way,
+do not panic and leave the editor.
+As long as you stay in the editor,
+the contents of the buffer remain accessible.
+Depending on the nature of the problem,
+it may be possible
+to restore the buffer to a more complete
+state with the undo command.
+After fixing the damaged buffer, you can again write the file
+to disk.
+.SH
+Further reading and other information
+.PP
+Edit is an editor designed for beginning and casual users.
+It is actually a version of a more powerful editor called
+.I ex.
+These lessons are intended to introduce you to the editor
+and its more commonly-used commands.
+We have not covered all of the editor's commands,
+but a selection of commands
+that should be sufficient to accomplish most of your editing tasks.
+You can find out more about the editor in the
+.I
+Ex Reference Manual,
+.R
+which is applicable to both
+.I ex
+and
+.I edit.
+One way to become familiar with the manual is to begin by reading
+the description of commands that you already know.
+.bd I 3
+.SH
+Using
+.I ex
+.fl
+.bd I
+.PP
+As you become more experienced with using the editor,
+you may still find that edit continues to meet your needs.
+However, should you become interested in using
+.I ex,
+it is easy to switch.
+To begin an editing session with
+.I ex,
+use the name
+.B ex
+in your command instead of
+.B edit.
+.PP
+Edit commands also work in
+.I ex,
+but the editing environment is somewhat different.
+You should be aware of a few differences
+between
+.I ex
+and
+.I edit.
+In edit, only the characters ``^'', ``$'', and ``\\'' have
+special meanings in searching the buffer
+or indicating characters to be changed by a substitute command.
+Several additional characters have special
+meanings in ex, as described in the
+.I
+Ex Reference Manual.
+.R
+Another feature of the edit environment prevents users from
+accidently entering two alternative modes of editing,
+.I open
+and
+.I visual,
+in which
+the editor behaves quite differently from normal command mode.
+If you are using ex and you encounter strange behavior,
+you may have accidently entered open mode by typing ``o''.
+Type the \s-2ESC\s0 key and then a ``Q''
+to get out of open or visual mode and back into
+the regular editor command mode.
+The document
+.I
+An Introduction to Display Editing with Vi\|\|
+.R
+provide full details of visual mode.
+.bp
+.SH
+.ce 1
+\s+2Index\s0
+.LP
+.sp 2
+.2C
+.nf
+addressing, \fIsee\fR line numbers
+ampersand, 20
+append mode, 6-7
+append (a) command, 6, 7, 9
+``At end of file'' (message), 18
+backslash (\\), 21
+buffer, 3
+caret (^), 10, 20
+change (c) command, 18
+command mode, 5-6
+``Command not found'' (message), 6
+context search, 10-12, 19-21
+control characters (``^'' notation), 10
+control-H, 7
+copy (co) command, 15
+corrections, 7, 16
+current filename, 21
+current line (\|.\|), 11, 17
+delete (d) command, 15-16
+dial-up, 5
+disk, 3
+documentation, 3, 23
+dollar ($), 10, 11, 17, 20-21
+dot (\f3\|.\|\f1) 11, 17
+edit (text editor), 3, 5, 23
+edit (e) command, 5, 9, 14
+editing commands:
+.in +.25i
+append (a), 6, 7, 9
+change (c), 18
+copy (co), 15
+delete (d), 15-16
+edit (text editor), 3, 5, 23
+edit (e), 5, 9, 14
+file (f), 21-22
+global (g), 19
+move (m), 14-15
+number (nu), 11
+preserve (pre), 22-23
+print (p), 10
+quit (q), 8, 13
+read (r), 22
+recover (rec), 22, 23
+substitute (s), 11-12, 19, 20
+undo (u), 16-17, 23
+write (w), 8, 13, 21, 22
+z, 12-13
+! (shell escape), 21
+$=, 17
++, 17
+\-, 17
+//, 12, 20
+??, 20
+\&., 11, 17
+\&.=, 11, 17
+.in -.25i
+entering text, 3, 6-7
+erasing
+.in +.25i
+characters (^H), 7
+lines (@), 7
+.in -.25i
+error corrections, 7, 16
+ex (text editor), 23
+\fIEx Reference Manual\fR, 23
+exclamation (!), 21
+file, 3
+file (f) command, 21-22
+file recovery, 22-23
+filename, 3, 21
+global (g) command, 19
+input mode, 6-7
+Interrupt (message), 9
+line numbers, \fIsee also\fR current line
+.in +.25i
+dollar sign ($), 10, 11, 17
+dot (\|.\|), 11, 17
+relative (+ and \-), 17
+.in -.25i
+list, 10
+logging in, 4-6
+logging out, 8
+``Login incorrect'' (message), 5
+minus (\-), 17
+move (m) command, 14-15
+``Negative address\(emfirst buffer line is 1'' (message), 18
+``No current filename'' (message), 8
+``No such file or directory'' (message), 5, 6
+``No write since last change'' (message), 21
+non-printing characters, 10
+``Nonzero address required'' (message), 18
+``Not an editor command'' (message), 6
+``Not that many lines in buffer'' (message), 18
+number (nu) command, 11
+password, 5
+period (\|.\|), 11, 17
+plus (+), 17
+preserve (pre) command, 22-23
+print (p) command, 10
+program, 3
+prompts
+.in .25i
+% (\s-2UNIX\s0), 5
+: (edit), 5, 6, 7
+\0 (append), 7
+.in -.25i
+question (?), 20
+quit (q) command, 8, 13
+read (r) command, 22
+recover (rec) command, 22, 23
+recovery, \fIsee\fR\| file recovery
+references, 3, 23
+remove (rm) command, 21, 22
+reverse command effects (undo), 16-17, 23
+searching, 10-12, 19-21
+shell, 21
+shell escape (!), 21
+slash (/), 11-12, 20
+special characters (^, $, \\), 10, 11, 17, 20-21
+substitute (s) command, 11-12, 19, 20
+terminals, 4-5
+text input mode, 7
+undo (u) command, 16-17, 23
+\s-1UNIX\s0, 3
+write (w) command, 8, 13, 21, 22
+z command, 12-13
+
diff --git a/share/doc/usd/12.vi/Makefile b/share/doc/usd/12.vi/Makefile
new file mode 100644
index 000000000000..7b2c080434cf
--- /dev/null
+++ b/share/doc/usd/12.vi/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+SUBDIR= vi viapwh summary
+
+.include <bsd.subdir.mk>
+
diff --git a/share/doc/usd/12.vi/Makefile.inc b/share/doc/usd/12.vi/Makefile.inc
new file mode 100644
index 000000000000..d96b8113d8cd
--- /dev/null
+++ b/share/doc/usd/12.vi/Makefile.inc
@@ -0,0 +1,4 @@
+# $FreeBSD$
+
+VOLUME= usd/12.vi
+MACROS= -ms
diff --git a/share/doc/usd/12.vi/summary/Makefile b/share/doc/usd/12.vi/summary/Makefile
new file mode 100644
index 000000000000..425536dce4d6
--- /dev/null
+++ b/share/doc/usd/12.vi/summary/Makefile
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+DOC= summary
+SRCS= vi.summary
+USE_TBL=
+
+.include <bsd.doc.mk>
diff --git a/share/doc/usd/12.vi/summary/vi.summary b/share/doc/usd/12.vi/summary/vi.summary
new file mode 100644
index 000000000000..8a09ce944407
--- /dev/null
+++ b/share/doc/usd/12.vi/summary/vi.summary
@@ -0,0 +1,468 @@
+.\" Copyright (c) 1980, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)vi.summary 8.3 (Berkeley) 8/18/96
+.\"
+.ds CH
+.ds CF
+.de TS
+.br
+.if !\\n(1T .RT
+.ul 0
+.ti \\n(.iu
+.if t .sp 0.25
+.if n .sp
+.if \\$1H .TQ
+.nr IX 1
+..
+.nr PS 9
+.ps 9
+.nr VS 11
+.vs 11
+.nr HM .50i
+.nr FM .25i
+.nr PO 1.0i
+.po 1.0i
+.nr LL 4.5i
+.ll 4.5i
+.de nc
+.bp
+..
+.de h
+.LG
+.B
+\\$1
+.R
+.NL
+..
+.LG
+.LG
+.B
+.ce
+Ex Quick Reference
+.R
+.NL
+.LP
+.LP
+.h "Entering/leaving ex"
+.TS
+aw(1.4i)b aw(1.8i).
+% ex \fIname\fP edit \fIname\fP, start at end
+% ex +\fIn\fP \fIname\fP ... at line \fIn\fP
+% ex \-t \fItag\fP start at \fItag\fP
+% ex \-r list saved files
+% ex \-r \fIname\fP recover file \fIname\fP
+% ex \fIname\fP ... edit first; rest via \fB:n\fP
+% ex \-R \fIname\fP read only mode
+: x exit, saving changes
+: q! exit, discarding changes
+.TE
+.h "Ex states"
+.TS
+lw(1i) lw(2.0i).
+Command T{
+Normal and initial state. Input prompted for by \fB:\fP.
+Your kill character cancels partial command.
+T}
+Insert T{
+Entered by \fBa\fP \fBi\fP and \fBc\fP.
+Arbitrary text then terminates with line having only \fB.\fP
+character on it or abnormally with interrupt.
+T}
+Open/visual T{
+Entered by \fBopen\fP or \fBvi\fP, terminates with \fBQ\fP
+or ^\e.
+T}
+.TE
+.h "Ex commands"
+.TS
+lw(.45i) lw(.08i)b lw(.45i) lw(.08i)b lw(.45i) lw(.08i)b.
+abbrev ab next n unabbrev una
+append a number nu undo u
+args ar open o unmap unm
+change c preserve pre version ve
+copy co print p visual vi
+delete d put pu write w
+edit e quit q xit x
+file f read re yank ya
+global g recover rec \fIwindow\fP z
+insert i rewind rew \fIescape\fP !
+join j set se \fIlshift\fP <
+list l shell sh \fIprint next\fP \fRCR\fP
+map source so \fIresubst\fP &
+mark ma stop st \fIrshift\fP >
+move m substitute s \fIscroll\fP ^D
+.TE
+.h "Ex command addresses"
+.TS
+lw(.3i)b lw(0.8i) lw(.3i)b lw(0.8i).
+\fIn\fP line \fIn\fP /\fIpat\fP next with \fIpat\fP
+\&. current ?\fIpat\fP previous with \fIpat\fP
+$ last \fIx\fP-\fIn\fP \fIn\fP before \fIx\fP
++ next \fIx\fP,\fIy\fP \fIx\fP through \fIy\fP
+\- previous \(aa\fIx\fP marked with \fIx\fP
++\fIn\fP \fIn\fP forward \(aa\(aa previous context
+% 1,$
+.TE
+.nc
+.h "Specifying terminal type"
+.TS
+aw(1.7i)b aw(1.5i).
+% setenv TERM \fItype\fP \fIcsh\fP and all version 6
+$ TERM=\fItype\fP; export TERM \fIsh\fP in Version 7
+See also \fItset\fR(1)
+.TE
+.h "Some terminal types"
+.TS
+lw(.4i) lw(.4i) lw(.4i) lw(.4i) lw(.4i).
+2621 43 adm31 dw1 h19
+2645 733 adm3a dw2 i100
+300s 745 c100 gt40 mime
+33 act4 dm1520 gt42 owl
+37 act5 dm2500 h1500 t1061
+4014 adm3 dm3025 h1510 vt52
+.TE
+.h "Initializing options"
+.TS
+lw(.9i)b aw(1.5i).
+EXINIT place \fBset\fP's here in environment var.
+set \fIx\fP enable option
+set no\fIx\fP disable option
+set \fIx\fP=\fIval\fP give value \fIval\fP
+set show changed options
+set all show all options
+set \fIx\fP? show value of option \fIx\fP
+.TE
+.h "Useful options"
+.TS
+lw(.9i)b lw(.3i) lw(1.0i).
+autoindent ai supply indent
+autowrite aw write before changing files
+ignorecase ic in scanning
+lisp \fB( ) { }\fP are s-exp's
+list print ^I for tab, $ at end
+magic \fB. [ *\fP special in patterns
+number nu number lines
+paragraphs para macro names which start ...
+redraw simulate smart terminal
+scroll command mode lines
+sections sect macro names ...
+shiftwidth sw for \fB< >\fP, and input \fB^D\fP
+showmatch sm to \fB)\fP and \fB}\fP as typed
+slowopen slow choke updates during insert
+window visual mode lines
+wrapscan ws around end of buffer?
+wrapmargin wm automatic line splitting
+.TE
+.LP
+.h "Scanning pattern formation"
+.TS
+aw(.9i)b aw(1.0i).
+\(ua beginning of line
+$ end of line
+\fB.\fR any character
+\e< beginning of word
+\e> end of word
+[\fIstr\fP] any char in \fIstr\fP
+[\(ua\fIstr\fP] ... not in \fIstr\fP
+[\fIx\-y\fP] ... between \fIx\fP and \fIy\fP
+* any number of preceding
+.TE
+.nc
+.LP
+.LG
+.LG
+.B
+.ce
+Vi Quick Reference
+.NL
+.R
+.LP
+.LP
+.h "Entering/leaving vi"
+.TS
+aw(1.4i)b aw(1.8i).
+% vi \fIname\fP edit \fIname\fP at top
+% vi +\fIn\fP \fIname\fP ... at line \fIn\fP
+% vi + \fIname\fP ... at end
+% vi \-r list saved files
+% vi \-r \fIname\fP recover file \fIname\fP
+% vi \fIname\fP ... edit first; rest via \fB:n\fP
+% vi \-t \fItag\fP start at \fItag\fP
+% vi +/\fIpat\fP \fIname\fP search for \fIpat\fP
+% view \fIname\fP read only mode
+ZZ exit from vi, saving changes
+^Z stop vi for later resumption
+.TE
+.h "The display"
+.TS
+lw(.75i) lw(2.2i).
+Last line T{
+Error messages, echoing input to \fB: / ?\fP and \fB!\fR,
+feedback about i/o and large changes.
+T}
+@ lines On screen only, not in file.
+~ lines Lines past end of file.
+^\fIx\fP Control characters, ^? is delete.
+tabs Expand to spaces, cursor at last.
+.TE
+.LP
+.h "Vi states"
+.TS
+lw(.75i) lw(2.2i).
+Command T{
+Normal and initial state. Others return here.
+ESC (escape) cancels partial command.
+T}
+Insert T{
+Entered by \fBa i A I o O c C s S\fP \fBR\fP.
+Arbitrary text then terminates with ESC character,
+or abnormally with interrupt.
+T}
+Last line T{
+Reading input for \fB: / ?\fP or \fB!\fP; terminate
+with ESC or CR to execute, interrupt to cancel.
+T}
+.TE
+.h "Counts before vi commands"
+.TS
+lw(1.5i) lw(1.7i)b.
+line/column number z G |
+scroll amount ^D ^U
+replicate insert a i A I
+repeat effect \fRmost rest\fP
+.TE
+.h "Simple commands"
+.TS
+lw(1.5i)b lw(1.7i).
+dw delete a word
+de ... leaving punctuation
+dd delete a line
+3dd ... 3 lines
+i\fItext\fP\fRESC\fP insert text \fIabc\fP
+cw\fInew\fP\fRESC\fP change word to \fInew\fP
+ea\fIs\fP\fRESC\fP pluralize word
+xp transpose characters
+.TE
+.nc
+.h "Interrupting, cancelling"
+.TS
+aw(0.75i)b aw(1.6i).
+ESC end insert or incomplete cmd
+^? (delete or rubout) interrupts
+^L reprint screen if \fB^?\fR scrambles it
+.TE
+.h "File manipulation"
+.TS
+aw(0.75i)b aw(1.6i).
+:w write back changes
+:wq write and quit
+:q quit
+:q! quit, discard changes
+:e \fIname\fP edit file \fIname\fP
+:e! reedit, discard changes
+:e + \fIname\fP edit, starting at end
+:e +\fIn\fR edit starting at line \fIn\fR
+:e # edit alternate file
+^\(ua synonym for \fB:e #\fP
+:w \fIname\fP write file \fIname\fP
+:w! \fIname\fP overwrite file \fIname\fP
+:sh run shell, then return
+:!\fIcmd\fP run \fIcmd\fR, then return
+:n edit next file in arglist
+:n \fIargs\fP specify new arglist
+:f show current file and line
+^G synonym for \fB:f\fP
+:ta \fItag\fP to tag file entry \fItag\fP
+^] \fB:ta\fP, following word is \fItag\fP
+.TE
+.h "Positioning within file"
+.TS
+aw(0.75i)b aw(1.6i).
+^F forward screenfull
+^B backward screenfull
+^D scroll down half screen
+^U scroll up half screen
+G goto line (end default)
+/\fIpat\fR next line matching \fIpat\fR
+?\fIpat\fR prev line matching \fIpat\fR
+n repeat last \fB/\fR or \fB?\fR
+N reverse last \fB/\fR or \fB?\fR
+/\fIpat\fP/+\fIn\fP n'th line after \fIpat\fR
+?\fIpat\fP?\-\fIn\fP n'th line before \fIpat\fR
+]] next section/function
+[[ previous section/function
+% find matching \fB( ) {\fP or \fB}\fP
+.TE
+.h "Adjusting the screen"
+.TS
+aw(0.75i)b aw(1.6i).
+^L clear and redraw
+^R retype, eliminate @ lines
+z\fRCR\fP redraw, current at window top
+z\- ... at bottom
+z\|. ... at center
+/\fIpat\fP/z\- \fIpat\fP line at bottom
+z\fIn\fP\|. use \fIn\fP line window
+^E scroll window down 1 line
+^Y scroll window up 1 line
+.TE
+.nc
+.h "Marking and returning
+.TS
+aw(0.5i)b aw(2.0i).
+\(ga\(ga previous context
+\(aa\(aa ... at first non-white in line
+m\fIx\fP mark position with letter \fIx\fP
+\(ga\fIx\fP to mark \fIx\fP
+\(aa\fIx\fP ... at first non-white in line
+.TE
+.h "Line positioning"
+.TS
+aw(0.5i)b aw(2.0i).
+H home window line
+L last window line
+M middle window line
++ next line, at first non-white
+\- previous line, at first non-white
+\fRCR\fP return, same as +
+\(da \fRor\fP j next line, same column
+\(ua \fRor\fP k previous line, same column
+.TE
+.h "Character positioning"
+.TS
+aw(0.5i)b aw(2.0i).
+\(ua first non white
+0 beginning of line
+$ end of line
+h \fRor\fP \(-> forward
+l \fRor\fP \(<- backwards
+^H same as \fB\(<-\fP
+\fRspace\fP same as \fB\(->\fP
+f\fIx\fP find \fIx\fP forward
+F\fIx\fP \fBf\fR backward
+t\fIx\fP upto \fIx\fP forward
+T\fIx\fP back upto \fIx\fP
+; repeat last \fBf F t\fP or \fBT\fP
+, inverse of \fB;\fP
+| to specified column
+% find matching \fB( { )\fP or \fB}\fR
+.TE
+.h "Words, sentences, paragraphs"
+.TS
+aw(0.5i)b aw(2.0i).
+w word forward
+b back word
+e end of word
+) to next sentence
+} to next paragraph
+( back sentence
+{ back paragraph
+W blank delimited word
+B back \fBW\fP
+E to end of \fBW\fP
+.TE
+.h "Commands for \s-2LISP\s0"
+.TS
+aw(0.5i)b aw(2.0i).
+) Forward s-expression
+} ... but don't stop at atoms
+( Back s-expression
+{ ... but don't stop at atoms
+.TE
+.nc
+.h "Corrections during insert"
+.TS
+aw(.5i)b aw(2.0i).
+^H erase last character
+^W erases last word
+\fRerase\fP your erase, same as \fB^H\fP
+\fRkill\fP your kill, erase input this line
+\e escapes \fB^H\fR, your erase and kill
+\fRESC\fP ends insertion, back to command
+^? interrupt, terminates insert
+^D backtab over \fIautoindent\fP
+\(ua^D kill \fIautoindent\fP, save for next
+0^D ... but at margin next also
+^V quote non-printing character
+.TE
+.h "Insert and replace"
+.TS
+aw(.5i)b aw(2.0i).
+a append after cursor
+i insert before
+A append at end of line
+I insert before first non-blank
+o open line below
+O open above
+r\fIx\fP replace single char with \fIx\fP
+R replace characters
+.TE
+.h "Operators (double to affect lines)"
+.TS
+aw(0.5i)b aw(2.0i).
+d delete
+c change
+< left shift
+> right shift
+! filter through command
+\&= indent for \s-2LISP\s0
+y yank lines to buffer
+.TE
+.h "Miscellaneous operations"
+.TS
+aw(0.5i)b aw(2.0i).
+C change rest of line
+D delete rest of line
+s substitute chars
+S substitute lines
+J join lines
+x delete characters
+X ... before cursor
+Y yank lines
+.TE
+.h "Yank and put"
+.TS
+aw(0.5i)b aw(2.0i).
+p put back lines
+P put before
+"\fIx\fPp put from buffer \fIx\fP
+"\fIx\fPy yank to buffer \fIx\fP
+"\fIx\fPd delete into buffer \fIx\fP
+.TE
+.h "Undo, redo, retrieve"
+.TS
+aw(0.5i)b aw(2.0i).
+u undo last change
+U restore current line
+\fB.\fP repeat last change
+"\fId\fP\|p retrieve \fId\fP'th last delete
+.TE
diff --git a/share/doc/usd/12.vi/vi/Makefile b/share/doc/usd/12.vi/vi/Makefile
new file mode 100644
index 000000000000..6021b092e236
--- /dev/null
+++ b/share/doc/usd/12.vi/vi/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+SRCS= vi.in vi.chars
+USE_TBL=
+
+.include <bsd.doc.mk>
diff --git a/share/doc/usd/12.vi/vi/vi.chars b/share/doc/usd/12.vi/vi/vi.chars
new file mode 100644
index 000000000000..7941065d1d0f
--- /dev/null
+++ b/share/doc/usd/12.vi/vi/vi.chars
@@ -0,0 +1,645 @@
+.\" Copyright (c) 1980, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)vi.chars 8.3 (Berkeley) 6/27/96
+.\"
+.bd S 3
+.pn 21
+.de iP
+.IP "\fB\\$1\fR" \\$2
+..
+.SH
+Appendix: character functions
+.PP
+This appendix gives the uses the editor makes of each character. The
+characters are presented in their order in the \s-2ASCII\s0 character
+set: Control characters come first, then most special characters, then
+the digits, upper and then lower case characters.
+.PP
+For each character we tell a meaning it has as a command and any meaning it
+has during an insert.
+If it has only meaning as a command, then only this is discussed.
+Section numbers in parentheses indicate where the character is discussed;
+a `f' after the section number means that the character is mentioned
+in a footnote.
+.iP "^@" 15
+Not a command character.
+If typed as the first character of an insertion it is replaced with the
+last text inserted, and the insert terminates. Only 128 characters are
+saved from the last insert; if more characters were inserted the mechanism
+is not available.
+A \fB^@\fR cannot be part of the file due to the editor implementation
+(7.5f).
+.iP "^A" 15
+Unused.
+.iP "^B" 15
+Backward window.
+A count specifies repetition.
+Two lines of continuity are kept if possible (2.1, 6.1, 7.2).
+.iP "^C" 15
+Unused.
+.iP "^D" 15
+As a command, scrolls down a half-window of text.
+A count gives the number of (logical) lines to scroll, and is remembered
+for future \fB^D\fR and \fB^U\fR commands (2.1, 7.2).
+During an insert, backtabs over \fIautoindent\fR white space at the beginning
+of a line (6.6, 7.5); this white space cannot be backspaced over.
+.iP "^E" 15
+Exposes one more line below the current screen in the file, leaving
+the cursor where it is if possible.
+(Version 3 only.)
+.iP "^F" 15
+Forward window. A count specifies repetition.
+Two lines of continuity are kept if possible (2.1, 6.1, 7.2).
+.iP "^G" 15
+Equivalent to \fB:f\fR\s-2CR\s0, printing the current file, whether
+it has been modified, the current line number and the number of lines
+in the file, and the percentage of the way through the file that you
+are.
+.iP "^H (\fR\s-2BS\s0\fP)" 15
+Same as
+.B "left arrow" .
+(See
+.B h ).
+During an insert, eliminates the last input character, backing over it
+but not erasing it; it remains so you can see what you typed if you
+wish to type something only slightly different (3.1, 7.5).
+.iP "^I\ (\fR\s-2TAB\s0\fP)" 15
+Not a command character.
+When inserted it prints as some
+number of spaces.
+When the cursor is at a tab character it rests at the last of the spaces
+which represent the tab.
+The spacing of tabstops is controlled by the \fItabstop\fR option (4.1, 6.6).
+.iP "^J\ (\fR\s-2LF\s0\fP)" 15
+Same as
+.B "down arrow"
+(see
+.B j ).
+.iP "^K" 15
+Unused.
+.iP "^L" 15
+The \s-2ASCII\s0 formfeed character, this causes the screen to be cleared
+and redrawn. This is useful after a transmission error, if characters
+typed by a program other than the editor scramble the screen,
+or after output is stopped by an interrupt (5.4, 7.2f).
+.ne 1i
+.iP "^M\ (\fR\s-2CR\s0\fP)" 15
+A carriage return advances to the next line, at the first non-white position
+in the line. Given a count, it advances that many lines (2.3).
+During an insert, a \s-2CR\s0 causes the insert to continue onto
+another line (3.1).
+.iP "^N" 15
+Same as
+.B "down arrow"
+(see
+.B j ).
+.iP "^O" 15
+Unused.
+.iP "^P" 15
+Same as
+.B "up arrow"
+(see
+.B k ).
+.iP "^Q" 15
+Not a command character.
+In input mode,
+.B ^Q
+quotes the next character, the same as
+.B ^V ,
+except that some teletype drivers will eat the
+.B ^Q
+so that the editor never sees it.
+.iP "^R" 15
+Redraws the current screen, eliminating logical lines not corresponding
+to physical lines (lines with only a single @ character on them).
+On hardcopy terminals in \fIopen\fR mode, retypes the current line
+(5.4, 7.2, 7.8).
+.iP "^S" 15
+Unused. Some teletype drivers use
+.B ^S
+to suspend output until
+.B ^Q is pressed.
+.iP "^T" 15
+Not a command character.
+During an insert, with \fIautoindent\fR set and at the beginning of the
+line, inserts \fIshiftwidth\fR white space.
+.iP "^U" 15
+Scrolls the screen up, inverting \fB^D\fR which scrolls down. Counts work as
+they do for \fB^D\fR, and the previous scroll amount is common to both.
+On a dumb terminal, \fB^U\fR will often necessitate clearing and redrawing
+the screen further back in the file (2.1, 7.2).
+.iP "^V" 15
+Not a command character.
+In input mode, quotes the next character so that it is possible
+to insert non-printing and special characters into the file (4.2, 7.5).
+.iP "^W" 15
+Not a command character.
+During an insert, backs up as \fBb\fR would in command mode; the deleted
+characters remain on the display (see \fB^H\fR) (7.5).
+.iP "^X" 15
+Unused.
+.iP "^Y" 15
+Exposes one more line above the current screen, leaving the cursor where
+it is if possible. (No mnemonic value for this key; however, it is next
+to \fB^U\fR which scrolls up a bunch.)
+(Version 3 only.)
+.iP "^Z" 15
+If supported by the Unix system,
+stops the editor, exiting to the top level shell.
+Same as \fB:stop\fP\s-2CR\s0.
+Otherwise, unused.
+.iP "^[\ (\fR\s-2ESC\s0\fP)" 15
+Cancels a partially formed command, such as a \fBz\fR when no following
+character has yet been given; terminates inputs on the last line (read
+by commands such as \fB: /\fR and \fB?\fR); ends insertions of new text
+into the buffer.
+If an \s-2ESC\s0 is given when quiescent in command state, the editor
+rings the bell or flashes the screen. You can thus hit \s-2ESC\s0 if
+you don't know what is happening till the editor rings the bell.
+If you don't know if you are in insert mode you can type \s-2ESC\s0\fBa\fR,
+and then material to be input; the material will be inserted correctly
+whether or not you were in insert mode when you started (1.5, 3.1, 7.5).
+.iP "^\e" 15
+Unused.
+.iP "^]" 15
+Searches for the word which is after the cursor as a tag. Equivalent
+to typing \fB:ta\fR, this word, and then a \s-2CR\s0.
+Mnemonically, this command is ``go right to'' (7.3).
+.iP "^\(ua" 15
+Equivalent to \fB:e #\fR\s-2CR\s0, returning to the previous position
+in the last edited file, or editing a file which you specified if you
+got a `No write since last change diagnostic' and do not want to have
+to type the file name again (7.3).
+(You have to do a \fB:w\fR before \fB^\(ua\fR
+will work in this case. If you do not wish to write the file you should
+do \fB:e!\ #\fR\s-2CR\s0 instead.)
+.iP "^_" 15
+Unused.
+Reserved as the command character for the
+Tektronix 4025 and 4027 terminal.
+.iP "\fR\s-2SPACE\s0\fP" 15
+Same as
+.B "right arrow"
+(see
+.B l ).
+.iP "!" 15
+An operator, which processes lines from the buffer with reformatting commands.
+Follow \fB!\fR with the object to be processed, and then the command name
+terminated by \s-2CR\s0. Doubling \fB!\fR and preceding it by a count
+causes count lines to be filtered; otherwise the count
+is passed on to the object after the \fB!\fR. Thus \fB2!}\fR\fIfmt\fR\s-2CR\s0
+reformats the next two paragraphs by running them through the program
+\fIfmt\fR. If you are working on \s-2LISP\s0,
+the command \fB!%\fR\fIgrind\fR\s-2CR\s0,*
+.FS
+*Both
+.I fmt
+and
+.I grind
+are Berkeley programs and may not be present at all installations.
+.FE
+given at the beginning of a
+function, will run the text of the function through the \s-2LISP\s0 grinder
+(6.7, 7.3).
+To read a file or the output of a command into the buffer use \fB:r\fR (7.3).
+To simply execute a command use \fB:!\fR (7.3).
+.tr "
+.iP  15
+Precedes a named buffer specification. There are named buffers \fB1\-9\fR
+used for saving deleted text and named buffers \fBa\-z\fR into which you can
+place text (4.3, 6.3)
+.tr 
+.iP "#" 15
+The macro character which, when followed by a number, will substitute
+for a function key on terminals without function keys (6.9).
+In input mode,
+if this is your erase character, it will delete the last character
+you typed in input mode, and must be preceded with a \fB\e\fR to insert
+it, since it normally backs over the last input character you gave.
+.iP "$" 15
+Moves to the end of the current line. If you \fB:se list\fR\s-2CR\s0,
+then the end of each line will be shown by printing a \fB$\fR after the
+end of the displayed text in the line. Given a count, advances to the
+count'th following end of line; thus \fB2$\fR advances to the end of the
+following line.
+.iP "%" 15
+Moves to the parenthesis or brace \fB{ }\fR which balances the parenthesis
+or brace at the current cursor position.
+.iP "&" 15
+A synonym for \fB:&\fR\s-2CR\s0, by analogy with the
+.I ex
+.B &
+command.
+.iP "\(aa" 15
+When followed by a \fB\(aa\fR returns to the previous context at the
+beginning of a line. The previous context is set whenever the current
+line is moved in a non-relative way.
+When followed by a letter \fBa\fR\-\fBz\fR, returns to the line which
+was marked with this letter with a \fBm\fR command, at the first non-white
+character in the line. (2.2, 5.3).
+When used with an operator such as \fBd\fR, the operation takes place
+over complete lines; if you use \fB\(ga\fR, the operation takes place
+from the exact marked place to the current cursor position within the
+line.
+.iP "(" 15
+Retreats to the beginning of a
+sentence, or to the beginning of a \s-2LISP\s0 s-expression
+if the \fIlisp\fR option is set.
+A sentence ends at a \fB. !\fR or \fB?\fR which is followed by either
+the end of a line or by two spaces. Any number of closing \fB) ] "\fR
+and \fB\(aa\fR characters may appear after the \fB. !\fR or \fB?\fR,
+and before the spaces or end of line. Sentences also begin
+at paragraph and section boundaries
+(see \fB{\fR and \fB[[\fR below).
+A count advances that many sentences (4.2, 6.8).
+.iP ")" 15
+Advances to the beginning of a sentence.
+A count repeats the effect.
+See \fB(\fR above for the definition of a sentence (4.2, 6.8).
+.iP "*" 15
+Unused.
+.iP "+" 15
+Same as \s-2CR\s0 when used as a command.
+.iP "," 15
+Reverse of the last \fBf F t\fR or \fBT\fR command, looking the other way
+in the current line. Especially useful after hitting too many \fB;\fR
+characters. A count repeats the search.
+.iP "\-" 15
+Retreats to the previous line at the first non-white character.
+This is the inverse of \fB+\fR and \s-2RETURN\s0.
+If the line moved to is not on the screen, the screen is scrolled, or
+cleared and redrawn if this is not possible.
+If a large amount of scrolling would be required the screen is also cleared
+and redrawn, with the current line at the center (2.3).
+.iP "\&." 15
+Repeats the last command which changed the buffer. Especially useful
+when deleting words or lines; you can delete some words/lines and then
+hit \fB.\fR to delete more and more words/lines.
+Given a count, it passes it on to the command being repeated. Thus after
+a \fB2dw\fR, \fB3.\fR deletes three words (3.3, 6.3, 7.2, 7.4).
+.iP "/" 15
+Reads a string from the last line on the screen, and scans forward for
+the next occurrence of this string. The normal input editing sequences may
+be used during the input on the bottom line; an returns to command state
+without ever searching.
+The search begins when you hit \s-2CR\s0 to terminate the pattern;
+the cursor moves to the beginning of the last line to indicate that the search
+is in progress; the search may then
+be terminated with a \s-2DEL\s0 or \s-2RUB\s0, or by backspacing when
+at the beginning of the bottom line, returning the cursor to
+its initial position.
+Searches normally wrap end-around to find a string
+anywhere in the buffer.
+.IP
+When used with an operator the enclosed region is normally affected.
+By mentioning an
+offset from the line matched by the pattern you can force whole lines
+to be affected. To do this give a pattern with a closing
+a closing \fB/\fR and then an offset \fB+\fR\fIn\fR or \fB\-\fR\fIn\fR.
+.IP
+To include the character \fB/\fR in the search string, you must escape
+it with a preceding \fB\e\fR.
+A \fB\(ua\fR at the beginning of the pattern forces the match to occur
+at the beginning of a line only; this speeds the search. A \fB$\fR at
+the end of the pattern forces the match to occur at the end of a line
+only.
+More extended pattern matching is available, see section 7.4;
+unless you set \fBnomagic\fR in your \fI\&.exrc\fR file you will have
+to preceed the characters \fB. [ *\fR and \fB~\fR in the search pattern
+with a \fB\e\fR to get them to work as you would naively expect (1.5, 2,2,
+6.1, 7.2, 7.4).
+.iP "0" 15
+Moves to the first character on the current line.
+Also used, in forming numbers, after an initial \fB1\fR\-\fB9\fR.
+.iP "1\-9" 15
+Used to form numeric arguments to commands (2.3, 7.2).
+.iP ":" 15
+A prefix to a set of commands for file and option manipulation and escapes
+to the system. Input is given on the bottom line and terminated with
+an \s-2CR\s0, and the command then executed. You can return to where
+you were by hitting \s-2DEL\s0 or \s-2RUB\s0 if you hit \fB:\fR accidentally
+(see primarily 6.2 and 7.3).
+.iP ";" 15
+Repeats the last single character find which used \fBf F t\fR or \fBT\fR.
+A count iterates the basic scan (4.1).
+.iP "<" 15
+An operator which shifts lines left one \fIshiftwidth\fR, normally 8
+spaces. Like all operators, affects lines when repeated, as in
+\fB<<\fR. Counts are passed through to the basic object, thus \fB3<<\fR
+shifts three lines (6.6, 7.2).
+.iP "=" 15
+Reindents line for \s-2LISP\s0, as though they were typed in with \fIlisp\fR
+and \fIautoindent\fR set (6.8).
+.iP ">" 15
+An operator which shifts lines right one \fIshiftwidth\fR, normally 8
+spaces. Affects lines when repeated as in \fB>>\fR. Counts repeat the
+basic object (6.6, 7.2).
+.iP "?" 15
+Scans backwards, the opposite of \fB/\fR. See the \fB/\fR description
+above for details on scanning (2.2, 6.1, 7.4).
+.iP "@" 15
+A macro character (6.9). If this is your kill character, you must escape it with a \e
+to type it in during input mode, as it normally backs over the input you
+have given on the current line (3.1, 3.4, 7.5).
+.iP "A" 15
+Appends at the end of line, a synonym for \fB$a\fR (7.2).
+.iP "B" 15
+Backs up a word, where words are composed of non-blank sequences, placing
+the cursor at the beginning of the word. A count repeats the effect
+(2.4).
+.iP "C" 15
+Changes the rest of the text on the current line; a synonym for \fBc$\fR.
+.iP "D" 15
+Deletes the rest of the text on the current line; a synonym for \fBd$\fR.
+.iP "E" 15
+Moves forward to the end of a word, defined as blanks and non-blanks,
+like \fBB\fR and \fBW\fR. A count repeats the effect.
+.iP "F" 15
+Finds a single following character, backwards in the current line.
+A count repeats this search that many times (4.1).
+.iP "G" 15
+Goes to the line number given as preceding argument, or the end of the
+file if no preceding count is given. The screen is redrawn with the
+new current line in the center if necessary (7.2).
+.iP "H" 15
+.B "Home arrow" .
+Homes the cursor to the top line on the screen. If a count is given,
+then the cursor is moved to the count'th line on the screen.
+In any case the cursor is moved to the first non-white character on the
+line. If used as the target of an operator, full lines are affected
+(2.3, 3.2).
+.iP "I" 15
+Inserts at the beginning of a line; a synonym for \fB\(uai\fR.
+.iP "J" 15
+Joins together lines, supplying appropriate white space: one space between
+words, two spaces after a \fB.\fR, and no spaces at all if the first
+character of the joined on line is \fB)\fR. A count causes that many
+lines to be joined rather than the default two (6.5, 7.1f).
+.iP "K" 15
+Unused.
+.iP "L" 15
+Moves the cursor to the first non-white character of the last line on
+the screen. With a count, to the first non-white of the count'th line
+from the bottom. Operators affect whole lines when used with \fBL\fR
+(2.3).
+.iP "M" 15
+Moves the cursor to the middle line on the screen, at the first non-white
+position on the line (2.3).
+.iP "N" 15
+Scans for the next match of the last pattern given to
+\fB/\fR or \fB?\fR, but in the reverse direction; this is the reverse
+of \fBn\fR.
+.iP "O" 15
+Opens a new line above the current line and inputs text there up to an
+\s-2ESC\s0. A count can be used on dumb terminals to specify a number
+of lines to be opened; this is generally obsolete, as the \fIslowopen\fR
+option works better (3.1).
+.iP "P" 15
+Puts the last deleted text back before/above the cursor. The text goes
+back as whole lines above the cursor if it was deleted as whole lines.
+Otherwise the text is inserted between the characters before and at the
+cursor. May be preceded by a named buffer specification \fB"\fR\fIx\fR
+to retrieve the contents of the buffer; buffers \fB1\fR\-\fB9\fR contain
+deleted material, buffers \fBa\fR\-\fBz\fR are available for general
+use (6.3).
+.iP "Q" 15
+Quits from \fIvi\fR to \fIex\fR command mode. In this mode, whole lines
+form commands, ending with a \s-2RETURN\s0. You can give all the \fB:\fR
+commands; the editor supplies the \fB:\fR as a prompt (7.7).
+.iP "R" 15
+Replaces characters on the screen with characters you type (overlay fashion).
+Terminates with an \s-2ESC\s0.
+.iP "S" 15
+Changes whole lines, a synonym for \fBcc\fR. A count substitutes for
+that many lines. The lines are saved in the numeric buffers, and erased
+on the screen before the substitution begins.
+.iP "T" 15
+Takes a single following character, locates the character before the
+cursor in the current line, and places the cursor just after that character.
+A count repeats the effect. Most useful with operators such as \fBd\fR
+(4.1).
+.iP "U" 15
+Restores the current line to its state before you started changing it
+(3.5).
+.iP "V" 15
+Unused.
+.iP "W" 15
+Moves forward to the beginning of a word in the current line,
+where words are defined as sequences of blank/non-blank characters.
+A count repeats the effect (2.4).
+.iP "X" 15
+Deletes the character before the cursor. A count repeats the effect,
+but only characters on the current line are deleted.
+.iP "Y" 15
+Yanks a copy of the current line into the unnamed buffer, to be put back
+by a later \fBp\fR or \fBP\fR; a very useful synonym for \fByy\fR.
+A count yanks that many lines. May be preceded by a buffer name to put
+lines in that buffer (7.4).
+.iP "ZZ" 15
+Exits the editor.
+(Same as \fB:x\fP\s-2CR\s0.)
+If any changes have been made, the buffer is written out to the current file.
+Then the editor quits.
+.iP "[[" 15
+Backs up to the previous section boundary. A section begins at each
+macro in the \fIsections\fR option,
+normally a `.NH' or `.SH' and also at lines which which start
+with a formfeed \fB^L\fR. Lines beginning with \fB{\fR also stop \fB[[\fR;
+this makes it useful for looking backwards, a function at a time, in C
+programs. If the option \fIlisp\fR is set, stops at each \fB(\fR at the
+beginning of a line, and is thus useful for moving backwards at the top
+level \s-2LISP\s0 objects. (4.2, 6.1, 6.6, 7.2).
+.iP "\e" 15
+Unused.
+.iP "]]" 15
+Forward to a section boundary, see \fB[[\fR for a definition (4.2, 6.1,
+6.6, 7.2).
+.iP "\(ua" 15
+Moves to the first non-white position on the current line (4.4).
+.iP "_" 15
+Unused.
+.iP "\(ga" 15
+When followed by a \fB\(ga\fR returns to the previous context.
+The previous context is set whenever the current
+line is moved in a non-relative way.
+When followed by a letter \fBa\fR\-\fBz\fR, returns to the position which
+was marked with this letter with a \fBm\fR command.
+When used with an operator such as \fBd\fR, the operation takes place
+from the exact marked place to the current position within the line;
+if you use \fB\(aa\fR, the operation takes place over complete lines
+(2.2, 5.3).
+.iP "a" 15
+Appends arbitrary text after the current cursor position; the insert
+can continue onto multiple lines by using \s-2RETURN\s0 within the insert.
+A count causes the inserted text to be replicated, but only if the inserted
+text is all on one line.
+The insertion terminates with an \s-2ESC\s0 (3.1, 7.2).
+.iP "b" 15
+Backs up to the beginning of a word in the current line. A word is a
+sequence of alphanumerics, or a sequence of special characters.
+A count repeats the effect (2.4).
+.iP "c" 15
+An operator which changes the following object, replacing it with the
+following input text up to an \s-2ESC\s0. If more than part of a single
+line is affected, the text which is changed away is saved in the numeric named
+buffers. If only part of the current line is affected, then the last
+character to be changed away is marked with a \fB$\fR.
+A count causes that many objects to be affected, thus both
+\fB3c)\fR and \fBc3)\fR change the following three sentences (7.4).
+.iP "d" 15
+An operator which deletes the following object. If more than part of
+a line is affected, the text is saved in the numeric buffers.
+A count causes that many objects to be affected; thus \fB3dw\fR is the
+same as \fBd3w\fR (3.3, 3.4, 4.1, 7.4).
+.iP "e" 15
+Advances to the end of the next word, defined as for \fBb\fR and \fBw\fR.
+A count repeats the effect (2.4, 3.1).
+.iP "f" 15
+Finds the first instance of the next character following the cursor on
+the current line. A count repeats the find (4.1).
+.iP "g" 15
+Unused.
+.sp
+Arrow keys
+.B h ,
+.B j ,
+.B k ,
+.B l ,
+and
+.B H .
+.iP "h" 15
+.B "Left arrow" .
+Moves the cursor one character to the left.
+Like the other arrow keys, either
+.B h ,
+the
+.B "left arrow"
+key, or one of the synonyms (\fB^H\fP) has the same effect.
+On v2 editors, arrow keys on certain kinds of terminals
+(those which send escape sequences, such as vt52, c100, or hp)
+cannot be used.
+A count repeats the effect (3.1, 7.5).
+.iP "i" 15
+Inserts text before the cursor, otherwise like \fBa\fR (7.2).
+.iP "j" 15
+.B "Down arrow" .
+Moves the cursor one line down in the same column.
+If the position does not exist,
+.I vi
+comes as close as possible to the same column.
+Synonyms include
+.B ^J
+(linefeed) and
+.B ^N .
+.iP "k" 15
+.B "Up arrow" .
+Moves the cursor one line up.
+.B ^P
+is a synonym.
+.iP "l" 15
+.B "Right arrow" .
+Moves the cursor one character to the right.
+\s-2SPACE\s0 is a synonym.
+.iP "m" 15
+Marks the current position of the cursor in the mark register which is
+specified by the next character \fBa\fR\-\fBz\fR. Return to this position
+or use with an operator using \fB\(ga\fR or \fB\(aa\fR (5.3).
+.iP "n" 15
+Repeats the last \fB/\fR or \fB?\fR scanning commands (2.2).
+.iP "o" 15
+Opens new lines below the current line; otherwise like \fBO\fR (3.1).
+.iP "p" 15
+Puts text after/below the cursor; otherwise like \fBP\fR (6.3).
+.iP "q" 15
+Unused.
+.iP "r" 15
+Replaces the single character at the cursor with a single character you
+type. The new character may be a \s-2RETURN\s0; this is the easiest
+way to split lines. A count replaces each of the following count characters
+with the single character given; see \fBR\fR above which is the more
+usually useful iteration of \fBr\fR (3.2).
+.iP "s" 15
+Changes the single character under the cursor to the text which follows
+up to an \s-2ESC\s0; given a count, that many characters from the current
+line are changed. The last character to be changed is marked with \fB$\fR
+as in \fBc\fR (3.2).
+.iP "t" 15
+Advances the cursor upto the character before the next character typed.
+Most useful with operators such as \fBd\fR and \fBc\fR to delete the
+characters up to a following character. You can use \fB.\fR to delete
+more if this doesn't delete enough the first time (4.1).
+.iP "u" 15
+Undoes the last change made to the current buffer. If repeated, will
+alternate between these two states, thus is its own inverse. When used
+after an insert which inserted text on more than one line, the lines are
+saved in the numeric named buffers (3.5).
+.iP "v" 15
+Unused.
+.iP "w" 15
+Advances to the beginning of the next word, as defined by \fBb\fR (2.4).
+.iP "x" 15
+Deletes the single character under the cursor. With a count deletes
+deletes that many characters forward from the cursor position, but only
+on the current line (6.5).
+.iP "y" 15
+An operator, yanks the following object into the unnamed temporary buffer.
+If preceded by a named buffer specification, \fB"\fR\fIx\fR, the text
+is placed in that buffer also. Text can be recovered by a later \fBp\fR
+or \fBP\fR (7.4).
+.iP "z" 15
+Redraws the screen with the current line placed as specified by the following
+character: \s-2RETURN\s0 specifies the top of the screen, \fB.\fR the
+center of the screen, and \fB\-\fR at the bottom of the screen.
+A count may be given after the \fBz\fR and before the following character
+to specify the new screen size for the redraw.
+A count before the \fBz\fR gives the number of the line to place in the
+center of the screen instead of the default current line. (5.4)
+.iP "{" 15
+Retreats to the beginning of the beginning of the preceding paragraph.
+A paragraph begins at each macro in the \fIparagraphs\fR option, normally
+`.IP', `.LP', `.PP', `.QP' and `.bp'.
+A paragraph also begins after a completely
+empty line, and at each section boundary (see \fB[[\fR above) (4.2, 6.8,
+7.6).
+.iP "|" 15
+Places the cursor on the character in the column specified
+by the count (7.1, 7.2).
+.iP "}" 15
+Advances to the beginning of the next paragraph. See \fB{\fR for the
+definition of paragraph (4.2, 6.8, 7.6).
+.iP "~" 15
+Unused.
+.iP "^?\ (\s-2\fRDEL\fP\s0)" 15
+Interrupts the editor, returning it to command accepting state (1.5,
+7.5)
+.bp
+\&.
diff --git a/share/doc/usd/12.vi/vi/vi.in b/share/doc/usd/12.vi/vi/vi.in
new file mode 100644
index 000000000000..c36ebe41743e
--- /dev/null
+++ b/share/doc/usd/12.vi/vi/vi.in
@@ -0,0 +1,2074 @@
+.\" Copyright (c) 1980, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)vi.in 8.5 (Berkeley) 8/18/96
+.\"
+.nr LL 6.5i
+.nr FL 6.5i
+.EH 'USD:11-%''An Introduction to Display Editing with Vi'
+.OH 'An Introduction to Display Editing with Vi''USD:11-%'
+.bd S 3
+.if t .ds dg \(dg
+.if n .ds dg +
+.if t .ds dd \(dd
+.if n .ds dd ++
+.\".RP
+.TL
+An Introduction to Display Editing with Vi
+.AU
+William Joy
+.AU
+Mark Horton
+.AI
+Computer Science Division
+Department of Electrical Engineering and Computer Science
+University of California, Berkeley
+Berkeley, Ca. 94720
+.AB
+.PP
+.I Vi
+(visual) is a display oriented interactive text editor.
+When using
+.I vi
+the screen of your terminal acts as a window into the file which you
+are editing. Changes which you make to the file are reflected
+in what you see.
+.PP
+Using
+.I vi
+you can insert new text any place in the file quite easily.
+Most of the commands to
+.I vi
+move the cursor around in the file.
+There are commands to move the cursor
+forward and backward in units of characters, words,
+sentences and paragraphs.
+A small set of operators, like
+.B d
+for delete and
+.B c
+for change, are combined with the motion commands to form operations
+such as delete word or change paragraph, in a simple and natural way.
+This regularity and the mnemonic assignment of commands to keys makes the
+editor command set easy to remember and to use.
+.PP
+.I Vi
+will work on a large number of display terminals,
+and new terminals are easily driven after editing a terminal description file.
+While it is advantageous to have an intelligent terminal which can locally
+insert and delete lines and characters from the display, the editor will
+function quite well on dumb terminals over slow phone lines.
+The editor makes allowance for the low bandwidth in these situations
+and uses smaller window sizes and
+different display updating algorithms to make best use of the
+limited speed available.
+.PP
+It is also possible to use the command set of
+.I vi
+on hardcopy terminals, storage tubes and ``glass tty's'' using a one line
+editing window; thus
+.I vi's
+command set is available on all terminals.
+The full command set of the more traditional, line
+oriented editor
+.I ex
+is available within
+.I vi;
+it is quite simple to switch between the two modes of editing.
+.AE
+.NH 1
+Getting started
+.PP
+.FS
+The financial support of an \s-2IBM\s0 Graduate Fellowship and the
+National Science Foundation under grants MCS74-07644-A03 and MCS78-07291
+is gratefully acknowledged.
+.FE
+This document provides a quick introduction to
+.I vi.
+(Pronounced \fIvee-eye\fP.)
+You should be running
+.I vi
+on a file you are familiar with while you are reading this.
+The first part of this document (sections 1 through 5)
+describes the basics of using
+.I vi.
+Some topics of special interest are presented in section 6, and
+some nitty-gritty details of how the editor functions are saved for section
+7 to avoid cluttering the presentation here.
+.PP
+There is also a short appendix here, which gives for each character the
+special meanings which this character has in \fIvi\fR. Attached to
+this document should be a quick reference card.
+This card summarizes the commands of
+.I vi
+in a very compact format. You should have the card handy while you are
+learning
+.I vi.
+.NH 2
+Specifying terminal type
+.PP
+Before you can start
+.I vi
+you must tell the system what kind of terminal you are using.
+Here is a (necessarily incomplete) list of terminal type codes.
+If your terminal does not appear here, you should consult with one of
+the staff members on your system to find out the code for your terminal.
+If your terminal does not have a code, one can be assigned and a description
+for the terminal can be created.
+.LP
+.TS
+center;
+ab ab ab
+a a a.
+Code Full name Type
+_
+2621 Hewlett-Packard 2621A/P Intelligent
+2645 Hewlett-Packard 264x Intelligent
+act4 Microterm ACT-IV Dumb
+act5 Microterm ACT-V Dumb
+adm3a Lear Siegler ADM-3a Dumb
+adm31 Lear Siegler ADM-31 Intelligent
+c100 Human Design Concept 100 Intelligent
+dm1520 Datamedia 1520 Dumb
+dm2500 Datamedia 2500 Intelligent
+dm3025 Datamedia 3025 Intelligent
+fox Perkin-Elmer Fox Dumb
+h1500 Hazeltine 1500 Intelligent
+h19 Heathkit h19 Intelligent
+i100 Infoton 100 Intelligent
+mime Imitating a smart act4 Intelligent
+t1061 Teleray 1061 Intelligent
+vt52 Dec VT-52 Dumb
+.TE
+.PP
+Suppose for example that you have a Hewlett-Packard HP2621A
+terminal. The code used by the system for this terminal is `2621'.
+In this case you can use one of the following commands to tell the system
+the type of your terminal:
+.DS
+% \fBsetenv TERM\fP 2621
+.DE
+This command works with the
+.I csh
+shell.
+If you are using the standard Bourne shell
+.I sh
+then you should give the commands
+.DS
+$ \fBTERM=\fP2621
+$ \fBexport TERM\fP
+.DE
+.PP
+If you want to arrange to have your terminal type set up automatically
+when you log in, you can use the
+.I tset
+program.
+If you dial in on a
+.I mime ,
+but often use hardwired ports, a typical line for your
+.I .login
+file (if you use csh) would be
+.DS
+\fBsetenv TERM \(gatset\fP \- \-d mime\(ga
+.DE
+or for your
+.I .profile
+file (if you use sh)
+.DS
+\fBTERM=\(gatse\fPt \- \-d mime\(ga
+.DE
+.I Tset
+knows which terminals are hardwired to each port
+and needs only to be told that when you dial in you
+are probably on a
+.I mime .
+.I Tset
+is usually used to change the erase and kill characters, too.
+.NH 2
+Editing a file
+.PP
+After telling the system which kind of terminal you have, you should
+make a copy of a file you are familiar with, and run
+.I vi
+on this file, giving the command
+.DS
+% \fBvi\fR \fIname\fR
+.DE
+replacing \fIname\fR with the name of the copy file you just created.
+The screen should clear and the text of your file should appear on the
+screen. If something else happens refer to the footnote.\*(dd
+.FS
+\*(dd If you gave the system an incorrect terminal type code then the
+editor may have just made a mess out of your screen. This happens when
+it sends control codes for one kind of terminal to some other
+kind of terminal. In this case hit
+the keys \fB:q\fR (colon and the q key) and then hit the \s-2RETURN\s0 key.
+This should get you back to the command level interpreter.
+Figure out what you did wrong (ask someone else if necessary) and try again.
+ Another thing which can go wrong is that you typed the wrong file name and
+the editor just printed an error diagnostic. In this case you should
+follow the above procedure for getting out of the editor, and try again
+this time spelling the file name correctly.
+ If the editor doesn't seem to respond to the commands which you type
+here, try sending an interrupt to it by hitting the \s-2DEL\s0 or \s-2RUB\s0
+key on your terminal, and then hitting the \fB:q\fR command again followed
+by a carriage return.
+.sp
+.FE
+.NH 2
+The editor's copy: the buffer
+.PP
+The editor does not directly modify the file which you are editing.
+Rather, the editor makes a copy of this file, in a place called the
+.I buffer,
+and remembers the file's
+name. You do not affect the contents of the file unless and until you
+write the changes you make back into the original file.
+.NH 2
+Notational conventions
+.PP
+In our examples, input which must be typed as is will be presented in
+\fBbold face\fR. Text which should be replaced with appropriate input
+will be given in \fIitalics\fR. We will represent special characters
+in \s-2SMALL CAPITALS\s0.
+.NH 2
+Arrow keys
+.PP
+The editor command set is independent of the terminal
+you are using. On most terminals with cursor positioning keys, these keys
+will also work within the editor.
+If you don't have cursor positioning keys, or even if you do, you can use
+the \fBh j k\fR and \fBl\fR keys as cursor positioning
+keys (these are labelled with arrows on an
+.I adm3a).*
+.PP
+(Particular note for the HP2621: on this terminal the function keys
+must be \fIshifted\fR (ick) to send to the machine, otherwise they
+only act locally. Unshifted use will leave the cursor positioned
+incorrectly.)
+.FS
+* As we will see later,
+.I h
+moves back to the left (like control-h which is a backspace),
+.I j
+moves down (in the same column),
+.I k
+moves up (in the same column),
+and
+.I l
+moves to the right.
+.FE
+.NH 2
+Special characters: \s-2ESC\s0, \s-2CR\s0 and \s-2DEL\s0
+.PP
+Several of these special characters are very important, so be sure to
+find them right now. Look on your keyboard for a key labelled \s-2ESC\s0
+or \s-2ALT\s0. It should be near the upper left corner of your terminal.
+Try hitting this key a few times. The editor will ring the bell
+to indicate that it is in a quiescent state.\*(dd
+.FS
+\*(dd On smart terminals where it is possible, the editor will quietly
+flash the screen rather than ringing the bell.
+.FE
+Partially formed commands are cancelled by \s-2ESC\s0, and when you insert
+text in the file you end the text insertion
+with \s-2ESC\s0. This key is a fairly
+harmless one to hit, so you can just hit it if you don't know
+what is going on until the editor rings the bell.
+.PP
+The \s-2CR\s0 or \s-2RETURN\s0 key is important because it is used
+to terminate certain commands.
+It is usually at the right side of the keyboard,
+and is the same command used at the end of each shell command.
+.PP
+Another very useful key is the \s-2DEL\s0 or \s-2RUB\s0 key, which generates
+an interrupt, telling the editor to stop what it is doing.
+It is a forceful way of making the editor listen
+to you, or to return it to the quiescent state if you don't know or don't
+like what is going on. Try hitting the `/' key on your terminal. This
+key is used when you want to specify a string to be searched for. The
+cursor should now be positioned at the bottom line of the terminal after
+a `/' printed as a prompt. You can get the cursor back to the current
+position by hitting the \s-2DEL\s0 or \s-2RUB\s0 key; try this now.*
+.FS
+* Backspacing over the `/' will also cancel the search.
+.FE
+From now on we will simply refer to hitting the \s-2DEL\s0 or \s-2RUB\s0
+key as ``sending an interrupt.''**
+.FS
+** On some systems, this interruptibility comes at a price: you cannot type
+ahead when the editor is computing with the cursor on the bottom line.
+.FE
+.PP
+The editor often echoes your commands on the last line of the terminal.
+If the cursor is on the first position of this last line, then the editor
+is performing a computation, such as computing a new position in the
+file after a search or running a command to reformat part of the buffer.
+When this is happening you can stop the editor by
+sending an interrupt.
+.NH 2
+Getting out of the editor
+.PP
+After you have worked with this introduction for a while, and you wish
+to do something else, you can give the command \fBZZ\fP
+to the editor.
+This will write the contents of the editor's buffer back into
+the file you are editing, if you made any changes, and then quit from
+the editor. You can also end an editor
+session by giving the command \fB:q!\fR\s-2CR\s0;\*(dg
+.FS
+\*(dg All commands which read from the last display line can also be
+terminated with a \s-2ESC\s0 as well as an \s-2CR\s0.
+.FE
+this is a dangerous but occasionally essential
+command which ends the editor session and discards all your changes.
+You need to know about this command in case you change the editor's
+copy of a file you wish only to look at. Be very careful
+not to give this command when you really want to save
+the changes you have made.
+.NH 1
+Moving around in the file
+.NH 2
+Scrolling and paging
+.PP
+The editor has a number of commands for moving around in the file.
+The most useful of these is generated by hitting the control and D keys
+at the same time, a control-D or `^D'. We will use this two character
+notation for referring to these control keys from now on. You may have
+a key labelled `^' on your terminal. This key will be represented as `\(ua'
+in this document; `^' is exclusively used as part of the `^x' notation
+for control characters.\*(dd
+.FS
+\*(dd If you don't have a `^' key on your terminal
+then there is probably a key labelled `\(ua'; in any case these characters
+are one and the same.
+.FE
+.PP
+As you know now if you tried hitting \fB^D\fR, this command scrolls down in
+the file. The \fBD\fR thus stands for down. Many editor commands are mnemonic
+and this makes them much easier to remember. For instance the command
+to scroll up is \fB^U\fR. Many dumb terminals can't scroll up at all, in which
+case hitting \fB^U\fR clears the screen and refreshes it
+with a line which is farther back in the file at the top.
+.PP
+If you want to see more of the file below where you are, you can
+hit \fB^E\fR to expose one more line at the bottom of the screen,
+leaving the cursor where it is.
+The command \fB^Y\fR (which is hopelessly non-mnemonic, but next to \fB^U\fR
+on the keyboard) exposes one more line at the top of the screen.
+.PP
+There are other ways to move around in the file; the keys \fB^F\fR and \fB^B\fR
+move forward and backward a page,
+keeping a couple of lines of continuity between screens
+so that it is possible to read through a file using these rather than
+\fB^D\fR and \fB^U\fR if you wish.
+.PP
+Notice the difference between scrolling and paging. If you are trying
+to read the text in a file, hitting \fB^F\fR to move forward a page
+will leave you only a little context to look back at. Scrolling on the
+other hand leaves more context, and happens more smoothly. You can continue
+to read the text as scrolling is taking place.
+.NH 2
+Searching, goto, and previous context
+.PP
+Another way to position yourself in the file is by giving the editor a string
+to search for. Type the character \fB/\fR followed by a string of characters
+terminated by \s-2CR\s0. The editor will position the cursor
+at the next occurrence of this string.
+Try hitting \fBn\fR to then go to the next occurrence of this string.
+The character \fB?\fR will search backwards from where you are, and is
+otherwise like \fB/\fR.\*(dg
+.FS
+\*(dg These searches will normally wrap around the end of the file, and thus
+find the string even if it is not on a line in the direction you search
+provided it is anywhere else in the file. You can disable this wraparound
+in scans by giving the command \fB:se nowrapscan\fR\s-2CR\s0,
+or more briefly \fB:se nows\fR\s-2CR\s0.
+.FE
+.PP
+If the search string you give the editor is not present in the
+file the editor will print
+a diagnostic on the last line of the screen, and the cursor will be returned
+to its initial position.
+.PP
+If you wish the search to match only at the beginning of a line, begin
+the search string with an \fB\(ua\fR. To match only at the end of
+a line, end the search string with a \fB$\fR.
+Thus \fB/\(uasearch\fR\s-2CR\s0 will search for the word `search' at
+the beginning of a line, and \fB/last$\fR\s-2CR\s0 searches for the
+word `last' at the end of a line.*
+.FS
+*Actually, the string you give to search for here can be a
+.I "regular expression"
+in the sense of the editors
+.I ex (1)
+and
+.I ed (1).
+If you don't wish to learn about this yet, you can disable this more
+general facility by doing
+\fB:se\ nomagic\fR\s-2CR\s0;
+by putting this command in
+EXINIT
+in your environment, you can have this always be in effect (more
+about
+.I EXINIT
+later.)
+.FE
+.PP
+The command \fBG\fR, when preceded by a number will position the cursor
+at that line in the file.
+Thus \fB1G\fR will move the cursor to
+the first line of the file. If you give \fBG\fR no count, then it moves
+to the end of the file.
+.PP
+If you are near the end of the file, and the last line is not at the bottom
+of the screen, the editor will place only the character `~' on each remaining
+line. This indicates that the last line in the file is on the screen;
+that is, the `~' lines are past the end of the file.
+.PP
+You can find out the state of the file you are editing by typing a \fB^G\fR.
+The editor will show you the name of the file you are editing, the number
+of the current line, the number of lines in the buffer, and the percentage
+of the way through the buffer which you are.
+Try doing this now, and remember the number of the line you are on.
+Give a \fBG\fR command to get to the end and then another \fBG\fR command
+to get back where you were.
+.PP
+You can also get back to a previous position by using the command
+\fB\(ga\(ga\fR (two back quotes).
+This is often more convenient than \fBG\fR because it requires no advance
+preparation.
+Try giving a \fBG\fR or a search with \fB/\fR or \fB?\fR and then a
+\fB\(ga\(ga\fR to get back to where you were. If you accidentally hit
+\fBn\fR or any command which moves you far away from a context of interest, you
+can quickly get back by hitting \fB\(ga\(ga\fR.
+.NH 2
+Moving around on the screen
+.PP
+Now try just moving the cursor around on the screen.
+If your terminal has arrow keys (4 or 5 keys with arrows
+going in each direction) try them and convince yourself
+that they work.
+If you don't have working arrow keys, you can always use
+.B h ,
+.B j ,
+.B k ,
+and
+.B l .
+Experienced users of
+.I vi
+prefer these keys to arrow keys,
+because they are usually right underneath their fingers.
+.PP
+Hit the \fB+\fR key. Each time you do, notice that the cursor
+advances to the next line in the file, at the first non-white position
+on the line. The \fB\-\fR key is like \fB+\fR but goes the other way.
+.PP
+These are very common keys for moving up and down lines in the file.
+Notice that if you go off the bottom or top with these keys then the
+screen will scroll down (and up if possible) to bring a line at a time
+into view. The \s-2RETURN\s0 key has the same effect as the \fB+\fR
+key.
+.PP
+.I Vi
+also has commands to take you to the top, middle and bottom of the screen.
+\fBH\fR will take you to the top (home) line on the screen.
+Try preceding it with a
+number as in \fB3H\fR.
+This will take you to the third line on the screen.
+Many
+.I vi
+commands take preceding numbers and do interesting things with them.
+Try \fBM\fR,
+which takes you to the middle line on the screen,
+and \fBL\fR,
+which takes you to the last line on the screen.
+\fBL\fR also takes counts, thus
+\fB5L\fR will take you to the fifth line from the bottom.
+.NH 2
+Moving within a line
+.PP
+Now try picking a word on some line on the screen, not the
+first word on the line.
+move the cursor using \s-2RETURN\s0 and \fB\-\fR to be on the line where
+the word is.
+Try hitting the \fBw\fR key. This will advance the cursor to the
+next word on the line.
+Try hitting the \fBb\fR key to back up words
+in the line.
+Also try the \fBe\fR key which advances you to the end of the current
+word rather than to the beginning of the next word.
+Also try \s-2SPACE\s0 (the space bar) which moves right one character
+and the \s-2BS\s0 (backspace or \fB^H\fR) key which moves left one character.
+The key \fBh\fR works as \fB^H\fR does and is useful if you don't have
+a \s-2BS\s0 key.
+(Also, as noted just above, \fBl\fR will move to the right.)
+.PP
+If the line had punctuation in it you may have noticed that
+that the \fBw\fR and \fBb\fR
+keys stopped at each group of punctuation. You can also go back and
+forwards words without stopping at punctuation by using \fBW\fR and \fBB\fR
+rather than the lower case equivalents. Think of these as bigger words.
+Try these on a few lines with punctuation to see how they differ from
+the lower case \fBw\fR and \fBb\fR.
+.PP
+The word keys wrap around the end of line,
+rather than stopping at the end. Try moving to a word on a line below
+where you are by repeatedly hitting \fBw\fR.
+.NH 2
+Summary
+.IP
+.TS
+lw(.50i)b a.
+\fR\s-2SPACE\s0\fP advance the cursor one position
+^B backwards to previous page
+^D scrolls down in the file
+^E exposes another line at the bottom
+^F forward to next page
+^G tell what is going on
+^H backspace the cursor
+^N next line, same column
+^P previous line, same column
+^U scrolls up in the file
+^Y exposes another line at the top
++ next line, at the beginning
+\- previous line, at the beginning
+/ scan for a following string forwards
+? scan backwards
+B back a word, ignoring punctuation
+G go to specified line, last default
+H home screen line
+M middle screen line
+L last screen line
+W forward a word, ignoring punctuation
+b back a word
+e end of current word
+n scan for next instance of \fB/\fR or \fB?\fR pattern
+w word after this word
+.TE
+.NH 2
+View
+.PP
+If you want to use the editor to look at a file,
+rather than to make changes,
+invoke it as
+.I view
+instead of
+.I vi .
+This will set the
+.I readonly
+option which will prevent you from
+accidently overwriting the file.
+.sp
+.NH 1
+Making simple changes
+.NH 2
+Inserting
+.PP
+One of the most useful commands is the
+\fBi\fR (insert) command.
+After you type \fBi\fR, everything you type until you hit \s-2ESC\s0
+is inserted into the file.
+Try this now; position yourself to some word in the file and try inserting
+text before this word.
+If you are on an dumb terminal it will seem, for a minute,
+that some of the characters in your line have been overwritten, but they will
+reappear when you hit \s-2ESC\s0.
+.PP
+Now try finding a word which can, but does not, end in an `s'.
+Position yourself at this word and type \fBe\fR (move to end of word), then
+\fBa\fR for append and then `s\s-2ESC\s0' to terminate the textual insert.
+This sequence of commands can be used to easily pluralize a word.
+.PP
+Try inserting and appending a few times to make sure you understand how
+this works; \fBi\fR placing text to the left of the cursor, \fBa\fR to
+the right.
+.PP
+It is often the case that you want to add new lines to the file you are
+editing, before or after some specific line in the file. Find a line
+where this makes sense and then give the command \fBo\fR to create a
+new line after the line you are on, or the command \fBO\fR to create
+a new line before the line you are on. After you create a new line in
+this way, text you type up to an \s-2ESC\s0 is inserted on the new line.
+.PP
+Many related editor commands
+are invoked by the same letter key and differ only in that one is given
+by a lower
+case key and the other is given by
+an upper case key. In these cases, the
+upper case key often differs from the lower case key in its sense of
+direction, with
+the upper case key working backward and/or up, while the lower case
+key moves forward and/or down.
+.PP
+Whenever you are typing in text, you can give many lines of input or
+just a few characters.
+To type in more than one line of text,
+hit a \s-2RETURN\s0 at the middle of your input. A new line will be created
+for text, and you can continue to type. If you are on a slow
+and dumb terminal the editor may choose to wait to redraw the
+tail of the screen, and will let you type over the existing screen lines.
+This avoids the lengthy delay which would occur if the editor attempted
+to keep the tail of the screen always up to date. The tail of the screen will
+be fixed up, and the missing lines will reappear, when you hit \s-2ESC\s0.
+.PP
+While you are inserting new text, you can use the characters you normally use
+at the system command level (usually \fB^H\fR or \fB#\fR) to backspace
+over the last
+character which you typed, and the character which you use to kill input lines
+(usually \fB@\fR, \fB^X\fR, or \fB^U\fR)
+to erase the input you have typed on the current line.\*(dg
+.FS
+\*(dg In fact, the character \fB^H\fR (backspace) always works to erase the
+last input character here, regardless of what your erase character is.
+.FE
+The character \fB^W\fR
+will erase a whole word and leave you after the space after the previous
+word; it is useful for quickly backing up in an insert.
+.PP
+Notice that when you backspace during an insertion the characters you
+backspace over are not erased; the cursor moves backwards, and the characters
+remain on the display. This is often useful if you are planning to type
+in something similar. In any case the characters disappear when when
+you hit \s-2ESC\s0; if you want to get rid of them immediately, hit an
+\s-2ESC\s0 and then \fBa\fR again.
+.PP
+Notice also that you can't erase characters which you didn't insert, and that
+you can't backspace around the end of a line. If you need to back up
+to the previous line to make a correction, just hit \s-2ESC\s0 and move
+the cursor back to the previous line. After making the correction you
+can return to where you were and use the insert or append command again.
+.sp .5
+.NH 2
+Making small corrections
+.PP
+You can make small corrections in existing text quite easily.
+Find a single character which is wrong or just pick any character.
+Use the arrow keys to find the character, or
+get near the character with the word motion keys and then either
+backspace (hit the \s-2BS\s0 key or \fB^H\fR or even just \fBh\fR) or
+\s-2SPACE\s0 (using the space bar)
+until the cursor is on the character which is wrong.
+If the character is not needed then hit the \fBx\fP key; this deletes
+the character from the file. It is analogous to the way you \fBx\fP
+out characters when you make mistakes on a typewriter (except it's not
+as messy).
+.PP
+If the character
+is incorrect, you can replace it with the correct character by giving
+the command \fBr\fR\fIc\fR,
+where \fIc\fR is replaced by the correct character.
+Finally if the character which is incorrect should be replaced
+by more than one character, give the command \fBs\fR which substitutes
+a string of characters, ending with \s-2ESC\s0, for it.
+If there are a small number of characters
+which are wrong you can precede \fBs\fR with a count of the number of
+characters to be replaced. Counts are also useful with \fBx\fR to specify
+the number of characters to be deleted.
+.NH 2
+More corrections: operators
+.PP
+You already know almost enough to make changes at a higher level.
+All you need to know now is that the
+.B d
+key acts as a delete operator. Try the command
+.B dw
+to delete a word.
+Try hitting \fB.\fR a few times. Notice that this repeats the effect
+of the \fBdw\fR. The command \fB.\fR repeats the last command which
+made a change. You can remember it by analogy with an ellipsis `\fB...\fR'.
+.PP
+Now try
+\fBdb\fR.
+This deletes a word backwards, namely the preceding word.
+Try
+\fBd\fR\s-2SPACE\s0. This deletes a single character, and is equivalent
+to the \fBx\fR command.
+.PP
+Another very useful operator is
+.B c
+or change. The command
+.B cw
+thus changes the text of a single word.
+You follow it by the replacement text ending with an \s-2ESC\s0.
+Find a word which you can change to another, and try this
+now.
+Notice that the end of the text to be changed was marked with the character
+`$' so that you can see this as you are typing in the new material.
+.sp .5
+.NH 2
+Operating on lines
+.PP
+It is often the case that you want to operate on lines.
+Find a line which you want to delete, and type
+\fBdd\fR,
+the
+.B d
+operator twice. This will delete the line.
+If you are on a dumb terminal, the editor may just erase the line on
+the screen, replacing it with a line with only an @ on it. This line
+does not correspond to any line in your file, but only acts as a place
+holder. It helps to avoid a lengthy redraw of the rest of the screen
+which would be necessary to close up the hole created by the deletion
+on a terminal without a delete line capability.
+.PP
+Try repeating the
+.B c
+operator twice; this will change a whole line, erasing its previous contents and
+replacing them with text you type up to an \s-2ESC\s0.\*(dg
+.FS
+\*(dg The command \fBS\fR is a convenient synonym for for \fBcc\fR, by
+analogy with \fBs\fR. Think of \fBS\fR as a substitute on lines, while
+\fBs\fR is a substitute on characters.
+.FE
+.PP
+You can delete or change more than one line by preceding the
+.B dd
+or
+.B cc
+with a count, i.e. \fB5dd\fR deletes 5 lines.
+You can also give a command like \fBdL\fR to delete all the lines up to
+and including
+the last line on the screen, or \fBd3L\fR to delete through the third from
+the bottom line. Try some commands like this now.*
+.FS
+* One subtle point here involves using the \fB/\fR search after a \fBd\fR.
+This will normally delete characters from the current position to the
+point of the match. If what is desired is to delete whole lines
+including the two points, give the pattern as \fB/pat/+0\fR, a line address.
+.FE
+Notice that the editor lets you know when you change a large number of
+lines so that you can see the extent of the change.
+The editor will also always tell you when a change you make affects text which
+you cannot see.
+.NH 2
+Undoing
+.PP
+Now suppose that the last change which you made was incorrect;
+you could use the insert, delete and append commands to put the correct
+material back. However, since it is often the case that we regret a
+change or make a change incorrectly, the editor provides a
+.B u
+(undo) command to reverse the last change which you made.
+Try this a few times, and give it twice in a row to notice that an
+.B u
+also undoes a
+.B u.
+.PP
+The undo command lets you reverse only a single change. After you make
+a number of changes to a line, you may decide that you would rather have
+the original state of the line back. The
+.B U
+command restores the current line to the state before you started changing
+it.
+.PP
+You can recover text which you delete, even if
+undo will not bring it back; see the section on recovering lost text
+below.
+.NH 2
+Summary
+.IP
+.TS
+lw(.50i)b a.
+\fR\s-2SPACE\s0\fP advance the cursor one position
+^H backspace the cursor
+^W erase a word during an insert
+\fRerase\fP your erase (usually ^H or #), erases a character during an insert
+\fRkill\fP your kill (usually @, ^X, or ^U), kills the insert on this line
+\&\fB.\fP repeats the changing command
+O opens and inputs new lines, above the current
+U undoes the changes you made to the current line
+a appends text after the cursor
+c changes the object you specify to the following text
+d deletes the object you specify
+i inserts text before the cursor
+o opens and inputs new lines, below the current
+u undoes the last change
+.TE
+.NH 1
+Moving about; rearranging and duplicating text
+.NH 2
+Low level character motions
+.PP
+Now move the cursor to a line where there is a punctuation or a bracketing
+character such as a parenthesis or a comma or period. Try the command
+\fBf\fR\fIx\fR where \fIx\fR is this character. This command finds
+the next \fIx\fR character to the right of the cursor in the current
+line. Try then hitting a \fB;\fR, which finds the next instance of the
+same character. By using the \fBf\fR command and then a sequence of
+\fB;\fR's you can often
+get to a particular place in a line much faster than with a sequence
+of word motions or \s-2SPACE\s0s.
+There is also a \fBF\fR command, which is like \fBf\fR, but searches
+backward. The \fB;\fR command repeats \fBF\fR also.
+.PP
+When you are operating on the text in a line it is often desirable to
+deal with the characters up to, but not including, the first instance of
+a character. Try \fBdf\fR\fIx\fR for some \fIx\fR now and
+notice that the \fIx\fR character is deleted. Undo this with \fBu\fR
+and then try \fBdt\fR\fIx\fR; the \fBt\fR here stands for to, i.e.
+delete up to the next \fIx\fR, but not the \fIx\fR. The command \fBT\fR
+is the reverse of \fBt\fR.
+.PP
+When working with the text of a single line, an \fB\(ua\fR moves the
+cursor to the first non-white position on the line, and a
+\fB$\fR moves it to the end of the line. Thus \fB$a\fR will append new
+text at the end of the current line.
+.PP
+Your file may have tab (\fB^I\fR) characters in it. These
+characters are represented as a number of spaces expanding to a tab stop,
+where tab stops are every 8 positions.*
+.FS
+* This is settable by a command of the form \fB:se ts=\fR\fIx\fR\s-2CR\s0,
+where \fIx\fR is 4 to set tabstops every four columns. This has
+effect on the screen representation within the editor.
+.FE
+When the cursor is at a tab, it sits on the last of the several spaces
+which represent that tab. Try moving the cursor back and forth over
+tabs so you understand how this works.
+.PP
+On rare occasions, your file may have nonprinting characters in it.
+These characters are displayed in the same way they are represented in
+this document, that is with a two character code, the first character
+of which is `^'. On the screen non-printing characters resemble a `^'
+character adjacent to another, but spacing or backspacing over the character
+will reveal that the two characters are, like the spaces representing
+a tab character, a single character.
+.PP
+The editor sometimes discards control characters,
+depending on the character and the setting of the
+.I beautify
+option,
+if you attempt to insert them in your file.
+You can get a control character in the file by beginning
+an insert and then typing a \fB^V\fR before the control
+character. The
+\fB^V\fR quotes the following character, causing it to be
+inserted directly into the file.
+.PP
+.NH 2
+Higher level text objects
+.PP
+In working with a document it is often advantageous to work in terms
+of sentences, paragraphs, and sections. The operations \fB(\fR and \fB)\fR
+move to the beginning of the previous and next sentences respectively.
+Thus the command \fBd)\fR will delete the rest of the current sentence;
+likewise \fBd(\fR will delete the previous sentence if you are at the
+beginning of the current sentence, or the current sentence up to where
+you are if you are not at the beginning of the current sentence.
+.PP
+A sentence is defined to end at a `.', `!' or `?' which is followed by
+either the end of a line, or by two spaces. Any number of closing `)',
+`]', `"' and `\(aa' characters may appear after the `.', `!' or `?' before
+the spaces or end of line.
+.PP
+The operations \fB{\fR and \fB}\fR move over paragraphs and the operations
+\fB[[\fR and \fB]]\fR move over sections.\*(dg
+.FS
+\*(dg The \fB[[\fR and \fB]]\fR operations
+require the operation character to be doubled because they can move the
+cursor far from where it currently is. While it is easy to get back
+with the command \fB\(ga\(ga\fP,
+these commands would still be frustrating
+if they were easy to hit accidentally.
+.FE
+.PP
+A paragraph begins after each empty line, and also
+at each of a set of paragraph macros, specified by the pairs of characters
+in the definition of the string valued option \fIparagraphs\fR.
+The default setting for this option defines the paragraph macros of the
+\fI\-ms\fR and \fI\-mm\fR macro packages, i.e. the `.IP', `.LP', `.PP'
+and `.QP', `.P' and `.LI' macros.\*(dd
+.FS
+\*(dd You can easily change or extend this set of macros by assigning a
+different string to the \fIparagraphs\fR option in your EXINIT.
+See section 6.2 for details.
+The `.bp' directive is also considered to start a paragraph.
+.FE
+Each paragraph boundary is also a sentence boundary. The sentence
+and paragraph commands can
+be given counts to operate over groups of sentences and paragraphs.
+.PP
+Sections in the editor begin after each macro in the \fIsections\fR option,
+normally `.NH', `.SH', `.H' and `.HU', and each line with a formfeed \fB^L\fR
+in the first column.
+Section boundaries are always line and paragraph boundaries also.
+.PP
+Try experimenting with the sentence and paragraph commands until you are
+sure how they work. If you have a large document, try looking through
+it using the section commands.
+The section commands interpret a preceding count as a different window size in
+which to redraw the screen at the new location, and this window size
+is the base size for newly drawn windows until another size is specified.
+This is very useful
+if you are on a slow terminal and are looking for a particular section.
+You can give the first section command a small count to then see each successive
+section heading in a small window.
+.NH 2
+Rearranging and duplicating text
+.PP
+The editor has a single unnamed buffer where the last deleted or
+changed away text is saved, and a set of named buffers \fBa\fR\-\fBz\fR
+which you can use to save copies of text and to move text around in
+your file and between files.
+.PP
+The operator
+.B y
+yanks a copy of the object which follows into the unnamed buffer.
+If preceded by a buffer name, \fB"\fR\fIx\fR\|\fBy\fR, where
+\fIx\fR here is replaced by a letter \fBa\-z\fR, it places the text in the named
+buffer. The text can then be put back in the file with the commands
+.B p
+and
+.B P;
+\fBp\fR puts the text after or below the cursor, while \fBP\fR puts the text
+before or above the cursor.
+.PP
+If the text which you
+yank forms a part of a line, or is an object such as a sentence which
+partially spans more than one line, then when you put the text back,
+it will be placed after the cursor (or before if you
+use \fBP\fR). If the yanked text forms whole lines, they will be put
+back as whole lines, without changing the current line. In this case,
+the put acts much like a \fBo\fR or \fBO\fR command.
+.PP
+Try the command \fBYP\fR. This makes a copy of the current line and
+leaves you on this copy, which is placed before the current line.
+The command \fBY\fR is a convenient abbreviation for \fByy\fR.
+The command \fBYp\fR will also make a copy of the current line, and place
+it after the current line. You can give \fBY\fR a count of lines to
+yank, and thus duplicate several lines; try \fB3YP\fR.
+.PP
+To move text within the buffer, you need to delete it in one place, and
+put it back in another. You can precede a delete operation by the
+name of a buffer in which the text is to be stored as in \fB"a5dd\fR
+deleting 5 lines into the named buffer \fIa\fR. You can then move the
+cursor to the eventual resting place of the these lines and do a \fB"ap\fR
+or \fB"aP\fR to put them back.
+In fact, you can switch and edit another file before you put the lines
+back, by giving a command of the form \fB:e \fR\fIname\fR\s-2CR\s0 where
+\fIname\fR is the name of the other file you want to edit. You will
+have to write back the contents of the current editor buffer (or discard
+them) if you have made changes before the editor will let you switch
+to the other file.
+An ordinary delete command saves the text in the unnamed buffer,
+so that an ordinary put can move it elsewhere.
+However, the unnamed buffer is lost when you change files,
+so to move text from one file to another you should use an unnamed buffer.
+.NH 2
+Summary.
+.IP
+.TS
+lw(.50i)b a.
+\(ua first non-white on line
+$ end of line
+) forward sentence
+} forward paragraph
+]] forward section
+( backward sentence
+{ backward paragraph
+[[ backward section
+f\fIx\fR find \fIx\fR forward in line
+p put text back, after cursor or below current line
+y yank operator, for copies and moves
+t\fIx\fR up to \fIx\fR forward, for operators
+F\fIx\fR f backward in line
+P put text back, before cursor or above current line
+T\fIx\fR t backward in line
+.TE
+.ne 1i
+.NH 1
+High level commands
+.NH 2
+Writing, quitting, editing new files
+.PP
+So far we have seen how to enter
+.I vi
+and to write out our file using either
+\fBZZ\fR or \fB:w\fR\s-2CR\s0. The first exits from
+the editor,
+(writing if changes were made),
+the second writes and stays in the editor.
+.PP
+If you have changed the editor's copy of the file but do not wish to
+save your changes, either because you messed up the file or decided that the
+changes are not an improvement to the file, then you can give the command
+\fB:q!\fR\s-2CR\s0 to quit from the editor without writing the changes.
+You can also reedit the same file (starting over) by giving the command
+\fB:e!\fR\s-2CR\s0. These commands should be used only rarely, and with
+caution, as it is not possible to recover the changes you have made after
+you discard them in this manner.
+.PP
+You can edit a different file without leaving the editor by giving the
+command \fB:e\fR\ \fIname\fR\s-2CR\s0. If you have not written out
+your file before you try to do this, then the editor will tell you this,
+and delay editing the other file. You can then give the command
+\fB:w\fR\s-2CR\s0 to save your work and then the \fB:e\fR\ \fIname\fR\s-2CR\s0
+command again, or carefully give the command \fB:e!\fR\ \fIname\fR\s-2CR\s0,
+which edits the other file discarding the changes you have made to the
+current file.
+To have the editor automatically save changes,
+include
+.I "set autowrite"
+in your EXINIT,
+and use \fB:n\fP instead of \fB:e\fP.
+.NH 2
+Escaping to a shell
+.PP
+You can get to a shell to execute a single command by giving a
+.I vi
+command of the form \fB:!\fIcmd\fR\s-2CR\s0.
+The system will run the single command
+.I cmd
+and when the command finishes, the editor will ask you to hit a \s-2RETURN\s0
+to continue. When you have finished looking at the output on the screen,
+you should hit \s-2RETURN\s0 and the editor will clear the screen and
+redraw it. You can then continue editing.
+You can also give another \fB:\fR command when it asks you for a \s-2RETURN\s0;
+in this case the screen will not be redrawn.
+.PP
+If you wish to execute more than one command in the shell, then you can
+give the command \fB:sh\fR\s-2CR\s0.
+This will give you a new shell, and when you finish with the shell, ending
+it by typing a \fB^D\fR, the editor will clear the screen and continue.
+.PP
+On systems which support it, \fB^Z\fP will suspend the editor
+and return to the (top level) shell.
+When the editor is resumed, the screen will be redrawn.
+.NH 2
+Marking and returning
+.PP
+The command \fB\(ga\(ga\fR returned to the previous place
+after a motion of the cursor by a command such as \fB/\fR, \fB?\fR or
+\fBG\fR. You can also mark lines in the file with single letter tags
+and return to these marks later by naming the tags. Try marking the
+current line with the command \fBm\fR\fIx\fR, where you should pick some
+letter for \fIx\fR, say `a'. Then move the cursor to a different line
+(any way you like) and hit \fB\(gaa\fR. The cursor will return to the
+place which you marked.
+Marks last only until you edit another file.
+.PP
+When using operators such as
+.B d
+and referring to marked lines, it is often desirable to delete whole lines
+rather than deleting to the exact position in the line marked by \fBm\fR.
+In this case you can use the form \fB\(aa\fR\fIx\fR rather than
+\fB\(ga\fR\fIx\fR. Used without an operator, \fB\(aa\fR\fIx\fR will move to
+the first non-white character of the marked line; similarly \fB\(aa\(aa\fR
+moves to the first non-white character of the line containing the previous
+context mark \fB\(ga\(ga\fR.
+.NH 2
+Adjusting the screen
+.PP
+If the screen image is messed up because of a transmission error to your
+terminal, or because some program other than the editor wrote output
+to your terminal, you can hit a \fB^L\fR, the \s-2ASCII\s0 form-feed
+character, to cause the screen to be refreshed.
+.PP
+On a dumb terminal, if there are @ lines in the middle of the screen
+as a result of line deletion, you may get rid of these lines by typing
+\fB^R\fR to cause the editor to retype the screen, closing up these holes.
+.PP
+Finally, if you wish to place a certain line on the screen at the top
+middle or bottom of the screen, you can position the cursor to that line,
+and then give a \fBz\fR command.
+You should follow the \fBz\fR command with a \s-2RETURN\s0 if you want
+the line to appear at the top of the window, a \fB.\fR if you want it
+at the center, or a \fB\-\fR if you want it at the bottom.
+.NH 1
+Special topics
+.NH 2
+Editing on slow terminals
+.PP
+When you are on a slow terminal, it is important to limit the amount
+of output which is generated to your screen so that you will not suffer
+long delays, waiting for the screen to be refreshed. We have already
+pointed out how the editor optimizes the updating of the screen during
+insertions on dumb terminals to limit the delays, and how the editor erases
+lines to @ when they are deleted on dumb terminals.
+.PP
+The use of the slow terminal insertion mode is controlled by the
+.I slowopen
+option. You can force the editor to use this mode even on faster terminals
+by giving the command \fB:se slow\fR\s-2CR\s0. If your system is sluggish
+this helps lessen the amount of output coming to your terminal.
+You can disable this option by \fB:se noslow\fR\s-2CR\s0.
+.PP
+The editor can simulate an intelligent terminal on a dumb one. Try
+giving the command \fB:se redraw\fR\s-2CR\s0. This simulation generates
+a great deal of output and is generally tolerable only on lightly loaded
+systems and fast terminals. You can disable this by giving the command
+ \fB:se noredraw\fR\s-2CR\s0.
+.PP
+The editor also makes editing more pleasant at low speed by starting
+editing in a small window, and letting the window expand as you edit.
+This works particularly well on intelligent terminals. The editor can
+expand the window easily when you insert in the middle of the screen
+on these terminals. If possible, try the editor on an intelligent terminal
+to see how this works.
+.PP
+You can control the size of the window which is redrawn each time the
+screen is cleared by giving window sizes as argument to the commands
+which cause large screen motions:
+.DS
+.B ": / ? [[ ]] \(ga \(aa"
+.DE
+Thus if you are searching for a particular instance of a common string
+in a file you can precede the first search command by a small number,
+say 3, and the editor will draw three line windows around each instance
+of the string which it locates.
+.PP
+You can easily expand or contract the window, placing the current line
+as you choose, by giving a number on a \fBz\fR command, after the \fBz\fR
+and before the following \s-2RETURN\s0, \fB.\fR or \fB\-\fR. Thus the
+command \fBz5.\fR redraws the screen with the current line in the center
+of a five line window.\*(dg
+.FS
+\*(dg Note that the command \fB5z.\fR has an entirely different effect,
+placing line 5 in the center of a new window.
+.FE
+.PP
+If the editor is redrawing or otherwise updating large portions of the
+display, you can interrupt this updating by hitting a \s-2DEL\s0 or \s-2RUB\s0
+as usual. If you do this you may partially confuse the editor about
+what is displayed on the screen. You can still edit the text on
+the screen if you wish; clear up the confusion
+by hitting a \fB^L\fR; or move or search again, ignoring the
+current state of the display.
+.PP
+See section 7.8 on \fIopen\fR mode for another way to use the
+.I vi
+command set on slow terminals.
+.NH 2
+Options, set, and editor startup files
+.PP
+The editor has a set of options, some of which have been mentioned above.
+The most useful options are given in the following table.
+.PP
+The options are of three kinds: numeric options, string options, and
+toggle options. You can set numeric and string options by a statement
+of the form
+.DS
+\fBset\fR \fIopt\fR\fB=\fR\fIval\fR
+.DE
+and toggle options can be set or unset by statements of one of the forms
+.DS
+\fBset\fR \fIopt\fR
+\fBset\fR \fBno\fR\fIopt\fR
+.DE
+.KF
+.TS
+lb lb lb lb
+l l l a.
+Name Default Description
+_
+autoindent noai Supply indentation automatically
+autowrite noaw Automatic write before \fB:n\fR, \fB:ta\fR, \fB^\(ua\fR, \fB!\fR
+ignorecase noic Ignore case in searching
+lisp nolisp \fB( { ) }\fR commands deal with S-expressions
+list nolist Tabs print as ^I; end of lines marked with $
+magic nomagic The characters . [ and * are special in scans
+number nonu Lines are displayed prefixed with line numbers
+paragraphs para=IPLPPPQPbpP LI Macro names which start paragraphs
+redraw nore Simulate a smart terminal on a dumb one
+sections sect=NHSHH HU Macro names which start new sections
+shiftwidth sw=8 Shift distance for <, > and input \fB^D\fP and \fB^T\fR
+showmatch nosm Show matching \fB(\fP or \fB{\fP as \fB)\fP or \fB}\fR is typed
+slowopen slow Postpone display updates during inserts
+term dumb The kind of terminal you are using.
+.TE
+.KE
+These statements can be placed in your EXINIT in your environment,
+or given while you are running
+.I vi
+by preceding them with a \fB:\fR and following them with a \s-2CR\s0.
+.PP
+You can get a list of all options which you have changed by the
+command \fB:set\fR\s-2CR\s0, or the value of a single option by the
+command \fB:set\fR \fIopt\fR\fB?\fR\s-2CR\s0.
+A list of all possible options and their values is generated by
+\fB:set all\fP\s-2CR\s0.
+Set can be abbreviated \fBse\fP.
+Multiple options can be placed on one line, e.g.
+\fB:se ai aw nu\fP\s-2CR\s0.
+.PP
+Options set by the \fBset\fP command only last
+while you stay in the editor.
+It is common to want to have certain options set whenever you
+use the editor.
+This can be accomplished by creating a list of \fIex\fP commands\*(dg
+.FS
+\*(dg
+All commands which start with
+.B :
+are \fIex\fP commands.
+.FE
+which are to be run every time you start up \fIex\fP, \fIedit\fP,
+or \fIvi\fP.
+A typical list includes a \fBset\fP command, and possibly a few
+\fBmap\fP commands.
+Since it is advisable to get these commands on one line, they can
+be separated with the | character, for example:
+.DS
+\fBset\fP ai aw terse|\fBmap\fP @ dd|\fBmap\fP # x
+.DE
+which sets the options \fIautoindent\fP, \fIautowrite\fP, \fIterse\fP,
+(the
+.B set
+command),
+makes @ delete a line,
+(the first
+.B map ),
+and makes # delete a character,
+(the second
+.B map ).
+(See section 6.9 for a description of the \fBmap\fP command)
+This string should be placed in the variable EXINIT in your environment.
+If you use the shell \fIcsh\fP,
+put this line in the file
+.I .login
+in your home directory:
+.DS
+setenv EXINIT \(aa\fBset\fP ai aw terse|\fBmap\fP @ dd|\fBmap\fP # x\(aa
+.DE
+If you use the standard shell \fIsh\fP,
+put these lines in the file
+.I .profile
+in your home directory:
+.DS
+EXINIT=\(aa\fBset\fP ai aw terse|\fBmap\fP @ dd|\fBmap\fP # x\(aa
+export EXINIT
+.DE
+Of course, the particulars of the line would depend on which options
+you wanted to set.
+.NH 2
+Recovering lost lines
+.PP
+You might have a serious problem if you delete a number of lines and then
+regret that they were deleted. Despair not, the editor saves the last
+9 deleted blocks of text in a set of numbered registers 1\-9.
+You can get the \fIn\fR'th previous deleted text back in your file by
+the command
+"\fR\fIn\fR\|\fBp\fR.
+The "\fR here says that a buffer name is to follow,
+\fIn\fR is the number of the buffer you wish to try
+(use the number 1 for now),
+and
+.B p
+is the put command, which puts text in the buffer after the cursor.
+If this doesn't bring back the text you wanted, hit
+.B u
+to undo this and then
+\fB\&.\fR
+(period)
+to repeat the put command.
+In general the
+\fB\&.\fR
+command will repeat the last change you made.
+As a special case, when the last command refers to a numbered text buffer,
+the \fB.\fR command increments the number of the buffer before repeating
+the command. Thus a sequence of the form
+.DS
+\fB"1pu.u.u.\fR
+.DE
+will, if repeated long enough, show you all the deleted text which has
+been saved for you.
+You can omit the
+.B u
+commands here to gather up all this text in the buffer, or stop after any
+\fB\&.\fR command to keep just the then recovered text.
+The command
+.B P
+can also be used rather than
+.B p
+to put the recovered text before rather than after the cursor.
+.NH 2
+Recovering lost files
+.PP
+If the system crashes, you can recover the work you were doing
+to within a few changes. You will normally receive mail when you next
+login giving you the name of the file which has been saved for you.
+You should then change to the directory where you were when the system
+crashed and give a command of the form:
+.DS
+% \fBvi \-r\fR \fIname\fR
+.DE
+replacing \fIname\fR with the name of the file which you were editing.
+This will recover your work to a point near where you left off.\*(dg
+.FS
+\*(dg In rare cases, some of the lines of the file may be lost. The
+editor will give you the numbers of these lines and the text of the lines
+will be replaced by the string `LOST'. These lines will almost always
+be among the last few which you changed. You can either choose to discard
+the changes which you made (if they are easy to remake) or to replace
+the few lost lines by hand.
+.FE
+.PP
+You can get a listing of the files which are saved for you by giving
+the command:
+.DS
+% \fBvi \-r\fR
+.DE
+If there is more than one instance of a particular file saved, the editor
+gives you the newest instance each time you recover it. You can thus
+get an older saved copy back by first recovering the newer copies.
+.PP
+For this feature to work,
+.I vi
+must be correctly installed by a super user on your system,
+and the
+.I mail
+program must exist to receive mail.
+The invocation ``\fIvi -r\fP'' will not always list all saved files,
+but they can be recovered even if they are not listed.
+.NH 2
+Continuous text input
+.PP
+When you are typing in large amounts of text it is convenient to have
+lines broken near the right margin automatically. You can cause this
+to happen by giving the command
+\fB:se wm=10\fR\s-2CR\s0.
+This causes all lines to be broken at a space at least 10 columns
+from the right hand edge of the screen.
+.PP
+If the editor breaks an input line and you wish to put it back together
+you can tell it to join the lines with \fBJ\fR. You can give \fBJ\fR
+a count of the number of lines to be joined as in \fB3J\fR to join 3
+lines. The editor supplies white space, if appropriate,
+at the juncture of the joined
+lines, and leaves the cursor at this white space.
+You can kill the white space with \fBx\fR if you don't want it.
+.NH 2
+Features for editing programs
+.PP
+The editor has a number of commands for editing programs.
+The thing that most distinguishes editing of programs from editing of text
+is the desirability of maintaining an indented structure to the body of
+the program. The editor has a
+.I autoindent
+facility for helping you generate correctly indented programs.
+.PP
+To enable this facility you can give the command \fB:se ai\fR\s-2CR\s0.
+Now try opening a new line with \fBo\fR and type some characters on the
+line after a few tabs. If you now start another line, notice that the
+editor supplies white space at the beginning of the line to line it up
+with the previous line. You cannot backspace over this indentation,
+but you can use \fB^D\fR key to backtab over the supplied indentation.
+.PP
+Each time you type \fB^D\fR you back up one position, normally to an
+8 column boundary. This amount is settable; the editor has an option
+called
+.I shiftwidth
+which you can set to change this value.
+Try giving the command \fB:se sw=4\fR\s-2CR\s0
+and then experimenting with autoindent again.
+.PP
+For shifting lines in the program left and right, there are operators
+.B <
+and
+.B >.
+These shift the lines you specify right or left by one
+.I shiftwidth.
+Try
+.B <<
+and
+.B >>
+which shift one line left or right, and
+.B <L
+and
+.B >L
+shifting the rest of the display left and right.
+.PP
+If you have a complicated expression and wish to see how the parentheses
+match, put the cursor at a left or right parenthesis and hit \fB%\fR.
+This will show you the matching parenthesis.
+This works also for braces { and }, and brackets [ and ].
+.PP
+If you are editing C programs, you can use the \fB[[\fR and \fB]]\fR keys
+to advance or retreat to a line starting with a \fB{\fR, i.e. a function
+declaration at a time. When \fB]]\fR is used with an operator it stops
+after a line which starts with \fB}\fR; this is sometimes useful with
+\fBy]]\fR.
+.NH 2
+Filtering portions of the buffer
+.PP
+You can run system commands over portions of the buffer using the operator
+\fB!\fR.
+You can use this to sort lines in the buffer, or to reformat portions
+of the buffer with a pretty-printer.
+Try typing in a list of random words, one per line and ending them
+with a blank line. Back up to the beginning of the list, and then give
+the command \fB!}sort\fR\s-2CR\s0. This says to sort the next paragraph
+of material, and the blank line ends a paragraph.
+.NH 2
+Commands for editing \s-2LISP\s0
+.PP
+If you are editing a \s-2LISP\s0 program you should set the option
+.I lisp
+by doing
+\fB:se\ lisp\fR\s-2CR\s0.
+This changes the \fB(\fR and \fB)\fR commands to move backward and forward
+over s-expressions.
+The \fB{\fR and \fB}\fR commands are like \fB(\fR and \fB)\fR but don't
+stop at atoms. These can be used to skip to the next list, or through
+a comment quickly.
+.PP
+The
+.I autoindent
+option works differently for \s-2LISP\s0, supplying indent to align at
+the first argument to the last open list. If there is no such argument
+then the indent is two spaces more than the last level.
+.PP
+There is another option which is useful for typing in \s-2LISP\s0, the
+.I showmatch
+option.
+Try setting it with
+\fB:se sm\fR\s-2CR\s0
+and then try typing a `(' some words and then a `)'. Notice that the
+cursor shows the position of the `(' which matches the `)' briefly.
+This happens only if the matching `(' is on the screen, and the cursor
+stays there for at most one second.
+.PP
+The editor also has an operator to realign existing lines as though they
+had been typed in with
+.I lisp
+and
+.I autoindent
+set. This is the \fB=\fR operator.
+Try the command \fB=%\fR at the beginning of a function. This will realign
+all the lines of the function declaration.
+.PP
+When you are editing \s-2LISP\s0,, the \fB[[\fR and \fR]]\fR advance
+and retreat to lines beginning with a \fB(\fR, and are useful for dealing
+with entire function definitions.
+.NH 2
+Macros
+.PP
+.I Vi
+has a parameterless macro facility, which lets you set it up so that
+when you hit a single keystroke, the editor will act as though
+you had hit some longer sequence of keys. You can set this up if
+you find yourself typing the same sequence of commands repeatedly.
+.PP
+Briefly, there are two flavors of macros:
+.IP a)
+Ones where you put the macro body in a buffer register, say \fIx\fR.
+You can then type \fB@x\fR to invoke the macro. The \fB@\fR may be followed
+by another \fB@\fR to repeat the last macro.
+.IP b)
+You can use the
+.I map
+command from
+.I vi
+(typically in your
+.I EXINIT )
+with a command of the form:
+.DS
+:map \fIlhs\fR \fIrhs\fR\s-2CR
+.DE
+mapping
+.I lhs
+into
+.I rhs.
+There are restrictions:
+.I lhs
+should be one keystroke (either 1 character or one function key)
+since it must be entered within one second
+(unless
+.I notimeout
+is set, in which case you can type it as slowly as you wish,
+and
+.I vi
+will wait for you to finish it before it echoes anything).
+The
+.I lhs
+can be no longer than 10 characters, the
+.I rhs
+no longer than 100.
+To get a space, tab or newline into
+.I lhs
+or
+.I rhs
+you should escape them with a \fB^V\fR.
+(It may be necessary to double the \fB^V\fR if the map
+command is given inside
+.I vi,
+rather than in
+.I ex.)
+Spaces and tabs inside the
+.I rhs
+need not be escaped.
+.PP
+Thus to make the \fBq\fR key write and exit the editor, you can give
+the command
+.DS
+:map q :wq\fB^V^V\fP\s-2CR CR\s0
+.DE
+which means that whenever you type \fBq\fR, it will be as though you
+had typed the four characters \fB:wq\fR\s-2CR\s0.
+A \fB^V\fR's is needed because without it the \s-2CR\s0 would end the
+\fB:\fR command, rather than becoming part of the
+.I map
+definition.
+There are two
+.B ^V 's
+because from within
+.I vi ,
+two
+.B ^V 's
+must be typed to get one.
+The first \s-2CR\s0 is part of the
+.I rhs ,
+the second terminates the : command.
+.PP
+Macros can be deleted with
+.DS
+unmap lhs
+.DE
+.PP
+If the
+.I lhs
+of a macro is ``#0'' through ``#9'', this maps the particular function key
+instead of the 2 character ``#'' sequence. So that terminals without
+function keys can access such definitions, the form ``#x'' will mean function
+key
+.I x
+on all terminals (and need not be typed within one second.)
+The character ``#'' can be changed by using a macro in the usual way:
+.DS
+:map \fB^V^V^I\fP #
+.DE
+to use tab, for example. (This won't affect the
+.I map
+command, which still uses
+.B #,
+but just the invocation from visual mode.
+.PP
+The undo command reverses an entire macro call as a unit,
+if it made any changes.
+.PP
+Placing a `!' after the word
+.B map
+causes the mapping to apply
+to input mode, rather than command mode.
+Thus, to arrange for \fB^T\fP to be the same as 4 spaces in input mode,
+you can type:
+.DS
+:map \fB^T\fP \fB^V\fP\o'b/'\o'b/'\o'b/'\o'b/'
+.DE
+where
+.B \o'b/'
+is a blank.
+The \fB^V\fP is necessary to prevent the blanks from being taken as
+white space between the
+.I lhs
+and
+.I rhs .
+.NH
+Word Abbreviations
+.PP
+A feature similar to macros in input mode is word abbreviation.
+This allows you to type a short word and have it expanded into
+a longer word or words.
+The commands are
+.B :abbreviate
+and
+.B :unabbreviate
+(\fB:ab\fP
+and
+.B :una )
+and have the same syntax as
+.B :map .
+For example:
+.DS
+:ab eecs Electrical Engineering and Computer Sciences
+.DE
+causes the word `eecs' to always be changed into the
+phrase `Electrical Engineering and Computer Sciences'.
+Word abbreviation is different from macros in that
+only whole words are affected.
+If `eecs' were typed as part of a larger word, it would
+be left alone.
+Also, the partial word is echoed as it is typed.
+There is no need for an abbreviation to be a single keystroke,
+as it should be with a macro.
+.NH 2
+Abbreviations
+.PP
+The editor has a number of short
+commands which abbreviate longer commands which we
+have introduced here. You can find these commands easily
+on the quick reference card.
+They often save a bit of typing and you can learn them as convenient.
+.NH 1
+Nitty-gritty details
+.NH 2
+Line representation in the display
+.PP
+The editor folds long logical lines onto many physical lines in the display.
+Commands which advance lines advance logical lines and will skip
+over all the segments of a line in one motion. The command \fB|\fR moves
+the cursor to a specific column, and may be useful for getting near the
+middle of a long line to split it in half. Try \fB80|\fR on a line which
+is more than 80 columns long.\*(dg
+.FS
+\*(dg You can make long lines very easily by using \fBJ\fR to join together
+short lines.
+.FE
+.PP
+The editor only puts full lines on the display; if there is not enough
+room on the display to fit a logical line, the editor leaves the physical
+line empty, placing only an @ on the line as a place holder. When you
+delete lines on a dumb terminal, the editor will often just clear the
+lines to @ to save time (rather than rewriting the rest of the screen.)
+You can always maximize the information on the screen by giving the \fB^R\fR
+command.
+.PP
+If you wish, you can have the editor place line numbers before each line
+on the display. Give the command \fB:se nu\fR\s-2CR\s0 to enable
+this, and the command \fB:se nonu\fR\s-2CR\s0 to turn it off.
+You can have tabs represented as \fB^I\fR and the ends of lines indicated
+with `$' by giving the command \fB:se list\fR\s-2CR\s0;
+\fB:se nolist\fR\s-2CR\s0 turns this off.
+.PP
+Finally, lines consisting of only the character `~' are displayed when
+the last line in the file is in the middle of the screen. These represent
+physical lines which are past the logical end of file.
+.NH 2
+Counts
+.PP
+Most
+.I vi
+commands will use a preceding count to affect their behavior in some way.
+The following table gives the common ways in which the counts are used:
+.DS
+.TS
+l lb.
+new window size : / ? [[ ]] \` \'
+scroll amount ^D ^U
+line/column number z G |
+repeat effect \fRmost of the rest\fP
+.TE
+.DE
+.PP
+The editor maintains a notion of the current default window size.
+On terminals which run at speeds greater than 1200 baud
+the editor uses the full terminal screen.
+On terminals which are slower than 1200 baud
+(most dialup lines are in this group)
+the editor uses 8 lines as the default window size.
+At 1200 baud the default is 16 lines.
+.PP
+This size is the size used when the editor clears and refills the screen
+after a search or other motion moves far from the edge of the current window.
+The commands which take a new window size as count all often cause the
+screen to be redrawn. If you anticipate this, but do not need as large
+a window as you are currently using, you may wish to change the screen
+size by specifying the new size before these commands.
+In any case, the number of lines used on the screen will expand if you
+move off the top with a \fB\-\fR or similar command or off the bottom
+with a command such as \s-2RETURN\s0 or \fB^D\fR.
+The window will revert to the last specified size the next time it is
+cleared and refilled.\*(dg
+.FS
+\*(dg But not by a \fB^L\fR which just redraws the screen as it is.
+.FE
+.PP
+The scroll commands \fB^D\fR and \fB^U\fR likewise remember the amount
+of scroll last specified, using half the basic window size initially.
+The simple insert commands use a count to specify a repetition of the
+inserted text. Thus \fB10a+\-\-\-\-\fR\s-2ESC\s0 will insert a grid-like
+string of text.
+A few commands also use a preceding count as a line or column number.
+.PP
+Except for a few commands which ignore any counts (such as \fB^R\fR),
+the rest of the editor commands use a count to indicate a simple repetition
+of their effect. Thus \fB5w\fR advances five words on the current line,
+while \fB5\fR\s-2RETURN\s0 advances five lines. A very useful instance
+of a count as a repetition is a count given to the \fB.\fR command, which
+repeats the last changing command. If you do \fBdw\fR and then \fB3.\fR,
+you will delete first one and then three words. You can then delete
+two more words with \fB2.\fR.
+.NH 2
+More file manipulation commands
+.PP
+The following table lists the file manipulation commands which you can
+use when you are in
+.I vi.
+.KF
+.DS
+.TS
+lb l.
+:w write back changes
+:wq write and quit
+:x write (if necessary) and quit (same as ZZ).
+:e \fIname\fP edit file \fIname\fR
+:e! reedit, discarding changes
+:e + \fIname\fP edit, starting at end
+:e +\fIn\fP edit, starting at line \fIn\fP
+:e # edit alternate file
+:w \fIname\fP write file \fIname\fP
+:w! \fIname\fP overwrite file \fIname\fP
+:\fIx,y\fPw \fIname\fP write lines \fIx\fP through \fIy\fP to \fIname\fP
+:r \fIname\fP read file \fIname\fP into buffer
+:r !\fIcmd\fP read output of \fIcmd\fP into buffer
+:n edit next file in argument list
+:n! edit next file, discarding changes to current
+:n \fIargs\fP specify new argument list
+:ta \fItag\fP edit file containing tag \fItag\fP, at \fItag\fP
+.TE
+.DE
+.KE
+All of these commands are followed by a \s-2CR\s0 or \s-2ESC\s0.
+The most basic commands are \fB:w\fR and \fB:e\fR.
+A normal editing session on a single file will end with a \fBZZ\fR command.
+If you are editing for a long period of time you can give \fB:w\fR commands
+occasionally after major amounts of editing, and then finish
+with a \fBZZ\fR. When you edit more than one file, you can finish
+with one with a \fB:w\fR and start editing a new file by giving a \fB:e\fR
+command,
+or set
+.I autowrite
+and use \fB:n\fP <file>.
+.PP
+If you make changes to the editor's copy of a file, but do not wish to
+write them back, then you must give an \fB!\fR after the command you
+would otherwise use; this forces the editor to discard any changes
+you have made. Use this carefully.
+.ne 1i
+.PP
+The \fB:e\fR command can be given a \fB+\fR argument to start at the
+end of the file, or a \fB+\fR\fIn\fR argument to start at line \fIn\fR\^.
+In actuality, \fIn\fR may be any editor command not containing a space,
+usefully a scan like \fB+/\fIpat\fR or \fB+?\fIpat\fR.
+In forming new names to the \fBe\fR command, you can use the character
+\fB%\fR which is replaced by the current file name, or the character
+\fB#\fR which is replaced by the alternate file name.
+The alternate file name is generally the last name you typed other than
+the current file. Thus if you try to do a \fB:e\fR and get a diagnostic
+that you haven't written the file, you can give a \fB:w\fR command and
+then a \fB:e #\fR command to redo the previous \fB:e\fR.
+.PP
+You can write part of the buffer to a file by finding out the lines
+that bound the range to be written using \fB^G\fR, and giving these
+numbers after the \fB:\fR
+and before the \fBw\fP, separated by \fB,\fR's.
+You can also mark these lines with \fBm\fR and
+then use an address of the form \fB\(aa\fR\fIx\fR\fB,\fB\(aa\fR\fIy\fR
+on the \fBw\fR command here.
+.PP
+You can read another file into the buffer after the current line by using
+the \fB:r\fR command.
+You can similarly read in the output from a command, just use \fB!\fR\fIcmd\fR
+instead of a file name.
+.PP
+If you wish to edit a set of files in succession, you can give all the
+names on the command line, and then edit each one in turn using the command
+\fB:n\fR. It is also possible to respecify the list of files to be edited
+by giving the \fB:n\fR command a list of file names, or a pattern to
+be expanded as you would have given it on the initial
+.I vi
+command.
+.PP
+If you are editing large programs, you will find the \fB:ta\fR command
+very useful. It utilizes a data base of function names and their locations,
+which can be created by programs such as
+.I ctags,
+to quickly find a function whose name you give.
+If the \fB:ta\fR command will require the editor to switch files, then
+you must \fB:w\fR or abandon any changes before switching. You can repeat
+the \fB:ta\fR command without any arguments to look for the same tag
+again.
+.NH 2
+More about searching for strings
+.PP
+When you are searching for strings in the file with \fB/\fR and \fB?\fR,
+the editor normally places you at the next or previous occurrence
+of the string. If you are using an operator such as \fBd\fR,
+\fBc\fR or \fBy\fR, then you may well wish to affect lines up to the
+line before the line containing the pattern. You can give a search of
+the form \fB/\fR\fIpat\fR\fB/\-\fR\fIn\fR to refer to the \fIn\fR'th line
+before the next line containing \fIpat\fR, or you can use \fB+\fR instead
+of \fB\-\fR to refer to the lines after the one containing \fIpat\fR.
+If you don't give a line offset, then the editor will affect characters
+up to the match place, rather than whole lines; thus use ``+0'' to affect
+to the line which matches.
+.PP
+You can have the editor ignore the case of words in the searches it does
+by giving the command \fB:se ic\fR\s-2CR\s0.
+The command \fB:se noic\fR\s-2CR\s0 turns this off.
+.ne 1i
+.PP
+Strings given to searches may actually be regular expressions.
+If you do not want or need this facility, you should
+.DS
+set nomagic
+.DE
+in your EXINIT.
+In this case,
+only the characters \fB\(ua\fR and \fB$\fR are special in patterns.
+The character \fB\e\fR is also then special (as it is most everywhere in
+the system), and may be used to get at the
+an extended pattern matching facility.
+It is also necessary to use a \e before a
+\fB/\fR in a forward scan or a \fB?\fR in a backward scan, in any case.
+The following table gives the extended forms when \fBmagic\fR is set.
+.DS
+.TS
+lb l.
+\(ua at beginning of pattern, matches beginning of line
+$ at end of pattern, matches end of line
+\fB\&.\fR matches any character
+\e< matches the beginning of a word
+\e> matches the end of a word
+[\fIstr\fP] matches any single character in \fIstr\fP
+[\(ua\fIstr\fP] matches any single character not in \fIstr\fP
+[\fIx\fP\-\fIy\fP] matches any character between \fIx\fP and \fIy\fP
+* matches any number of the preceding pattern
+.TE
+.DE
+If you use \fBnomagic\fR mode, then
+the \fB. [\fR and \fB*\fR primitives are given with a preceding
+\e.
+.NH 2
+More about input mode
+.PP
+There are a number of characters which you can use to make corrections
+during input mode. These are summarized in the following table.
+.sp .5
+.DS
+.TS
+lb l.
+^H deletes the last input character
+^W deletes the last input word, defined as by \fBb\fR
+erase your erase character, same as \fB^H\fP
+kill your kill character, deletes the input on this line
+\e escapes a following \fB^H\fP and your erase and kill
+\s-2ESC\s0 ends an insertion
+\s-2DEL\s0 interrupts an insertion, terminating it abnormally
+\s-2CR\s0 starts a new line
+^D backtabs over \fIautoindent\fP
+0^D kills all the \fIautoindent\fP
+\(ua^D same as \fB0^D\fP, but restores indent next line
+^V quotes the next non-printing character into the file
+.TE
+.DE
+.sp .5
+.PP
+The most usual way of making corrections to input is by typing \fB^H\fR
+to correct a single character, or by typing one or more \fB^W\fR's to
+back over incorrect words. If you use \fB#\fR as your erase character
+in the normal system, it will work like \fB^H\fR.
+.PP
+Your system kill character, normally \fB@\fR, \fB^X\fP or \fB^U\fR,
+will erase all
+the input you have given on the current line.
+In general, you can neither
+erase input back around a line boundary nor can you erase characters
+which you did not insert with this insertion command. To make corrections
+on the previous line after a new line has been started you can hit \s-2ESC\s0
+to end the insertion, move over and make the correction, and then return
+to where you were to continue. The command \fBA\fR which appends at the
+end of the current line is often useful for continuing.
+.PP
+If you wish to type in your erase or kill character (say # or @) then
+you must precede it with a \fB\e\fR, just as you would do at the normal
+system command level. A more general way of typing non-printing characters
+into the file is to precede them with a \fB^V\fR. The \fB^V\fR echoes
+as a \fB\(ua\fR character on which the cursor rests. This indicates that
+the editor expects you to type a control character. In fact you may
+type any character and it will be inserted into the file at that point.*
+.FS
+* This is not quite true. The implementation of the editor does
+not allow the \s-2NULL\s0 (\fB^@\fR) character to appear in files. Also
+the \s-2LF\s0 (linefeed or \fB^J\fR) character is used by the editor
+to separate lines in the file, so it cannot appear in the middle of a
+line. You can insert any other character, however, if you wait for the
+editor to echo the \fB\(ua\fR before you type the character. In fact,
+the editor will treat a following letter as a request for the corresponding
+control character. This is the only way to type \fB^S\fR or \fB^Q\fP,
+since the system normally uses them to suspend and resume output
+and never gives them to the editor to process.
+.FE
+.PP
+If you are using \fIautoindent\fR you can backtab over the indent which
+it supplies by typing a \fB^D\fR. This backs up to a \fIshiftwidth\fR
+boundary.
+This only works immediately after the supplied \fIautoindent\fR.
+.PP
+When you are using \fIautoindent\fR you may wish to place a label at
+the left margin of a line. The way to do this easily is to type \fB\(ua\fR
+and then \fB^D\fR. The editor will move the cursor to the left margin
+for one line, and restore the previous indent on the next. You can also
+type a \fB0\fR followed immediately by a \fB^D\fR if you wish to kill
+all the indent and not have it come back on the next line.
+.NH 2
+Upper case only terminals
+.PP
+If your terminal has only upper case, you can still use
+.I vi
+by using the normal
+system convention for typing on such a terminal.
+Characters which you normally type are converted to lower case, and you
+can type upper case letters by preceding them with a \e.
+The characters { ~ } | \(ga are not available on such terminals, but you
+can escape them as \e( \e\(ua \e) \e! \e\(aa.
+These characters are represented on the display in the same way they
+are typed.\*(dd
+.FS
+\*(dd The \e character you give will not echo until you type another
+key.
+.FE
+.NH 2
+Vi and ex
+.PP
+.I Vi
+is actually one mode of editing within the editor
+.I ex.
+When you are running
+.I vi
+you can escape to the line oriented editor of
+.I ex
+by giving the command
+\fBQ\fR.
+All of the
+.B :
+commands which were introduced above are available in
+.I ex.
+Likewise, most
+.I ex
+commands can be invoked from
+.I vi
+using :.
+Just give them without the \fB:\fR and follow them with a \s-2CR\s0.
+.PP
+In rare instances, an internal error may occur in
+.I vi.
+In this case you will get a diagnostic and be left in the command mode of
+.I ex.
+You can then save your work and quit if you wish by giving a command
+\fBx\fR after the \fB:\fR which \fIex\fR prompts you with, or you can
+reenter \fIvi\fR by giving
+.I ex
+a
+.I vi
+command.
+.PP
+There are a number of things which you can do more easily in
+.I ex
+than in
+.I vi.
+Systematic changes in line oriented material are particularly easy.
+You can read the advanced editing documents for the editor
+.I ed
+to find out a lot more about this style of editing.
+Experienced
+users often mix their use of
+.I ex
+command mode and
+.I vi
+command mode to speed the work they are doing.
+.NH 2
+Open mode: vi on hardcopy terminals and ``glass tty's''
+\(dd
+.PP
+If you are on a hardcopy terminal or a terminal which does not have a cursor
+which can move off the bottom line, you can still use the command set of
+.I vi,
+but in a different mode.
+When you give a
+.I vi
+command, the editor will tell you that it is using
+.I open
+mode.
+This name comes from the
+.I open
+command in
+.I ex,
+which is used to get into the same mode.
+.PP
+The only difference between
+.I visual
+mode
+and
+.I open
+mode is the way in which the text is displayed.
+.PP
+In
+.I open
+mode the editor uses a single line window into the file, and moving backward
+and forward in the file causes new lines to be displayed, always below the
+current line.
+Two commands of
+.I vi
+work differently in
+.I open:
+.B z
+and
+\fB^R\fR.
+The
+.B z
+command does not take parameters, but rather draws a window of context around
+the current line and then returns you to the current line.
+.PP
+If you are on a hardcopy terminal,
+the
+.B ^R
+command will retype the current line.
+On such terminals, the editor normally uses two lines to represent the
+current line.
+The first line is a copy of the line as you started to edit it, and you work
+on the line below this line.
+When you delete characters, the editor types a number of \e's to show
+you the characters which are deleted. The editor also reprints the current
+line soon after such changes so that you can see what the line looks
+like again.
+.PP
+It is sometimes useful to use this mode on very slow terminals which
+can support
+.I vi
+in the full screen mode.
+You can do this by entering
+.I ex
+and using an
+.I open
+command.
+.LP
+.SH
+Acknowledgements
+.PP
+Bruce Englar encouraged the early development of this display editor.
+Peter Kessler helped bring sanity to version 2's command layout.
+Bill Joy wrote versions 1 and 2.0 through 2.7,
+and created the framework that users see in the present editor.
+Mark Horton added macros and other features and made the
+editor work on a large number of terminals and Unix systems.
diff --git a/share/doc/usd/12.vi/viapwh/Makefile b/share/doc/usd/12.vi/viapwh/Makefile
new file mode 100644
index 000000000000..f20582dda5aa
--- /dev/null
+++ b/share/doc/usd/12.vi/viapwh/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+DOC= viapwh
+SRCS= vi.apwh.ms
+
+.include <bsd.doc.mk>
diff --git a/share/doc/usd/12.vi/viapwh/vi.apwh.ms b/share/doc/usd/12.vi/viapwh/vi.apwh.ms
new file mode 100644
index 000000000000..6b0763055ca9
--- /dev/null
+++ b/share/doc/usd/12.vi/viapwh/vi.apwh.ms
@@ -0,0 +1,1081 @@
+.\" Copyright (c) 1980, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)vi.apwh.ms 8.2 (Berkeley) 8/18/96
+.\"
+.nr LL 6.5i
+.nr FL 6.5i
+.TL
+Vi Command & Function Reference
+.AU CB 2675
+Alan P.W. Hewett
+.sp
+Revised for version 2.12 by Mark Horton
+.CB
+.NH 1
+Author's Disclaimer
+.LP
+This document does not claim to be 100% complete. There are a
+few commands listed in the original document that I was unable
+to test either because I do not speak \fBlisp\fR, because they
+required programs we don't have, or because I wasn't able to make
+them work. In these cases I left the command out. The commands
+listed in this document have been tried and are known to work.
+It is expected that prospective users of this document will read
+it once to get the flavor of everything that \fBvi\fR can do
+and then use it as a reference document. Experimentation is
+recommended. If you don't understand a command, try it and
+see what happens.
+.LP
+[Note: In revising this document, I have attempted to make it
+completely reflect version 2.12 of
+.B vi .
+It does not attempt to document the VAX version (version 3),
+but with one or two exceptions (wrapmargin, arrow keys)
+everything said about 2.12 should apply to 3.1.
+.I "Mark Horton" ]
+.NH 1
+Notation
+.LP
+\fB[option]\fR is used to denote optional parts of a command.
+Many \fBvi\fR commands have an optional count. \fB[cnt]\fR
+means that an optional number may precede the command to
+multiply or iterate the command.
+\fB{variable item}\fR is used to denote parts of the command
+which must appear, but can take a number of different values.
+\fB<character [-character]>\fR means that the character or
+one of the characters in the range described between the
+two angle brackets is to be typed.
+For example \fB<esc>\fR means
+the \fBescape\fR key is to be typed. \fB<a-z>\fR means that a
+lower case letter is to be typed. \fB^<character>\fR means that
+the character is to be typed as a \fBcontrol\fR character, that is,
+with the \fB<cntl>\fR key held down while simultaneously typing
+the specified character. In this document control characters will
+be denoted using the \fIupper case\fR character, but
+^<uppercase chr> and ^<lowercase chr> are equivalent. That is, for
+example, \fB<^D>\fR is equal to \fB<^d>\fR.
+The most common character abbreviations
+used in this list are as follows:
+.VL 8
+.IP <esc> 8
+escape, octal 033
+.IP <cr> 8
+carriage return, ^M, octal 015
+.IP <lf> 8
+linefeed ^J, octal 012
+.IP <nl> 8
+newline, ^J, octal 012 (same as linefeed)
+.IP <bs> 8
+backspace, ^H, octal 010
+.IP <tab> 8
+tab, ^I, octal 011
+.IP <bell> 8
+bell, ^G, octal 07
+.IP <ff> 8
+formfeed, ^L, octal 014
+.IP <sp> 8
+space, octal 040
+.IP <del> 8
+delete, octal 0177
+.LE
+.sp 1
+.NH 1
+Basics
+.LP
+To run \fBvi\fR the shell variable \fBTERM\fR must be defined and
+exported to your environment.
+How you do this depends on which shell you are using.
+You can tell which shell you have by the character it
+prompts you for commands with.
+The Bourne shell prompts with `$', and the C shell prompts with `%'.
+For these examples, we will suppose
+that you are using an HP 2621 terminal, whose termcap name is ``2621''.
+.NH 2
+Bourne Shell
+.LP
+To manually set your terminal type to 2621 you would type:
+.DS
+TERM=2621
+export TERM
+.DE
+.PP
+There are various ways of having this automatically or
+semi-automatically done when you log in.
+Suppose you usually dial in on a 2621.
+You want to tell this to the machine, but still have it
+work when you use a hardwired terminal.
+The recommended way, if you have the
+.B tset
+program, is to use the sequence
+.DS
+tset \-s \-d 2621 > tset$$
+\&. tset$$
+rm tset$$
+.DE
+in your .login (for csh) or the same thing using `.' instead of `source'
+in your .profile (for sh).
+The above line says that if you are dialing in you are on a 2621,
+but if you are on a hardwired terminal it figures out your terminal
+type from an on-line list.
+.NH 2
+The C Shell
+.LP
+To manually set your terminal type to 2621 you would type:
+.DS
+setenv TERM 2621
+.DE
+.PP
+There are various ways of having this automatically or
+semi-automatically done when you log in.
+Suppose you usually dial in on a 2621.
+You want to tell this to the machine, but still have it
+work when you use a hardwired terminal.
+The recommended way, if you have the
+.B tset
+program, is to use the sequence
+.DS
+tset \-s \-d 2621 > tset$$
+source tset$$
+rm tset$$
+.DE
+in your .login.*
+.FS
+* On a version 6 system
+without environments, the invocation of tset
+is simpler, just add the line ``tset \-d 2621''
+to your .login or .profile.
+.FE
+The above line says that if you are dialing in you are on a 2621,
+but if you are on a hardwired terminal it figures out your terminal
+type from an on-line list.
+.NH 1
+Normal Commands
+.LP
+\fBVi\fR is a visual editor with a window on the file. What
+you see on the screen is \fBvi\fR's current notion of
+what your file will contain,
+(at this point in the file),
+when it is written out.
+Most commands do not cause any change in the screen until the
+complete command is typed. Should you get confused while
+typing a command, you can abort the command by typing an
+<del> character. You will know you are back to command level
+when you hear a <bell>. Usually typing an <esc> will produce the
+same result. When \fBvi\fR gets an improperly formatted command
+it rings the <bell>.
+Following are the \fBvi\fR commands broken down by function.
+.NH 2
+Entry and Exit
+.LP
+To enter
+.B vi
+on a particular
+.I file ,
+type
+.DS
+\fBvi\fP \fIfile\fP
+.DE
+The file will be read in and the cursor will be placed at the beginning
+of the first line.
+The first screenfull of the file will be displayed on the terminal.
+.PP
+To get out of the editor, type
+.DS
+ZZ
+.DE
+If you are in some special mode, such as input mode
+or the middle of a multi-keystroke command, it may
+be necessary to type <esc> first.
+.NH 2
+Cursor and Page Motion
+.LP
+.VL 16
+.B NOTE:
+The arrow keys (see the next four commands)
+on certain kinds of terminals will not work with the
+PDP-11 version of vi. The control versions or the hjkl versions will
+work on any terminal. Experienced users prefer the hjkl keys because
+they are always right under their fingers. Beginners often prefer
+the arrow keys, since they do not require memorization of which hjkl
+key is which.
+The mnemonic value of hjkl is clear from looking at the keyboard of an adm3a.
+.sp
+.IP "[cnt]<bs> or [cnt]h or [cnt]\(<-" 16
+.br
+Move the cursor to the left one character. Cursor stops at the left
+margin of the page.
+If cnt is given, these commands move that many spaces.
+.IP "[cnt]^N or [cnt]j or [cnt]\(da or [cnt]<lf>" 16
+.br
+Move down one line.
+Moving off the screen scrolls the window to force a new line
+onto the screen.
+Mnemonic: \fBN\fRext
+.IP "[cnt]^P or [cnt]k or [cnt]\(ua" 16
+.br
+Move up one line.
+Moving off the top of the screen forces new text onto the screen.
+Mnemonic: \fBP\fRrevious
+.IP "[cnt]<sp> or [cnt]l or [cnt]\(->" 16
+.br
+Move to the right one character.
+Cursor will not go beyond the end of the line.
+.IP [cnt]- 16
+Move the cursor up the screen to the beginning of the next line.
+Scroll if necessary.
+.IP "[cnt]+ or [cnt]<cr>" 16
+.sp 1
+Move the cursor down the screen to the beginning of the next line.
+Scroll up if necessary.
+.IP "[cnt]$" 16
+Move the cursor to the end of the line.
+If there is a count, move to the end of the line "cnt" lines
+forward in the file.
+.IP "^" 16
+Move the cursor to the beginning of the first word on the line.
+.IP "0" 16
+Move the cursor to the left margin of the current line.
+.IP "[cnt]|" 16
+Move the cursor to the column specified by the count. The default is
+column zero.
+.IP "[cnt]w" 16
+Move the cursor to the beginning of the next word. If there
+is a count, then move forward that many words and
+position the cursor at the beginning of the word.
+Mnemonic: next-\fBw\fRord
+.IP "[cnt]W" 16
+Move the cursor to the beginning of the next word which follows
+a "white space" (<sp>,<tab>, or <nl>). Ignore other punctuation.
+.IP "[cnt]b" 16
+Move the cursor to the preceding word. Mnemonic: \fBb\fRackup-word
+.IP "[cnt]B" 16
+Move the cursor to the preceding word that is separated from the
+current word by a "white space" (<sp>,<tab>, or <nl>).
+.IP "[cnt]e" 16
+Move the cursor to the end of the current word or the end of the
+"cnt"'th word hence. Mnemonic: \fBe\fRnd-of-word
+.IP "[cnt]E" 16
+Move the cursor to the end of the current word which is delimited by
+"white space" (<sp>,<tab>, or <nl>).
+.IP "[line number]G" 16
+.br
+Move the cursor to the line specified. Of particular use are the
+sequences "1G" and "G", which move the cursor to the beginning and
+the end of the file respectively. Mnemonic: \fBG\fRo-to
+.LP
+.B NOTE:
+The next four commands (^D, ^U, ^F, ^B)
+are not true motion commands, in that they
+cannot be used as the object of commands such as delete or change.
+.IP "[cnt]^D" 16
+Move the cursor down in the file by "cnt" lines (or the last "cnt"
+if a new count isn't given. The initial default is half a page.) The
+screen is simultaneously scrolled up. Mnemonic: \fBD\fRown
+.IP "[cnt]^U" 16
+Move the cursor up in the file by "cnt" lines. The screen is simultaneously
+scrolled down. Mnemonic: \fBU\fRp
+.IP "[cnt]^F" 16
+Move the cursor to the next page. A count moves that many pages.
+Two lines of the previous page are kept on the screen for continuity if
+possible. Mnemonic: \fBF\fRorward-a-page
+.IP "[cnt]^B" 16
+Move the cursor to the previous page. Two lines of the current page
+are kept if possible. Mnemonic: \fBB\fRackup-a-page
+.IP "[cnt](" 16
+Move the cursor to the beginning of the next sentence.
+A sentence is defined as ending with a ".", "!", or "?"
+followed by two spaces or a <nl>.
+.IP "[cnt])" 16
+Move the cursor backwards to the beginning of a sentence.
+.IP "[cnt]}" 16
+Move the cursor to the beginning of the next paragraph. This command
+works best inside \fBnroff\fR documents. It understands two sets of
+\fBnroff\fR macros, \fB\-ms\fR and \fB\-mm\fR, for which the
+commands ".IP", ".LP", ".PP", ".QP", "P", as well as the nroff command ".bp"
+are considered to be paragraph delimiters.
+A blank line also delimits a paragraph.
+The \fBnroff\fR macros that it accepts as paragraph delimiters is
+adjustable. See \fBparagraphs\fR under the \fBSet Commands\fR section.
+.IP "[cnt]{" 16
+Move the cursor backwards to the beginning of a paragraph.
+.IP "]]" 16
+Move the cursor to the next "section", where a section is defined by
+two sets of \fBnroff\fR macros, \fB\-ms\fR and \fB\-mm\fR, in which
+".NH", ".SH", and ".H" delimit a section. A line beginning with a <ff><nl>
+sequence, or a line beginning with a "{" are also considered to
+be section delimiters. The last option makes it
+useful for finding the beginnings of C functions.
+The \fBnroff\fR macros that are used for section delimiters can be adjusted.
+See \fBsections\fR under the \fBSet Commands\fR section.
+.IP "[[" 16
+Move the cursor backwards to the beginning of a section.
+.IP "%" 16
+Move the cursor to the matching parenthesis
+or brace. This is very useful in C or lisp code. If the
+cursor is sitting on a \fB( ) {\fR or \fB}\fR the cursor
+is moved to the matching character at the other end of the
+section. If the cursor is not sitting on a brace or a
+parenthesis, \fBvi\fR searches forward until it finds one
+and then jumps to the match mate.
+.IP "[cnt]H" 16
+If there is no count move the cursor to the top left position on the screen.
+If there is a count, then move the cursor to the beginning of the line
+"cnt" lines from the top of the screen. Mnemonic: \fBH\fRome
+.IP "[cnt]L" 16
+If there is no count move the cursor to the beginning
+of the last line on the screen.
+If there is a count, then move the cursor to the beginning of the line
+"cnt" lines from the bottom of the screen. Mnemonic: \fBL\fRast
+.IP "M" 16
+Move the cursor to the beginning of the middle line on the screen.
+Mnemonic: \fBM\fRiddle
+.IP "m<a-z>" 16
+This command does not move the cursor, but it \fBmarks\fR the place
+in the file and the character "<a-z>" becomes the label for referring
+to this location in the file. See the next two commands. Mnemonic:
+\fBm\fRark
+.B NOTE:
+The mark command is not a motion, and cannot be used as the target
+of commands such as delete.
+.IP "\(aa<a-z>" 16
+Move the cursor to the beginning of the line that is marked with the label
+"<a-z>".
+.IP "\(ga<a-z>" 16
+Move the cursor to the exact position on the line that was marked with
+with the label "<a-z>".
+.IP "\(aa\(aa" 16
+Move the cursor back to the beginning of the line where it was before the
+last "non-relative" move. A "non-relative" move is something such as a
+search or a jump to a specific line in the file, rather than moving the
+cursor or scrolling the screen.
+.IP "\(ga\(ga" 16
+Move the cursor back to the exact spot on the line where it was located
+before the last "non-relative" move.
+.LE
+.NH 2
+Searches
+.LP
+The following commands allow you to search for items in a file.
+.VL 16
+.IP [cnt]f{chr} 16
+.sp 1
+Search forward on the line for the next or "cnt"'th occurrence of
+the character "chr". The cursor is placed \fBat\fR the character
+of interest. Mnemonic: \fBf\fRind character
+.IP [cnt]F{chr} 16
+.sp 1
+Search backwards on the line for the next or "cnt"'th occurrence of
+the character "chr". The cursor is placed \fBat\fR the character
+of interest.
+.IP [cnt]t{chr} 16
+.sp 1
+Search forward on the line for the next or "cnt"'th occurrence of
+the character "chr". The cursor is placed \fBjust preceding\fR
+the character of interest. Mnemonic: move cursor up \fBt\fRo character
+.IP [cnt]T{chr} 16
+.sp 1
+Search backwards on the line for the next or "cnt"'th occurrence of
+the character "chr". The cursor is placed \fBjust preceding\fR
+the character of interest.
+.IP "[cnt];" 16
+Repeat the last "f", "F", "t" or "T" command.
+.IP "[cnt]," 16
+Repeat the last "f", "F", "t" or "T" command, but in the opposite
+search direction. This is useful if you overshoot.
+.IP "[cnt]/[string]/<nl>" 16
+.br
+Search forward for the next occurrence of "string".
+Wrap around at the end of the file
+does occur.
+The final \fB</>\fR is not required.
+.IP "[cnt]?[string]?<nl>" 16
+.br
+Search backwards for the next occurrence of "string". If a count is
+specified, the count becomes the new window size. Wrap around at the beginning
+of the file does occur.
+The final \fB<?>\fR is not required.
+.IP n 16
+Repeat the last /[string]/ or ?[string]? search. Mnemonic: \fBn\fRext
+occurrence.
+.IP N 16
+Repeat the last /[string]/ or ?[string]? search, but in the reverse
+direction.
+.IP ":g/[string]/[editor command]<nl>" 16
+.sp 1
+Using the \fB:\fR syntax it is possible to do global searches ala the
+standard UNIX "ed" editor.
+.LE
+.NH 2
+Text Insertion
+.LP
+The following commands allow for the insertion of text. All multicharacter
+text insertions are terminated with an <esc> character.
+The last change
+can always be \fBundone\fR by typing a \fBu\fR.
+The text insert in insertion mode can contain newlines.
+.VL 16
+.IP a{text}<esc> 16
+Insert text immediately following the cursor position.
+Mnemonic: \fBa\fRppend
+.IP A{text}<esc> 16
+Insert text at the end of the current line.
+Mnemonic: \fBA\fRppend
+.IP i{text}<esc> 16
+Insert text immediately preceding the cursor position.
+Mnemonic: \fBi\fRnsert
+.IP I{text}<esc> 16
+Insert text at the beginning of the current line.
+.IP o{text}<esc> 16
+Insert a new line after the line on which the cursor appears and
+insert text there. Mnemonic: \fBo\fRpen new line
+.IP O{text}<esc> 16
+Insert a new line preceding the line on which the cursor appears
+and insert text there.
+.LE
+.NH 2
+Text Deletion
+.LP
+The following commands allow the user to delete text in various ways.
+All changes can always be \fBundone\fR by typing the \fBu\fR command.
+.VL 16
+.IP "[cnt]x" 16
+Delete the character or characters starting at the cursor position.
+.IP "[cnt]X" 16
+Delete the character or characters starting at the character preceding
+the cursor position.
+.IP "D" 16
+Deletes the remainder of the line starting at the cursor.
+Mnemonic: \fBD\fRelete the rest of line
+.IP "[cnt]d{motion}" 16
+.br
+Deletes one or more occurrences of the specified motion.
+Any motion from sections 4.1 and 4.2 can be used here.
+The d can be stuttered (e.g. [cnt]dd) to delete cnt lines.
+.LE
+.NH 2
+Text Replacement
+.LP
+The following commands allow the user to simultaneously delete and
+insert new text. All such actions can be \fBundone\fR by typing
+\fBu\fR following the command.
+.VL 16
+.IP "r<chr>" 16
+Replaces the character at the current cursor position with <chr>. This
+is a one character replacement. No <esc> is required for termination.
+Mnemonic: \fBr\fReplace character
+.IP "R{text}<esc>" 16
+Starts overlaying the characters on the screen with whatever you type.
+It does not stop until an <esc> is typed.
+.IP "[cnt]s{text}<esc>" 16
+Substitute for "cnt" characters beginning at the current cursor
+position. A "$" will appear at the position in the text where the
+"cnt"'th character appears so you will know how much you are erasing.
+Mnemonic: \fBs\fRubstitute
+.IP "[cnt]S{text}<esc>" 16
+Substitute for the entire current line (or lines). If no count is given,
+a "$" appears at the end of the current line. If a count of more than
+1 is given, all the lines to be replaced are deleted before the insertion
+begins.
+.IP "[cnt]c{motion}{text}<esc>" 16
+.br
+Change the specified "motion" by replacing it with the
+insertion text. A "$" will appear at the end of the last item
+that is being deleted unless the deletion involves whole lines.
+Motion's can be any motion from sections 4.1 or 4.2.
+Stuttering the c (e.g. [cnt]cc) changes cnt lines.
+.LE
+.NH 2
+Moving Text
+.LP
+\fBVi\fR provides a number of ways of moving chunks of text around.
+There are nine buffers into which each piece of text which is deleted
+or "yanked" is put in addition to the "undo" buffer.
+The most recent deletion or yank is in the "undo" buffer and also
+usually in buffer
+1, the next most recent in buffer 2, and so forth. Each new deletion
+pushes down all the older deletions. Deletions older than 9
+disappear. There is also
+a set of named registers, a-z, into which text can optionally
+be placed. If any delete or replacement type command is preceded
+by \fB"<a-z>\fR, that named buffer will contain the text deleted
+after the command is executed. For example, \fB"a3dd\fR will delete
+three lines starting at the current line and put them in buffer \fB"a\fR.*
+.FS
+* Referring to an upper case letter as a buffer name (A-Z) is the
+same as referring to the lower case letter, except that text placed
+in such a buffer is appended to it instead of replacing it.
+.FE
+There are two more basic commands and
+some variations useful in getting and putting text into a file.
+.VL 16
+.IP ["<a-z>][cnt]y{motion} 16
+.sp 1
+Yank the specified item or "cnt" items and put in the "undo" buffer or
+the specified buffer. The variety of "items" that can be yanked
+is the same as those that can be deleted with the "d" command or
+changed with the "c" command. In the same way that "dd" means
+delete the current line and "cc" means replace the current line,
+"yy" means yank the current line.
+.IP ["<a-z>][cnt]Y 16
+Yank the current line or the "cnt" lines starting from the current
+line. If no buffer is specified, they will go into the "undo" buffer,
+like any delete would. It is equivalent to "yy".
+Mnemonic: \fBY\fRank
+.IP ["<a-z>]p 16
+Put "undo" buffer or the specified buffer down \fBafter\fR the cursor.
+If whole lines were yanked or deleted into the buffer, then they will be
+put down on the line following the line the cursor is on. If
+something else was deleted, like a word or sentence, then it will
+be inserted immediately following the cursor.
+Mnemonic: \fBp\fRut buffer
+.IP
+It should be noted that text in the named buffers remains there when you
+start editing a new file with the \fB:e file<esc>\fR command. Since
+this is so, it is possible to copy or delete text from one file and
+carry it over to another file in the buffers.
+However, the undo buffer and the ability to undo are lost when
+changing files.
+.IP ["<a-z>]P 16
+Put "undo" buffer or the specified buffer down \fBbefore\fR the cursor.
+If whole lines where yanked or deleted into the buffer, then they will be
+put down on the line preceding the line the cursor is on. If
+something else was deleted, like a word or sentence, then it will
+be inserted immediately preceding the cursor.
+.IP [cnt]>{motion} 16
+The shift operator will right shift all the text from the line on which
+the cursor is located to the line where the \fBmotion\fR is located.
+The text is shifted by one \fBshiftwidth\fR. (See section 6.)
+\fB>>\fR means right shift the current line or lines.
+.IP [cnt]<{motion} 16
+The shift operator will left shift all the text from the line on which
+the cursor is located to the line where the \fBitem\fR is located.
+The text is shifted by one \fBshiftwidth\fR. (See section 6.)
+\fB<<\fR means left shift the current line or lines.
+Once the line has reached the left margin it is not further affected.
+.IP [cnt]={motion} 16
+Prettyprints the indicated area according to
+.B lisp
+conventions.
+The area should be a lisp s-expression.
+.LE
+.NH 2
+Miscellaneous Commands
+.LP
+\fBVi\fR has a number of miscellaneous commands that are very
+useful. They are:
+.VL 16
+.IP ZZ 16
+This is the normal way to exit from vi.
+If any changes have been made, the file is written out.
+Then you are returned to the shell.
+.IP ^L 16
+Redraw the current screen. This is useful if someone "write"s you
+while you are in "vi" or if for any reason garbage gets onto the
+screen.
+.IP ^R 16
+On dumb terminals, those not having the "delete line" function
+(the vt100 is such a terminal), \fBvi\fR saves redrawing the
+screen when you delete a line by just marking the line with an
+"@" at the beginning and blanking the line. If you want to
+actually get rid of the lines marked with "@" and see what the
+page looks like, typing a ^R will do this.
+.IP \s+4.\s0 16
+"Dot" is a particularly useful command. It repeats the last
+text modifying command. Therefore you can type a command once and
+then to another place and repeat it by just typing ".".
+.IP u 16
+Perhaps the most important command in the editor,
+u undoes the last command that changed the buffer.
+Mnemonic: \fBu\fRndo
+.IP U 16
+Undo all the text modifying commands performed on the current line
+since the last time you moved onto it.
+.IP [cnt]J 16
+Join the current line and the following line. The <nl> is deleted
+and the two lines joined, usually with a space between the
+end of the first line and the beginning of what was the second
+line. If the first line ended with a "period", then two spaces
+are inserted.
+A count joins the next cnt lines.
+Mnemonic: \fBJ\fRoin lines
+.IP Q 16
+Switch to \fBex\fR editing mode.
+In this mode \fBvi\fR will behave very much like \fBed\fR.
+The editor in this mode will operate on single lines normally and
+will not attempt to keep the "window" up to date.
+Once in this mode it is also possible to switch to the \fBopen\fR
+mode of editing. By entering the command \fB[line number]open<nl>\fR
+you enter this mode. It is similar to the normal visual mode
+except the window is only \fBone\fR line long.
+Mnemonic: \fBQ\fRuit visual mode
+.IP ^] 16
+An abbreviation for a tag command.
+The cursor should be positioned at the beginning of a word.
+That word is taken as a tag name, and the tag with that
+name is found as if it had been typed in a :tag command.
+.IP [cnt]!{motion}{UNIX\ cmd}<nl> 16
+.br
+Any UNIX filter
+(e.g. command that reads the standard input and outputs something
+to the standard output) can be sent a section of the current file and
+have the output of the command replace the original text. Useful
+examples are programs like \fBcb\fR, \fBsort\fR, and
+\fBnroff\fR. For instance, using \fBsort\fR it would be possible to
+sort a section of the current file into a new list.
+Using \fB!!\fR means take a line or lines starting at the line the
+cursor is currently on and pass them to the UNIX command.
+.B NOTE:
+To just escape to the shell for one command,
+use :!{cmd}<nl>, see section 5.
+.IP z{cnt}<nl> 16
+This resets the current window size to "cnt" lines and redraws the screen.
+.LE
+.NH 2
+Special Insert Characters
+.LP
+There are some characters that have special meanings during
+insert modes. They are:
+.VL 16
+.IP ^V 16
+During inserts, typing a ^V allows you to quote control characters
+into the file. Any character typed after the ^V will be inserted
+into the file.
+.IP [^]^D\ or\ [0]^D 16
+<^D> without any argument backs up one \fBshiftwidth\fR. This is necessary
+to remove indentation that was inserted by the \fBautoindent\fR feature.
+^<^D> temporarily removes all the autoindentation, thus placing the cursor
+at the left margin. On the next line, the previous indent level will be
+restored. This is useful for putting "labels" at the left margin.
+0<^D> says remove all autoindents and stay that way. Thus the cursor
+moves to the left margin and stays there on successive lines until
+<tab>'s are typed. As with the <tab>, the <^D> is only effective before
+any other "non-autoindent" controlling characters are typed.
+Mnemonic: \fBD\fRelete a shiftwidth
+.IP ^W 16
+If the cursor is sitting on a word, <^W> moves the cursor back to the beginning
+of the word, thus erasing the word from the insert.
+Mnemonic: erase \fBW\fRord
+.IP <bs> 16
+The backspace always serves as an erase during insert modes in addition
+to your normal "erase" character. To insert a <bs> into your file, use
+the <^V> to quote it.
+.LE
+.NH 1
+\fB:\fR Commands
+.LP
+Typing a ":" during command mode causes \fBvi\fR to put the cursor at
+the bottom on the screen in preparation for a command. In the
+":" mode, \fBvi\fR can be given most \fBed\fR commands. It is
+also from this mode that you exit from \fBvi\fR or switch to different
+files. All commands of this variety are terminated by a <nl>, <cr>,
+or <esc>.
+.VL 16
+.IP ":w[!] [file]" 16
+Causes \fBvi\fR to write out the current text to the disk. It is
+written to the file you are editing unless "file" is supplied. If
+"file" is supplied, the write is directed to that file instead. If
+that file already exists, \fBvi\fR will not perform the write unless
+the "!" is supplied indicating you
+.I really
+want to destroy the older copy of the file.
+.IP :q[!] 16
+Causes \fBvi\fR to exit. If you have modified the file you are
+looking at currently and haven't written it out, \fBvi\fR will
+refuse to exit unless the "!" is supplied.
+.IP ":e[!] [+[cmd]] [file]" 16
+.sp 1
+Start editing a new file called "file" or start editing the current
+file over again. The command ":e!" says "ignore the changes I've made
+to this file and start over from the beginning". It is useful if
+you really mess up the file. The optional "+" says instead of starting
+at the beginning, start at the "end", or,
+if "cmd" is supplied, execute "cmd" first.
+Useful cases of this are where cmd is "n" (any integer) which starts
+at line number n,
+and "/text", which searches for "text" and starts at the line where
+it is found.
+.IP "^^" 16
+Switch back to the place you were before your last tag command.
+If your last tag command stayed within the file, ^^ returns to that tag.
+If you have no recent tag command, it will return to the
+same place in the previous file that it was showing when you switched
+to the current file.
+.IP ":n[!]" 16
+Start editing the next file in the argument list. Since \fBvi\fR
+can be called with multiple file names, the ":n" command tells it to
+stop work on the current file and switch to the next file. If the
+current file was modifies, it has to be written out before the ":n"
+will work or else the "!" must be supplied, which says discard the
+changes I made to the current file.
+.IP ":n[!] file [file file ...]" 16
+.sp
+Replace the current argument list with a new list of files and start
+editing the first file in this new list.
+.IP ":r file" 16
+Read in a copy of "file" on the line after the cursor.
+.IP ":r !cmd" 16
+Execute the "cmd" and take its output and put it into the file after
+the current line.
+.IP ":!cmd" 16
+Execute any UNIX shell command.
+.IP ":ta[!] tag" 16
+.B Vi
+looks in the file named
+.B tags
+in the current directory.
+.B Tags
+is a file of lines in the format:
+.sp 1
+.ti +8
+tag filename \fBvi\fR-search-command
+.sp 1
+If \fBvi\fR finds the tag you specified in the \fB:ta\fR command,
+it stops editing the current file if necessary and if the current file is
+up to date on the disk and switches to the file specified and uses the
+search pattern specified to find the "tagged" item of interest. This
+is particularly useful when editing multi-file C programs such as the
+operating system. There is a program called \fBctags\fR which will
+generate an appropriate \fBtags\fR file for C and f77
+programs so that by saying
+\fB:ta function<nl>\fR you will be switched to that function.
+It could also be useful when editing multi-file documents, though the
+\fBtags\fR file would have to be generated manually.
+.LE
+.NH 1
+Special Arrangements for Startup
+.PP
+\fBVi\fR takes the value of \fB$TERM\fR and looks up the characteristics
+of that terminal in the file \fB/etc/termcap\fR.
+If you don't know \fBvi\fR's name for the terminal you are working
+on, look in \fB/etc/termcap\fR.
+.PP
+When \fBvi\fR starts, it attempts to read the variable EXINIT
+from your environment.*
+If that exists, it takes the values in it as the default values
+for certain of its internal constants. See the section on "Set Values"
+for further details.
+If EXINIT doesn't exist you will get all the normal defaults.
+.FS
+* On version 6 systems
+Instead of EXINIT, put the startup commands in the file .exrc
+in your home directory.
+.FE
+.PP
+Should you inadvertently hang up the phone while inside
+.B vi ,
+or should the computer crash,
+all may not be lost.
+Upon returning to the system, type:
+.DS
+vi \-r file
+.DE
+This will normally recover the file. If there is more than one
+temporary file for a specific file name, \fBvi\fR recovers the
+newest one. You can get an older version by recovering the
+file more than once.
+The command "vi -r" without a file name gives you the list of files
+that were saved in the last system crash
+(but
+.I not
+the file just saved when the phone was hung up).
+.NH 1
+Set Commands
+.LP
+\fBVi\fR has a number of internal variables and switches which can be
+set to achieve special affects.
+These options come in three forms, those that are switches, which toggle
+from off to on and back, those that require a numeric value, and those
+that require an alphanumeric string value.
+The toggle options are set by a command of the form:
+.DS
+:set option<nl>
+.DE
+and turned off with the command:
+.DS
+:set nooption<nl>
+.DE
+Commands requiring a value are set with a command of the form:
+.DS
+:set option=value<nl>
+.DE
+To display the value of a specific option type:
+.DS
+:set option?<nl>
+.DE
+To display only those that you have changed type:
+.DS
+:set<nl>
+.DE
+and to display the long table of all the settable parameters and
+their current values type:
+.DS
+:set all<nl>
+.DE
+.PP
+Most of the options have a long form and an abbreviation. Both are
+listed in the following table as well as the normal default value.
+.PP
+To arrange to have values other than the default used every time you
+enter
+.B vi ,
+place the appropriate
+.B set
+command in EXINIT in your environment, e.g.
+.DS
+EXINIT='set ai aw terse sh=/bin/csh'
+export EXINIT
+.DE
+or
+.DS
+setenv EXINIT 'set ai aw terse sh=/bin/csh'
+.DE
+for
+.B sh
+and
+.B csh ,
+respectively.
+These are usually placed in your .profile or .login.
+If you are running a system without environments (such as version 6)
+you can place the set command in the file .exrc in your home
+directory.
+.VL 16
+.IP autoindent\ ai 16
+Default: noai Type: toggle
+.br
+When in autoindent mode, vi helps you indent code by starting each
+line in the same column as the preceding line.
+Tabbing to the right with <tab> or <^T> will move this boundary to
+the right, and it can be moved to the left with <^D>.
+.IP autoprint\ ap 16
+Default: ap Type: toggle
+.br
+Causes the current line to be printed after each ex text modifying command.
+This is not of much interest in the normal \fBvi\fR visual mode.
+.IP autowrite\ aw 16
+Default: noaw type: toggle
+.br
+Autowrite causes an automatic write to be done if there are unsaved
+changes before certain commands which change files or otherwise
+interact with the outside world.
+These commands are :!, :tag, :next, :rewind, ^^, and ^].
+.IP beautify\ bf 16
+Default: nobf Type: toggle
+.br
+Causes all control characters except <tab>, <nl>, and <ff> to be discarded.
+.IP directory\ dir 16
+Default: dir=/tmp Type: string
+.br
+This is the directory in which \fBvi\fR puts its temporary file.
+.IP errorbells\ eb 16
+Default: noeb Type: toggle
+.br
+Error messages are preceded by a <bell>.
+.IP hardtabs\ ht 16
+Default: hardtabs=8 Type: numeric
+.br
+This option contains the value of hardware tabs in your terminal, or
+of software tabs expanded by the Unix system.
+.IP ignorecase\ ic 16
+Default: noic Type: toggle
+.br
+All upper case characters are mapped to lower case in regular expression
+matching.
+.IP lisp 16
+Default: nolisp Type: toggle
+.br
+Autoindent for \fBlisp\fR code. The commands \fB( ) [[\fR and \fB]]\fR
+are modified appropriately to affect s-expressions and functions.
+.IP list 16
+Default: nolist Type: toggle
+.br
+All printed lines have the <tab> and <nl> characters displayed visually.
+.IP magic 16
+Default: magic Type: toggle
+.br
+Enable the metacharacters for matching. These include \fB. * < > [string]
+[^string]\fR and \fB[<chr>-<chr>]\fR.
+.IP number\ nu 16
+Default: nonu Type: toggle
+.br
+Each line is displayed with its line number.
+.IP open 16
+Default: open Type: toggle
+.br
+When set, prevents entering open or visual modes from ex or edit.
+Not of interest from vi.
+.IP optimize\ opt 16
+Default: opt Type: toggle
+.br
+Basically of use only when using the \fBex\fR capabilities. This
+option prevents automatic <cr>s from taking place,
+and speeds up output of indented lines,
+at the expense of losing typeahead on some versions of UNIX.
+.IP paragraphs\ para 16
+Default: para=IPLPPPQPP\ bp Type: string
+.br
+Each pair of characters in the string indicate \fBnroff\fR macros
+which are to be treated as the beginning of a paragraph for the
+\fB{\fR and \fB}\fR commands. The default string is for the \fB-ms\fR
+and \fB-mm\fR macros.
+To indicate one letter \fBnroff\fR macros, such as \fB.P\fR or \fB.H\fR,
+quote a space in for the second character position. For example:
+.sp 1
+.ti +8
+:set paragraphs=P\e bp<nl>
+.sp 1
+would cause \fBvi\fR to consider \fB.P\fR and \fB.bp\fR as paragraph
+delimiters.
+.IP prompt 16
+Default: prompt Type: toggle
+.br
+In
+.B ex
+command mode the prompt character \fB:\fR will be printed when
+\fBex\fR is waiting for a command. This is not of interest from vi.
+.IP redraw 16
+Default: noredraw Type: toggle
+.br
+On dumb terminals, force the screen to always be up to date,
+by sending great amounts of output. Useful only at high speeds.
+.IP report 16
+Default: report=5 Type: numeric
+.br
+This sets the threshold for the number of lines modified. When
+more than this number of lines are modified, removed, or yanked,
+\fBvi\fR will report the number of lines changed at the bottom of
+the screen.
+.IP scroll 16
+Default: scroll={1/2 window} Type: numeric
+.br
+This is the number of lines that the screen scrolls up or down when
+using the <^U> and <^D> commands.
+.IP sections 16
+Default: sections=SHNHH HU Type: string
+.br
+Each two character pair of this string specify \fBnroff\fR macro names
+which are to be treated as the beginning of a section by the
+\fB]]\fR and \fB[[\fR commands. The default string is for the \fB-ms\fR
+and \fB-mm\fR macros.
+To enter one letter \fBnroff\fR macros, use a quoted space as the
+second character.
+See \fBparagraphs\fR for a fuller explanation.
+.IP shell\ sh 16
+Default: sh=from environment SHELL or /bin/sh Type: string
+.br
+This is the name of the \fBsh\fR to be used for "escaped" commands.
+.IP shiftwidth\ sw 16
+Default: sw=8 Type: numeric
+.br
+This is the number of spaces that a <^T> or <^D> will move over for
+indenting, and the amount < and > shift by.
+.IP showmatch\ sm 16
+Default: nosm Type: toggle
+.br
+When a \fB)\fR or \fB}\fR is typed, show the matching \fB(\fR or \fB{\fR
+by moving the cursor to it for one second if it is on the current screen.
+.IP slowopen\ slow 16
+Default: terminal dependent Type: toggle
+.br
+On terminals that are slow and unintelligent, this option prevents the
+updating of the screen some of the time to improve speed.
+.IP tabstop\ ts 16
+Default: ts=8 Type: numeric
+.br
+<tab>s are expanded to boundaries that are multiples of this value.
+.IP taglength\ tl 16
+Default: tl=0 Type: numeric
+.br
+If nonzero, tag names are only significant to this many characters.
+.IP term 16
+Default: (from environment \fBTERM\fP, else dumb) Type: string
+.br
+This is the terminal and controls the visual displays. It cannot be
+changed when in "visual" mode,
+you have to Q to command mode, type a
+set term command, and do ``vi.'' to get back into visual.
+Or exit vi, fix $TERM, and reenter.
+The definitions that drive a particular
+terminal type are found in the file \fB/etc/termcap\fR.
+.IP terse 16
+Default: terse Type: toggle
+.br
+When set, the error diagnostics are short.
+.IP warn 16
+Default: warn Type: toggle
+.br
+The user is warned if she/he tries to escape to
+the shell without writing out the current changes.
+.IP window 16
+Default: window={8 at 600 baud or less, 16 at 1200 baud, and screen
+size \- 1 at 2400 baud or more} Type: numeric
+.br
+This is the number of lines in the window whenever \fBvi\fR must redraw
+an entire screen. It is useful to make this size smaller if you are
+on a slow line.
+.IP w300,\ w1200,\ w9600
+.br
+These set window, but only within the corresponding speed ranges.
+They are useful in an EXINIT to fine tune window sizes.
+For example,
+.DS
+set w300=4 w1200=12
+.DE
+causes a 4 lines window at speed up to 600 baud, a 12 line window at 1200
+baud, and a full screen (the default) at over 1200 baud.
+.IP wrapscan\ ws 16
+Default: ws Type: toggle
+.br
+Searches will wrap around the end of the file when is option is set. When
+it is off, the search will terminate when it reaches the end or the
+beginning of the file.
+.IP wrapmargin\ wm 16
+Default: wm=0 Type: numeric
+.br
+\fBVi\fR will automatically insert a <nl> when it finds a natural
+break point (usually a <sp> between words) that occurs within
+"wm" spaces of the right margin.
+Therefore with "wm=0" the option is off. Setting it to 10 would
+mean that any time you are within 10 spaces of the right margin
+\fBvi\fR would be looking for a <sp> or <tab> which it could
+replace with a <nl>. This is convenient for people who forget
+to look at the screen while they type.
+(In version 3, wrapmargin behaves more like nroff, in that the
+boundary specified by the distance from the right edge of the screen
+is taken as the rightmost edge of the area where a break is allowed,
+instead of the leftmost edge.)
+.IP writeany\ wa 16
+Default: nowa Type: toggle
+.br
+\fBVi\fR normally makes a number of checks before it writes out a file.
+This prevents the user from inadvertently destroying a file. When the
+"writeany" option is enabled, \fBvi\fR no longer makes these checks.
+.LE
diff --git a/share/doc/usd/13.viref/Makefile b/share/doc/usd/13.viref/Makefile
new file mode 100644
index 000000000000..49226ba37074
--- /dev/null
+++ b/share/doc/usd/13.viref/Makefile
@@ -0,0 +1,34 @@
+# From: @(#)Makefile 8.16 (Berkeley) 8/15/94
+# $FreeBSD$
+
+VOLUME= usd/13.viref
+SRCS= vi.ref-patched
+EXTRA= ex.cmd.roff ref.so set.opt.roff vi.cmd.roff
+MACROS= -me
+CLEANFILES= vi.ref-patched index
+TRFLAGS= -U # this is to hide warnings only
+USE_SOELIM=
+USE_TBL=
+
+vi.ref-patched: vi.ref
+ sed -e 's:^\.so index.so$$:&.\\*[.T]:' ${.ALLSRC} > ${.TARGET}
+
+PRINTERDEVICE?= ascii
+.for _dev in ${PRINTERDEVICE}
+EXTRA+= index.so.${_dev}
+CLEANFILES+= index.so.${_dev}
+
+# Build index.so as a side-effect of building the paper.
+index.so.${_dev}: ${SRCS} ${EXTRA:Nindex.so.${_dev}}
+ sed -e 's:^\.so index\.so\.\\\*\[\.T\]$$::' vi.ref-patched | \
+ ${ROFF.${_dev}} -U -z
+ sed -e 's/MINUSSIGN/-/' \
+ -e 's/DOUBLEQUOTE/""/' \
+ -e "s/SQUOTE/'/" \
+ -e 's/ /__SPACE/g' < index | \
+ sort -u '-t ' -k 1,1 -k 2n | awk -f ${SRCDIR}/merge.awk | \
+ sed -e 's/__SPACE/ /g' \
+ -e "s/^\\(['\\.]\\)/\\\\\&\\1/" > ${.TARGET}
+.endfor
+
+.include <bsd.doc.mk>
diff --git a/share/doc/usd/13.viref/ex.cmd.roff b/share/doc/usd/13.viref/ex.cmd.roff
new file mode 100644
index 000000000000..382e635a6fdd
--- /dev/null
+++ b/share/doc/usd/13.viref/ex.cmd.roff
@@ -0,0 +1,1924 @@
+.\" Copyright (c) 1994
+.\" The Regents of the University of California. All rights reserved.
+.\" Copyright (c) 1994, 1995, 1996
+.\" Keith Bostic. All rights reserved.
+.\"
+.\" See the LICENSE file for redistribution information.
+.\"
+.\" @(#)ex.cmd.roff 8.41 (Berkeley) 8/17/96
+.\"
+.SH 1 "Ex Description"
+.pp
+The following words have special meanings for
+.CO ex
+commands.
+.KY "<end-of-file>"
+.IP "<end-of-file>"
+The end-of-file character is used to scroll the screen in the
+.CO ex
+editor.
+This character is normally
+.LI <control-D> .
+However, whatever character is set for the current terminal is supported
+as well as
+.LI <control-D> .
+.KY "line"
+.IP "line"
+A single-line address, given in any of the forms described in the
+section entitled
+.QB "Ex Addressing" .
+The default for
+.LI line
+is the current line.
+.KY "range"
+.IP "range"
+A line, or a pair of line addresses, separated by a comma or semicolon.
+(See the section entitled
+.QB "Ex Addressing"
+for more information.)
+The default for range is the current line
+.i only ,
+i.e.
+.QT \&.,. .
+A percent sign
+.PQ %
+stands for the range
+.QT 1,$ .
+The starting address must be less than, or equal to, the ending address.
+.KY "count"
+.IP "count"
+A positive integer, specifying the number of lines to be affected by
+the command; the default is 1.
+Generally, a count past the end-of-file may be specified, e.g. the
+command
+.QT "p 3000"
+in a 10 line file is acceptable, and will print from the current line
+through the last line in the file.
+.KY "flags"
+.IP "flags"
+One or more of the characters
+.QQ # ,
+.QQ p ,
+and
+.QQ l .
+When a command that accepts these flags completes, the addressed line(s)
+are written out as if by the corresponding
+.CO # ,
+.CO l
+or
+.CO p
+commands.
+In addition, any number of
+.QT +
+or
+.QT \-
+characters can be specified before, after, or during the flags, in which
+case the line written is not necessarily the one affected by the command,
+but rather the line addressed by the offset address specified.
+The default for
+.LI flags
+is none.
+.KY "file"
+.IP "file"
+A pattern used to derive a pathname; the default is the current file.
+File names are subjected to normal
+.XR sh 1
+word expansions.
+.pp
+Anywhere a file name is specified, it is also possible to use
+the special string
+.QT /tmp .
+This will be replaced with a temporary file name which can be used
+for temporary work, e.g.
+.QT ":e /tmp"
+creates and edits a new file.
+.pp
+If both a count and a range are specified for commands that use either,
+the starting line for the command is the
+.i last
+line addressed by the range, and
+.LI count - 1
+subsequent lines are affected by the command, e.g. the command
+.QT 2,3p4
+prints out lines 3, 4, 5 and 6.
+.pp
+When only a line or range is specified, with no command, the implied
+command is either a
+.CO list ,
+.CO number
+or
+.CO print
+command.
+The command used is the most recent of the three commands to have been
+used (including any use as a flag).
+If none of these commands have been used before, the
+.CO print
+command is the implied command.
+When no range or count is specified and the command line is a blank line,
+the current line is incremented by 1 and then the current line is displayed.
+.pp
+Zero or more whitespace characters may precede or follow the addresses,
+count, flags, or command name.
+Any object following a command name (such as buffer, file, etc.),
+that begins with an alphabetic character,
+should be separated from the command name by at least one whitespace
+character.
+.pp
+Any character, including
+.LI <carriage-return> ,
+.QT %
+and
+.QT #
+retain their literal value when preceded by a backslash.
+.SH 1 "Ex Commands"
+.pp
+The following section describes the commands available in the
+.CO ex
+editor.
+In each entry below, the tag line is a usage synopsis for the command.
+.pp
+Each command can be entered as the abbreviation
+(those characters in the synopsis command word preceding the
+.QQ [
+character),
+the full command (all characters shown for the command word,
+omitting the
+.QQ [
+and
+.QQ ]
+characters),
+or any leading subset of the full command down to the abbreviation.
+For example, the args command (shown as
+.QT ar[gs]
+in the synopsis)
+can be entered as
+.QT ar ,
+.QT arg
+or
+.QT args .
+.pp
+Each
+.CO ex
+command described below notes the new current line after it
+is executed, as well as any options that affect the command.
+.\" I cannot get a double quote to print to save my life. The ONLY way
+.\" I've been able to get this to work is with the .tr command.
+.tr Q"
+.ds ms Q
+.KY DOUBLEQUOTE
+.IP "\*(ms"
+.tr QQ
+A comment.
+Command lines beginning with the double-quote character
+.PQ """"
+are ignored.
+This permits comments in editor scripts and startup files.
+.KY "<control-D>"
+.KY "<end-of-file>"
+.IP "<control-D>"
+.IP "<end-of-file>"
+Scroll the screen.
+Write the next N lines, where N is the value of the
+.OP scroll
+option.
+The command is the end-of-file terminal character, which may be
+different on different terminals.
+Traditionally, it is the
+.LI <control-D>
+key.
+.sp
+Historically, the
+.CO eof
+command ignored any preceding count, and the
+.LI <end-of-file>
+character was ignored unless it was entered as the first character
+of the command.
+This implementation treats it as a command
+.i only
+if entered as the first character of the command line, and otherwise
+treats it as any other character.
+.SS
+.SP Line:
+Set to the last line written.
+.SP Options:
+Affected by the
+.OP scroll
+option.
+.SE
+.KY "!"
+.IP "! argument(s)"
+.Ip "[range]! argument(s)"
+Execute a shell command, or filter lines through a shell command.
+In the first synopsis, the remainder of the line after the
+.QT !
+character is passed to the program named by the
+.OP shell
+option, as a single argument.
+.sp
+Within the rest of the line,
+.QT %
+and
+.QT #
+are expanded into the current and alternate pathnames, respectively.
+The character
+.QT !
+is expanded with the command text of the previous
+.CO !
+command.
+(Therefore, the command
+.CO !!
+repeats the previous
+.CO !
+command.)
+The special meanings of
+.QT % ,
+.QT # ,
+and
+.QT !
+can be overridden by escaping them with a backslash.
+If no
+.CO !
+or
+.CO :!
+command has yet been executed, it is an error to use an unescaped
+.QT !
+character.
+The
+.CO !
+command does
+.i not
+do shell expansion on the strings provided as arguments.
+If any of the above expansions change the command the user entered,
+the command is redisplayed at the bottom of the screen.
+.sp
+.CO Ex
+then executes the program named by the
+.OP shell
+option, with a
+.b \-c
+flag followed by the arguments (which are bundled into a single argument).
+.sp
+The
+.CO !
+command is permitted in an empty file.
+.sp
+If the file has been modified since it was last completely written,
+the
+.Co !
+command will warn you.
+.sp
+A single
+.QT !
+character is displayed when the command completes.
+.sp
+In the second form of the
+.CO !
+command, the remainder of the line after the
+.QT !
+is passed to the program named by the
+.OP shell
+option, as described above.
+The specified lines are passed to the program as standard input,
+and the standard and standard error output of the program replace
+the original lines.
+.SS
+.SP Line:
+Unchanged if no range was specified, otherwise set to the first
+line of the range.
+.SP Options:
+Affected by the
+.OP shell
+and
+.OP warn
+options.
+.SE
+.KY "#"
+.IP "[range] # [count] [flags]"
+.KY "number"
+.Ip "[range] nu[mber] [count] [flags]"
+Display the selected lines, each preceded with its line number.
+.sp
+The line number format is
+.QQ %6d ,
+followed by two spaces.
+.SS
+.SP Line:
+Set to the last line displayed.
+.SP Options:
+Affected by the
+.OP list
+option.
+.SE
+.KY "@"
+.IP "@ buffer"
+.KY "*"
+.Ip "* buffer"
+Execute a buffer.
+Each line in the named buffer is executed as an
+.CO ex
+command.
+If no buffer is specified, or if the specified buffer is
+.QT @
+or
+.QT * ,
+the last buffer executed is used.
+.KY <
+.IP "[range] <[< ...] [count] [flags]"
+Shift lines left or right.
+The specified lines are shifted to the left (for the
+.CO <
+command) or right (for the
+.CO >
+command), by the number of columns specified by the
+.OP shiftwidth
+option.
+Only leading whitespace characters are deleted when shifting left;
+once the first column of the line contains a nonblank character,
+the
+.CO shift
+command will succeed, but the line will not be modified.
+.sp
+If the command character
+.CO <
+or
+.CO >
+is repeated more than once, the command is repeated once for each
+additional command character.
+.SS
+.SP Line:
+If the current line is set to one of the lines that are affected
+by the command, it is unchanged.
+Otherwise, it is set to the first nonblank character of the lowest
+numbered line shifted.
+.SP Options:
+Affected by the
+.OP shiftwidth
+option.
+.SE
+.KY =
+.IP "[line] = [flags]"
+Display the line number of
+.LI line
+(which defaults to the last line in the file).
+.SS
+.SP Line:
+Unchanged.
+.SP Options:
+None.
+.SE
+.KY >
+.IP "[range] >[> ...] [count] [flags]"
+Shift right.
+The specified lines are shifted to the right by the number of columns
+specified by the
+.OP shiftwidth
+option, by inserting tab and space characters.
+Empty lines are not changed.
+.sp
+If the command character
+.QT >
+is repeated more than once, the command is repeated once for each
+additional command character.
+.SS
+.SP Line:
+Set to the last line modified by the command.
+.SP Options:
+Affected by the
+.OP shiftwidth
+option.
+.SE
+.KY abbrev
+.IP "ab[brev] lhs rhs"
+Add an abbreviation to the current abbreviation list.
+When inserting text in
+.CO vi ,
+each time a non-word character is entered after a word character,
+a set of characters ending at the word character are checked for
+a match with
+.LI lhs .
+If a match is found, they are replaced with
+.LI rhs .
+The set of characters that are checked for a match are defined as follows,
+for inexplicable historical reasons.
+If only one or two characters were entered before the non-word character
+that triggered the check,
+and after the beginning of the insertion,
+or the beginning of the line or the file,
+or the last
+.LI <blank>
+character that was entered,
+then the one or the both characters are checked for a match.
+Otherwise, the set includes both characters,
+as well as the characters that precede them that are the same word
+class (i.e. word or non-word) as the
+.b second
+to last character entered before the non-word character that triggered
+the check,
+back to the first
+.LI <blank> character,
+the beginning of the insertion,
+or the beginning of the line or the file.
+.sp
+For example, the abbreviations:
+.sp
+.ne 3v
+.ft C
+.TS
+r l l.
+:abbreviate abc ABC
+:abbreviate #i #include
+:abbreviate /*#i /*#include
+.TE
+.ft R
+will all work, while the abbreviations:
+.sp
+.ne 2v
+.ft C
+.TS
+r l l.
+:abbreviate a#i A#include
+:abbreviate /* /********************
+.TE
+.ft R
+will not work, and are not permitted by
+.CO nvi .
+.sp
+To keep the abbreviation expansion from happening,
+the character immediately following the
+.LI lhs
+characters should be quoted with a
+.LI <literal-next>
+character.
+.sp
+The replacement
+.LI rhs
+is itself subject to both further abbreviation expansion and further
+map expansion.
+.SS
+.SP Line:
+Unchanged.
+.SP Options:
+None.
+.SE
+.KY append
+.IP "[line] a[ppend][!]"
+The input text is appended to the specified line.
+If line 0 is specified, the text is inserted at the beginning of the file.
+Set to the last line input.
+If no lines are input, then set to
+.LI line ,
+or to the first line of the file if a
+.LI line
+of 0 was specified.
+Following the command name with a
+.QT !
+character causes the
+.OP autoindent
+option to be toggled for the duration of the command.
+.SS
+.SP Line:
+Unchanged.
+.SP Options:
+Affected by the
+.OP autoindent
+and
+.OP number
+options.
+.SE
+.KY args
+.IP "ar[gs]"
+Display the argument list.
+The current argument is displayed inside of
+.QT [
+and
+.QT ]
+characters.
+The argument list is the list of operands specified on startup,
+which can be replaced using the
+.CO next
+command.
+.SS
+.SP Line:
+Unchanged.
+.SP Options:
+None.
+.SE
+.KY bg
+.IP bg
+.CO Vi
+mode only.
+Background the current screen.
+The screen is unchanged,
+but is no longer accessible and disappears from the display.
+Use the
+.CO fg
+command to bring the screen back to the display foreground.
+.SS
+.SP Line:
+Set to the current line when the screen was last edited.
+.SP Options:
+None.
+.SE
+.KY change
+.IP "[range] c[hange][!] [count]"
+Replace the lines with input text.
+Following the command name with a
+.QT !
+character causes the
+.OP autoindent
+option to be toggled for the duration of the command.
+.SS
+.SP Line:
+Set to the last line input, or, if no lines were input,
+set to the line before the target line, or to the first
+line of the file if there are no lines preceding the target line.
+.SP Options:
+Affected by the
+.OP autoindent
+and
+.OP number
+options.
+.SE
+.KY cd
+.KY chdir
+.IP "chd[ir][!] [directory]"
+.Ip "cd[!] [directory]"
+Change the current working directory.
+The
+.LI directory
+argument is subjected to
+.XR sh 1
+word expansions.
+When invoked with no directory argument and the
+.LI HOME
+environment variable is set, the directory named by the
+.LI HOME
+environment variable becomes the new current directory.
+Otherwise, the new current directory becomes the directory returned
+by the
+.XR getpwent 3
+routine.
+.sp
+The
+.CO chdir
+command will fail if the file has been modified since the last complete
+write of the file.
+You can override this check by appending a
+.QT !
+character to the command.
+.SS
+.SP Line:
+Unchanged.
+.SP Options:
+Affected by the
+.OP cdpath
+option.
+.SE
+.KY copy
+.KY t
+.IP "[range] co[py] line [flags]"
+.Ip "[range] t line [flags]"
+Copy the specified lines (range) after the destination line.
+Line 0 may be specified to insert the lines at the beginning of
+the file.
+.SS
+.SP Line:
+Unchanged.
+.SP Options:
+None.
+.SE
+.KY cscope
+.IP "cs[cope] command [args]"
+Execute a
+.CO cscope
+command.
+For more information, see the section of the reference manual entitled
+.QB "Tags, Tag Stacks, and Cscope" .
+.KY delete
+.IP "[range] d[elete] [buffer] [count] [flags]"
+Delete the lines from the file.
+The deleted text is saved in the specified buffer, or, if no buffer
+is specified, in the unnamed buffer.
+If the command name is followed by a letter that could be interpreted
+as either a buffer name or a flag value (because neither a
+.LI count
+or
+.LI flags
+values were given),
+.CO ex
+treats the letter as a
+.LI flags
+value if the letter immediately follows the command name,
+without any whitespace separation.
+If the letter is preceded by whitespace characters,
+it treats it as a buffer name.
+.SS
+.SP Line:
+Set to the line following the deleted lines,
+or to the last line if the deleted lines were at the end.
+.SP Options:
+None.
+.SE
+.KY display
+.IP "di[splay] b[uffers] | c[onnections] | s[creens] | t[ags]"
+Display buffers,
+.CO cscope
+connections, screens or tags.
+The
+.CO display
+command takes one of three additional arguments, which are as follows:
+.SS
+.SP b[uffers]
+Display all buffers (including named, unnamed, and numeric)
+that contain text.
+.SP c[onnections]
+Display the source directories for all attached
+.CO cscope
+databases.
+.SP s[creens]
+Display the file names of all background screens.
+.SP t[ags]
+Display the tags stack.
+.SE
+.SS
+.SP Line:
+Unchanged.
+.SP Options:
+None.
+.SE
+.KY edit
+.IP "e[dit][!] [+cmd] [file]"
+.Ip "ex[!] [+cmd] [file]"
+Edit a different file.
+If the current buffer has been modified since the last complete write,
+the command will fail.
+You can override this by appending a
+.QT !
+character to the command name.
+.sp
+If the
+.QT +cmd
+option is specified, that
+.CO ex
+command will be executed in the new file.
+Any
+.CO ex
+command may be used, although the most common use of this feature is
+to specify a line number or search pattern to set the initial location
+in the new file.
+.sp
+Capitalizing the first letter of the command, i.e.
+.CO Edit
+or
+.CO Ex ,
+while in
+.CO vi
+mode, will edit the file in a new screen.
+In this case, any modifications to the current file are ignored.
+.SS
+.SP Line:
+If you have previously edited the file, the current line will be set
+to your last position in the file.
+If that position does not exist, or you have not previously edited the
+file, the current line will be set to the first line of the file if
+you are in
+.CO vi
+mode, and the last line of the file if you are in
+.CO ex .
+.SP Options:
+None.
+.SE
+.KY exusage
+.IP "exu[sage] [command]"
+Display usage for an
+.CO ex
+command.
+If
+.LI command
+is specified, a usage statement for that command is displayed.
+Otherwise, usage statements for all
+.CO ex
+commands are displayed.
+.SS
+.SP Line:
+Unchanged.
+.SP Options:
+None.
+.SE
+.KY file
+.IP "f[ile] [file]"
+Display and optionally change the file name.
+If a file name is specified, the current pathname is changed to the
+specified name.
+The current pathname, the number of lines, and the current position
+in the file are displayed.
+.SS
+.SP Line:
+Unchanged.
+.SP Options:
+None.
+.SE
+.KY fg
+.IP "fg [name]"
+.CO Vi
+mode only.
+Foreground the specified screen.
+If the argument name doesn't exactly match the name of a file displayed
+by a background screen,
+it is compared against the last component of each of the file names.
+If no background screen is specified,
+the first background screen is foregrounded.
+.sp
+By default,
+foregrounding causes the current screen to be swapped with the backgrounded
+screen.
+Capitalizing the first letter of the command, i.e.
+.CO Fg ,
+will foreground the backgrounded screen in a new screen instead of
+swapping it with the current screen.
+.SS
+.SP Line:
+Set to the current line when the screen was last edited.
+.SP Options:
+None.
+.SE
+.KY global
+.IP "[range] g[lobal] /pattern/ [commands]"
+.KY v
+.Ip "[range] v /pattern/ [commands]"
+Apply commands to lines matching (or not matching) a pattern.
+The lines within the given range that match
+.PQ g[lobal] ,
+or do not match
+.PQ v
+the given pattern are selected.
+Then, the specified
+.CO ex
+command(s) are executed with the current line
+.PQ \&.
+set to each selected line.
+If no range is specified, the entire file is searched for matching,
+or not matching, lines.
+.sp
+Multiple commands can be specified, one per line, by escaping each
+.LI <newline>
+character with a backslash, or by separating commands with a
+.QT |
+character.
+If no commands are specified, the command defaults to the
+.CO print
+command.
+.sp
+For the
+.CO append ,
+.CO change
+and
+.CO insert
+commands, the input text must be part of the global command line.
+In this case, the terminating period can be omitted if it ends the commands.
+.sp
+The
+.CO visual
+command may also be specified as one of the
+.CO ex
+commands.
+In this mode, input is taken from the terminal.
+Entering a
+.CO Q
+command in
+.CO vi
+mode causes the next line matching the pattern to be selected and
+.CO vi
+to be reentered, until the list is exhausted.
+.sp
+The
+.CO global ,
+.CO v
+and
+.CO undo
+commands cannot be used as part of these commands.
+.sp
+The editor options
+.OP autoindent ,
+.OP autoprint
+and
+.OP report
+are turned off for the duration of the
+.CO global
+and
+.CO v
+commands.
+.SS
+.SP Line:
+The last line modified.
+.SP Options:
+Affected by the
+.OP ignorecase
+and
+.OP magic
+options.
+Turns off the
+.OP autoindent ,
+.OP autoprint
+and
+.OP report
+options.
+.SE
+.KY help
+.IP "he[lp]"
+Display a help message.
+.SS
+.SP Line:
+Unchanged.
+.SP Options:
+None.
+.SE
+.KY insert
+.IP "[line] i[nsert][!]"
+The input text is inserted before the specified line.
+Following the command name with a
+.QT !
+character causes the
+.OP autoindent
+option setting to be toggled for the duration of this command.
+.SS
+.SP Line:
+Set to the last line input; if no lines were input,
+set to the line before the target line, or to the first line
+of the file if there are no lines preceding the target line.
+Affected by the
+.OP autoindent
+and
+.OP number
+options.
+.SE
+.KY join
+.IP "[range] j[oin][!] [count] [flags]"
+Join lines of text together.
+.sp
+A
+.LI count
+specified to the
+.Sy join
+command specifies that the last line of the
+.LI range
+plus
+.LI count
+subsequent lines will be joined.
+(Note, this differs by one from the general rule where only
+.LI count - 1
+subsequent lines are affected.)
+.sp
+If the current line ends with a whitespace character, all whitespace
+is stripped from the next line.
+Otherwise, if the next line starts with a open parenthesis
+.PQ ( ,
+do nothing.
+Otherwise, if the current line ends with a question mark
+.PQ ? ,
+period
+.PQ \&.
+or exclamation point
+.PQ ! ,
+insert two spaces.
+Otherwise, insert a single space.
+.sp
+Appending a
+.QT !
+character to the command name causes a simpler join with no
+white-space processing.
+.SS
+.SP Line:
+Unchanged.
+.SP Options:
+None.
+.SE
+.KY list
+.IP "[range] l[ist] [count] [flags]"
+Display the lines unambiguously.
+Tabs are displayed as
+.QT ^I ,
+and the end of the line is marked with a
+.QT $
+character.
+.SS
+.SP Line:
+Set to the last line displayed.
+.SP Options:
+Affected by the
+.OP number
+option.
+.SE
+.KY map
+.IP "map[!] [lhs rhs]"
+Define or display maps (for
+.CO vi
+only).
+.sp
+If
+.QT lhs
+and
+.QT rhs
+are not specified, the current set of command mode maps are displayed.
+If a
+.QT !
+character is appended to to the command,
+the text input mode maps are displayed.
+.sp
+Otherwise, when the
+.QT lhs
+character sequence is entered in
+.CO vi ,
+the action is as if the corresponding
+.QT rhs
+had been entered.
+If a
+.QT !
+character is appended to the command name,
+the mapping is effective during text input mode,
+otherwise, it is effective during command mode.
+This allows
+.QT lhs
+to have two different macro definitions at the same time: one for command
+mode and one for input mode.
+.sp
+Whitespace characters require escaping with a
+.LI <literal-next>
+character to be entered in the
+.LI lhs
+string in visual mode.
+.sp
+Normally, keys in the
+.LI rhs
+string are remapped (see the
+.OP remap
+option),
+and it is possible to create infinite loops.
+However, keys which map to themselves are not further remapped,
+regardless of the setting of the
+.OP remap
+option.
+For example, the command
+.QT ":map n nz."
+maps the
+.QT n
+key to the
+.CO n
+and
+.CO z
+commands.
+.sp
+To exit an infinitely looping map, use the terminal
+.LI <interrupt>
+character.
+.SS
+.SP Line:
+Unchanged.
+.SP Options:
+Affected by the
+.OP remap
+option.
+.SE
+.KY mark
+.KY k
+.IP "[line] ma[rk] <character>"
+.Ip "[line] k <character>"
+Mark the line with the mark
+.LI <character> .
+The expressions
+.QT '<character>
+and
+.QT `<character>
+can then be used as an address in any command that uses one.
+.SS
+.SP Line:
+Unchanged.
+.SP Options:
+None.
+.SE
+.KY move
+.IP "[range] m[ove] line"
+Move the specified lines after the target line.
+A target line of 0 places the lines at the beginning of the file.
+.SS
+.SP Line:
+Set to the first of the moved lines.
+.SP Options:
+None.
+.SE
+.KY mkexrc
+.IP "mk[exrc][!] file"
+Write the abbreviations, editor options and maps to the specified
+file.
+Information is written in a form which can later be read back in
+using the
+.CO ex
+.CO source
+command.
+If
+.LI file
+already exists, the
+.CO mkexrc
+command will fail.
+This check can be overridden by appending a
+.QT !
+character to the command.
+.SS
+.SP Line:
+Unchanged.
+.SP Options:
+None.
+.SE
+.KY next
+.IP "n[ext][!] [file ...]"
+Edit the next file from the argument list.
+The
+.CO next
+command will fail if the file has been modified since the last complete
+write.
+This check can be overridden by appending the
+.QT !
+character to the command name.
+The argument list can optionally be replaced by specifying a new one
+as arguments to this command.
+In this case, editing starts with the first file on the new list.
+.sp
+Capitalizing the first letter of the command, i.e.
+.CO Next ,
+while in
+.CO vi
+mode, will set the argument list and edit the file in a new screen.
+In this case, any modifications to the current file are ignored.
+.SS
+.SP Line:
+Set as described for the
+.CO edit
+command.
+.SP Options:
+Affected by the options
+.OP autowrite
+and
+.OP writeany .
+.SE
+.KY open
+.IP "[line] o[pen] /pattern/ [flags]"
+Enter open mode.
+Open mode is the same as being in
+.CO vi ,
+but with a one-line window.
+All the standard
+.CO vi
+commands are available.
+If a match is found for the optional RE argument,
+the cursor is set to the start of the matching pattern.
+.sp
+.i "This command is not yet implemented."
+.SS
+.SP Line:
+Unchanged, unless the optional RE is specified, in which case it is
+set to the line where the matching pattern is found.
+.SP Options:
+Affected by the
+.OP open
+option.
+.SE
+.KY preserve
+.IP "pre[serve]"
+Save the file in a form that can later be recovered using the
+.CO ex
+.b \-r
+option.
+When the file is preserved, an email message is sent to the user.
+.SS
+.SP Line:
+Unchanged.
+.SP Options:
+None.
+.SE
+.KY previous
+.IP "prev[ious][!]"
+Edit the previous file from the argument list.
+The
+.CO previous
+command will fail if the file has been modified since the last complete
+write.
+This check can be overridden by appending the
+.QT !
+character to the command name.
+.sp
+Capitalizing the first letter of the command, i.e.
+.CO Previous ,
+while in
+.CO vi
+mode, will edit the file in a new screen.
+In this case, any modifications to the current file are ignored.
+.SS
+.SP Line:
+Set as described for the
+.CO edit
+command.
+.SP Options:
+Affected by the options
+.OP autowrite
+and
+.OP writeany .
+None.
+.SE
+.KY print
+.IP "[range] p[rint] [count] [flags]"
+Display the specified lines.
+.SS
+.SP Line:
+Set to the last line displayed.
+.SP Options:
+Affected by the
+.OP list
+and
+.OP number
+option.
+.SE
+.KY put
+.IP "[line] pu[t] [buffer]"
+Append buffer contents to the current line.
+If a buffer is specified, its contents are appended to the line,
+otherwise, the contents of the unnamed buffer are used.
+.SS
+.SP Line:
+Set to the line after the current line.
+.SP Options:
+None.
+.SE
+.KY quit
+.IP "q[uit][!]"
+End the editing session.
+If the file has been modified since the last complete write, the
+.CO quit
+command will fail.
+This check may be overridden by appending a
+.QT !
+character to the command.
+.sp
+If there are more files to edit, the
+.CO quit
+command will fail.
+Appending a
+.QT !
+character to the command name or entering two
+.CO quit
+commands (i.e.
+.CO wq ,
+.CO quit ,
+.CO xit
+or
+.CO ZZ )
+in a row) will override this check and the editor will exit.
+.SS
+.SP Line:
+Unchanged.
+.SP Options:
+None.
+.SE
+.KY read
+.IP "[line] r[ead][!] [file]"
+Read a file.
+A copy of the specified file is appended to the line.
+If
+.LI line
+is 0, the copy is inserted at the beginning of the file.
+If no file is specified, the current file is read; if there is no
+current file, then
+.LI file
+becomes the current file.
+If there is no current file and no
+.LI file
+is specified, then the
+.CO read
+command will fail.
+.sp
+If
+.LI file
+is preceded by a
+.QT !
+character,
+.LI file
+is treated as if it were a shell command, and passed to the program
+named by the
+.OP shell
+edit option.
+The standard and standard error outputs of that command are read into
+the file after the specified line.
+The special meaning of the
+.QT !
+character can be overridden by escaping it with a backslash
+.PQ \e
+character.
+.SS
+.SP Line:
+When executed from
+.CO ex ,
+the current line is set to the last line read.
+When executed from
+.CO vi ,
+the current line is set to the first line read.
+.SP Options:
+None.
+.SE
+.KY recover
+.IP "rec[over] file"
+Recover
+.LI file
+if it was previously saved.
+If no saved file by that name exists, the
+.CO recover
+command behaves equivalently to the
+.CO edit
+command.
+.SS
+.SP Line:
+Set as described for the
+.CO edit
+command.
+.SP Options:
+None.
+.SE
+.KY resize
+.IP "res[ize] [+|-]size"
+.CO Vi
+mode only.
+Grow or shrink the current screen.
+If
+.LI size
+is a positive, signed number, the current screen is grown by that many lines.
+If
+.LI size
+is a negative, signed number, the current screen is shrunk by that many lines.
+If
+.LI size
+is not signed, the current screen is set to the specified
+.LI size .
+Applicable only to split screens.
+.SS
+.SP Line:
+Unchanged.
+.SP Options:
+None.
+.SE
+.KY rewind
+.IP "rew[ind][!]"
+Rewind the argument list.
+If the current file has been modified since the last complete write,
+the
+.CO rewind
+command will fail.
+This check may be overridden by appending the
+.QT !
+character to the command.
+.sp
+Otherwise, the current file is set to the first file in the argument
+list.
+.SS
+.SP Line:
+Set as described for the
+.CO edit
+command.
+.SP Options:
+Affected by the
+.OP autowrite
+and
+.OP writeany
+options.
+.SE
+.KY set
+.IP "se[t] [option[=[value]] ...] [nooption ...] [option? ...] [all]"
+Display or set editor options.
+When no arguments are specified, the editor option
+.OP term ,
+and any editor options whose values have been changed from the
+default settings are displayed.
+If the argument
+.LI all
+is specified, the values of all of editor options are displayed.
+.sp
+Specifying an option name followed by the character
+.QT ?
+causes the current value of that option to be displayed.
+The
+.QT ?
+can be separated from the option name by whitespace characters.
+The
+.QT ?
+is necessary only for Boolean valued options.
+Boolean options can be given values by the form
+.QT "set option"
+to turn them on, or
+.QT "set nooption"
+to turn them off.
+String and numeric options can be assigned by the form
+.QT "set option=value" .
+Any whitespace characters in strings can be included literally by preceding
+each with a backslash.
+More than one option can be set or listed by a single set command,
+by specifying multiple arguments, each separated from the next by
+whitespace characters.
+.SS
+.SP Line:
+Unchanged.
+.SP Options:
+None.
+.SE
+.KY shell
+.IP "sh[ell]"
+Run the shell program.
+The program named by the
+.OP shell
+option is run with a
+.b \-i
+(for interactive) flag.
+Editing is resumed when that program exits.
+.SS
+.SP Line:
+Unchanged.
+.SP Options:
+Affected by the
+.OP shell
+option.
+.SE
+.KY source
+.IP "so[urce] file"
+Read and execute
+.CO ex
+commands from a file.
+.CO Source
+commands may be nested.
+.SS
+.SP Line:
+Unchanged.
+.SP Options:
+None.
+.SE
+.KY substitute
+.IP "[range] s[ubstitute] [/pattern/replace/] [options] [count] [flags]"
+.KY &
+.Ip "[range] & [options] [count] [flags]"
+.KY ~
+.Ip "[range] ~ [options] [count] [flags]"
+Make substitutions.
+Replace the first instance of
+.LI pattern
+with the string
+.LI replace
+on the specified line(s).
+If the
+.QT /pattern/repl/
+argument is not specified, the
+.QT /pattern/repl/
+from the previous
+.CO substitute
+command is used.
+Any character other than an alphabetic, numeric, <blank> or backslash
+character may be used as the delimiter.
+.sp
+If
+.LI options
+includes the letter
+.QT c
+(confirm), you will be prompted for confirmation before each replacement
+is done.
+An affirmative response (in English, a
+.QT y
+character) causes the replacement to be made.
+A quit response (in English, a
+.QT q
+character) causes the
+.CO substitute
+command to be terminated.
+Any other response causes the replacement not to be made, and the
+.CO substitute
+command continues.
+If
+.LI options
+includes the letter
+.QT g
+(global), all nonoverlapping instances of
+.LI pattern
+in the line are replaced.
+.sp
+The
+.CO &
+version of the command is the same as not specifying a pattern
+or replacement string to the
+.CO substitute
+command, and the
+.QT &
+is replaced by the pattern and replacement information from the
+previous substitute command.
+.sp
+The
+.CO ~
+version of the command is the same as
+.CO &
+and
+.CO s ,
+except that the search pattern used is the last RE used in
+.i any
+command, not necessarily the one used in the last
+.CO substitute
+command.
+.sp
+For example, in the sequence
+.ft C
+.(b
+s/red/blue/
+/green
+~
+.)b
+.ft R
+the
+.QT ~
+is equivalent to
+.QT s/green/blue/ .
+.sp
+The
+.CO substitute
+command may be interrupted, using the terminal interrupt character.
+All substitutions completed before the interrupt are retained.
+.SS
+.SP Line:
+Set to the last line upon which a substitution was made.
+.SP Options:
+Affected by the
+.OP ignorecase
+and
+.OP magic
+option.
+.SE
+.KY suspend
+.IP "su[spend][!]"
+.KY stop
+.Ip "st[op][!]"
+.KY <control-Z>
+.Ip <control-Z>
+Suspend the edit session.
+Appending a
+.QT !
+character to these commands turns off the
+.OP autowrite
+option for the command.
+.SS
+.SP Line:
+Unchanged.
+.SP Options:
+Affected by the
+.OP autowrite
+and
+.OP writeany
+options.
+.SE
+.KY tag
+.IP "ta[g][!] tagstring"
+Edit the file containing the specified tag.
+If the tag is in a different file, then the new file is edited.
+If the current file has been modified since the last complete write,
+the
+.CO tag
+command will fail.
+This check can be overridden by appending the
+.QT !
+character to the command name.
+.sp
+The
+.CO tag
+command searches for
+.LI tagstring
+in the tags file(s) specified by the
+.Op tags
+option.
+(See
+.XR ctags 1
+for more information on tags files.)
+.sp
+Capitalizing the first letter of the command, i.e.
+.CO Tag ,
+while in
+.CO vi
+mode, will edit the file in a new screen.
+In this case, any modifications to the current file are ignored.
+.SS
+.SP Line:
+Set to the line indicated by the tag.
+.SP Options:
+Affected by the
+.OP autowrite ,
+.OP taglength ,
+.OP tags
+and
+.OP writeany
+options.
+.SE
+.KY tagnext
+.IP "tagn[ext][!]"
+Edit the file containing the next context for the current tag.
+If the context is in a different file, then the new file is edited.
+If the current file has been modified since the last complete write,
+the
+.CO tagnext
+command will fail.
+This check can be overridden by appending the
+.QT !
+character to the command name.
+.sp
+Capitalizing the first letter of the command, i.e.
+.CO Tagnext ,
+while in
+.CO vi
+mode, will edit the file in a new screen.
+In this case, any modifications to the current file are ignored.
+.SS
+.SP Line:
+Set to the line indicated by the tag.
+.SP Options:
+Affected by the
+.OP autowrite
+and
+.OP writeany
+options.
+.SE
+.KY tagpop
+.IP "tagp[op][!] [file | number]"
+Pop to the specified tag in the tags stack.
+If neither
+.LI file
+or
+.LI number
+is specified, the
+.CO tagpop
+command pops to the most recent entry on the tags stack.
+If
+.LI file
+or
+.LI number
+is specified, the
+.CO tagpop
+command pops to the most recent entry in the tags stack for that file,
+or numbered entry in the tags stack, respectively.
+(See the
+.CO display
+command for information on displaying the tags stack.)
+.sp
+If the file has been modified since the last complete write, the
+.CO tagpop
+command will fail.
+This check may be overridden by appending a
+.QT !
+character to the command name.
+.SS
+.SP Line:
+Set to the line indicated by the tag.
+.SP Options:
+Affected by the
+.OP autowrite
+and
+.OP writeany
+options.
+.SE
+.KY tagprev
+.IP "tagp[rev][!]"
+Edit the file containing the previous context for the current tag.
+If the context is in a different file, then the new file is edited.
+If the current file has been modified since the last complete write,
+the
+.CO tagprev
+command will fail.
+This check can be overridden by appending the
+.QT !
+character to the command name.
+.sp
+Capitalizing the first letter of the command, i.e.
+.CO Tagprev ,
+while in
+.CO vi
+mode, will edit the file in a new screen.
+In this case, any modifications to the current file are ignored.
+.SS
+.SP Line:
+Set to the line indicated by the tag.
+.SP Options:
+Affected by the
+.OP autowrite
+and
+.OP writeany
+options.
+.SE
+.KY tagtop
+.IP "tagt[op][!]"
+Pop to the least recent tag on the tags stack, clearing the tags stack.
+.sp
+If the file has been modified since the last complete write, the
+.CO tagtop
+command will fail.
+This check may be overridden by appending a
+.QT !
+character to the command name.
+.SS
+.SP Line:
+Set to the line indicated by the tag.
+.SP Options:
+Affected by the
+.OP autowrite
+and
+.OP writeany
+options.
+.SE
+.KY unabbrev
+.IP "una[bbrev] lhs"
+Delete an abbreviation.
+Delete
+.LI lhs
+from the current list of abbreviations.
+.SS
+.SP Line:
+Unchanged.
+.SP Options:
+None.
+.SE
+.KY undo
+.IP "u[ndo]"
+Undo the last change made to the file.
+Changes made by
+.CO global ,
+.CO v ,
+.CO visual
+and map sequences are considered a single command.
+If repeated, the
+.CO u
+command alternates between these two states, and is its own inverse.
+.SS
+.SP Line:
+Set to the last line modified by the command.
+.SP Options:
+None.
+.SE
+.KY unmap
+.IP "unm[ap][!] lhs"
+Unmap a mapped string.
+Delete the command mode map definition for
+.LI lhs .
+If a
+.QT !
+character is appended to the command name, delete the text input mode
+map definition instead.
+.SS
+.SP Line:
+Unchanged.
+.SP Options:
+None.
+.SE
+.KY version
+.IP "ve[rsion]"
+Display the version of the
+.CO ex/vi
+editor.
+.KY visual
+.IP "[line] vi[sual] [type] [count] [flags]"
+.CO Ex
+mode only.
+Enter
+.CO vi .
+The
+.LI type
+is optional, and can be
+.QT \- ,
+.QT +
+or
+.QT ^ ,
+as in the
+.CO ex
+.CO z
+command, to specify the position of the specified line in the screen
+window.
+(The default is to place the line at the top of the screen window.)
+A
+.LI count
+specifies the number of lines that will initially be displayed.
+(The default is the value of the
+.OP window
+editor option.)
+.SS
+.SP Line:
+Unchanged unless
+.LI line
+is specified, in which case it is set to that line.
+.SP Options:
+None.
+.SE
+.KY visual
+.IP "vi[sual][!] [+cmd] [file]"
+.CO Vi
+mode only.
+Edit a new file.
+Identical to the
+.QT "edit[!] [+cmd] [file]"
+command.
+.sp
+Capitalizing the first letter of the command, i.e.
+.CO Visual ,
+will edit the file in a new screen.
+In this case, any modifications to the current file are ignored.
+.KY viusage
+.IP "viu[sage] [command]"
+Display usage for a
+.CO vi
+command.
+If
+.LI command
+is specified, a usage statement for that command is displayed.
+Otherwise, usage statements for all
+.CO vi
+commands are displayed.
+.SS
+.SP Line:
+Unchanged.
+.SP Options:
+None.
+.SE
+.KY write
+.IP "[range] w[rite][!] [>>] [file]"
+.Ip "[range] w[rite] [!] [file]"
+.KY wn
+.Ip "[range] wn[!] [>>] [file]"
+.KY wq
+.Ip "[range] wq[!] [>>] [file]"
+Write the file.
+The specified lines (the entire file, if no range is given) is written
+to
+.LI file .
+If
+.LI file
+is not specified, the current pathname is used.
+If
+.LI file
+is specified, and it exists, or if the current pathname was set using the
+.CO file
+command, and the file already exists, these commands will fail.
+Appending a
+.QT !
+character to the command name will override this check and the write
+will be attempted, regardless.
+.sp
+Specifying the optional
+.QT >>
+string will cause the write to be appended to the file, in which case
+no tests are made for the file already existing.
+.sp
+If the file is preceded by a
+.QT !
+character, the program named by the shell edit option is
+invoked with file as its second argument, and the specified
+lines are passed as standard input to that command.
+The
+.QT !
+in this usage must be separated from command name by at least one
+whitespace character.
+The special meaning of the
+.QT !
+may be overridden by escaping it with a backslash
+.PQ \e
+character.
+.sp
+The
+.CO wq
+version of the write command will exit the editor after writing the file,
+if there are no further files to edit.
+Appending a
+.QT !
+character to the command name or entering two
+.QQ quit
+commands (i.e.
+.CO wq ,
+.CO quit ,
+.CO xit
+or
+.CO ZZ )
+in a row) will override this check and the editor will exit,
+ignoring any files that have not yet been edited.
+.sp
+The
+.CO wn
+version of the write command will move to the next file after writing
+the file, unless the write fails.
+.SS
+.SP Line:
+Unchanged.
+.SP Options:
+Affected by the
+.OP readonly
+and
+.OP writeany
+options.
+.SE
+.KY xit
+.IP "[range] x[it][!] [file]"
+Write the file if it has been modified.
+The specified lines are written to
+.LI file ,
+if the file has been modified since the last complete write to any
+file.
+If no
+.LI range
+is specified, the entire file is written.
+.sp
+The
+.CO xit
+command will exit the editor after writing the file,
+if there are no further files to edit.
+Appending a
+.QT !
+character to the command name or entering two
+.QQ quit
+commands (i.e.
+.CO wq ,
+.CO quit ,
+.CO xit
+or
+.CO ZZ )
+in a row) will override this check and the editor will exit,
+ignoring any files that have not yet been edited.
+.SS
+.SP Line:
+Unchanged.
+.SP Options:
+Affected by the
+.OP readonly
+and
+.OP writeany
+options.
+.SE
+.KY yank
+.IP "[range] ya[nk] [buffer] [count]"
+Copy the specified lines to a buffer.
+If no buffer is specified, the unnamed buffer is used.
+.SS
+.SP Line:
+Unchanged.
+.SP Options:
+None.
+.SE
+.KY z
+.IP "[line] z [type] [count] [flags]"
+Adjust the window.
+If no
+.LI type
+is specified, then
+.LI count
+lines following the specified line are displayed.
+The default
+.LI count
+is the value of the
+.OP window
+option.
+The
+.LI type
+argument changes the position at which
+.LI line
+is displayed on the screen by changing the number of lines
+displayed before and after
+.LI line .
+The following
+.LI type
+characters may be used:
+.SS
+.SP \-
+Place the line at the bottom of the screen.
+.SP +
+Place the line at the top of the screen.
+.SP \&.
+Place the line in the middle of the screen.
+.SP ^
+Write out count lines starting
+.LI "count * 2"
+lines before
+.LI line ;
+the net effect of this is that a
+.QT z^
+command following a
+.CO z
+command writes the previous page.
+.SP =
+Center
+.LI line
+on the screen with a line of hyphens displayed immediately before and
+after it.
+The number of preceding and following lines of text displayed are
+reduced to account for those lines.
+.SE
+.SS
+.SP Line:
+Set to the last line displayed, with the exception of the
+.Dq Li \&=
+.LI type ,
+where the current line is set to the line specified by the command.
+.SP Options:
+Affected by the
+.OP scroll
+option.
+.SE
diff --git a/share/doc/usd/13.viref/ref.so b/share/doc/usd/13.viref/ref.so
new file mode 100644
index 000000000000..a82c79258bb1
--- /dev/null
+++ b/share/doc/usd/13.viref/ref.so
@@ -0,0 +1,103 @@
+.\" Copyright (c) 1994
+.\" The Regents of the University of California. All rights reserved.
+.\" Copyright (c) 1994, 1995, 1996
+.\" Keith Bostic. All rights reserved.
+.\"
+.\" See the LICENSE file for redistribution information.
+.\"
+.\" @(#)ref.so 8.9 (Berkeley) 8/17/96
+.\"
+.\"
+.\" indented paragraph, with spaces between the items, bold font
+.de IP
+.\".tm arg 1 \\$1 arg 2 \\$2 arg 3 \\$3
+.sp 1
+.nr PS \\n(ps
+.nr ps 0
+.ip "\fB\\$1\fP" \\$2
+.nr ps \\n(PS
+.br
+..
+.\" indented paragraph, no spaces between the items, bold font
+.de Ip
+.\".tm arg 1 \\$1 arg 2 \\$2 arg 3 \\$3
+.nr PS \\n(ps
+.nr ps 0
+.ns
+.ip "\fB\\$1\fP" \\$2
+.nr ps \\n(PS
+.br
+..
+.\" start nested .IP
+.de SS
+.sp
+.ba +5n
+..
+.\" end nested .IP
+.de SE
+.ba -5n
+..
+.\" nested .IP, no spaces, normal font
+.de SP
+.\".tm arg 1 \\$1 arg 2 \\$2 arg 3 \\$3
+.nr PS \\n(ps
+.nr ps 0
+.ns
+.ip "\\$1" 9n
+.nr ps \\n(PS
+..
+.\" typewriter font
+.de LI
+\&\fC\\$1\fP\\$2
+..
+.\" ex/vi names in command font
+.de EV
+\&\fB\\$1\fP/\fB\\$2\fP\\$3
+..
+.\" command names
+.de CO
+\&\fB\\$1\fP\\$2
+..
+.\" key words for index
+.de KY
+.sy echo >>index '\\$1 \\n%'
+..
+.\" option names
+.de OP
+\&\fB\\$1\fP\\$2
+..
+.\" paren quoted (typewriter font)
+.de PQ
+(\*(lq\fC\\$1\fP\*(rq)\\$2
+..
+.\" quoted bold
+.de QB
+\*(lq\fB\\$1\fP\*(rq\\$2
+..
+.\" quoted command
+.de QC
+\*(lq\fB\\$1\fP\*(rq\\$2
+..
+.\" quoted option
+.de QO
+\*(lq\fB\\$1\fP\*(rq\\$2
+..
+.\" quoted (no font change)
+.de QQ
+\*(lq\\$1\*(rq\\$2
+..
+.\" quoted (typewriter font)
+.de QT
+\*(lq\fC\\$1\fP\*(rq\\$2
+..
+.\" section macro to build TOC
+.de SH
+.(x
+\\$2
+.)x
+.sh \\$1 "\\$2"
+..
+.\" manual section
+.de XR
+\&\fI\\$1\fP(\\$2)\\$3
+..
diff --git a/share/doc/usd/13.viref/set.opt.roff b/share/doc/usd/13.viref/set.opt.roff
new file mode 100644
index 000000000000..838412897ab0
--- /dev/null
+++ b/share/doc/usd/13.viref/set.opt.roff
@@ -0,0 +1,1303 @@
+.\" Copyright (c) 1994
+.\" The Regents of the University of California. All rights reserved.
+.\" Copyright (c) 1994, 1995, 1996
+.\" Keith Bostic. All rights reserved.
+.\"
+.\" See the LICENSE file for redistribution information.
+.\"
+.\" @(#)set.opt.roff 8.66 (Berkeley) 10/10/96
+.\"
+.SH 1 "Set Options"
+.pp
+There are a large number of options that may be set (or unset) to
+change the editor's behavior.
+This section describes the options, their abbreviations and their
+default values.
+.pp
+In each entry below, the first part of the tag line is the full name
+of the option, followed by any equivalent abbreviations.
+(Regardless of the abbreviations, it is only necessary to use the
+minimum number of characters necessary to distinguish an abbreviation
+from all other commands for it to be accepted, in
+.EV nex nvi .
+Historically, only the full name and the official abbreviations
+were accepted by
+.EV ex vi .
+Using full names in your startup files and environmental variables will
+probably make them more portable.)
+The part in square brackets is the default value of the option.
+Most of the options are boolean, i.e. they are either on or off,
+and do not have an associated value.
+.pp
+Options apply to both
+.CO ex
+and
+.CO vi
+modes, unless otherwise specified.
+.pp
+With a few exceptions,
+all options are settable per screen, i.e. the
+.OP tags
+option can be set differently in each screen.
+The exceptions are the
+.OP columns ,
+.OP lines ,
+.OP secure
+and
+.OP term
+options.
+Changing these options modifies the respective information for all screens.
+.pp
+For information on modifying the options or to display the options and
+their current values, see the
+.QQ set
+command in the section entitled
+.QB "Ex Commands" .
+.KY altwerase
+.IP "altwerase [off]"
+.CO Vi
+only.
+Change how
+.CO vi
+does word erase during text input.
+When this option is set, text is broken up into three classes:
+alphabetic, numeric and underscore characters, other nonblank
+characters, and blank characters.
+Changing from one class to another marks the end of a word.
+In addition, the class of the first character erased is ignored
+(which is exactly what you want when erasing pathname components).
+.KY autoindent
+.IP "autoindent, ai [off]"
+If this option is set, whenever you create a new line (using the
+.CO vi
+.CO A ,
+.CO a ,
+.CO C ,
+.CO c ,
+.CO I ,
+.CO i ,
+.CO O ,
+.CO o ,
+.CO R ,
+.CO r ,
+.CO S ,
+and
+.CO s
+commands, or the
+.CO ex
+.CO append ,
+.CO change ,
+and
+.CO insert
+commands) the new line is automatically indented to align the cursor with
+the first nonblank character of the line from which you created it.
+Lines are indented using tab characters to the extent possible (based on
+the value of the
+.OP tabstop
+option) and then using space characters as necessary.
+For commands inserting text into the middle of a line, any blank characters
+to the right of the cursor are discarded, and the first nonblank character
+to the right of the cursor is aligned as described above.
+.sp
+The indent characters are themselves somewhat special.
+If you do not enter more characters on the new line before moving to
+another line, or entering
+.LI <escape> ,
+the indent character will be deleted and the line will be empty.
+For example, if you enter
+.LI <carriage-return>
+twice in succession,
+the line created by the first
+.LI <carriage-return>
+will not have any characters in it,
+regardless of the indentation of the previous or subsequent line.
+.sp
+Indent characters also require that you enter additional erase characters
+to delete them.
+For example,
+if you have an indented line, containing only blanks, the first
+.LI <word-erase>
+character you enter will erase up to end of the indent characters,
+and the second will erase back to the beginning of the line.
+(Historically, only the
+.LI <control-D>
+key would erase the indent characters.
+Both the
+.LI <control-D>
+key and the usual erase keys work in
+.CO nvi .)
+In addition, if the cursor is positioned at the end of the indent
+characters, the keys
+.QT 0<control-D>
+will erase all of the indent characters for the current line,
+resetting the indentation level to 0.
+Similarly, the keys
+.QT ^<control-D>
+will erase all of the indent characters for the current line,
+leaving the indentation level for future created lines unaffected.
+.sp
+Finally, if the
+.OP autoindent
+option is set, the
+.CO S
+and
+.CO cc
+commands change from the first nonblank of the line to the end of the
+line, instead of from the beginning of the line to the end of the line.
+.KY autoprint
+.IP "autoprint, ap [off]"
+.CO Ex
+only.
+Cause the current line to be automatically displayed after the
+.CO ex
+commands
+.CO < ,
+.CO > ,
+.CO copy ,
+.CO delete ,
+.CO join ,
+.CO move ,
+.CO put ,
+.CO t ,
+.CO Undo ,
+and
+.CO undo .
+This automatic display is suppressed during
+.CO global
+and
+.CO v
+commands, and for any command where optional flags are used to explicitly
+display the line.
+.KY autowrite
+.IP "autowrite, aw [off]"
+If this option is set, the
+.CO vi
+.CO ! ,
+.CO ^^ ,
+.CO ^]
+and
+.CO <control-Z>
+commands, and the
+.CO ex
+.CO edit ,
+.CO next ,
+.CO rewind ,
+.CO stop ,
+.CO suspend ,
+.CO tag ,
+.CO tagpop ,
+and
+.CO tagtop
+commands automatically write the current file back to the current file name
+if it has been modified since it was last written.
+If the write fails, the command fails and goes no further.
+.sp
+Appending the optional force flag character
+.QT !
+to the
+.CO ex
+commands
+.CO next ,
+.CO rewind ,
+.CO stop ,
+.CO suspend ,
+.CO tag ,
+.CO tagpop ,
+and
+.CO tagtop
+stops the automatic write from being attempted.
+.sp
+(Historically, the
+.CO next
+command ignored the optional force flag.)
+Note, the
+.CO ex
+commands
+.CO edit ,
+.CO quit ,
+.CO shell ,
+and
+.CO xit
+are
+.i not
+affected by the
+.OP autowrite
+option.
+.sp
+The
+.OP autowrite
+option is ignored if the file is considered read-only for any reason.
+.\" I cannot get a double quote to print between the square brackets
+.\" to save my life. The ONLY way I've been able to get this to work
+.\" is with the .tr command.
+.tr Q"
+.ds ms backup [QQ]
+.KY backup
+.IP "\*(ms"
+.tr QQ
+If this option is set, it specifies a pathname used as a backup file,
+and, whenever a file is written, the file's current contents are copied
+to it.
+The pathname is
+.QT \&# ,
+.QT \&%
+and
+.QT \&!
+expanded.
+.sp
+If the first character of the pathname is
+.QT \&N ,
+a version number is appended to the pathname (and the
+.QT \&N
+character is then discarded).
+Version numbers are always incremented, and each backup file will have
+a version number one greater than the highest version number currently
+found in the directory.
+.sp
+Backup files must be regular files, owned by the real user ID of the
+user running the editor, and not accessible by any other user.
+.KY beautify
+.IP "beautify, bf [off]"
+If this option is set, all control characters that are not currently being
+specially interpreted, other than
+.LI <tab> ,
+.LI <newline> ,
+and
+.LI <form-feed> ,
+are
+discarded from commands read in by
+.CO ex
+from command files, and from input text entered to
+.CO vi
+(either into the file or to the colon command line).
+Text files read by
+.EV ex vi
+are
+.i not
+affected by the
+.OP beautify
+option.
+.KY cdpath
+.IP "cdpath [environment variable CDPATH, or current directory]"
+This option is used to specify a colon separated list of directories
+which are used as path prefixes for any relative path names used as
+arguments for the
+.CO cd
+command.
+The value of this option defaults to the value of the environmental
+variable
+.LI CDPATH
+if it is set, otherwise to the current directory.
+For compatibility with the POSIX 1003.2 shell, the
+.CO cd
+command does
+.i not
+check the current directory as a path prefix for relative path names
+unless it is explicitly specified.
+It may be so specified by entering an empty string or a
+.QT \&.
+character into the
+.LI CDPATH
+variable or the option value.
+.KY cedit
+.IP "cedit [no default]"
+This option adds the ability to edit the colon command-line history.
+This option is set to a string.
+Whenever the first character of that string is entered on the colon
+command line,
+you will enter a normal editing window on the collected commands that
+you've entered on the
+.CO vi
+colon command-line.
+You may then modify and/or execute the commands.
+All normal text editing is available,
+except that you cannot use
+.CO <control-W>
+to switch to an alternate screen.
+Entering a
+.CO <carriage-return>
+will execute the current line of the screen window as an ex command in
+the context of the screen from which you created the colon command-line
+screen,
+and you will then return to that screen.
+.sp
+Because of
+.CO vi \&'s
+parsing rules, it can be difficult to set the colon command-line edit
+character to the
+.LI <escape>
+character.
+To set it to
+.LI <escape> ,
+use
+.QT "set cedit=<literal-next><escape>" .
+.sp
+If the
+.OP cedit
+edit option is set to the same character as the
+.OP filec
+edit option,
+.CO vi
+will perform colon command-line editing if the character is entered as
+the first character of the line,
+otherwise,
+.CO vi
+will perform file name expansion.
+.KY columns
+.IP "columns, co [80]"
+The number of columns in the screen.
+Setting this option causes
+.EV ex vi
+to set (or reset) the environmental variable
+.LI COLUMNS .
+See the section entitled
+.QB "Sizing the Screen"
+more information.
+.KY comment
+.IP "comment [off]"
+.CO Vi
+only.
+If the first non-empty line of the file begins with the string
+.QT # ,
+.QT /\&*
+or
+.QT // ,
+this option causes
+.CO vi
+to skip to the end of that shell, C or C++ comment (probably a
+terribly boring legal notice) before displaying the file.
+.KY directory
+.IP "directory, dir [environment variable TMPDIR, or /tmp]"
+The directory where temporary files are created.
+The environmental variable
+.LI TMPDIR
+is used as the default value if it exists, otherwise
+.LI /tmp
+is used.
+.KY edcompatible
+.IP "edcompatible, ed [off]"
+Remember the values of the
+.QQ c
+and
+.QQ g
+suffixes to the
+.CO substitute
+commands, instead of initializing them as unset for each new
+command.
+Specifying pattern and replacement strings to the
+.CO substitute
+command unsets the
+.QQ c
+and
+.QQ g
+suffixes as well.
+.KY escapetime
+.IP "escapetime [1]"
+The 10th's of a second
+.EV ex vi
+waits for a subsequent key to complete an
+.LI <escape>
+key mapping.
+.KY errorbells
+.IP "errorbells, eb [off]"
+.CO Ex
+only.
+.CO Ex
+error messages are normally presented in inverse video.
+If that is not possible for the terminal, setting this option causes
+error messages to be announced by ringing the terminal bell.
+.KY exrc
+.IP "exrc, ex [off]"
+If this option is turned on in the EXINIT environment variables,
+or the system or $HOME startup files,
+the local startup files are read,
+unless they are the same as the system or $HOME startup files or
+fail to pass the standard permission checks.
+See the section entitled
+.QB "Startup Information"
+for more information.
+.KY extended
+.IP "extended [off]"
+This option causes all regular expressions to be treated as POSIX
+1003.2 Extended Regular Expressions (which are similar to historic
+.XR egrep 1
+style expressions).
+.KY filec
+.IP "filec [no default]"
+This option adds the ability to do shell expansion when entering input
+on the colon command line.
+This option is set to a string.
+Whenever the first character of that string is entered on the colon
+command line,
+the <blank> delimited string immediately before the cursor is expanded
+as if it were followed by a
+.LI \&*
+character, and file name expansion for the
+.CO ex
+edit command was done.
+If no match is found, the screen is flashed and text input resumed.
+If a single match results, that match replaces the expanded text.
+In addition, if the single match is for a directory, a
+.LI \&/
+character is appended and file completion is repeated.
+If more than a single match results,
+any unique prefix shared by the matches replaces the expanded text,
+the matches are displayed,
+and text input resumed.
+.sp
+Because of
+.CO vi \&'s
+parsing rules, it can be difficult to set the path completion character
+to two command values,
+.LI <escape>
+and
+.LI <tab> .
+To set it to
+.LI <escape> ,
+use
+.QT "set filec=<literal-next><escape>" .
+To set it to
+.LI <tab> ,
+use
+.QT "set filec=\e<tab>" .
+.sp
+If the
+.OP cedit
+edit option is set to the same character as the
+.OP filec
+edit option,
+.CO vi
+will perform colon command-line editing if the character is entered as
+the first character of the line,
+otherwise,
+.CO vi
+will perform file name expansion.
+.KY flash
+.IP "flash [on]"
+This option causes the screen to flash instead of beeping the keyboard,
+on error, if the terminal has the capability.
+.KY hardtabs
+.IP "hardtabs, ht [8]"
+This option defines the spacing between hardware tab settings, i.e.
+the tab expansion done by the operating system and/or the terminal
+itself.
+As
+.EV nex nvi
+never writes
+.LI <tab>
+characters to the terminal, unlike historic versions of
+.EV ex vi ,
+this option does not currently have any affect.
+.KY iclower
+.IP "iclower [off]"
+The
+.OP iclower
+edit option makes all Regular Expressions case-insensitive,
+as long as an upper-case letter does not appear in the search string.
+.KY ignorecase
+.IP "ignorecase, ic [off]"
+This option causes regular expressions, both in
+.CO ex
+commands and in searches,
+to be evaluated in a case-insensitive manner.
+.KY keytime
+.IP "keytime [6]"
+The 10th's of a second
+.EV ex vi
+waits for a subsequent key to complete a key mapping.
+.KY leftright
+.IP "leftright [off]"
+.CO Vi
+only.
+This option causes the screen to be scrolled left-right to view
+lines longer than the screen, instead of the traditional
+.CO vi
+screen interface which folds long lines at the right-hand margin
+of the terminal.
+.KY lines
+.IP "lines, li [24]"
+.CO Vi
+only.
+The number of lines in the screen.
+Setting this option causes
+.EV ex vi
+to set (or reset) the environmental variable
+.LI LINES .
+See the section entitled
+.QB "Sizing the Screen"
+for more information.
+.KY lisp
+.IP "lisp [off]"
+.CO Vi
+only.
+This option changes the behavior of the
+.CO vi
+.CO ( ,
+.CO ) ,
+.CO { ,
+.CO } ,
+.CO [[
+and
+.CO ]]
+commands to match the Lisp language.
+Also, the
+.OP autoindent
+option's behavior is changed to be appropriate for Lisp.
+.sp
+.i "This option is not yet implemented."
+.KY list
+.IP "list [off]"
+This option causes lines to be displayed in an unambiguous fashion.
+Specifically, tabs are displayed as control characters, i.e.
+.QT ^I ,
+and the ends of lines are marked with a
+.QT $
+character.
+.KY lock
+.IP "lock [on]"
+This option causes the editor to attempt to get an exclusive lock on
+any file being edited, read or written.
+Reading or writing a file that cannot be locked produces a warning
+message, but no other effect.
+Editing a file that cannot be locked results in a read only edit session,
+as if the
+.OP readonly
+edit option were set.
+.KY magic
+.IP "magic [on]"
+This option is on by default.
+Turning the
+.OP magic
+option off causes all regular expression characters except for
+.QT ^
+and
+.QT $ ,
+to be treated as ordinary characters.
+To re-enable characters individually, when the
+.OP magic
+option is off,
+precede them with a backslash
+.QT \e
+character.
+See the section entitled
+.QB "Regular Expressions and Replacement Strings"
+for more information.
+.KY matchtime
+.IP "matchtime [7]"
+.CO Vi
+only.
+The 10th's of a second
+.CO vi
+pauses on the matching character when the
+.OP showmatch
+option is set.
+.KY mesg
+.IP "mesg [on]"
+This option allows other users to contact you using the
+.XR talk 1
+and
+.XR write 1
+utilities, while you are editing.
+.EV Ex vi
+does not turn message on, i.e. if messages were turned off when the
+editor was invoked, they will stay turned off.
+This option only permits you to disallow messages for the edit session.
+See the
+.XR mesg 1
+utility for more information.
+.KY msgcat
+.IP "msgcat [./]"
+This option selects a message catalog to be used to display error and
+informational messages in a specified language.
+If the value of this option ends with a '/', it is treated as the name
+of a directory that contains a message catalog
+.QT "vi_XXXX" ,
+where
+.QT XXXX
+is the value of the
+.LI LANG
+environmental variable, if it's set, or the value of the
+.LI LC_MESSAGES
+environmental variable if it's not.
+If neither of those environmental variables are set,
+or if the option doesn't end in a '/',
+the option is treated as the full path name of the message catalog to use.
+.sp
+If any messages are missing from the catalog,
+the backup text (English) is used instead.
+.sp
+See the distribution file
+.LI catalog/README
+for additional information on building and installing message catalogs.
+.KY modelines
+.IP "modelines, modeline [off]"
+If the
+.OP modelines
+option is set,
+.EV ex vi
+has historically scanned the first and last five lines of each file as
+it is read for editing, looking for any
+.CO ex
+commands that have been placed in those lines.
+After the startup information has been processed, and before the user
+starts editing the file, any commands embedded in the file are executed.
+.sp
+Commands were recognized by the letters
+.QQ e
+or
+.QQ v
+followed by
+.QQ x
+or
+.QQ i ,
+at the beginning of a line or following a tab or space character,
+and followed by a
+.QQ : ,
+an
+.CO ex
+command, and another
+.QQ : .
+.sp
+This option is a security problem of immense proportions,
+and should not be used under any circumstances.
+.sp
+.i "This option will never be implemented."
+.\" I cannot get a double quote to print between the square brackets
+.\" to save my life. The ONLY way I've been able to get this to work
+.\" is with the .tr command.
+.tr Q"
+.ds ms noprint [QQ]
+.KY noprint
+.IP "\*(ms"
+.tr QQ
+Characters that are never handled as printable characters.
+By default, the C library function
+.XR isprint 3
+is used to determine if a character is printable or not.
+This edit option overrides that decision.
+.KY number
+.IP "number, nu [off]"
+Precede each line displayed with its current line number.
+.KY octal
+.IP "octal [off]"
+Display unknown characters as octal numbers
+.PQ "\e###" ,
+instead of the default
+hexadecimal
+.PQ "\ex##" .
+.KY open
+.IP "open [on]"
+.CO Ex
+only.
+If this option is not set, the
+.CO open
+and
+.CO visual
+commands are disallowed.
+.KY optimize
+.IP "optimize, opt [on]"
+.CO Vi
+only.
+Throughput of text is expedited by setting the terminal not to do automatic
+carriage returns when printing more than one (logical) line of output,
+greatly speeding output on terminals without addressable cursors when text
+with leading white space is printed.
+.sp
+.i "This option is not yet implemented."
+.KY paragraphs
+.IP "paragraphs, para [IPLPPPQPP LIpplpipbp]"
+.CO Vi
+only.
+Define additional paragraph boundaries for the
+.CO {
+and
+.CO }
+commands.
+The value of this option must be a character string consisting
+of zero or more character pairs.
+.sp
+In the text to be edited, the character string
+.LI "<newline>.<char-pair>" ,
+(where
+.LI <char-pair>
+is one of the character pairs in the option's value)
+defines a paragraph boundary.
+For example, if the option were set to
+.LI "LaA<space>##" ,
+then all of the following additional paragraph boundaries would be
+recognized:
+.sp
+.(l
+<newline>.La
+<newline>.A<space>
+<newline>.##
+.)l
+.KY path
+.IP "path []"
+The path option can be used to specify a <colon>-separated list of
+paths, similar to the
+.LI PATH
+environment variable in the shells.
+If this option is set,
+the name of the file to be edited is not an absolute pathname,
+the first component of the filename is not
+.QT \&.
+or
+.QT \&.. ,
+and the file to be edited doesn't exist in the current directory,
+the elements of the
+.OP path
+option are sequentially searched for a file of the specified name.
+If such a file is found, it is edited.
+.\" I cannot get a double quote to print between the square brackets
+.\" to save my life. The ONLY way I've been able to get this to work
+.\" is with the .tr command.
+.tr Q"
+.ds ms print [QQ]
+.KY print
+.IP "\*(ms"
+.tr QQ
+Characters that are always handled as printable characters.
+By default, the C library function
+.XR isprint 3
+is used to determine if a character is printable or not.
+This edit option overrides that decision.
+.KY prompt
+.IP "prompt [on]"
+.CO Ex
+only.
+This option causes
+.CO ex
+to prompt for command input with a
+.QT :
+character; when it is not set, no prompt is displayed.
+.KY readonly
+.IP "readonly, ro [off]"
+This option causes a force flag to be required to attempt to write the file.
+Setting this option is equivalent to using the
+.b \-R
+command line option,
+or executing the
+.CO vi
+program using the name
+.CO view .
+.sp
+The
+.OP readonly
+edit option is not usually persistent, like other edit options.
+If the
+.b \-R
+command line option is set,
+.CO vi
+is executed as
+.CO view ,
+or the
+.OP readonly
+edit option is explicitly set,
+all files edited in the screen will be marked readonly,
+and the force flag will be required to write them.
+However, if none of these conditions are true,
+or the
+.OP readonly
+edit option is explicitly unset,
+then the
+.OP readonly
+edit option will toggle based on the write permissions of the file currently
+being edited as of when it is loaded into the edit buffer.
+In other words, the
+.OP readonly
+edit option will be set if the current file lacks write permissions,
+and will not be set if the user has write permissions for the file.
+.KY recdir
+.IP "recdir [/var/tmp/vi.recover]"
+The directory where recovery files are stored.
+.sp
+If you change the value of
+.OP recdir ,
+be careful to choose a directory whose contents are not regularly
+deleted.
+Bad choices include directories in memory based filesystems,
+or
+.LI /tmp ,
+on most systems,
+as their contents are removed when the machine is rebooted.
+.sp
+Public directories like
+.LI /usr/tmp
+and
+.LI /var/tmp
+are usually safe, although some sites periodically prune old files
+from them.
+There is no requirement that you use a public directory,
+e.g. a sub-directory of your home directory will work fine.
+.sp
+Finally, if you change the value of
+.OP recdir ,
+you must modify the recovery script to operate in your chosen recovery
+area.
+.sp
+See the section entitled
+.QB "Recovery"
+for further information.
+.KY redraw
+.IP "redraw, re [off]"
+.CO Vi
+only.
+The editor simulates (using great amounts of output), an intelligent
+terminal on a dumb terminal (e.g. during insertions in
+.CO vi
+the characters to the right of the cursor are refreshed as each input
+character is typed).
+.sp
+.i "This option is not yet implemented."
+.KY remap
+.IP "remap [on]"
+If this option is set,
+it is possible to define macros in terms of other macros.
+Otherwise, each key is only remapped up to one time.
+For example, if
+.QT A
+is mapped to
+.QT B ,
+and
+.QT B
+is mapped to
+.QT C ,
+The keystroke
+.QT A
+will be mapped to
+.QT C
+if the
+.OP remap
+option is set, and to
+.QT B
+if it is not set.
+.KY report
+.IP "report [5]"
+Set the threshold of the number of lines that need to be changed or
+yanked before a message will be displayed to the user.
+For everything but the yank command, the value is the largest value
+about which the editor is silent, i.e. by default, 6 lines must be
+deleted before the user is notified.
+However, if the number of lines yanked is greater than
+.i "or equal to"
+the set value, it is reported to the user.
+.KY ruler
+.IP "ruler [off]"
+.CO Vi
+only.
+Display a row/column ruler on the colon command line.
+.KY scroll
+.IP "scroll, scr [(environment variable LINES - 1) / 2]"
+Set the number of lines scrolled by the
+.CO ex
+.CO <control-D>
+and
+.CO <end-of-file>
+commands.
+.sp
+Historically, the
+.CO ex
+.CO z
+command, when specified without a count, used two times the size of the
+scroll value; the POSIX 1003.2 standard specified the window size, which
+is a better choice.
+.KY searchincr
+.IP "searchincr [off]"
+The
+.OP searchincr
+edit option makes the search commands
+.CO \&/
+and
+.CO \&?
+incremental, i.e. the screen is updated and the cursor moves to the matching
+text as the search pattern is entered.
+If the search pattern is not found,
+the screen is beeped and the cursor remains on the colon-command line.
+Erasing characters from the search pattern backs the cursor up to the
+previous matching text.
+.KY sections
+.IP "sections, sect [NHSHH HUnhsh]"
+.CO Vi
+only.
+Define additional section boundaries for the
+.CO [[
+and
+.CO ]]
+commands.
+The
+.OP sections
+option should be set to a character string consisting of zero or
+more character pairs.
+In the text to be edited, the character string
+.LI "<newline>.<char-pair>" ,
+(where
+.LI <char-pair>
+is one of the character pairs in the option's value),
+defines a section boundary in the same manner that
+.OP paragraphs
+option boundaries are defined.
+.KY secure
+.IP "secure [off]"
+The
+.OP secure
+edit option turns off all access to external programs.
+This means that the versions of the
+.CO read
+and
+.CO write
+commands that filter text through other programs,
+the
+.CO vi
+.CO \&!
+and
+.CO <control-Z>
+commands,
+the
+.CO ex
+.CO \&! ,
+.CO script ,
+.CO shell ,
+.CO stop
+and
+.CO suspend
+commands and file name expansion will not be permitted.
+Once set,
+the
+.OP secure
+edit option may not be unset.
+.KY shell
+.IP "shell, sh [environment variable SHELL, or /bin/sh]"
+Select the shell used by the editor.
+The specified path is the pathname of the shell invoked by the
+.CO vi
+.CO !
+shell escape command and by the
+.CO ex
+.CO shell
+command.
+This program is also used to resolve any shell meta-characters in
+.CO ex
+commands.
+.\" I cannot get a double quote to print between the square brackets
+.\" to save my life. The ONLY way I've been able to get this to work
+.\" is with the .tr command.
+.tr Q"
+.ds ms shellmeta [~{[*?$`'Q\e]
+.KY shellmeta
+.IP "\*(ms"
+.tr QQ
+The set of characters that
+.CO ex
+checks for when doing file name expansion.
+If any of the specified characters are found in the file name arguments
+to the
+.CO ex
+commands,
+the arguments are expanded using the program defined by the
+.OP shell
+option.
+The default set of characters is a union of meta characters
+from the Version 7 and the Berkeley C shell.
+.KY shiftwidth
+.IP "shiftwidth, sw [8]"
+Set the autoindent and shift command indentation width.
+This width is used by the
+.OP autoindent
+option and by the
+.CO < ,
+.CO > ,
+and
+.CO shift
+commands.
+.KY showmatch
+.IP "showmatch, sm [off]"
+.CO Vi
+only.
+This option causes
+.CO vi ,
+when a
+.QT }
+or
+.QT )
+is entered, to briefly move the cursor the matching
+.QT {
+or
+.QT ( .
+See the
+.OP matchtime
+option for more information.
+.KY showmode
+.IP "showmode, smd [off]"
+.CO Vi
+only.
+This option causes
+.CO vi
+to display a string identifying the current editor mode on the colon
+command line.
+The string is preceded by an asterisk (``*'') if the file has been
+modified since it was last completely written,
+.KY sidescroll
+.IP "sidescroll [16]"
+.CO Vi
+only.
+Sets the number of columns that are shifted to the left or right,
+when
+.CO vi
+is doing left-right scrolling and the left or right margin is
+crossed.
+See the
+.OP leftright
+option for more information.
+.KY slowopen
+.IP "slowopen, slow [off]"
+This option affects the display algorithm used by
+.CO vi ,
+holding off display updating during input of new text to improve
+throughput when the terminal in use is slow and unintelligent.
+.sp
+.i "This option is not yet implemented."
+.KY sourceany
+.IP "sourceany [off]"
+If this option is turned on,
+.CO vi
+historically read startup files that were owned by someone other than
+the editor user.
+See the section entitled
+.QB "Startup Information"
+for more information.
+This option is a security problem of immense proportions,
+and should not be used under any circumstances.
+.sp
+.i "This option will never be implemented."
+.KY tabstop
+.IP "tabstop, ts [8]"
+This option sets tab widths for the editor display.
+.KY taglength
+.IP "taglength, tl [0]"
+This option sets the maximum number of characters that are considered
+significant in a tag name.
+Setting the value to 0 makes all of the characters in the tag name
+significant.
+.KY tags
+.IP "tags, tag [tags /var/db/libc.tags /sys/kern/tags]"
+Sets the list of tags files, in search order,
+which are used when the editor searches for a tag.
+.KY term
+.IP "term, ttytype, tty [environment variable TERM]"
+Set the terminal type.
+Setting this option causes
+.EV ex vi
+to set (or reset) the environmental variable
+.LI TERM .
+.KY terse
+.IP "terse [off]"
+This option has historically made editor messages less verbose.
+It has no effect in this implementation.
+See the
+.OP verbose
+option for more information.
+.KY tildeop
+.IP "tildeop [off]"
+Modify the
+.CO ~
+command to take an associated motion.
+.KY timeout
+.IP "timeout, to [on]"
+If this option is set,
+.EV ex vi
+waits for a specific period for a subsequent key to complete a key
+mapping (see the
+.OP keytime
+option).
+If the option is not set, the editor waits until enough keys are
+entered to resolve the ambiguity, regardless of how long it takes.
+.KY ttywerase
+.IP "ttywerase [off]"
+.CO Vi
+only.
+This option changes how
+.CO vi
+does word erase during text input.
+If this option is set, text is broken up into two classes,
+blank characters and nonblank characters.
+Changing from one class to another marks the end of a word.
+.KY verbose
+.IP "verbose [off]"
+.CO Vi
+only.
+.CO Vi
+historically bells the terminal for many obvious mistakes, e.g. trying
+to move past the left-hand margin, or past the end of the file.
+If this option is set, an error message is displayed for all errors.
+.KY w300
+.IP "w300 [no default]"
+.CO Vi
+only.
+Set the window size if the baud rate is less than 1200 baud.
+See the
+.OP window
+option for more information.
+.KY w1200
+.IP "w1200 [no default]"
+.CO Vi
+only.
+Set the window size if the baud rate is equal to 1200 baud.
+See the
+.OP window
+option for more information.
+.KY w9600
+.IP "w9600 [no default]"
+.CO Vi
+only.
+Set the window size if the baud rate is greater than 1200 baud.
+See the
+.OP window
+option for more information.
+.KY warn
+.IP "warn [on]"
+.CO Ex
+only.
+This option causes a warning message to the terminal if the file has
+been modified, since it was last written, before a
+.CO !
+command.
+.KY window
+.IP "window, w, wi [environment variable LINES - 1]"
+This option determines the default number of lines in a screenful,
+as displayed by the
+.CO z
+command.
+It also determines the number of lines scrolled by the
+.CO vi
+commands
+.CO <control-B>
+and
+.CO <control-F> ,
+and the default number of lines scrolled by the
+.CO vi
+commands
+.CO <control-D>
+and
+.CO <control-U> .
+The value of window can be unrelated to the real screen size,
+although it starts out as the number of lines on the screen.
+See the section entitled
+.QB "Sizing the Screen"
+for more information.
+Setting the value of the
+.OP window
+option is the same as using the
+.b \-w
+command line option.
+.sp
+If the value of the
+.OP window
+option (as set by the
+.OP window ,
+.OP w300 ,
+.OP w1200
+or
+.OP w9600
+options) is smaller than the actual size of the screen,
+large screen movements will result in displaying only that smaller
+number of lines on the screen.
+(Further movements in that same area will result in the screen being
+filled.)
+This can provide a performance improvement when viewing different
+places in one or more files over a slow link.
+.sp
+Resetting the window size does not reset the default number of lines
+scrolled by the
+.CO <control-D>
+and
+.CO <control-U>
+commands.
+.KY windowname
+.IP "windowname [off]"
+.CO Vi
+changes the name of the editor's icon/window to the current file name
+when it's possible and not destructive, i.e.,
+when the editor can restore it to its original value on exit or when
+the icon/window will be discarded as the editor exits.
+If the
+.OP windowname
+edit option is set,
+.CO vi
+will change the icon/window name even when it's destructive and the
+icon/window name will remain after the editor exits.
+(This is the case for
+.XR xterm 1 ).
+.KY wraplen
+.IP "wraplen, wl [0]"
+This option is identical to the
+.OP wrapmargin
+option, with the exception that it specifies the number of columns
+from the
+.i left
+margin before the line splits, not the right margin.
+.sp
+If both
+.OP wraplen
+and
+.OP wrapmargin
+are set, the
+.OP wrapmargin
+value is used.
+.KY wrapmargin
+.IP "wrapmargin, wm [0]"
+.CO Vi
+only.
+If the value of the
+.OP wrapmargin
+option is non-zero,
+.CO vi
+will split lines so that they end at least that number of columns
+before the right-hand margin of the screen.
+(Note, the value of
+.OP wrapmargin
+is
+.i not
+a text length.
+In a screen that is 80 columns wide, the command
+.QT ":set wrapmargin=8"
+attempts to keep the lines less than or equal to 72 columns wide.)
+.sp
+Lines are split at the previous whitespace character closest to the
+number.
+Any trailing whitespace characters before that character are deleted.
+If the line is split because of an inserted
+.LI <space>
+or
+.LI <tab>
+character, and you then enter another
+.LI <space>
+character, it is discarded.
+.sp
+If wrapmargin is set to 0,
+or if there is no blank character upon which to split the line,
+the line is not broken.
+.sp
+If both
+.OP wraplen
+and
+.OP wrapmargin
+are set, the
+.OP wrapmargin
+value is used.
+.KY wrapscan
+.IP "wrapscan, ws [on]"
+This option causes searches to wrap around the end or the beginning
+of the file, and back to the starting point.
+Otherwise, the end or beginning of the file terminates the search.
+.KY writeany
+.IP "writeany, wa [off]"
+If this option is set, file-overwriting checks that would usually be
+made before the
+.CO write
+and
+.CO xit
+commands, or before an automatic write (see the
+.OP autowrite
+option), are not made.
+This allows a write to any file, provided the file permissions allow it.
diff --git a/share/doc/usd/13.viref/vi.cmd.roff b/share/doc/usd/13.viref/vi.cmd.roff
new file mode 100644
index 000000000000..12030cd52b08
--- /dev/null
+++ b/share/doc/usd/13.viref/vi.cmd.roff
@@ -0,0 +1,3085 @@
+.\" Copyright (c) 1994
+.\" The Regents of the University of California. All rights reserved.
+.\" Copyright (c) 1994, 1995, 1996
+.\" Keith Bostic. All rights reserved.
+.\"
+.\" See the LICENSE file for redistribution information.
+.\"
+.\" @(#)vi.cmd.roff 8.49 (Berkeley) 8/17/96
+.\"
+.SH 1 "Vi Description"
+.pp
+.CO Vi
+takes up the entire screen to display the edited file,
+except for the bottom line of the screen.
+The bottom line of the screen is used to enter
+.CO ex
+commands, and for
+.CO vi
+error and informational messages.
+If no other information is being displayed,
+the default display can show the current cursor row and cursor column,
+an indication of whether the file has been modified,
+and the current mode of the editor.
+See the
+.OP ruler
+and
+.OP showmode
+options for more information.
+.pp
+Empty lines do not have any special representation on the screen,
+but lines on the screen that would logically come after the end of
+the file are displayed as a single tilde
+.PQ ~
+character.
+To differentiate between empty lines and lines consisting of only
+whitespace characters, use the
+.OP list
+option.
+Historically, implementations of
+.CO vi
+have also displayed some lines as single asterisk
+.PQ @
+characters.
+These were lines that were not correctly displayed, i.e. lines on the
+screen that did not correspond to lines in the file, or lines that did
+not fit on the current screen.
+.CO Nvi
+never displays lines in this fashion.
+.pp
+.CO Vi
+is a modeful editor, i.e. it has two modes,
+.QQ command
+mode and
+.QQ "text input"
+mode.
+When
+.CO vi
+first starts, it is in command mode.
+There are several commands that change
+.CO vi
+into text input mode.
+The
+.LI <escape>
+character is used to resolve the text input into the file,
+and exit back into command mode.
+In
+.CO vi
+command mode, the cursor is always positioned on the last column of
+characters which take up more than one column on the screen.
+In
+.CO vi
+text insert mode, the cursor is positioned on the first column of
+characters which take up more than one column on the screen.
+.pp
+When positioning the cursor to a new line and column,
+the type of movement is defined by the distance to the new cursor position.
+If the new position is close,
+the screen is scrolled to the new location.
+If the new position is far away,
+the screen is repainted so that the new position is on the screen.
+If the screen is scrolled,
+it is moved a minimal amount,
+and the cursor line will usually appear at the top or bottom of the screen.
+If the screen is repainted,
+the cursor line will appear in the center of the screen,
+unless the cursor is sufficiently close to the beginning or end of the file
+that this isn't possible.
+If the
+.OP leftright
+option is set, the screen may be scrolled or repainted in a horizontal
+direction as well as in a vertical one.
+.pp
+A major difference between the historical
+.CO vi
+presentation and
+.CO nvi
+is in the scrolling and screen oriented position commands,
+.CO <control-B> ,
+.CO <control-D> ,
+.CO <control-E> ,
+.CO <control-F> ,
+.CO <control-U> ,
+.CO <control-Y> ,
+.CO H ,
+.CO L
+and
+.CO M .
+In historical implementations of
+.CO vi ,
+these commands acted on physical (as opposed to logical, or screen)
+lines.
+For lines that were sufficiently long in relation to the size of the
+screen, this meant that single line scroll commands might repaint the
+entire screen, scrolling or screen positioning commands might not change
+the screen or move the cursor at all, and some lines simply could not
+be displayed, even though
+.CO vi
+would edit the file that contained them.
+In
+.CO nvi ,
+these commands act on logical, i.e. screen lines.
+You are unlikely to notice any difference unless you are editing files
+with lines significantly longer than a screen width.
+.pp
+.CO Vi
+keeps track of the currently
+.QQ "most attractive"
+cursor position.
+Each command description (for commands that alter the current cursor
+position),
+specifies if the cursor is set to a specific location in the line,
+or if it is moved to the
+.QQ "most attractive cursor position" .
+The latter means that the cursor is moved to the cursor position that
+is horizontally as close as possible to the current cursor position.
+If the current line is shorter than the cursor position
+.CO vi
+would select, the cursor is positioned on the last character in the line.
+(If the line is empty, the cursor is positioned on the first column
+of the line.)
+If a command moves the cursor to the most attractive position,
+it does not alter the current cursor position, and a subsequent
+movement will again attempt to move the cursor to that position.
+Therefore, although a movement to a line shorter than the currently
+most attractive position will cause the cursor to move to the end of
+that line, a subsequent movement to a longer line will cause the
+cursor to move back to the most attractive position.
+.pp
+In addition, the
+.CO $
+command makes the end of each line the most attractive cursor position
+rather than a specific column.
+.pp
+Each
+.CO vi
+command described below notes where the cursor ends up after it is
+executed.
+This position is described in terms of characters on the line, i.e.
+.QQ "the previous character" ,
+or,
+.QQ "the last character in the line" .
+This is to avoid needing to continually refer to on what part of the
+character the cursor rests.
+.pp
+The following words have special meaning for
+.CO vi
+commands.
+.KY "previous context"
+.IP "previous context"
+The position of the cursor before the command which caused the
+last absolute movement was executed.
+Each
+.CO vi
+command described in the next section that is considered an
+absolute movement is so noted.
+In addition, specifying
+.i any
+address to an
+.CO ex
+command is considered an absolute movement.
+.KY "motion"
+.IP "motion"
+A second
+.CO vi
+command can be used as an optional trailing argument to the
+.CO vi
+.CO \&< ,
+.CO \&> ,
+.CO \&! ,
+.CO \&c ,
+.CO \&d ,
+.CO \&y ,
+and (depending on the
+.OP tildeop
+option)
+.CO \&~
+commands.
+This command indicates the end of the region of text that's affected by
+the command.
+The motion command may be either the command character repeated (in
+which case it means the current line) or a cursor movement command.
+In the latter case, the region affected by the command is from the
+starting or stopping cursor position which comes first in the file,
+to immediately before the starting or stopping cursor position which
+comes later in the file.
+Commands that operate on lines instead of using beginning and ending
+cursor positions operate on all of the lines that are wholly or
+partially in the region.
+In addition, some other commands become line oriented depending on
+where in the text they are used.
+The command descriptions below note these special cases.
+.sp
+The following commands may all be used as motion components for
+.CO vi
+commands:
+.sp
+.ne 12v
+.ft C
+.TS
+r r r r.
+<control-A> <control-H> <control-J> <control-M>
+<control-N> <control-P> <space> $
+% '<character> ( )
++ , - /
+0 ; ? B
+E F G H
+L M N T
+W [[ ]] ^
+\&_ `<character> b e
+f h j k
+l n t w
+{ | }
+.TE
+.ft R
+.sp
+The optional count prefix available for some of the
+.CO vi
+commands that take motion commands,
+or the count prefix available for the
+.CO vi
+commands that are used as motion components,
+may be included and is
+.i always
+considered part of the motion argument.
+For example, the commands
+.QT c2w
+and
+.QT 2cw
+are equivalent, and the region affected by the
+.CO c
+command is two words of text.
+In addition,
+if the optional count prefix is specified for both the
+.CO vi
+command and its motion component,
+the effect is multiplicative and is considered part of the motion argument.
+For example, the commands
+.QT 4cw
+and
+.QT 2c2w
+are equivalent, and the region affected by the
+.CO c
+command is four words of text.
+.KY "count"
+.IP "count"
+A positive number used as an optional argument to most commands,
+either to give a size or a position (for display or movement commands),
+or as a repeat count (for commands that modify text).
+The count argument is always optional and defaults to 1 unless otherwise
+noted in the command description.
+.sp
+When a
+.CO vi
+command synopsis shows both a
+.LI [buffer]
+and
+.LI [count] ,
+they may be presented in any order.
+.KY word
+.IP word
+Generally, in languages where it is applicable,
+.CO vi
+recognizes two kinds of words.
+First, a sequence of letters, digits and underscores,
+delimited at both ends by:
+characters other than letters, digits, or underscores,
+the beginning or end of a line, and the beginning or end of the file.
+Second, a sequence of characters other than letters, digits, underscores,
+or whitespace characters, delimited at both ends by: a letter, digit,
+underscore, or whitespace character,
+the beginning or end of a line, and the beginning or end of the file.
+For example, the characters
+.QT " !@#abc$%^ "
+contain three words:
+.QT "!@#" ,
+.QT "abc"
+and
+.QT "$%^" .
+.sp
+Groups of empty lines (or lines containing only whitespace characters)
+are treated as a single word.
+.KY "bigword"
+.IP "bigword"
+A set of non-whitespace characters preceded and followed by whitespace
+characters or the beginning or end of the file or line.
+For example, the characters
+.QT " !@#abc$%^ "
+contain one bigword:
+.QT "!@#abc$%^" .
+.sp
+Groups of empty lines (or lines containing only whitespace characters)
+are treated as a single bigword.
+.KY "paragraph"
+.IP "paragraph"
+An area of text that begins with either the beginning of a file,
+an empty line, or a section boundary, and continues until either
+an empty line, section boundary, or the end of the file.
+.sp
+Groups of empty lines (or lines containing only whitespace characters)
+are treated as a single paragraph.
+.sp
+Additional paragraph boundaries can be defined using the
+.OP paragraphs
+option.
+.KY "section"
+.IP "section"
+An area of text that starts with the beginning of the file or a line
+whose first character is an open brace
+.PQ {
+and continues until the next section or the end of the file.
+.sp
+Additional section boundaries can be defined using the
+.OP sections
+option.
+.KY "sentence"
+.IP "sentence"
+An area of text that begins with either the beginning of the file or the
+first nonblank character following the previous sentence, paragraph, or
+section boundary and continues until the end of the file or a period
+.PQ \&.
+exclamation point
+.PQ !
+or question mark
+.PQ ?
+character,
+followed by either an end-of-line or two whitespace characters.
+Any number of closing parentheses
+.PQ ) ,
+brackets
+.PQ ] ,
+double-quote
+.PQ """"
+or single quote
+.PQ '
+characters can appear between the period, exclamation point,
+or question mark and the whitespace characters or end-of-line.
+.sp
+Groups of empty lines (or lines containing only whitespace characters)
+are treated as a single sentence.
+.SH 1 "Vi Commands"
+.pp
+The following section describes the commands available in the command
+mode of the
+.CO vi
+editor.
+In each entry below, the tag line is a usage synopsis for the command
+character.
+In addition, the final line and column the cursor rests upon,
+and any options which affect the command are noted.
+.KY <control-A>
+.IP "[count] <control-A>"
+Search forward
+.LI count
+times for the current word.
+The current word begins at the first non-whitespace character on or
+after the current cursor position,
+and extends up to the next non-word character or the end of the line.
+The search is literal, i.e. no characters in the word have any special
+meaning in terms of Regular Expressions.
+It is an error if no matching pattern is found between the starting position
+and the end of the file.
+.sp
+The
+.CO <control-A>
+command is an absolute movement.
+The
+.CO <control-A>
+command may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+character oriented.
+.SS
+.SP Line:
+Set to the line where the word is found.
+.SP Column:
+Set to the first character of the word.
+.SP Options:
+Affected by the
+.OP ignorecase
+and
+.OP wrapscan
+options.
+.SE
+.KY <control-B>
+.IP "[count] <control-B>"
+Page backward
+.LI count
+screens.
+Two lines of overlap are maintained, if possible,
+by displaying the window starting at line
+.LI "(top_line - count * window_size) + 2" ,
+where
+.LI window_size
+is the value of the
+.OP window
+option.
+(In the case of split screens, this size is corrected to the
+current screen size.)
+It is an error if the movement is past the beginning of the file.
+.SS
+.SP Line:
+Set to the last line of text displayed on the screen.
+.SP Column:
+Set to the first nonblank character of the line.
+.SP Options:
+Affected by the
+.OP window
+option.
+.SE
+.KY <control-D>
+.IP "[count] <control-D>"
+Scroll forward
+.LI count
+lines.
+If
+.LI count
+is not specified, scroll forward the number of lines specified by the last
+.CO <control-D>
+or
+.CO <control-U>
+command.
+If this is the first
+.CO <control-D>
+or
+.CO <control-U>
+command,
+scroll forward half the number of lines in the screen.
+(In the case of split screens, the default scrolling distance is
+corrected to half the current screen size.)
+It is an error if the movement is past the end of the file.
+.SS
+.SP Line:
+Set to the current line plus the number of lines scrolled.
+.SP Column:
+Set to the first nonblank character of the line.
+.SP Options:
+None.
+.SE
+.KY <control-E>
+.IP "[count] <control-E>"
+Scroll forward
+.LI count
+lines, leaving the cursor on the current line and column, if possible.
+It is an error if the movement is past the end of the file.
+.SS
+.SP Line:
+Unchanged unless the current line scrolls off the screen,
+in which case it is set to the first line on the screen.
+.SP Column:
+Unchanged unless the current line scrolls off the screen,
+in which case it is set to the most attractive cursor position.
+.SP Options:
+None.
+.SE
+.KY <control-F>
+.IP "[count] <control-F>"
+Page forward
+.LI count
+screens.
+Two lines of overlap are maintained, if possible,
+by displaying the window starting at line
+.LI "top_line + count * window_size - 2" ,
+where
+.LI window_size
+is the value of the
+.OP window
+option.
+(In the case of split screens, this size is corrected to the
+current screen size.)
+It is an error if the movement is past the end of the file.
+.SS
+.SP Line:
+Set to the first line on the screen.
+.SP Column:
+Set to the first nonblank character of the current line.
+.SP Options:
+Affected by the
+.OP window
+option.
+.SE
+.KY <control-G>
+.IP "<control-G>"
+Display the file information.
+The information includes the current pathname, the current line,
+the number of total lines in the file, the current line as a percentage
+of the total lines in the file, if the file has been modified,
+was able to be locked, if the file's name has been changed,
+and if the edit session is read-only.
+.SS
+.SP Line:
+Unchanged.
+.SP Column:
+Unchanged.
+.SP Options:
+None.
+.SE
+.KY <control-H>
+.IP "[count] <control-H>"
+.Ip "[count] h"
+Move the cursor back
+.LI count
+characters in the current line.
+It is an error if the cursor is on the first character in the line.
+.sp
+The
+.CO <control-H>
+and
+.CO h
+commands may be used as the motion component of other
+.CO vi
+commands,
+in which case any text copied into a buffer is character oriented.
+.SS
+.SP Line:
+Unchanged.
+.SP Column:
+Set to the
+.LI "current - count"
+character, or, the first character in the line if
+.LI count
+is greater than or equal to the number of characters in the line
+before the cursor.
+.SP Options:
+None.
+.SE
+.KY <control-J>
+.IP "[count] <control-J>"
+.KY <control-N>
+.Ip "[count] <control-N>"
+.KY j
+.Ip "[count] j"
+Move the cursor down
+.LI count
+lines without changing the current column.
+It is an error if the movement is past the end of the file.
+.sp
+The
+.CO <control-J> ,
+.CO <control-N>
+and
+.CO j
+commands may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+line oriented.
+.SS
+.SP Line:
+Set to the current line plus
+.LI count .
+.SP Column:
+The most attractive cursor position.
+.SP Options:
+None.
+.SE
+.KY <control-L>
+.IP "<control-L>"
+.KY <control-R>
+.Ip "<control-R>"
+Repaint the screen.
+.SS
+.SP Line:
+Unchanged.
+.SP Column:
+Unchanged.
+.SP Options:
+None.
+.SE
+.KY <control-M>
+.IP "[count] <control-M>"
+.KY +
+.Ip "[count] +"
+Move the cursor down
+.LI count
+lines to the first nonblank character of that line.
+It is an error if the movement is past the end of the file.
+.sp
+The
+.CO <control-M>
+and
+.CO +
+commands may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+line oriented.
+.SS
+.SP Line:
+Set to the current line plus
+.LI count .
+.SP Column:
+Set to the first nonblank character in the line.
+.SP Options:
+None.
+.SE
+.KY <control-P>
+.IP "[count] <control-P>"
+.KY k
+.Ip "[count] k"
+Move the cursor up
+.LI count
+lines, without changing the current column.
+It is an error if the movement is past the beginning of the file.
+.sp
+The
+.CO <control-P>
+and
+.CO k
+commands may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+line oriented.
+.SS
+.SP Line:
+Set to the current line minus
+.LI count .
+.SP Column:
+The most attractive cursor position.
+.SP Options:
+None.
+.SE
+.KY <control-T>
+.IP "<control-T>"
+Return to the most recent tag context.
+The
+.CO <control-T>
+command is an absolute movement.
+.SS
+.SP Line:
+Set to the context of the previous tag command.
+.SP Column:
+Set to the context of the previous tag command.
+.SP Options:
+None.
+.SE
+.KY <control-U>
+.IP "[count] <control-U>"
+Scroll backward
+.LI count
+lines.
+If
+.LI count
+is not specified, scroll backward the number of lines specified by the
+last
+.CO <control-D>
+or
+.CO <control-U>
+command.
+If this is the first
+.CO <control-D>
+or
+.CO <control-U>
+command,
+scroll backward half the number of lines in the screen.
+(In the case of split screens, the default scrolling distance is
+corrected to half the current screen size.)
+It is an error if the movement is past the beginning of the file.
+.SS
+.SP Line:
+Set to the current line minus the amount scrolled.
+.SP Column:
+Set to the first nonblank character in the line.
+.SP Options:
+None.
+.SE
+.KY <control-W>
+.IP "<control-W>"
+Switch to the next lower screen in the window, or, to the first
+screen if there are no lower screens in the window.
+.SS
+.SP Line:
+Set to the previous cursor position in the window.
+.SP Column:
+Set to the previous cursor position in the window.
+.SP Options:
+None.
+.SE
+.KY <control-Y>
+.IP "[count] <control-Y>"
+Scroll backward
+.LI count
+lines, leaving the current line and column as is, if possible.
+It is an error if the movement is past the beginning of the file.
+.SS
+.SP Line:
+Unchanged unless the current line scrolls off the screen,
+in which case it is set to the last line of text displayed
+on the screen.
+.SP Column:
+Unchanged unless the current line scrolls off the screen,
+in which case it is the most attractive cursor position.
+.SP Options:
+None.
+.SE
+.KY <control-Z>
+.IP "<control-Z>"
+Suspend the current editor session.
+If the file has been modified since it was last completely written,
+and the
+.OP autowrite
+option is set, the file is written before the editor session is
+suspended.
+If this write fails, the editor session is not suspended.
+.SS
+.SP Line:
+Unchanged.
+.SP Column:
+Unchanged.
+.SP Options:
+Affected by the
+.OP autowrite
+option.
+.SE
+.KY <escape>
+.IP "<escape>"
+Execute
+.CO ex
+commands or cancel partial commands.
+If an
+.CO ex
+command is being entered (e.g.
+.CO / ,
+.CO ? ,
+.CO :
+or
+.CO ! ),
+the command is executed.
+If a partial command has been entered, e.g.
+.QT "[0-9]*" ,
+or
+.QT "[0-9]*[!<>cdy]" ,
+the command is cancelled.
+Otherwise, it is an error.
+.SS
+.SP Line:
+When an
+.CO ex
+command is being executed, the current line is set as described for
+that command.
+Otherwise, unchanged.
+.SP Column:
+When an
+.CO ex
+command is being executed, the current column is set as described for
+that command.
+Otherwise, unchanged.
+.SP Options:
+None.
+.SE
+.KY <control-]>
+.IP "<control-]>"
+Push a tag reference onto the tag stack.
+The tags files (see the
+.OP tags
+option for more information) are searched for a tag matching the
+current word.
+The current word begins at the first non-whitespace character on or
+after the current cursor position,
+and extends up to the next non-word character or the end of the line.
+If a matching tag is found, the current file is discarded and the
+file containing the tag reference is edited.
+.sp
+If the current file has been modified since it was last completely
+written, the command will fail.
+The
+.CO <control-]>
+command is an absolute movement.
+.SS
+.SP Line:
+Set to the line containing the matching tag string.
+.SP Column:
+Set to the start of the matching tag string.
+.SP Options:
+Affected by the
+.OP tags
+and
+.OP taglength
+options.
+.SE
+.KY <control-^>
+.IP "<control-^>"
+Switch to the most recently edited file.
+.sp
+If the file has been modified since it was last completely written,
+and the
+.OP autowrite
+option is set, the file is written out.
+If this write fails, the command will fail.
+Otherwise, if the current file has been modified since it was last
+completely written, the command will fail.
+.SS
+.SP Line:
+Set to the line the cursor was on when the file was last edited.
+.SP Column:
+Set to the column the cursor was on when the file was last edited.
+.SP Options:
+Affected by the
+.OP autowrite
+option.
+.SE
+.KY <space>
+.IP "[count] <space>"
+.KY l
+.Ip "[count] l"
+Move the cursor forward
+.LI count
+characters without changing the current line.
+It is an error if the cursor is on the last character in the line.
+.sp
+The
+.CO <space>
+and
+.CO \&l
+commands may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+character oriented.
+In addition, these commands may be used as the motion components
+of other commands when the cursor is on the last character in the
+line, without error.
+.SS
+.SP Line:
+Unchanged.
+.SP Column:
+Set to the current character plus the next
+.LI count
+characters, or to the last character on the line if
+.LI count
+is greater than the number of characters in the line after the
+current character.
+.SP Options:
+None.
+.SE
+.KY !
+.IP "[count] ! motion shell-argument(s)<carriage-return>"
+Replace text with results from a shell command.
+Pass the lines specified by the
+.LI count
+and
+.LI motion
+arguments as standard input to the program named by the
+.OP shell
+option, and replace those lines with the output (both
+standard error and standard output) of that command.
+.sp
+After the motion is entered,
+.CO vi
+prompts for arguments to the shell command.
+.sp
+Within those arguments,
+.QT %
+and
+.QT #
+characters are expanded to the current and alternate pathnames,
+respectively.
+The
+.QT !
+character is expanded with the command text of the previous
+.CO !
+or
+.CO :!
+commands.
+(Therefore, the command
+.CO !<motion>!
+repeats the previous
+.CO !
+command.)
+The special meanings of
+.QT % ,
+.QT #
+and
+.QT !
+can be overridden by escaping them with a backslash.
+If no
+.CO !
+or
+.CO :!
+command has yet been executed,
+it is an error to use an unescaped
+.QT !
+character as a shell argument.
+The
+.CO !
+command does
+.i not
+do shell expansion on the strings provided as arguments.
+If any of the above expansions change the arguments the user entered,
+the command is redisplayed at the bottom of the screen.
+.sp
+.CO Vi
+then executes the program named by the
+.OP shell
+option, with a
+.b \-c
+flag followed by the arguments (which are bundled into a single argument).
+.sp
+The
+.CO !
+command is permitted in an empty file.
+.sp
+If the file has been modified since it was last completely written,
+the
+.CO !
+command will warn you.
+.SS
+.SP Line:
+The first line of the replaced text.
+.SP Column:
+The first column of the replaced text.
+.SP Options:
+Affected by the
+.OP shell
+option.
+.SE
+.KY #
+.IP "[count] # #|+|-"
+Increment or decrement the number referenced by the cursor.
+If the trailing character is a
+.LI \&+
+or
+.LI \&# ,
+the number is incremented by
+.LI count .
+If the trailing character is a
+.LI \&- ,
+the number is decremented by
+.LI count .
+.sp
+A leading
+.QT \&0X
+or
+.QT \&0x
+causes the number to be interpreted as a hexadecimal number.
+Otherwise, a leading
+.QT \&0
+causes the number to be interpreted as an octal number, unless a non-octal
+digit is found as part of the number.
+Otherwise, the number is interpreted as a decimal number, and may
+have a leading
+.LI \&+
+or
+.LI \&-
+sign.
+The current number begins at the first non-blank character at or after
+the current cursor position, and extends up to the end of the line or
+the first character that isn't a possible character for the numeric type.
+The format of the number (e.g. leading 0's, signs) is retained unless
+the new value cannot be represented in the previous format.
+.sp
+Octal and hexadecimal numbers, and the result of the operation, must fit
+into an
+.QT "unsigned long" .
+Similarly, decimal numbers and their result must fit into a
+.QT "signed long" .
+It is an error to use this command when the cursor is not positioned at
+a number.
+.sp
+.SS
+.SP Line:
+Unchanged.
+.SP Column:
+Set to the first character in the cursor number.
+.SP Options:
+None.
+.SE
+.KY $
+.IP "[count] $"
+Move the cursor to the end of a line.
+If
+.LI count
+is specified, the cursor moves down
+.LI "count - 1"
+lines.
+.sp
+It is not an error to use the
+.CO $
+command when the cursor is on the last character in the line or
+when the line is empty.
+.sp
+The
+.CO $
+command may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+character oriented, unless the cursor is at, or before the first
+nonblank character in the line, in which case it is line oriented.
+It is not an error to use the
+.CO $
+command as a motion component when the cursor is on the last character
+in the line, although it is an error when the line is empty.
+.SS
+.SP Line:
+Set to the current line plus
+.LI count
+minus 1.
+.SP Column:
+Set to the last character in the line.
+.SP Options:
+None.
+.SE
+.KY %
+.IP %
+Move to the matching character.
+The cursor moves to the parenthesis or curly brace which
+.i matches
+the parenthesis or curly brace found at the current cursor position
+or which is the closest one to the right of the cursor on the line.
+It is an error to execute the
+.CO %
+command on a line without a parenthesis or curly brace.
+Historically, any
+.LI count
+specified to the
+.CO %
+command was ignored.
+.sp
+The
+.CO %
+command is an absolute movement.
+The
+.CO %
+command may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+character oriented, unless the starting point of the region is at
+or before the first nonblank character on its line, and the ending
+point is at or after the last nonblank character on its line, in
+which case it is line oriented.
+.SS
+.SP Line:
+Set to the line containing the matching character.
+.SP Column:
+Set to the matching character.
+.SP Options:
+None.
+.SE
+.KY &
+.IP "&"
+Repeat the previous substitution command on the current line.
+.sp
+Historically, any
+.LI count
+specified to the
+.CO &
+command was ignored.
+.SS
+.SP Line:
+Unchanged.
+.SP Column:
+Unchanged if the cursor was on the last character in the line,
+otherwise, set to the first nonblank character in the line.
+.SP Options:
+Affected by the
+.OP edcompatible ,
+.OP extended ,
+.OP ignorecase
+and
+.OP magic
+options.
+.SE
+.KY SQUOTE<character>
+.IP \'<character>
+.KY `<character>
+.Ip `<character>
+Return to a context marked by the character
+.LI <character> .
+If
+.LI <character>
+is the
+.QT '
+or
+.QT `
+character, return to the previous context.
+If
+.LI <character>
+is any other character,
+return to the context marked by that character (see the
+.CO m
+command for more information).
+If the command is the
+.CO \'
+command, only the line value is restored,
+and the cursor is placed on the first nonblank character of that line.
+If the command is the
+.CO `
+command, both the line and column values are restored.
+.sp
+It is an error if the context no longer exists because of
+line deletion.
+(Contexts follow lines that are moved, or which are deleted
+and then restored.)
+.sp
+The
+.CO \'
+and
+.CO `
+commands are both absolute movements.
+They may be used as a motion component for other
+.CO vi
+commands.
+For the
+.CO \'
+command, any text copied into a buffer is line oriented.
+For the
+.CO `
+command,
+any text copied into a buffer is character oriented,
+unless it both starts and stops at the first character in the line,
+in which case it is line oriented.
+In addition, when using the
+.CO `
+command as a motion component,
+commands which move backward and started at the first character in the line,
+or move forward and ended at the first character in the line,
+are corrected to the last character of the line preceding the starting and
+ending lines, respectively.
+.SS
+.SP Line:
+Set to the line from the context.
+.SP Column:
+Set to the first nonblank character in the line, for the
+.CO \'
+command, and set to the context's column for the
+.CO `
+command.
+.SP Options:
+None.
+.SE
+.KY (
+.IP "[count] ("
+Back up
+.LI count
+sentences.
+.sp
+The
+.CO (
+command is an absolute movement.
+The
+.CO (
+command may be used as the motion component of other
+.CO vi
+commands,
+in which case any text copied into a buffer is character oriented,
+unless the starting and stopping points of the region are the first
+character in the line,
+in which case it is line oriented.
+If it is line oriented,
+the starting point of the region is adjusted to be the end of the line
+immediately before the starting cursor position.
+.SS
+.SP Line:
+Set to the line containing the beginning of the sentence.
+.SP Column:
+Set to the first nonblank character of the sentence.
+.SP Options:
+Affected by the
+.OP lisp
+option.
+.SE
+.KY )
+.IP "[count] )"
+Move forward
+.LI count
+sentences.
+.sp
+The
+.CO )
+command is an absolute movement.
+The
+.CO )
+command may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+character oriented, unless the starting point of the region is the
+first character in the line, in which case it is line oriented.
+In the latter case, if the stopping point of the region is also
+the first character in the line, it is adjusted to be the end of the
+line immediately before it.
+.SS
+.SP Line:
+Set to the line containing the beginning of the sentence.
+.SP Column:
+Set to the first nonblank character of the sentence.
+.SP Options:
+Affected by the
+.OP lisp
+option.
+.SE
+.KY ,
+.IP "[count] ,"
+Reverse find character
+.LI count
+times.
+Reverse the last
+.CO F ,
+.CO f ,
+.CO T
+or
+.CO t
+command, searching the other way in the line,
+.LI count
+times.
+It is an error if a
+.CO F ,
+.CO f ,
+.CO T
+or
+.CO t
+command has not been performed yet.
+.sp
+The
+.CO ,
+command may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+character oriented.
+.SS
+.SP Line:
+Unchanged.
+.SP Column:
+Set to the searched-for character for the
+.CO F
+and
+.CO f
+commands,
+before the character for the
+.CO t
+command
+and after the character for the
+.CO T
+command.
+.SP Options:
+None.
+.SE
+.KY MINUSSIGN
+.IP "[count] \-"
+Move to the first nonblank of the previous line,
+.LI count
+times.
+.sp
+It is an error if the movement is past the beginning of the file.
+.sp
+The
+.CO -
+command may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+line oriented.
+.SS
+.SP Line:
+Set to the current line minus
+.LI count .
+.SP Column:
+Set to the first nonblank character in the line.
+.SP Options:
+None.
+.SE
+.KY \&.
+.IP "[count] \&."
+Repeat the last
+.CO vi
+command that modified text.
+The repeated command may be a command and motion component combination.
+If
+.LI count
+is specified, it replaces
+.i both
+the count specified for the repeated command, and, if applicable, for
+the repeated motion component.
+If
+.LI count
+is not specified, the counts originally specified to the command being
+repeated are used again.
+.sp
+As a special case, if the
+.CO \.
+command is executed immediately after the
+.CO u
+command, the change log is rolled forward or backward, depending on
+the action of the
+.CO u
+command.
+.SS
+.SP Line:
+Set as described for the repeated command.
+.SP Column:
+Set as described for the repeated command.
+.SP Options:
+None.
+.SE
+.KY /RE/
+.IP "/RE<carriage-return>"
+.Ip "/RE/ [offset]<carriage-return>"
+.KY ?RE?
+.Ip "?RE<carriage-return>"
+.Ip "?RE? [offset]<carriage-return>"
+.KY N
+.Ip "N"
+.KY n
+.Ip "n"
+Search forward or backward for a regular expression.
+The commands beginning with a slash
+.PQ /
+character are forward searches, the commands beginning with a
+question mark
+.PQ ?
+are backward searches.
+.CO Vi
+prompts with the leading character on the last line of the screen
+for a string.
+It then searches forward or backward in the file for the next
+occurrence of the string, which is interpreted as a Basic Regular
+Expression.
+.sp
+The
+.CO /
+and
+.CO ?
+commands are absolute movements.
+They may be used as the motion components of other
+.CO vi
+commands, in which case any text copied into a buffer is
+character oriented, unless the search started and ended on
+the first column of a line, in which case it is line oriented.
+In addition, forward searches ending at the first character of a line,
+and backward searches beginning at the first character in the line,
+are corrected to begin or end at the last character of the previous line.
+(Note, forward and backward searches can occur for both
+.CO /
+and
+.CO ?
+commands, if the
+.OP wrapscan
+option is set.)
+.sp
+If an offset from the matched line is specified (i.e. a trailing
+.QT /
+or
+.QT ?
+character is followed by a signed offset), the buffer will always
+be line oriented (e.g.
+.QT /string/+0
+will always guarantee a line orientation).
+.sp
+The
+.CO N
+command repeats the previous search, but in the reverse direction.
+The
+.CO n
+command repeats the previous search.
+If either the
+.CO N
+or
+.CO n
+commands are used as motion components for the
+.CO !
+command, you will not be prompted for the text of the bang command,
+instead the previous bang command will be executed.
+.sp
+Missing RE's (e.g.
+.QT //<carriage-return> ,
+.QT /<carriage-return> ,
+.QT ??<carriage-return> ,
+or
+.QT ?<carriage-return>
+search for the last search RE, in the indicated direction.
+.sp
+Searches may be interrupted using the
+.LI <interrupt>
+character.
+.sp
+Multiple search patterns may be grouped together by delimiting
+them with semicolons and zero or more whitespace characters, e.g.
+.LI "/foo/ ; ?bar?"
+searches forward for
+.LI foo
+and then, from that location, backwards for
+.LI bar .
+When search patterns are grouped together in this manner,
+the search patterns are evaluated left to right with the
+final cursor position determined by the last search pattern.
+.sp
+It is also permissible to append a
+.CO z
+command to the search strings, e.g.
+.LI "/foo/ z."
+searches forward for the next occurrence of
+.LI foo ,
+and then positions that line in the middle of screen.
+.SS
+.SP Line:
+Set to the line in which the match occurred.
+.SP Column:
+Set to the first character of the matched string.
+.SP Options:
+Affected by the
+.OP edcompatible ,
+.OP extended ,
+.OP ignorecase ,
+.OP magic ,
+and
+.OP wrapscan
+options.
+.SE
+.KY 0
+.IP "0"
+Move to the first character in the current line.
+It is not an error to use the
+.CO 0
+command when the cursor is on the first character in the line,
+.sp
+The
+.CO 0
+command may be used as the motion component of other
+.CO vi
+commands,
+in which case it is an error if the cursor is on the first character
+in the line,
+and any text copied into a buffer is character oriented.
+.SS
+.SP Line:
+Unchanged.
+.SP Column:
+Set to the first character in the line.
+.SP Options:
+None.
+.SE
+.KY :
+.IP ":"
+Execute an
+.CO ex
+command.
+.CO Vi
+prompts for an
+.CO ex
+command on the last line of the screen, using a colon
+.PQ :
+character.
+The command is terminated by a
+.LI <carriage-return> ,
+.LI <newline>
+or
+.LI <escape>
+character; all of these characters may be escaped by using a
+.LI "<literal-next>"
+character.
+The command is then executed.
+.sp
+If the
+.CO ex
+command writes to the screen,
+.CO vi
+will prompt the user for a
+.LI <carriage-return>
+before continuing
+when the
+.CO ex
+command finishes.
+Large amounts of output from the
+.CO ex
+command will be paged for the user, and the user prompted for a
+.LI <carriage-return>
+or
+.LI <space>
+key to continue.
+In some cases, a quit (normally a
+.QQ q
+character) or
+.LI <interrupt>
+may be entered to interrupt the
+.CO ex
+command.
+.sp
+When the
+.CO ex
+command finishes, and the user is prompted to resume visual mode,
+it is also possible to enter another
+.QT :
+character followed by another
+.CO ex
+command.
+.SS
+.SP Line:
+The current line is set as described for the
+.CO ex
+command.
+.SP Column:
+The current column is set as described for the
+.CO ex
+command.
+.SP Options:
+Affected as described for the
+.CO ex
+command.
+.SE
+.KY ;
+.IP "[count] ;"
+Repeat the last character find
+.LI count
+times.
+The last character find is one of the
+.CO F ,
+.CO f ,
+.CO T
+or
+.CO t
+commands.
+It is an error if a
+.CO F ,
+.CO f ,
+.CO T
+or
+.CO t
+command has not been performed yet.
+.sp
+The
+.CO ;
+command may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+character oriented.
+.SS
+.SP Line:
+Unchanged.
+.SP Column:
+Set to the searched-for character for the
+.CO F
+and
+.CO f
+commands,
+before the character for the
+.CO t
+command
+and after the character for the
+.CO T
+command.
+.SP Options:
+None.
+.SE
+.KY <
+.IP "[count] < motion"
+.KY >
+.Ip "[count] > motion"
+Shift lines left or right.
+Shift the number of lines in the region specified by the
+.LI count
+and
+.LI motion
+left (for the
+.CO <
+command) or right (for the
+.CO >
+command) by the number of columns specified by the
+.OP shiftwidth
+option.
+Only whitespace characters are deleted when shifting left.
+Once the first character in the line no longer contains a whitespace
+character, the command will succeed,
+but the line will not be modified.
+.SS
+.SP Line:
+Unchanged.
+.SP Column:
+Set to the first nonblank character in the line.
+.SP Options:
+Affected by the
+.OP shiftwidth
+option.
+.SE
+.KY @
+.IP "@ buffer"
+Execute a named buffer.
+Execute the named buffer as
+.CO vi
+commands.
+The buffer may include
+.CO ex
+commands, too, but they must be expressed as a
+.CO :
+command.
+If the buffer is line oriented,
+.LI <newline>
+characters are logically appended to each line of the buffer.
+If the buffer is character oriented,
+.LI <newline>
+characters are logically appended to all but the last line in the buffer.
+.sp
+If the buffer name is
+.QT @ ,
+or
+.QT * ,
+then the last buffer executed shall be used.
+It is an error to specify
+.QT @@
+or
+.QT @*
+if there were no previous buffer executions.
+The text of a buffer may contain a
+.CO @
+command,
+and it is possible to create infinite loops in this manner.
+(The
+.LI <interrupt>
+character may be used to interrupt the loop.)
+.SS
+.SP Line:
+The current line is set as described for the command(s).
+.SP Column:
+The current column is set as described for the command(s).
+.SP Options:
+None.
+.SE
+.KY A
+.IP "[count] A"
+Enter input mode, appending the text after the end of the line.
+If
+.LI count
+is specified, the text is repeatedly input
+.LI "count - 1"
+more times after input mode is exited.
+.SS
+.SP Line:
+Set to the last line upon which characters were entered.
+.SP Column:
+Set to the last character entered.
+.SP Options:
+Affected by the
+.OP altwerase ,
+.OP autoindent ,
+.OP beautify ,
+.OP showmatch ,
+.OP ttywerase
+and
+.OP wrapmargin
+options.
+.SE
+.KY B
+.IP "[count] B"
+Move backward
+.LI count
+bigwords.
+Move the cursor backward to the beginning of a bigword by repeating the
+following algorithm: if the current position is at the beginning of a
+bigword or the character at the current position cannot be part of a bigword,
+move to the first character of the preceding bigword.
+Otherwise, move to the first character of the bigword at the current position.
+If no preceding bigword exists on the current line, move to the first
+character of the last bigword on the first preceding line that contains a
+bigword.
+.sp
+The
+.CO B
+command may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+character oriented.
+.SS
+.SP Line:
+Set to the line containing the word selected.
+.SP Column:
+Set to the first character of the word selected.
+.SP Options:
+None.
+.SE
+.KY C
+.IP "[buffer] [count] C"
+Change text from the current position to the end-of-line.
+If
+.LI count
+is specified, the input text replaces from the current position to
+the end-of-line, plus
+.LI "count - 1"
+subsequent lines.
+.SS
+.SP Line:
+Set to the last line upon which characters were entered.
+.SP Column:
+Set to the last character entered.
+.SP Options:
+Affected by the
+.OP altwerase ,
+.OP autoindent ,
+.OP beautify ,
+.OP showmatch ,
+.OP ttywerase
+and
+.OP wrapmargin
+options.
+.SE
+.KY D
+.IP "[buffer] D"
+Delete text from the current position to the end-of-line.
+.sp
+It is not an error to execute the
+.CO D
+command on an empty line.
+.SS
+.SP Line:
+Unchanged.
+.SP Column:
+Set to the character before the current character, or, column 1 if
+the cursor was on column 1.
+.SP Options:
+None.
+.SE
+.KY E
+.IP "[count] E"
+Move forward
+.LI count
+end-of-bigwords.
+Move the cursor forward to the end of a bigword by repeating the
+following algorithm: if the current position is the end of a
+bigword or the character at that position cannot be part of a bigword,
+move to the last character of the following bigword.
+Otherwise, move to the last character of the bigword at the current
+position.
+If no succeeding bigword exists on the current line,
+move to the last character of the first bigword on the next following
+line that contains a bigword.
+.sp
+The
+.CO E
+command may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+character oriented.
+.SS
+.SP Line:
+Set to the line containing the word selected.
+.SP Column:
+Set to the last character of the word selected.
+.SP Options:
+None.
+.SE
+.KY F
+.IP "[count] F <character>"
+Search
+.LI count
+times backward through the current line for
+.LI <character> .
+.sp
+The
+.CO F
+command may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+character oriented.
+.SS
+.SP Line:
+Unchanged.
+.SP Column:
+Set to the searched-for character.
+.SP Options:
+None.
+.SE
+.KY G
+.IP "[count] G"
+Move to line
+.LI count ,
+or the last line of the file if
+.LI count
+not specified.
+.sp
+The
+.CO G
+command is an absolute movement.
+The
+.CO \&G
+command may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+line oriented.
+.SS
+.SP Line:
+Set to
+.LI count ,
+if specified, otherwise, the last line.
+.SP Column:
+Set to the first nonblank character in the line.
+.SP Options:
+None.
+.SE
+.KY H
+.IP "[count] H"
+Move to the screen line
+.LI "count - 1"
+lines below the top of the screen.
+.sp
+The
+.CO H
+command is an absolute movement.
+The
+.CO H
+command may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+line oriented.
+.SS
+.SP Line:
+Set to the line
+.LI "count - 1"
+lines below the top of the screen.
+.SP Column:
+Set to the first nonblank character of the
+.i screen
+line.
+.SP Options:
+None.
+.SE
+.KY I
+.IP "[count] I"
+Enter input mode, inserting the text at the beginning of the line.
+If
+.LI count
+is specified, the text input is repeatedly input
+.LI "count - 1"
+more times.
+.SS
+.SP Line:
+Set to the last line upon which characters were entered.
+.SP Column:
+Set to the last character entered.
+.SP Options:
+None.
+.SE
+.KY J
+.IP "[count] J"
+Join lines.
+If
+.LI count
+is specified,
+.LI count
+lines are joined; a minimum of two lines are always joined,
+regardless of the value of
+.LI count .
+.sp
+If the current line ends with a whitespace character, all whitespace
+is stripped from the next line.
+Otherwise, if the next line starts with a open parenthesis
+.PQ (
+do nothing.
+Otherwise, if the current line ends with a question mark
+.PQ ? ,
+period
+.PQ \&.
+or exclamation point
+.PQ ! ,
+insert two spaces.
+Otherwise, insert a single space.
+.sp
+It is not an error to join lines past the end of the file,
+i.e. lines that do not exist.
+.SS
+.SP Line:
+Unchanged.
+.SP Column:
+Set to the character after the last character of the next-to-last
+joined line.
+.SP Options:
+None.
+.SE
+.KY L
+.IP "[count] L"
+Move to the screen line
+.LI "count - 1"
+lines above the bottom of the screen.
+.sp
+The
+.CO L
+command is an absolute movement.
+The
+.CO L
+command may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+line oriented.
+.SS
+.SP Line:
+Set to the line
+.LI "count - 1"
+lines above the bottom of the screen.
+.SP Column:
+Set to the first nonblank character of the
+.i screen
+line.
+.SP Options:
+None.
+.SE
+.KY M
+.IP " M"
+Move to the screen line in the middle of the screen.
+.sp
+The
+.CO M
+command is an absolute movement.
+The
+.CO M
+command may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+line oriented.
+.sp
+Historically, any
+.LI count
+specified to the
+.CO M
+command was ignored.
+.SS
+.SP Line:
+Set to the line in the middle of the screen.
+.SP Column:
+Set to the first nonblank character of the
+.i screen
+line.
+.SP Options:
+None.
+.SE
+.KY O
+.IP "[count] O"
+Enter input mode, appending text in a new line above the current line.
+If
+.LI count
+is specified, the text input is repeatedly input
+.LI "count - 1"
+more times.
+.sp
+Historically, any
+.LI count
+specified to the
+.CO O
+command was ignored.
+.SS
+.SP Line:
+Set to the last line upon which characters were entered.
+.SP Column:
+Set to the last character entered.
+.SP Options:
+Affected by the
+.OP altwerase ,
+.OP autoindent ,
+.OP beautify ,
+.OP showmatch ,
+.OP ttywerase
+and
+.OP wrapmargin
+options.
+.SE
+.KY P
+.IP "[buffer] P"
+Insert text from a buffer.
+Text from the buffer (the unnamed buffer by default) is inserted
+before the current column or, if the buffer is line oriented,
+before the current line.
+.SS
+.SP Line:
+Set to the lowest numbered line insert,
+if the buffer is line oriented, otherwise unchanged.
+.SP Column:
+Set to the first nonblank character of the appended text,
+if the buffer is line oriented, otherwise, the last character
+of the appended text.
+.SP Options:
+None.
+.SE
+.KY Q
+.IP "Q"
+Exit
+.CO vi
+(or visual) mode and switch to
+.CO ex
+mode.
+.SS
+.SP Line:
+Unchanged.
+.SP Column:
+No longer relevant.
+.SP Options:
+None.
+.SE
+.KY R
+.IP "[count] R"
+Enter input mode, replacing the characters in the current line.
+If
+.LI count
+is specified, the text input is repeatedly input
+.LI "count - 1"
+more times.
+.sp
+If the end of the current line is reached, no more characters are
+replaced and any further characters input are appended to the line.
+.SS
+.SP Line:
+Set to the last line upon which characters were entered.
+.SP Column:
+Set to the last character entered.
+.SP Options:
+Affected by the
+.OP altwerase ,
+.OP autoindent ,
+.OP beautify ,
+.OP showmatch ,
+.OP ttywerase
+and
+.OP wrapmargin
+options.
+.SE
+.KY S
+.IP "[buffer] [count] S"
+Substitute
+.LI count
+lines.
+.SS
+.SP Line:
+Set to the last line upon which characters were entered.
+.SP Column:
+Set to the last character entered.
+.SP Options:
+Affected by the
+.OP altwerase ,
+.OP autoindent ,
+.OP beautify ,
+.OP showmatch ,
+.OP ttywerase
+and
+.OP wrapmargin
+options.
+.SE
+.KY T
+.IP "[count] T <character>"
+Search backward,
+.LI count
+times,
+through the current line for the character
+.i after
+the specified
+.LI <character> .
+.sp
+The
+.CO T
+command may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+character oriented.
+.SS
+.SP Line:
+Unchanged.
+.SP Column:
+Set to the character
+.i after
+the searched-for character.
+.SP Options:
+None.
+.SE
+.KY U
+.IP "U"
+Restore the current line to its state before the cursor last
+moved to it.
+.SS
+.SP Line:
+Unchanged.
+.SP Column:
+The first character in the line.
+.SP Options:
+None.
+.SE
+.KY W
+.IP "[count] W"
+Move forward
+.LI count
+bigwords.
+Move the cursor forward to the beginning of a bigword by repeating the
+following algorithm: if the current position is within a bigword or the
+character at that position cannot be part of a bigword, move to the first
+character of the next bigword.
+If no subsequent bigword exists on the current line,
+move to the first character of the first bigword on the first following
+line that contains a bigword.
+.sp
+The
+.CO W
+command may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+character oriented.
+.SS
+.SP Line:
+The line containing the word selected.
+.SP Column:
+The first character of the word selected.
+.SP Options:
+None.
+.SE
+.KY X
+.IP "[buffer] [count] X"
+Delete
+.LI count
+characters before the cursor.
+If the number of characters to be deleted is greater than or equal to
+the number of characters to the beginning of the line, all of the
+characters before the current cursor position, to the beginning of the
+line, are deleted.
+.SS
+.SP Line:
+Unchanged.
+.SP Column:
+Set to the current character minus
+.LI count ,
+or the first character if count is greater than the number of
+characters in the line before the cursor.
+.SP Options:
+None.
+.SE
+.KY Y
+.IP "[buffer] [count] Y"
+Copy (or
+.QQ yank )
+.LI count
+lines into the specified buffer.
+.SS
+.SP Line:
+Unchanged.
+.SP Column:
+Unchanged.
+.SP Options:
+None.
+.SE
+.KY ZZ
+.IP "ZZ"
+Write the file and exit
+.CO vi .
+The file is only written if it has been modified since the last
+complete write of the file to any file.
+.sp
+The
+.CO ZZ
+command will exit the editor after writing the file,
+if there are no further files to edit.
+Entering two
+.QQ quit
+commands (i.e.
+.CO wq ,
+.CO quit ,
+.CO xit
+or
+.CO ZZ )
+in a row will override this check and the editor will exit,
+ignoring any files that have not yet been edited.
+.SS
+.SP Line:
+Unchanged.
+.SP Column:
+Unchanged.
+.SP Options:
+None.
+.SE
+.KY [[
+.IP "[count] [["
+Back up
+.LI count
+section boundaries.
+.sp
+The
+.CO [[
+command is an absolute movement.
+The
+.CO [[
+command may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+character oriented, unless the starting position is column 0,
+in which case it is line oriented.
+.sp
+It is an error if the movement is past the beginning of the file.
+.SS
+.SP Line:
+Set to the previous line that is
+.LI count
+section boundaries back,
+or the first line of the file if no more section boundaries exist
+preceding the current line.
+.SP Column:
+Set to the first nonblank character in the line.
+.SP Options:
+Affected by the
+.OP sections
+option.
+.SE
+.KY ]]
+.IP "[count] ]]"
+Move forward
+.LI count
+section boundaries.
+.sp
+The
+.CO ]]
+command is an absolute movement.
+The
+.CO ]]
+command may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+character oriented, unless the starting position is column 0,
+in which case it is line oriented.
+.sp
+It is an error if the movement is past the end of the file.
+.SS
+.SP Line:
+Set to the line that is
+.LI count
+section boundaries forward,
+or to the last line of the file if no more section
+boundaries exist following the current line.
+.SP Column:
+Set to the first nonblank character in the line.
+.SP Options:
+Affected by the
+.OP sections
+option.
+.SE
+.KY ^
+.IP "\&^"
+Move to first nonblank character on the current line.
+.sp
+The
+.CO ^
+command may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+character oriented.
+.SS
+.SP Line:
+Unchanged.
+.SP Column:
+Set to the first nonblank character of the current line.
+.SP Options:
+None.
+.SE
+.KY _
+.IP "[count] _"
+Move down
+.LI "count - 1"
+lines, to the first nonblank character.
+The
+.CO _
+command may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+line oriented.
+.sp
+It is not an error to execute the
+.CO _
+command when the cursor is on the first character in the line.
+.SS
+.SP Line:
+The current line plus
+.LI "count - 1" .
+.SP Column:
+The first nonblank character in the line.
+.SP Options:
+None.
+.SE
+.KY a
+.IP "[count] a"
+Enter input mode, appending the text after the cursor.
+If
+.LI count
+is specified, the text input is repeatedly input
+.LI "count - 1"
+more times.
+.SS
+.SP Line:
+Set to the last line upon which characters were entered.
+.SP Column:
+Set to the last character entered.
+.SP Options:
+Affected by the
+.OP altwerase ,
+.OP autoindent ,
+.OP beautify ,
+.OP showmatch ,
+.OP ttywerase
+and
+.OP wrapmargin
+options.
+.SE
+.KY b
+.IP "[count] b"
+Move backward
+.LI count
+words.
+Move the cursor backward to the beginning of a word by repeating the
+following algorithm: if the current position is at the beginning of a word,
+move to the first character of the preceding word.
+Otherwise, the current position moves to the first character of the word
+at the current position.
+If no preceding word exists on the current line, move to the first
+character of the last word on the first preceding line that contains
+a word.
+.sp
+The
+.CO b
+command may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+character oriented.
+.SS
+.SP Line:
+Set to the line containing the word selected.
+.SP Column:
+Set to the first character of the word selected.
+.SP Options:
+None.
+.SE
+.KY c
+.IP "[buffer] [count] c motion"
+Change the region of text specified by the
+.LI count
+and
+.LI motion .
+If only part of a single line is affected, then the last character
+being changed is marked with a
+.QT $ .
+Otherwise, the region of text is deleted, and input mode is entered.
+.SS
+.SP Line:
+Set to the last line upon which characters were entered.
+.SP Column:
+Set to the last character entered.
+.SP Options:
+Affected by the
+.OP altwerase ,
+.OP autoindent ,
+.OP beautify ,
+.OP showmatch ,
+.OP ttywerase
+and
+.OP wrapmargin
+options.
+.SE
+.KY d
+.IP "[buffer] [count] d motion"
+Delete the region of text specified by the
+.LI count
+and
+.LI motion .
+.SS
+.SP Line:
+Set to the line where the region starts.
+.SP Column:
+Set to the first character in the line after the last character in the
+region.
+If no such character exists, set to the last character before the region.
+.SP Options:
+None.
+.SE
+.KY e
+.IP "[count] e"
+Move forward
+.LI count
+end-of-words.
+Move the cursor forward to the end of a word by repeating the following
+algorithm: if the current position is the end of a word,
+move to the last character of the following word.
+Otherwise, move to the last character of the word at the current position.
+If no succeeding word exists on the current line, move to the last character
+of the first word on the next following line that contains a word.
+.sp
+The
+.CO e
+command may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+character oriented.
+.SS
+.SP Line:
+Set to the line containing the word selected.
+.SP Column:
+Set to the last character of the word selected.
+.SP Options:
+None.
+.SE
+.KY f
+.IP "[count] f <character>"
+Search forward,
+.LI count
+times, through the rest of the current line for
+.LI <character> .
+.sp
+The
+.CO f
+command may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+character oriented.
+.SS
+.SP Line:
+Unchanged.
+.SP Column:
+Set to the searched-for character.
+.SP Options:
+None.
+.SE
+.KY i
+.IP "[count] i"
+Enter input mode, inserting the text before the cursor.
+If
+.LI count
+is specified, the text input is repeatedly input
+.LI "count - 1"
+more times.
+.SS
+.SP Line:
+Set to the last line upon which characters were entered.
+.SP Column:
+Set to the last character entered.
+.SP Options:
+Affected by the
+.OP altwerase ,
+.OP autoindent ,
+.OP beautify ,
+.OP showmatch ,
+.OP ttywerase
+and
+.OP wrapmargin
+options.
+.SE
+.KY m
+.IP "m <character>"
+Save the current context (line and column) as
+.LI <character> .
+The exact position is referred to by
+.QT `<character> .
+The line is referred to by
+.QT '<character> .
+.sp
+Historically,
+.LI <character>
+was restricted to lower-case letters.
+.CO Nvi
+permits the use of any character.
+.SS
+.SP Line:
+Unchanged.
+.SP Column:
+Unchanged.
+.SP Options:
+None.
+.SE
+.KY o
+.IP "[count] o"
+Enter input mode, appending text in a new line under the current line.
+If
+.LI count
+is specified, the text input is repeatedly input
+.LI "count - 1"
+more times.
+.sp
+Historically, any
+.LI count
+specified to the
+.CO o
+command was ignored.
+.SS
+.SP Line:
+Set to the last line upon which characters were entered.
+.SP Column:
+Set to the last character entered.
+.SP Options:
+Affected by the
+.OP altwerase ,
+.OP autoindent ,
+.OP beautify ,
+.OP showmatch ,
+.OP ttywerase
+and
+.OP wrapmargin
+options.
+.SE
+.KY p
+.IP "[buffer] p"
+Append text from a buffer.
+Text from the buffer (the unnamed buffer by default) is appended
+after the current column or, if the buffer is line oriented,
+after the current line.
+.SS
+.SP Line:
+Set to the first line appended, if the buffer is line oriented,
+otherwise unchanged.
+.SP Column:
+Set to the first nonblank character of the appended text if the buffer
+is line oriented, otherwise, the last character of the appended text.
+.SP Options:
+None.
+.SE
+.KY r
+.IP "[count] r <character>"
+Replace characters.
+The next
+.LI count
+characters in the line are replaced with
+.LI <character> .
+Replacing characters with
+.LI <newline>
+characters results in creating new, empty lines into the file.
+.sp
+If
+.LI <character>
+is
+.LI <escape> ,
+the command is cancelled.
+.SS
+.SP Line:
+Unchanged unless the replacement character is a
+.LI <newline> ,
+in which case it is set to the current line plus
+.LI "count - 1" .
+.SP Column:
+Set to the last character replaced,
+unless the replacement character is a
+.LI <newline> ,
+in which case the cursor is in column 1 of the last line inserted.
+.SP Options:
+None.
+.SE
+.KY s
+.IP "[buffer] [count] s"
+Substitute
+.LI count
+characters in the current line starting with the current character.
+.SS
+.SP Line:
+Set to the last line upon which characters were entered.
+.SP Column:
+Set to the last character entered.
+.SP Options:
+Affected by the
+.OP altwerase ,
+.OP autoindent ,
+.OP beautify ,
+.OP showmatch ,
+.OP ttywerase
+and
+.OP wrapmargin
+options.
+.SE
+.KY t
+.IP "[count] t <character>"
+Search forward,
+.LI count
+times, through the current line for the character immediately
+.i before
+.LI <character> .
+.sp
+The
+.CO t
+command may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+character oriented.
+.SS
+.SP Line:
+Unchanged.
+.SP Column:
+Set to the character
+.i before
+the searched-for character.
+.SP Options:
+None.
+.SE
+.KY u
+.IP "u"
+Undo the last change made to the file.
+If repeated, the
+.CO u
+command alternates between these two states, and is its own inverse.
+When used after an insert that inserted text on more than one line,
+the lines are saved in the numeric buffers.
+.sp
+The
+.CO \&.
+command, when used immediately after the
+.CO u
+command, causes the change log to be rolled forward or backward,
+depending on the action of the
+.CO u
+command.
+.SS
+.SP Line:
+Set to the position of the first line changed, if the reversal affects
+only one line or represents an addition or change; otherwise, the line
+preceding the deleted text.
+.SP Column:
+Set to the cursor position before the change was made.
+.SP Options:
+None.
+.SE
+.KY w
+.IP "[count] w"
+Move forward
+.LI count
+words.
+Move the cursor forward to the beginning of a word by repeating the
+following algorithm: if the current position is at the
+beginning of a word, move to the first character of the next word.
+If no subsequent word exists on the current line, move to the first
+character of the first word on the first following line that contains
+a word.
+.sp
+The
+.CO w
+command may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+character oriented.
+.SS
+.SP Line:
+Set to the line containing the word selected.
+.SP Column:
+Set to the first character of the word selected.
+.SP Options:
+None.
+.SE
+.KY x
+.IP "[buffer] [count] x"
+Delete
+.LI count
+characters.
+The deletion is at the current character position.
+If the number of characters to be deleted is greater than or equal to
+the number of characters to the end of the line, all of the characters
+from the current cursor position to the end of the line are deleted.
+.SS
+.SP Line:
+Unchanged.
+.SP Column:
+Unchanged unless the last character in the line is deleted and the cursor
+is not already on the first character in the line, in which case it is
+set to the previous character.
+.SP Options:
+None.
+.SE
+.KY y
+.IP "[buffer] [count] y motion"
+Copy (or
+.QQ yank )
+the text region specified by the
+.LI count
+and
+.LI motion ,
+into a buffer.
+.SS
+.SP Line:
+Unchanged, unless the region covers more than a single line,
+in which case it is set to the line where the region starts.
+.SP Column:
+Unchanged, unless the region covers more than a single line,
+in which case it is set to the character were the region starts.
+.SP Options:
+None.
+.SE
+.KY z
+.IP "[count1] z [count2] type"
+Redraw the screen with a window
+.LI count2
+lines long, with line
+.LI count1
+placed as specified by the
+.LI type
+character.
+If
+.LI count1
+is not specified, it defaults to the current line.
+If
+.LI count2
+is not specified, it defaults to the current window size.
+.sp
+The following
+.LI type
+characters may be used:
+.SS
+.SP +
+If
+.LI count1
+is specified, place the line
+.LI count1
+at the top of the screen.
+Otherwise, display the screen after the current screen, similarly to the
+.CO <control-F>
+command.
+.SP <carriage-return>
+Place the line
+.LI count1
+at the top of the screen.
+.SP \&.
+Place the line
+.LI count1
+in the center of the screen.
+.SP \-
+Place the line
+.LI count1
+at the bottom of the screen.
+.SP ^
+If
+.LI count1
+is specified, place the line that is at the top of the screen
+when
+.LI count1
+is at the bottom of the screen, at the bottom of the screen,
+i.e. display the screen before the screen before
+.LI count1 .
+Otherwise, display the screen before the current screen, similarly to the
+.CO <control-B>
+command.
+.SE
+.SS
+.SP Line:
+Set to
+.LI count1
+unless
+.LI count1
+is not specified and the
+.LI type
+character was either
+.QT ^
+or
+.QT + ,
+in which case it is set to the line before the first line on the
+previous screen or the line after the last line on the previous
+screen, respectively.
+.SP Column:
+Set to the first nonblank character in the line.
+.SP Options:
+None.
+.SE
+.KY {
+.IP "[count] {"
+Move backward
+.LI count
+paragraphs.
+.sp
+The
+.CO {
+command is an absolute movement.
+The
+.CO {
+command may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+character oriented, unless the starting character is the first
+character on its line, in which case it is line oriented.
+.SS
+.SP Line:
+Set to the line containing the beginning of the previous paragraph.
+.SP Column:
+Set to the first nonblank character in the line.
+.SP Options:
+Affected by the
+.OP paragraph
+option.
+.SE
+.KY |
+.IP "[count] |"
+Move to a specific
+.i column
+position on the current line.
+.sp
+The
+.CO |
+command may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+character oriented.
+It is an error to use the
+.CO |
+command as a motion component and for the cursor not to move.
+.SS
+.SP Line:
+Unchanged.
+.SP Column:
+Set to the character occupying the column position identified by
+.LI count ,
+if the position exists in the line.
+If the column length of the current line is less than
+.LI count ,
+the cursor is moved to the last character in the line.
+.SP Options:
+None.
+.SE
+.KY }
+.IP "[count] }"
+Move forward
+.LI count
+paragraphs.
+.sp
+The
+.CO }
+command is an absolute movement.
+The
+.CO }
+command may be used as the motion component of other
+.CO vi
+commands, in which case any text copied into a buffer is
+character oriented, unless the starting character is at or
+before any nonblank characters in its line,
+in which case it is line oriented.
+.SS
+.SP Line:
+Set to the line containing the beginning of the next paragraph.
+.SP Column:
+Set to the first nonblank character in the line.
+.SP Options:
+Affected by the
+.OP paragraph
+option.
+.SE
+.KY ~
+.IP "[count] ~"
+Reverse the case of the next
+.LI count
+character(s).
+This is the historic semantic for the
+.CO ~
+command and it is only in effect if the
+.OP tildeop
+option is not set.
+.sp
+Lowercase alphabetic characters are changed to uppercase,
+and uppercase characters are changed to lowercase.
+No other characters are affected.
+.sp
+Historically, the
+.CO ~
+command did not take an associated count, nor did it move past the
+end of the current line.
+As it had no associated motion it was difficult to change the case
+of large blocks of text.
+In
+.CO nvi ,
+if the cursor is on the last character of a line, and there are
+more lines in the file, the cursor moves to the next line.
+.sp
+It is not an error to specify a count larger than the number of
+characters between the cursor and the end of the file.
+.SS
+.SP Line:
+Set to the line of the character after
+.LI count
+characters, or, end of file.
+.SP Column:
+Set to the character after
+.LI count
+characters, or, end-of-file.
+.SP Options:
+Affected by the
+.OP tildeop
+option.
+.SE
+.KY ~
+.IP "[count] ~ motion"
+Reverse the case of the characters in a text region specified by the
+.LI count
+and
+.LI motion .
+Only in effect if the
+.OP tildeop
+option is set.
+.sp
+Lowercase characters are changed to uppercase,
+and uppercase characters are changed to lowercase.
+No other characters are affected.
+.SS
+.SP Line:
+Set to the line of the character after the last character in the region.
+.SP Column:
+Set to the character after the last character in the region.
+.SP Options:
+Affected by the
+.OP tildeop
+option.
+.SE
+.KY <interrupt>
+.IP "<interrupt>"
+Interrupt the current operation.
+Many of the potentially long-running
+.CO vi
+commands may be interrupted using the terminal interrupt character.
+These operations include searches, file reading and writing, filter
+operations and map character expansion.
+Interrupts are also enabled when running commands outside of
+.CO vi .
+.sp
+If the
+.LI <interrupt>
+character is used to interrupt while entering an
+.CO ex
+command, the command is aborted, the cursor returns to its previous
+position, and
+.CO vi
+remains in command mode.
+.sp
+Generally, if the
+.LI <interrupt>
+character is used to interrupt any
+operation, any changes made before the interrupt are left in place.
+.SS
+.SP Line:
+Dependent on the operation being interrupted.
+.SP Column:
+Dependent on the operation being interrupted.
+.SP Options:
+None.
+.SH 1 "Vi Text Input Commands"
+.pp
+The following section describes the commands available in the text
+input mode of the
+.CO vi
+editor.
+.pp
+Historically,
+.CO vi
+implementations only permitted the characters inserted on the current
+line to be erased.
+In addition, only the
+.LI <control-D>
+erase character and the
+.QT 0<control-D>
+and
+.QT ^<control-D>
+erase strings could erase autoindent characters.
+(Autoindent characters include both the characters inserted automatically
+at the beginning of an input line as well as characters inserted using the
+.LI <control-T>
+command.)
+This implementation permits erasure to continue past the beginning
+of the current line, and back to where text input mode was entered.
+In addition, autoindent characters may be erased using the standard
+erase characters.
+For the line and word erase characters, reaching the autoindent
+characters forms a
+.QQ soft
+boundary, denoting the end of the current word or line erase.
+Repeating the word or line erase key will erase the autoindent characters.
+.pp
+Historically,
+.CO vi
+always used
+.LI <control-H>
+and
+.LI <control-W>
+as character and word erase characters, respectively, regardless of
+the current terminal settings.
+This implementation accepts, in addition to these two characters,
+the current terminal characters for those operations.
+.KY <nul>
+.IP "<nul>"
+If the first character of the input is a
+.LI <nul> ,
+the previous input is replayed, as if just entered.
+.KY <control-D>
+.IP "<control-D>"
+If the previous character on the line was an autoindent character,
+erase characters to move the cursor back to the column immediately
+after the previous (1-based) column which is a multiple of the
+.OP shiftwidth
+edit option.
+This may result in any number of
+.LI <tab>
+and
+.LI <space>
+characters preceding the cursor being changed.
+.sp
+Otherwise, if the
+.OP autoindent
+option is set and the user is entering the first character in the line,
+.LI <control-D>
+is ignored.
+Otherwise, a literal
+.LI <control-D>
+character is entered.
+.KY ^<control-D>
+.IP "^<control-D>"
+If the previous character on the line was an autoindent character,
+erase all of the autoindent characters on the line.
+In addition, the autoindent level is reset to 0.
+.KY 0<control-D>
+.IP "0<control-D>"
+If the previous character on the line was an autoindent character,
+erase all of the autoindent characters on the line.
+The autoindent level is not altered.
+.KY <control-T>
+.IP "<control-T>"
+Insert sufficient
+.LI <tab>
+and
+.LI <space>
+characters to move the cursor forward to the column immediately
+after the next (1-based) column which is a multiple of the
+.OP shiftwidth
+edit option.
+This may result in any number of
+.LI <tab>
+and
+.LI <space>
+characters preceding the cursor being changed.
+.sp
+Historically,
+.CO vi
+did not permit the
+.LI <control-T>
+command to be used unless the cursor was at the first column of a new
+line or it was preceded only by autoindent characters.
+.CO Nvi
+permits it to be used at any time during insert mode.
+.KY <erase>
+.IP <erase>
+.KY <control-H>
+.Ip <control-H>
+Erase the last character.
+.KY "<literal-next>"
+.IP "<literal-next>"
+Quote the next character.
+The next character will not be mapped (see the
+.CO map
+command for more information)
+or interpreted specially.
+A carat
+.PQ ^
+character will be displayed immediately as a placeholder,
+but will be replaced by the next character.
+.KY <escape>
+.IP <escape>
+If on the colon command line, and the
+.OP filec
+edit option is set, behave as described for that option.
+Otherwise, if on the colon command line,
+execute the command.
+Otherwise, if not on the colon command line,
+resolve all text input into the file, and return to command mode.
+.KY "<line erase>"
+.IP "<line erase>"
+Erase the current line.
+.KY "<control-W>"
+.IP "<control-W>"
+.KY "<word erase>"
+.Ip "<word erase>"
+Erase the last word.
+The definition of word is dependent on the
+.OP altwerase
+and
+.OP ttywerase
+options.
+.KY "<control-X>"
+.IP "<control-X>[0-9A-Fa-f]+"
+Insert a character with the specified hexadecimal value into the text.
+The value is delimited by any non-hexadecimal character or the input
+of the maximum number of characters that can be translated into a single
+character value.
+.KY <interrupt>
+.IP "<interrupt>"
+Interrupt text input mode, returning to command mode.
+If the
+.LI <interrupt>
+character is used to interrupt inserting text into the file,
+it is as if the
+.LI <escape>
+character was used; all text input up to the interruption is
+resolved into the file.
diff --git a/share/doc/usd/13.viref/vi.ref b/share/doc/usd/13.viref/vi.ref
new file mode 100644
index 000000000000..12a483f1edb1
--- /dev/null
+++ b/share/doc/usd/13.viref/vi.ref
@@ -0,0 +1,1840 @@
+.\" Copyright (c) 1994
+.\" The Regents of the University of California. All rights reserved.
+.\" Copyright (c) 1994, 1995, 1996
+.\" Keith Bostic. All rights reserved.
+.\"
+.\" This document may not be republished without written permission from
+.\" Keith Bostic.
+.\"
+.\" See the LICENSE file for redistribution information.
+.\"
+.\" @(#)vi.ref 8.88 (Berkeley) 10/19/96
+.\"
+.\" $FreeBSD$
+.\"
+.so ref.so
+.tp
+.(l C
+.ps 12
+.ft B
+Vi/Ex Reference Manual
+.ft
+.ps
+.sp
+.i "Keith Bostic"
+.sp
+Computer Science Division
+Department of Electrical Engineering and Computer Science
+University of California, Berkeley
+Berkeley, California 94720
+.sp 1
+.)l
+.sp 3
+.(l C
+.i Abstract
+.)l
+.(q
+.pp
+This document is the reference guide for the 4.4BSD
+implementations of
+.EV nex nvi ,
+which are implementations of the historic Berkeley
+.EV ex vi
+editors.
+.)q
+.sp 3
+.(l C
+.i Licensing
+.)l
+.sp
+.lp
+Copyright (c) 1991, 1992, 1993, 1994
+.ti +5
+The Regents of the University of California. All Rights Reserved.
+.lp
+Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996
+.ti +5
+Keith Bostic. All Rights Reserved.
+.sp
+.pp
+The vi program is freely redistributable. You are welcome to copy,
+modify and share it with others under the conditions listed in the
+LICENSE file. If any company (not individual!) finds vi sufficiently
+useful that you would have purchased it, or if any company wishes to
+redistribute it, contributions to the authors would be appreciated.
+.bp 2
+.(l C
+.i Acknowledgements
+.)l
+.sp
+.(q
+.pp
+Bruce Englar encouraged the early development of the historic
+.EV ex vi
+editor.
+Peter Kessler helped bring sanity to version 2's command layout.
+Bill Joy wrote versions 1 and 2.0 through 2.7,
+and created the framework that users see in the present editor.
+Mark Horton added macros and other features and made
+.EV ex vi
+work on a large number of terminals and Unix systems.
+.pp
+.CO Nvi
+is originally derived from software contributed to the University of
+California, Berkeley by Steve Kirkendall, the author of the
+.CO vi
+clone
+.CO elvis .
+.pp
+IEEE Standard Portable Operating System Interface for Computer
+Environments (POSIX) 1003.2 style Regular Expression support was
+done by Henry Spencer.
+.pp
+The curses library was originally done by Ken Arnold.
+Scrolling and reworking for
+.CO nvi
+was done by Elan Amir.
+.pp
+George Neville-Neil added the Tcl interpreter,
+and Sven Verdoolaege added the Perl interpreter.
+.pp
+Rob Mayoff added Cscope support.
+.pp
+The Institute of Electrical and Electronics Engineers has
+given us permission to reprint portions of their documentation.
+Portions of this document are reprinted and reproduced from
+IEEE Std 1003.2-1992, IEEE Standard Portable Operating
+System Interface for Computer Environments (POSIX),
+copyright 1992 by the Institute of Electrical and Electronics
+Engineers, Inc.
+.pp
+The financial support of UUNET Communications Services is gratefully
+acknowledged.
+.)q
+.sy echo -n >index
+.oh 'Vi/Ex Reference''USD:13-%'
+.eh 'USD:13-%''Vi/Ex Reference'
+.bp 4
+.SH 1 Description
+.pp
+.CO Vi
+is a screen oriented text editor.
+.CO Ex
+is a line-oriented text editor.
+.CO Ex
+and
+.CO vi
+are different interfaces to the same program,
+and it is possible to switch back and forth during an edit session.
+.CO View
+is the equivalent of using the
+.b \-R
+(read-only) option of
+.CO vi .
+.pp
+This reference manual is the one provided with the
+.EV nex nvi
+versions of the
+.EV ex vi
+text editors.
+.EV Nex nvi
+are intended as bug-for-bug compatible replacements for the original
+Fourth Berkeley Software Distribution (4BSD)
+.EV ex vi
+programs.
+This reference manual is accompanied by a traditional-style manual page.
+That manual page describes the functionality found in
+.EV ex vi
+in far less detail than the description here.
+In addition, it describes the system interface to
+.EV ex vi ,
+e.g. command line options, session recovery, signals,
+environmental variables, and similar things.
+.pp
+This reference is intended for users already familiar with
+.EV ex vi .
+Anyone else should almost certainly read a good tutorial on the
+editor first.
+If you are in an unfamiliar environment,
+and you absolutely have to get work done immediately,
+see the section entitled
+.QB "Fast Startup"
+in the manual page.
+It is probably enough to get you started.
+.pp
+There are a few features in
+.EV nex nvi
+that are not found in historic versions of
+.EV ex vi .
+Some of the more interesting of those features are briefly described
+in the next section, entitled
+.QB "Additional Features" .
+For the rest of this document,
+.EV nex nvi
+is used only when it is necessary to distinguish it from the historic
+implementations of
+.EV ex vi .
+.pp
+Future versions of this software will be periodically made available
+by anonymous ftp, and can be retrieved from
+.LI ftp.cs.berkeley.edu ,
+in the directory
+.LI ucb/4bsd .
+.SH 1 "Additional Features in Nex/Nvi"
+.pp
+There are a few features in
+.EV nex nvi
+that are not found in historic versions of
+.EV ex vi .
+Some of the more interesting of these are as follows:
+.IP "8-bit clean data, large lines, files"
+.EV Nex nvi
+will edit any format file.
+Line lengths are limited by available memory,
+and file sizes are limited by available disk space.
+The
+.CO vi
+text input mode command
+.CO <control-X>
+can insert any possible character value into the text.
+.IP "Background and foreground screens"
+The
+.CO bg
+command backgrounds the current screen, and the
+.CO fg
+command foregrounds backgrounded screens.
+The
+.CO display
+command can be used to list the background screens.
+.IP "Command Editing"
+You can enter a normal editing window on the collected commands that
+you've entered on the
+.CO vi
+colon command-line,
+and then modify and/or execute the commands.
+See the
+.OP cedit
+edit option for more information.
+.IP "Displays"
+The
+.CO display
+command can be used to display the current buffers, the backgrounded
+screens, and the tags stack.
+.IP "Extended Regular Expressions"
+The
+.CO extended
+option causes Regular Expressions to be interpreted as as Extended
+Regular Expressions, (i.e. \fIegrep\fP(1) style Regular Expressions).
+.IP "File Name Completion"
+It is possible to do file name completion and file name displays when
+entering commands on the
+.CO vi
+colon command-line.
+See the
+.OP filec
+option for more information.
+.IP "Infinite undo"
+Changes made during an edit session may be rolled backward and forward.
+A
+.CO \&.
+command immediately after a
+.CO u
+command continues either forward or backward depending on whether the
+.CO u
+command was an undo or a redo.
+.IP "Left-right scrolling"
+The
+.CO leftright
+option causes
+.CO nvi
+to do left-right screen scrolling, instead of the traditional
+.CO vi
+line wrapping.
+.IP "Message Catalogs"
+It is possible to display informational and error messages in different
+languages by providing a catalog of messages.
+See the
+.OP msgcat
+option and the file
+.LI "catalog/README"
+for more information.
+.IP "Incrementing numbers"
+The
+.CO \&#
+command increments or decrements the number referenced by the cursor.
+.IP "Previous file"
+The
+.CO previous
+command edits the previous file from the argument list.
+.IP "Scripting languages"
+The
+.CO ":pe[rl] cmd" ,
+.CO ":perld[o] cmd"
+and
+.CO ":tc[l] cmd"
+commands execute Perl and Tcl/Tk commands, respectively,
+on lines from the edit buffer.
+See the
+.QB "Scripting Languages"
+section and the specific commands for more information.
+.\".IP "Shell screens"
+.\"The
+.\".CO ":sc[ript] [file ...]"
+.\"command runs a shell in the screen.
+.\"Editing is unchanged, with the exception that a \fC<carriage-return>\fP
+.\"enters the current line (stripped of any prompt) as input to the
+.\"shell.
+.IP "Split screens"
+The
+.CO Edit ,
+.CO Ex ,
+.CO Next ,
+.CO Previous ,
+.CO Tag
+and
+.CO Visual
+(in
+.CO vi
+mode) commands divide the screen into multiple editing regions and
+then perform their normal function in a new screen area.
+The
+.CO <control-W>
+command rotates between the foreground screens.
+The
+.CO resize
+command can be used to grow or shrink a particular screen.
+.IP "Tag stacks"
+Tags are now maintained in a stack.
+The
+.CO <control-T>
+command returns to the previous tag location.
+The
+.CO tagpop
+command returns to the most recent tag location by default, or,
+optionally to a specific tag number in the tag stack,
+or the most recent tag from a specified file.
+The
+.CO display
+command can be used to list the tags stack.
+The
+.CO tagtop
+command returns to the top of the tag stack.
+.IP "Usage information"
+The
+.CO exusage
+and
+.CO viusage
+commands provide usage information for all of the
+.CO ex
+and
+.CO vi
+commands by default, or, optionally, for a specific command or key.
+.IP "Word search"
+The
+.CO <control-A>
+command searches for the word referenced by the cursor.
+.SH 1 "Startup Information"
+.pp
+.EV Ex vi
+interprets one of two possible environmental variables and reads up to
+three of five possible files during startup.
+The variables and files are expected to contain
+.CO ex
+commands, not
+.CO vi
+commands.
+In addition, they are interpreted
+.i before
+the file to be edited is read, and therefore many
+.CO ex
+commands may not be used.
+Generally, any command that requires output to the screen or that
+needs a file upon which to operate, will cause an error if included
+in a startup file or environmental variable.
+.pp
+Because the
+.CO ex
+command set supported by
+.EV nex nvi
+is a superset of the command set supported by historical implementations of
+.CO ex ,
+.EV nex nvi
+can use the startup files created for the historical implementations,
+but the converse may not be true.
+.pp
+If the
+.b \-s
+(the historic \- option)
+is specified, or if standard input is redirected from a file,
+all environmental variables and startup files are ignored.
+.pp
+Otherwise, startup files and environmental variables are handled
+in the following order:
+.np
+The file
+.LI /etc/vi.exrc
+is read,
+as long as it is owned by root or the effective user ID of the user.
+.np
+The environmental variable
+.LI NEXINIT
+(or the variable
+.LI EXINIT ,
+if
+.LI NEXINIT
+is not set) is interpreted.
+.np
+If neither
+.LI NEXINIT
+or
+.LI EXINIT
+was set, and the
+.LI HOME
+environmental variable is set, the file
+.LI $HOME/.nexrc
+(or the file
+.LI $HOME/.exrc ,
+if
+.LI $HOME/.nexrc
+does not exist) is read,
+as long as the effective user ID of the user is root or is the same as
+the owner of the file.
+.sp
+When the $HOME directory is being used for both
+.EV nex nvi
+and an historic implementation of
+.EV ex vi ,
+a possible solution is to put
+.EV nex nvi
+specific commands in the
+.LI \&.nexrc
+file, along with a
+.CO ":source $HOME/.exrc"
+command to read in the commands common to both implementations.
+.np
+If the
+.OP exrc
+option was turned on by one of the previous startup information
+sources, the file
+.LI \&.nexrc
+(or the file
+.LI \&.exrc ,
+if
+.LI \&.nexrc
+does not exist) is read, as long as the effective user ID of the user
+is the same as the owner of the file.
+.pp
+No startup file is read if it is writable by anyone other than its owner.
+.pp
+It is not an error for any of the startup environmental variables or files
+not to exist.
+.pp
+Once all environmental variables are interpreted,
+and all startup files are read,
+the first file to be edited is read in (or a temporary file is created).
+Then, any commands specified using the
+.b \-c
+option are executed, in the context of that file.
+.SH 1 "Recovery"
+.pp
+There is no recovery program for
+.EV nex nvi ,
+nor does
+.EV nex nvi
+run setuid.
+Recovery files are created readable and writable by the owner only.
+Users may recover any file which they can read,
+and the superuser may recover any edit session.
+.pp
+Edit sessions are backed by files in the directory named by the
+.OP recdir
+option (the directory
+.LI /var/tmp/vi.recover
+by default), and are named
+.QC vi.XXXXXX ,
+where
+.QC XXXXXX
+is a number related to the process ID.
+When a file is first modified,
+a second recovery file containing an email message for the user is created,
+and is named
+.QC recover.XXXXXX ,
+where, again,
+.QC XXXXXX
+is associated with the process ID.
+Both files are removed at the end of a normal edit session,
+but will remain if the edit session is abnormally terminated
+or the user runs the
+.CO ex
+.CO preserve
+command.
+.pp
+The
+.OP recdir
+option may be set in either the user's or system's startup information,
+changing the recovery directory.
+(Note, however, that if a memory based file system is used as the backup
+directory, each system reboot will delete all of the recovery files!
+The same caution applies to directories such as
+.LI /tmp
+which are cleared of their contents by a system reboot, or
+.LI /usr/tmp
+which is periodically cleared of old files on many systems.)
+.pp
+The recovery directory should be owned by root, or at least by a pseudo-user.
+In addition, if directory
+.QQ sticky-bit
+semantics are available, the directory should have the sticky-bit
+set so that files may only be removed by their owners.
+The recovery directory must be read, write, and executable by any user,
+i.e. mode 1777.
+.pp
+If the recovery directory does not exist,
+.EV ex vi
+will attempt to create it.
+This can result in the recovery directory being owned by a normal user,
+which means that that user will be able to remove other user's recovery
+and backup files.
+This is annoying, but is not a security issue as the user cannot
+otherwise access or modify the files.
+.pp
+The recovery file has all of the necessary information in it to enable the
+user to recover the edit session.
+In addition, it has all of the necessary email headers for
+.XR sendmail 8 .
+When the system is rebooted, all of the files in
+.LI /var/tmp/vi.recover
+named
+.QC recover.XXXXXX
+should be sent to their owners, by email, using the
+.b \-t
+option of
+.CO sendmail
+(or a similar mechanism in other mailers).
+If
+.EV ex vi
+receives a hangup (SIGHUP) signal, or the user executes the
+.CO ex
+.CO preserve
+command,
+.EV ex vi
+will automatically email the recovery information to the user.
+.pp
+If your system does not have the
+.CO sendmail
+utility (or a mailer program which supports its interface)
+the source file
+.LI nvi/common/recover.c
+will have to be modified to use your local mail delivery programs.
+Note, if
+.EV nex nvi
+is changed to use another mailer,
+it is important to remember that the owner of the file given to
+the mailer is the
+.EV nex nvi
+user, so nothing in the file should be trusted as it may have been
+modified in an effort to compromise the system.
+.pp
+Finally, the owner execute bit is set on backup files when they are
+created, and unset when they are first modified, e.g. backup files
+that have no associated email recovery file will have this bit set.
+(There is also a small window where empty files can be created and
+not yet have this bit set.
+This is due to the method in which the files are created.)
+Such files should be deleted when the system reboots.
+.pp
+A simple way to do this cleanup is to run the Bourne shell script
+.CO recover ,
+from your
+.LI /etc/rc.local
+(or other system startup) file.
+The script should work with the historic Bourne shell,
+a POSIX 1003.2 shell or the Korn shell.
+The
+.CO recover
+script is installed as part of the
+.EV nex nvi
+installation process.
+.pp
+Consult the manual page for details on recovering preserved or
+aborted editing sessions.
+.SH 1 "Sizing the Screen"
+.pp
+The size of the screen can be set in a number of ways.
+.EV Ex vi
+takes the following steps until values are obtained for both the
+number of rows and number of columns in the screen.
+.np
+If the environmental variable
+.LI LINES
+exists,
+it is used to specify the number of rows in the screen.
+.np
+If the environmental variable
+.LI COLUMNS
+exists,
+it is used to specify the number of columns in the screen.
+.np
+The TIOCGWINSZ
+.XR ioctl 2
+is attempted on the standard error file descriptor.
+.np
+The termcap entry (or terminfo entry on System V machines)
+is checked for the
+.QQ li
+entry (rows) and the
+.QQ co
+entry (columns).
+.np
+The number of rows is set to 24, and the number of columns is set to 80.
+.pp
+If a window change size signal (SIGWINCH) is received,
+the new window size is retrieved using the TIOCGWINSZ
+.XR ioctl 2
+call, and all other information is ignored.
+.SH 1 "Character Display"
+.pp
+In both
+.CO ex
+and
+.CO vi
+printable characters as defined by
+.XR isprint 3
+are displayed using the local character set.
+.pp
+Non-printable characters, for which
+.XR iscntrl 3
+returns true, and which are less than octal \e040,
+are displayed as the string
+.QT ^<character> ,
+where
+.LI <character>
+is the character that is the original character's value offset from the
+.QT @
+character.
+For example, the octal character \e001 is displayed as
+.QT ^A .
+If
+.XR iscntrl 3
+returns true for the octal character \e177,
+it is displayed as the string
+.QT ^? .
+All other characters are displayed as either hexadecimal values,
+in the form
+.QT "0x<high-halfbyte> ... 0x<low-halfbyte>" ,
+or as octal values, in the form
+.QT "\e<high-one-or-two-bits> ... \e<low-three-bits>" .
+The display of unknown characters is based on the value of the
+.OP octal
+option.
+.pp
+In
+.CO vi
+command mode, the cursor is always positioned on the last column of
+characters which take up more than one column on the screen.
+In
+.CO vi
+text input mode, the cursor is positioned on the first column of
+characters which take up more than one column on the screen.
+.SH 1 "Multiple Screens"
+.pp
+.CO Nvi
+supports multiple screens by dividing the window into regions.
+It also supports stacks of screens by permitting the user to change
+the set of screens that are currently displayed.
+.pp
+The
+.CO Edit ,
+.CO Ex ,
+.CO Fg ,
+.CO Next ,
+.CO Previous ,
+.CO Tag
+and
+.CO Visual
+(in
+.CO vi
+mode)
+commands divide the current screen into two regions of approximately
+equal size and then perform their usual action in a new screen area.
+If the cursor is in the lower half of the screen, the screen will split
+up, i.e. the new screen will be above the old one.
+If the cursor is in the upper half of the screen, the new screen will be
+below the old one.
+.pp
+When more than one screen is editing a file, changes in any screen are
+reflected in all other screens editing the same file.
+Exiting a screen without saving any changes (or explicitly discarding
+them) is permitted until the last screen editing the file is exited,
+at which time the changes must be saved or discarded.
+.pp
+The
+.CO resize
+command permits resizing of individual screens.
+Screens may be grown, shrunk or set to an absolute number of rows.
+.pp
+The
+.CO ^W
+command is used to switch between screens.
+Each
+.CO ^W
+moves to the next lower screen in the window, or to the first screen
+in the window if there are no lower screens.
+.pp
+The
+.CO bg
+command
+.QQ backgrounds
+the current screen.
+The screen disappears from the window,
+and the rows it occupied are taken over by a neighboring screen.
+It is an error to attempt to background the only screen in the window.
+.pp
+The
+.CO "display screens"
+command displays the names of the files associated with the current
+backgrounded screens in the window.
+.pp
+The
+.CO "fg [file]"
+command moves the specified screen from the list of backgrounded screens
+to the foreground.
+If no file argument is specified, the first screen on the list is
+foregrounded.
+By default,
+foregrounding consists of backgrounding the current screen,
+and replacing its space in the window with the foregrounded screen.
+.pp
+Capitalizing the first letter of the command, i.e.
+.CO Fg ,
+will foreground the backgrounded screen in a new screen instead of
+swapping it with the current screen.
+.pp
+If the last foregrounded screen in the window is exited,
+and there are backgrounded screens,
+the first screen on the list of backgrounded screens takes over the window.
+.SH 1 "Tags, Tag Stacks, and Cscope"
+.pp
+.CO Nvi
+supports the historic
+.CO vi
+tag command
+.CO <control-]> ,
+and the historic
+.CO ex
+tag command
+.CO tag .
+These commands change the current file context to a new location,
+based on information found in the
+.LI tags
+files.
+If you are unfamiliar with these commands,
+you should review their description in the
+.CO ex
+and
+.CO vi
+commands section of this manual.
+For additional information on tags files,
+see the discussion of the
+.OP tags
+edit option and the system
+.XR ctags 1
+manual page.
+.pp
+In addition,
+.CO nvi
+supports the notion of
+.QQ "tags stacks" ,
+using the
+.CO <control-T>
+command.
+The
+.CO <control-T>
+command returns the user to the previous context, i.e.,
+the last place from which a
+.CO <control-]>
+or
+.CO "tag"
+command was entered.
+These three commands provide the basic functionality which allows you
+to use
+.CO vi
+to review source code in a structured manner.
+.pp
+.CO Nvi
+also provides two other basic
+.CO ex
+commands for tag support:
+.CO tagpop
+and
+.CO tagtop .
+The
+.CO tagpop
+command is identical to the
+.CO <control-T>
+command,
+with the additional functionality that you may specify that modifications
+to the current file are to be discarded.
+This cannot be done using the
+.CO <control-T>
+command.
+The
+.CO tagtop
+command discards all of the contexts that have been pushed onto the tag
+stack, returning to the context from which the first
+.CO <control-]>
+or
+.CO tag
+command was entered.
+.pp
+The historic
+.XR ctags 1
+tags file format supports only a single location per tag,
+normally the function declaration or structure or string definition.
+More sophisticated source code tools often provide multiple locations
+per tag, e.g.,
+a list of the places from which a function is called or a string
+definition is used.
+An example of this functionality is the System V source code tool,
+.CO cscope .
+.sp
+.CO Cscope
+creates a database of information on source code files,
+and supports a query language for that information as described in the
+.XR cscope 1
+manual page.
+.CO Nvi
+contains an interface to the
+.CO cscope
+query language which permits you to query
+.CO cscope
+and then sequentially step through the locations in the sources files which
+.CO cscope
+returns.
+There are two
+.CO nvi
+commands which support this ability to step through multiple locations.
+They are the
+.CO ex
+commands
+.CO tagnext
+and
+.CO tagprev .
+The
+.CO tagnext
+command moves to the next location for the current tag.
+The
+.CO tagprev
+command moves to the previous location for the current tag.
+(See the
+.CO tagnext
+and
+.CO tagprev
+command discussion in the
+.CO ex
+commands section of this manual for more information.)
+At any time during this sequential walk,
+you may use the
+.CO <control-]> ,
+.CO tag
+or
+.CO cscope
+commands to move to a new tag context, and then use the
+.CO <control-T>
+or
+.CO tagpop
+commands to return and continue stepping through the locations for this
+tag.
+This is similar to the previous model of a simple tag stack,
+except that each entry in the tag stack may have more than one file context
+that is of interest.
+.pp
+Although there is no widely distributed version of
+.XR ctags 1
+that creates tags files with multiple locations per tag,
+.CO nvi
+has been written to understand the obvious extension to the historic
+tags file format, i.e., more than a single line in the tags file with
+the same initial tag name.
+If you wish to extend your
+.CO ctags
+implementation or other tool with which you build tags files,
+this extension should be simple and will require no changes to
+.CO nvi .
+.pp
+The
+.CO nvi
+and
+.CO cscope
+interface is based on the new
+.CO ex
+command
+.CO cscope ,
+which has five subcommands:
+.CO add ,
+.CO find ,
+.CO help ,
+.CO kill
+and
+.CO reset .
+The subcommand
+.CO find
+itself has eight subcommands:
+.CO \&c ,
+.CO \&d ,
+.CO \&e ,
+.CO \&f ,
+.CO \&g ,
+.CO \&i ,
+.CO \&s
+and
+.CO \&t .
+.pp
+.IP "cs[cope] a[dd] file"
+The
+.CO add
+command attaches to the specified
+.CO cscope
+database.
+The file name is expanded using the standard filename expansions.
+If
+.CO file
+is a directory, the file
+.QQ cscope.out
+in that directory is used as the database.
+.pp
+After
+.CO nvi
+attaches to a new database,
+all subsequent
+.CO cscope
+queries will be asked of that database.
+The result of any single query is the collection of response to the query
+from all of the attached databases.
+.sp
+If the
+.QQ CSCOPE_DIRS
+environmental variable is set when
+.CO nvi
+is run,
+it is expected to be a <colon> or <blank>-separated list of
+.CO cscope
+databases or directories containing
+.CO cscope
+databases, to which the user wishes to attach.
+.IP ":cs[cope] f[ind] c|d|e|f|g|i|s|t buffer|pattern"
+The
+.CO find
+command is the
+.CO cscope
+query command for
+.CO nvi .
+For this command,
+.CO nvi
+queries all attached
+.CO cscope
+databases for the pattern.
+If the pattern is a double-quote character followed by a valid buffer
+name (e.g.,
+.LI """<character>" ),
+then the contents of the named buffer are used as the pattern.
+Otherwise, the pattern is a Regular Expression.
+.sp
+The
+.CO find
+command pushes the current location onto the tags stack,
+and switches to the first location resulting from the query,
+if the query returned at least one result.
+.sp
+File names returned by the
+.CO cscope
+query, if not absolute paths, are searched for relative to the directory
+where the
+.CO cscope
+database is located.
+In addition, if the file
+.QQ cscope.tpath
+appears in the same directory as the
+.CO cscope
+database,
+it is expected to contain a colon-separated list of directory names
+where files referenced by its associated
+.CO cscope
+database may be found.
+.sp
+The
+.CO find
+subcommand is one of the following:
+.SS
+.SP \&c
+Find callers of the name.
+.SP \&d
+Find all function calls made from name.
+.SP \&e
+Find pattern.
+.SP \&f
+Find files with name as substring.
+.SP \&g
+Find definition of name.
+.SP \&i
+Find files #including name.
+.SP \&s
+Find all uses of name.
+.SP \&t
+Find assignments to name.
+.SE
+.IP ":cs[cope] h[elp] [command]"
+List the
+.CO cscope
+commands,
+or optionally list usage help for any single
+.CO cscope
+command.
+.IP ":display c[onnections]"
+Display the list of
+.CO cscope
+databases to which
+.CO nvi
+is currently connected.
+.IP ":cs[cope] k[ill] #"
+Disconnect from a specific
+.CO cscope
+database.
+The connection number is the one displayed by the
+.CO ex
+.CO "display connections"
+command.
+.IP ":cs[cope] r[eset]"
+Disconnect from all attached
+.CO cscope
+databases.
+.pp
+Cscope is not freely redistributable software,
+but is fairly inexpensive and easily available.
+To purchase a copy of
+.CO cscope ,
+see http://www.att.com/ssg/products/toolchest.html.
+.SH 1 "Regular Expressions and Replacement Strings"
+.pp
+Regular expressions are used in line addresses,
+as the first part of the
+.CO ex
+.CO substitute ,
+.CO global ,
+and
+.CO v
+commands, and in search patterns.
+.pp
+The regular expressions supported by
+.EV ex vi
+are, by default, the Basic Regular Expressions (BRE's) described in the
+IEEE POSIX Standard 1003.2.
+The
+.OP extended
+option causes all regular expressions to be interpreted as the Extended
+Regular Expressions (ERE's) described by the same standard.
+(See
+.XR re_format 7
+for more information.)
+Generally speaking, BRE's are the Regular Expressions found in
+.XR ed 1
+and
+.XR grep 1 ,
+and ERE's are the Regular Expressions found in
+.XR egrep 1 .
+.pp
+The following is not intended to provide a description of Regular
+Expressions.
+The information here only describes strings and characters which
+have special meanings in the
+.EV ex vi
+version of RE's,
+or options which change the meanings of characters that normally
+have special meanings in RE's.
+.np
+An empty RE (e.g.
+.QT //
+or
+.QT ??
+is equivalent to the last RE used.
+.np
+The construct
+.QT \e<
+matches the beginning of a word.
+.np
+The construct
+.QT \e>
+matches the end of a word.
+.np
+The character
+.QT ~
+matches the replacement part of the last
+.CO substitute
+command.
+.pp
+When the
+.OP magic
+option is
+.i not
+set, the only characters with special meanings are a
+.QT ^
+character at the beginning of an RE, a
+.QT $
+character at the end of an RE, and the escaping character
+.QT \e .
+The characters
+.QT \&. ,
+.QT * ,
+.QT [
+and
+.QT ~
+are treated as ordinary characters unless preceded by a
+.QT \e ;
+when preceded by a
+.QT \e
+they regain their special meaning.
+.pp
+Replacement strings are the second part of a
+.CO substitute
+command.
+.pp
+The character
+.QT &
+(or
+.QT \e&
+if the
+.OP magic
+option is
+.i not
+set) in the replacement string stands for the text matched by the RE
+that is being replaced.
+The character
+.QT ~
+(or
+.QT \e~
+if the
+.OP magic
+option is
+.i not
+set) stands for the replacement part of the previous
+.CO substitute
+command.
+It is only valid after a
+.CO substitute
+command has been performed.
+.pp
+The string
+.QT \e# ,
+where
+.QT #
+is an integer value from 1 to 9, stands for the text matched by
+the portion of the RE enclosed in the
+.QT # 'th
+set of escaped parentheses, e.g.
+.QT \e(
+and
+.QT \e) .
+For example,
+.QT "s/abc\e(.*\e)def/\e1/"
+deletes the strings
+.QT abc
+and
+.QT def
+from the matched pattern.
+.pp
+The strings
+.QT \el ,
+.QT \eu ,
+.QT \eL
+and
+.QT \eU
+can be used to modify the case of elements in the replacement string.
+The string
+.QT \el
+causes the next character to be converted to lowercase;
+the string
+.QT \eu
+behaves similarly, but converts to uppercase
+(e.g.
+.LI s/abc/\eU&/
+replaces the string
+.LI abc
+with
+.LI ABC ).
+The string
+.QT \eL
+causes characters up to the end of the string or the next occurrence
+of the strings
+.QT \ee
+or
+.QT \eE
+to be converted to lowercase;
+the string
+.QT \eU
+behaves similarly, but converts to uppercase.
+.pp
+If the entire replacement pattern is
+.QT % ,
+then the last replacement pattern is used again.
+.pp
+In
+.CO vi ,
+inserting a
+.LI <control-M>
+into the replacement string will cause
+the matched line to be split into two lines at that point.
+(The
+.LI <control-M>
+will be discarded.)
+.SH 1 "Scripting Languages"
+.pp
+The
+.CO nvi
+editor currently supports two scripting languages, Tcl/Tk and Perl.
+(Note that Perl4 isn't sufficient, and that the Perl5 used must be
+version 5.002 or later.
+See the
+.QB "Building Nvi"
+section for more information.
+.pp
+The scripting language interface is still being worked on,
+therefore the following information is probably incomplete,
+probably wrong in cases, and likely to change.
+See the
+.LI perl_api
+and
+.LI tcl_api
+source directories for more information.
+As a quick reference, the following function calls are provided for
+both the Perl and Tcl interfaces.
+The Perl interface uses a slightly different naming convention,
+e.g. ``viFindScreen'' is named ``VI::FindScreen''.
+.IP "viFindScreen file"
+Return the
+.LI "screenId" associated with
+.LI file .
+.IP "viAppendLine screenId lineNumber text"
+Append
+.LI text
+as a new line after line number
+.LI lineNumber ,
+in the screen
+.LI screenId .
+.IP "viDelLine screenId lineNum"
+Delete the line
+.LI lineNumber
+from the screen
+.LI screenId .
+.IP "viGetLine screenId lineNumber"
+Return the line
+.LI lineNumber
+from the screen
+.LI screenId .
+.IP "viInsertLine screenId lineNumber text"
+Insert
+.LI text
+as a new line before line number
+.LI lineNumber
+in the screen
+.LI screenId .
+.IP "viLastLine screenId"
+Return the line number of the last line in the screen
+.LI screenId .
+.IP "viSetLine screenId lineNumber text"
+Change the line
+.LI lineNumber
+in the screen
+.LI screenId
+to match the specified
+.LI text .
+.IP "viGetMark screenId mark"
+Return the current line and column for the specified
+.LI mark
+from the screen
+.LI screenId .
+.IP "viSetMark screenId mark line column"
+Set the specified
+.LI mark
+to be at line
+.LI line ,
+column
+.LI column ,
+in the screen
+.LI screenId .
+.IP "viGetCursor screenId"
+Return the current line and column for the cursor in the screen
+.LI screenId .
+.IP "viSetCursor screenId line column"
+Set the cursor in the screen
+.LI screenId
+to the specified
+.LI line
+and
+.LI column .
+.IP "viMsg screenId text"
+Display the specified
+.LI text
+as a vi message in the screen
+.LI screenId .
+.IP "viNewScreen screenId [file]"
+Create a new screen.
+.IP "viEndScreen screenId"
+Exit the screen
+.LI screenId .
+.IP "viSwitchScreen screenId screenId"
+Switch from the screen
+.LI screenId
+to the screen
+.LI screenId .
+.IP "viMapKey screenId key tclproc"
+Map the specified
+.LI key
+in the screen
+.LI screenId
+to the Tcl procedure
+.LI tclproc .
+.IP "viUnmMapKey screenId key"
+Unmap the specified
+.LI key
+in the screen
+.LI screenId
+.IP "viGetOpt screenId option"
+Return the value of the specified
+.LI option
+from the screen
+.LI screenId .
+.IP "viSetOpt screenId command"
+Set one or more options in the screen
+.LI screenId .
+.SH 1 "General Editor Description"
+.pp
+When
+.CO ex
+or
+.CO vi
+are executed,
+the text of a file is read (or a temporary file is created),
+and then all editing changes happen within the context of the
+copy of the file.
+.i "No changes affect the actual file until the file is written out" ,
+either using a write command or another command which is affected by the
+.OP autowrite
+option.
+.pp
+All files are locked (using the
+.XR flock 2
+or
+.XR fcntl 2
+interfaces) during the edit session,
+to avoid inadvertently making modifications to multiple copies of the file.
+If a lock cannot be obtained for a file because it is locked by another
+process, the edit session is read-only (as if the
+.OP readonly
+option or the
+.b \-R
+flag had been specified).
+If a lock cannot be obtained for other reasons, the edit session will
+continue, but the file status information
+(see the
+.CO <control-G>
+command) will reflect this fact.
+.pp
+Both
+.CO ex
+and
+.CO vi
+are modeful editors, i.e. they have two modes,
+.QQ command
+mode and
+.QQ "text input"
+mode.
+The former is intended to permit you to enter commands which modifies
+already existing text.
+The latter is intended to permit you to enter new text.
+When
+.CO ex
+first starts running, it is in command mode, and usually displays a prompt
+(see the
+.OP prompt
+option for more information).
+The prompt is a single colon
+.PQ :
+character.
+There are three commands that switch
+.CO ex
+into text input mode:
+.CO append ,
+.CO change
+and
+.CO insert .
+Once in input mode, entering a line containing only a single period
+.PQ \&.
+ends text input mode and returns to command mode,
+where the prompt is redisplayed.
+.pp
+When
+.CO vi
+first starts running, it is in command mode as well.
+There are eleven commands that switch
+.CO vi
+into text input mode:
+.CO A ,
+.CO a ,
+.CO C ,
+.CO c ,
+.CO I ,
+.CO i ,
+.CO O ,
+.CO o ,
+.CO R ,
+.CO S
+and
+.CO s .
+Once in input mode, entering an
+.LI <escape>
+character ends text input mode and returns to command mode.
+.pp
+.EV Ex vi
+present three different interfaces to editing a file.
+.CO Ex
+presents a line oriented interface.
+.CO Vi
+presents a full screen display oriented interface,
+also known as
+.QQ "visual mode" .
+In addition, there is a third mode,
+.QQ "open mode" ,
+which is line oriented,
+but supports cursor movement and editing within the displayed line,
+similarly to visual mode.
+Open mode is not yet implemented in
+.CO nvi .
+.pp
+The following words have special meanings in both the
+.CO ex
+and
+.CO vi
+command descriptions:
+.KY <interrupt>
+.IP <interrupt>
+The interrupt character is used to interrupt the current operation.
+Normally
+.LI <control-C> ,
+whatever character is set for the current terminal is used.
+.KY "<literal-next>"
+.IP "<literal-next>"
+The literal next character is used to escape the subsequent character
+from any special meaning.
+This character is always
+.LI <control-V> .
+If the terminal is not set up to do XON/XOFF flow control,
+then
+.LI <control-Q>
+is used to mean literal next as well.
+.KY "current pathname"
+.IP "current pathname"
+The pathname of the file currently being edited by vi.
+When the percent character
+.PQ %
+appears in a file name entered as part of an
+.CO ex
+command argument, it is replaced by the current pathname.
+(The
+.QT %
+character can be escaped by preceding it with a backslash.)
+.KY "alternate pathname"
+.IP "alternate pathname"
+The name of the last file name mentioned in an
+.CO ex
+command, or,
+the previous current pathname if the last file mentioned
+becomes the current file.
+When the hash mark character
+.PQ #
+appears in a file name entered as part of an
+.CO ex
+command argument, it is replaced by the alternate pathname.
+(The
+.QT #
+character can be escaped by preceding it with a backslash.)
+.KY buffer
+.IP buffer
+One of a number of named areas for saving copies of text.
+Commands that change or delete text can save the changed or deleted
+text into a specific buffer, for later use, if the command allows
+it (i.e. the
+.CO ex
+.CO change
+command cannot save the changed text in a named buffer).
+Buffers are named with a single character, preceded by a double quote,
+e.g.
+.LI """<character>"
+in
+.CO vi
+and
+without the double quote, e.g.
+.LI <character> ,
+in
+.CO ex .
+(The double quote isn't necessary for
+.CO ex
+because buffers names are denoted by their position in the command line.)
+Historic implementations of
+.EV ex vi
+limited
+.LI <character>
+to the alphanumeric characters;
+.EV nex nvi
+permits the use of any character without another meaning in the position
+where a buffer name is expected.
+.sp
+Buffers named by uppercase characters are the same as buffers
+named by lowercase characters, e.g. the buffer named by the
+English character
+.QT A
+is the same as the buffer named by the character
+.QT a ,
+with the exception that, if the buffer contents are being changed (as
+with a text deletion or
+.CO vi
+.CO change
+command), the text is
+.i appended
+to the buffer, instead of replacing the current contents.
+.sp
+The buffers named by the numeric characters (in English,
+.QT 1
+through
+.QT 9 ),
+are special.
+If a region of text including characters from more than one line,
+or a single line of text specified by using a line-oriented motion,
+is changed or deleted in the file using the
+.CO vi
+.CO change
+or
+.CO delete
+commands, a copy of the text is placed into the numeric buffer
+.QT 1 ,
+regardless of the user specifying another buffer in which to save it.
+In addition, there are a few commands which, when used as a
+.LI motion
+with the
+.CO vi
+.CO change
+and
+.CO delete
+commands,
+.i always
+copy the specified region of text into the numeric buffers regardless
+of the region including characters from more than one line.
+These commands are:
+.sp
+.ne 3v
+.ft C
+.TS
+r r r r.
+<control-A> % ( )
+`<character> / ? N
+n { }
+.TE
+.ft R
+.sp
+Before this copy is done, the previous contents of buffer
+.QT 1
+are moved into buffer
+.QT 2 ,
+.QT 2
+into buffer
+.QT 3 ,
+and so on.
+The contents of buffer
+.QT 9
+are discarded.
+In
+.CO vi ,
+text may be explicitly stored into the numeric buffers.
+In this case, the buffer rotation described above occurs before the
+replacement of the buffer's contents.
+The numeric buffers are only available in
+.LI visual
+and
+.LI open
+modes,
+and are not accessible by
+.CO ex
+in any way, although changed and deleted text is still stored there
+while in
+.CO ex
+mode.
+.sp
+When a
+.CO vi
+command synopsis shows both a
+.LI [buffer]
+and a
+.LI [count] ,
+they may be presented in any order.
+.sp
+Finally, all buffers are either
+.QQ line
+or
+.QQ character
+oriented.
+All
+.CO ex
+commands which store text into buffers are line oriented.
+Some
+.CO vi
+commands which store text into buffers are line oriented,
+and some are character oriented; the description for each applicable
+.CO vi
+command notes whether text copied into buffers using the command
+is line or character oriented.
+In addition, the
+.CO vi
+command
+.CO "display buffers"
+displays the current orientation for each buffer.
+Generally, the only importance attached to this orientation is that
+if the buffer is subsequently inserted into the text, line oriented
+buffers create new lines for each of the lines they contain, and
+character oriented buffers create new lines for any lines
+.i other
+than the first and last lines they contain.
+The first and last lines are inserted into the text at the current
+cursor position, becoming part of the current line.
+If there is more than one line in the buffer, however, the current
+line itself will be split.
+.KY "unnamed buffer"
+.IP "unnamed buffer"
+The unnamed buffer is a text storage area which is used by commands
+that use or operate on a buffer when no buffer is specified by the user.
+If the command stores text into a buffer,
+the text is stored into the unnamed buffer even if a buffer is also
+specified by the user.
+It is not possible to append text to the unnamed buffer.
+If text is appended to a named buffer,
+the named buffer contains both the old and new text,
+while the unnamed buffer contains only the new text.
+There is no way to explicitly reference the unnamed buffer.
+.sp
+Historically, the contents of the unnamed buffer were discarded by many
+different commands, even ones that didn't store text into it.
+.EV Nex nvi
+never discards the contents of the unnamed buffer until new text
+replaces them.
+.KY whitespace
+.IP whitespace
+The characters <tab> and <space>.
+.KY "<carriage-return>"
+.IP "<carriage-return>"
+The character represented by an ASCII
+.LI <control-M> .
+This character is almost always treated identically to a
+.LI <newline>
+character, but differs in that it can be escaped into the file text or
+into a command.
+.KY <newline>
+.IP <newline>
+The character represented by an ASCII
+.LI <control-J> .
+This character is almost always treated identically to a
+.LI <control-M>
+character, but differs in that it cannot be escaped into the file text or
+into a command.
+.oh 'Vi/Ex Reference (Vi Commands)''USD:13-%'
+.eh 'USD:13-%''Vi/Ex Reference (Vi Commands)'
+.so vi.cmd.roff
+.oh 'Vi/Ex Reference''USD:13-%'
+.eh 'USD:13-%''Vi/Ex Reference'
+.SH 1 "Ex Addressing"
+.pp
+Addressing in
+.CO ex
+(and when
+.CO ex
+commands are executed from
+.CO vi )
+relates to the current line.
+In general, the current line is the last line affected by a command.
+The exact effect on the current line is discussed under the description
+of each command.
+When the file contains no lines, the current line is zero.
+.pp
+Addresses are constructed by one or more of the following methods:
+.np
+The address
+.QT \&.
+refers to the current line.
+.np
+The address
+.QT $
+refers to the last line of the file.
+.np
+The address
+.QT N ,
+where
+.LI N
+is a positive number, refers to the N-th line of the file.
+.np
+The address
+.QT '<character>
+or
+.QT `<character>
+refers to the line marked with the name
+.LI <character> .
+(See the
+.CO k
+or
+.CO m
+commands for more information on how to mark lines.)
+.np
+A regular expression (RE) enclosed by slashes
+.PQ /
+is an address,
+and it refers to the first line found by searching forward from the line
+.i after
+the current line toward the end of the file, and stopping at the
+first line containing a string matching the RE.
+(The trailing slash can be omitted at the end of the command line.)
+.sp
+If no RE is specified, i.e. the pattern is
+.QT // ,
+the last RE used in any command is used in the search.
+.sp
+If the
+.OP extended
+option is set, the RE is handled as an extended RE, not a basic RE.
+If the
+.OP wrapscan
+option is set, the search wraps around to the beginning of the file
+and continues up to and including the current line, so that the entire
+file is searched.
+.sp
+The form
+.QT \e/
+is accepted for historic reasons,
+and is identical to
+.QT // .
+.np
+An RE enclosed in question marks
+.PQ ?
+addresses the first line found by searching backward from the line
+.i preceding
+the current line, toward the beginning of the file and stopping at the
+first line containing a string matching the RE.
+(The trailing question mark can be omitted at the end of a command line.)
+.sp
+If no RE is specified, i.e. the pattern is
+.QT ?? ,
+the last RE used in any command is used in the search.
+.sp
+If the
+.OP extended
+option is set, the RE is handled as an extended RE, not a basic RE.
+If the
+.OP wrapscan
+option is set, the search wraps around from the beginning of the file to
+the end of the file and continues up to and including the current line,
+so that the entire file is searched.
+.sp
+The form
+.QT \e?
+is accepted for historic reasons, and is identical to
+.QT ?? .
+.np
+An address followed by a plus sign
+.PQ +
+or a minus sign
+.PQ -
+followed by a number is an offset address and refers to the address
+plus (or minus) the indicated number of lines.
+If the address is omitted, the addition or subtraction is done with
+respect to the current line.
+.np
+An address of
+.QT +
+or
+.QT \-
+followed by a number is an offset from the current line.
+For example,
+.QT \-5
+is the same as
+.QT \&.\-5 .
+.np
+An address ending with
+.QT +
+or
+.QT -
+has 1 added to or subtracted from the address, respectively.
+As a consequence of this rule and of the previous rule, the address
+.QT \-
+refers to the line preceding the current line.
+Moreover, trailing
+.QT +
+and
+.QT \-
+characters have a cumulative effect.
+For example,
+.QT ++\-++
+refers to the current line plus 3.
+.np
+A percent sign
+.PQ %
+is equivalent to the address range
+.QT 1,$ .
+.pp
+.CO Ex
+commands require zero, one, or two addresses.
+It is an error to specify an address to a command which requires zero
+addresses.
+.pp
+If the user provides more than the expected number of addresses to any
+.CO ex
+command, the first addresses specified are discarded.
+For example,
+.QT 1,2,3,5 print
+prints lines 3 through 5, because the
+.CO print
+command only takes two addresses.
+.pp
+The addresses in a range are separated from each other by a comma
+.PQ ,
+or a semicolon
+.PQ ; .
+In the latter case, the current line
+.PQ \&.
+is set to the first address, and only then is the second address calculated.
+This feature can be used to determine the starting line for forward and
+backward searches (see rules (5) and (6) above).
+The second address of any two-address sequence corresponds to a line that
+follows, in the file, the line corresponding to the first address.
+The first address must be less than or equal to the second address.
+The first address must be greater than or equal to the first line of the
+file, and the last address must be less than or equal to the last line
+of the file.
+.oh 'Vi/Ex Reference (Ex Commands)''USD:13-%'
+.eh 'USD:13-%''Vi/Ex Reference (Ex Commands)'
+.so ex.cmd.roff
+.oh 'Vi/Ex Reference (Options)''USD:13-%'
+.eh 'USD:13-%''Vi/Ex Reference (Options)'
+.so set.opt.roff
+.oh 'Vi/Ex Reference''USD:13-%'
+.eh 'USD:13-%''Vi/Ex Reference'
+.bp
+.SH 1 Index
+.lp
+.2c +0.5i 3
+.ta \n($luR
+.nf
+.so index.so
+.fi
+.\" Force the TOC to an odd page, in case it's a duplex printer.
+.if o .bp
+.bp 3
+.1c
+.ce 1
+\fB\s+2Table of Contents\s0\fP
+.sp
+.xp
diff --git a/share/doc/usd/18.msdiffs/ms.diffs b/share/doc/usd/18.msdiffs/ms.diffs
index 3bd8de6fb7bd..de937af9b6fe 100644
--- a/share/doc/usd/18.msdiffs/ms.diffs
+++ b/share/doc/usd/18.msdiffs/ms.diffs
@@ -37,6 +37,7 @@
.AM
.OH 'A Revised Version of \*ms''USD:18-%'
.EH 'USD:18-%''A Revised Version of \*ms'
+.ND
.TL
A Revised Version of \*ms
.AU
diff --git a/share/doc/usd/22.trofftut/tt00 b/share/doc/usd/22.trofftut/tt00
index f8c5ea7cf4b8..cb893ffddda4 100644
--- a/share/doc/usd/22.trofftut/tt00
+++ b/share/doc/usd/22.trofftut/tt00
@@ -46,6 +46,7 @@
.OH 'A TROFF Tutorial''USD:22-%'
.\".RP
.\" .....TM 76-1273-7 39199 39199-11
+.ND
.TL
A TROFF Tutorial
.AU "MH 2C-518" 6021
diff --git a/share/doc/usd/Makefile b/share/doc/usd/Makefile
index d7344aa8aa07..5fcb6b305017 100644
--- a/share/doc/usd/Makefile
+++ b/share/doc/usd/Makefile
@@ -10,6 +10,10 @@ SUBDIR= title \
05.dc \
06.bc \
07.mail \
+ 10.exref \
+ 11.vitut \
+ 12.vi \
+ 13.viref \
18.msdiffs \
19.memacros \
20.meref \
diff --git a/share/doc/usd/contents/contents.ms b/share/doc/usd/contents/contents.ms
index f18d046f40b2..03fde207c0f2 100644
--- a/share/doc/usd/contents/contents.ms
+++ b/share/doc/usd/contents/contents.ms
@@ -35,6 +35,7 @@
..
.OH '''USD Contents'
.EH 'USD Contents'''
+.ND
.TL
UNIX User's Supplementary Documents (USD)
.if !r.U .nr .U 0
diff --git a/share/dtrace/siftr b/share/dtrace/siftr
new file mode 100755
index 000000000000..d12d35f2d1aa
--- /dev/null
+++ b/share/dtrace/siftr
@@ -0,0 +1,68 @@
+#!/usr/sbin/dtrace -s
+/*-
+ * Copyright (c) 2015 George V. Neville-Neil
+ * 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$
+ *
+ * The siftr D script collects data from the SIFTR kernel module.
+ *
+ * Usage: siftr
+ */
+
+#pragma D option quiet
+tcp:kernel::siftr
+{
+ printf("direction %s state %s local %d remote %d\n",
+ siftr_dir_string[args[0]->direction],
+ tcp_state_string[args[0]->conn_state],
+ args[0]->tcp_localport,
+ args[0]->tcp_foreignport);
+ printf("snd_cwnd %d snd_wnd %d rcv_wnd %d snd_bwnd %d snd_ssthresh %d\n",
+ args[0]->snd_cwnd,
+ args[0]->snd_wnd,
+ args[0]->rcv_wnd,
+ args[0]->snd_bwnd,
+ args[0]->snd_ssthresh);
+ printf("\tmax_seg_size %u smoothed_rtt %d sack_enabled %d\n",
+ args[0]->max_seg_size,
+ args[0]->smoothed_rtt,
+ args[0]->sack_enabled);
+ printf("\tsnd_scale %d rcv_scale %d flags 0x%x rxt_length %d\n",
+ args[0]->snd_scale,
+ args[0]->rcv_scale,
+ args[0]->flags,
+ args[0]->rxt_length);
+ printf("\tsnd_buf_hiwater %u snd_buf_cc %u rcv_buf_hiwater %u\n",
+ args[0]->snd_buf_hiwater,
+ args[0]->snd_buf_cc,
+ args[0]->rcv_buf_hiwater);
+ printf("\trcv_buf_cc %u sent_inflight_bytes %u t_segqlen %d\n",
+ args[0]->rcv_buf_cc,
+ args[0]->sent_inflight_bytes,
+ args[0]->t_segqlen);
+ printf("\tflowid %u flowtype %u\n",
+ args[0]->flowid,
+ args[0]->flowtype);
+}
diff --git a/share/man/man4/ada.4 b/share/man/man4/ada.4
index fd38b33cad17..6f2964e1b5c2 100644
--- a/share/man/man4/ada.4
+++ b/share/man/man4/ada.4
@@ -156,6 +156,7 @@ ATA device nodes
.Xr ahci 4 ,
.Xr cam 4 ,
.Xr da 4 ,
+.Xr mvs 4 ,
.Xr siis 4
.Sh HISTORY
The
diff --git a/share/man/man4/smb.4 b/share/man/man4/smb.4
index afe4605b449f..de053f4f25a8 100644
--- a/share/man/man4/smb.4
+++ b/share/man/man4/smb.4
@@ -1,5 +1,6 @@
.\" Copyright (c) 1998, Nicolas Souchu
.\" Copyright (c) 2004, Joerg Wunsch
+.\" Copyright (c) 2015, Michael Gmelin <freebsd@grem.de>
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@@ -25,7 +26,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd February 6, 2009
+.Dd April 25, 2015
.Dt SMB 4
.Os
.Sh NAME
@@ -36,10 +37,10 @@
.Sh DESCRIPTION
The
.Em smb
-character device driver provides generic i/o to any
+character device driver provides generic I/O to any
.Xr smbus 4
instance.
-In order to control SMB devices, use
+To control SMB devices, use
.Pa /dev/smb?
with the ioctls described below.
Any of these ioctl commands takes a pointer to
@@ -49,124 +50,145 @@ as its argument.
#include <sys/types.h>
struct smbcmd {
- char cmd;
- int count;
- u_char slave;
+ u_char cmd;
+ u_char reserved;
+ u_short op;
union {
- char byte;
- short word;
-
- char *byte_ptr;
- short *word_ptr;
-
- struct {
- short sdata;
- short *rdata;
- } process;
- } data;
+ char byte;
+ char buf[2];
+ short word;
+ } wdata;
+ union {
+ char byte;
+ char buf[2];
+ short word;
+ } rdata;
+ int slave;
+ char *wbuf; /* use wdata if NULL */
+ int wcount;
+ char *rbuf; /* use rdata if NULL */
+ int rcount;
};
.Ed
.Pp
The
.Fa slave
field is always used, and provides the address of the
-SMBus slave device to talk to.
+SMBus slave device.
The slave address is specified in the seven most significant bits
-.Pq i.e. Dq "left-justified" .
+.Pq i.e., Dq "left-justified" .
The least significant bit of the slave address must be zero.
.Pp
.Bl -column ".Dv SMB_QUICK_WRITE" -compact
.It Em Ioctl Ta Em Description
.Pp
.It Dv SMB_QUICK_WRITE Ta
-The
.Em QuickWrite
-command just issues the device address with write intent
-to the bus, without transferring any data.
+does not transfer any data.
+It just issues the device address with write intent to the bus.
.It Dv SMB_QUICK_READ Ta
-The
.Em QuickRead
-command just issues the device address with read intent
-to the bus, without transferring any data.
+does not transfer any data.
+It just issues the device address with read intent to the bus.
.It Dv SMB_SENDB Ta
-The
.Em SendByte
-command sends the byte provided in the
+sends the byte provided in
.Fa cmd
-field to the device.
+to the device.
.It Dv SMB_RECVB Ta
-The
.Em ReceiveByte
-command reads a single byte from the device which will
-be returned in the
-.Fa cmd
-field.
+reads a single byte from the device which is returned in
+.Fa cmd .
.It Dv SMB_WRITEB Ta
-The
.Em WriteByte
-command first sends the byte from the
+first sends the byte from
.Fa cmd
-field to the device, followed by the byte given in
-.Fa data.byte .
+to the device, followed by the byte given in
+.Fa wdata.byte .
.It Dv SMB_WRITEW Ta
-The
.Em WriteWord
-command first sends the byte from the
+first sends the byte from
.Fa cmd
-field to the device, followed by the word given in
-.Fa data.word .
+to the device, followed by the word given in
+.Fa wdata.word .
Note that the SMBus byte-order is little-endian by definition.
.It Dv SMB_READB Ta
-The
.Em ReadByte
-command first sends the byte from the
+first sends the byte from
.Fa cmd
-field to the device, and then reads one byte of data from
+to the device, then reads one byte of data from
the device.
-The returned data will be stored in the location pointed to by
-.Fa data.byte_ptr .
+Returned data is stored in
+.Fa rdata.byte .
.It Dv SMB_READW Ta
-The
.Em ReadWord
-command first sends the byte from the
+first sends the byte from
.Fa cmd
-field to the device, and then reads one word of data from
+to the device, then reads one word of data from
the device.
-The returned data will be stored in the location pointed to by
-.Fa data.word_ptr .
+Returned data is stored in
+.Fa rdata.word .
.It Dv SMB_PCALL Ta
-The
.Em ProcedureCall
-command first sends the byte from the
+first sends the byte from
.Fa cmd
-field to the device, followed by the word provided in
-.Fa data.process.sdata .
-It then reads one word of data from the device, and returns it
-in the location pointed to by
-.Fa data.process.rdata .
+to the device, followed by the word provided in
+.Fa wdata.word .
+It then reads one word of data from the device and returns it
+in
+.Fa rdata.word .
.It Dv SMB_BWRITE Ta
-The
.Em BlockWrite
-command first sends the byte from the
+first sends the byte from
.Fa cmd
-field to the device, followed by
-.Fa count
+to the device, followed by
+.Fa wcount
bytes of data that are taken from the buffer pointed to by
-.Fa data.byte_ptr .
+.Fa wbuf .
The SMBus specification mandates that no more than 32 bytes of
-data can be transferred in a single block read or write command.
-This value is available in the constant
+data can be transferred in a single block read or write command,
+but since
+.Xr smbus 4
+is also used to access I2C devices, the limit has been increased
+to 1024.
+This value can be read from the constant
.Dv SMB_MAXBLOCKSIZE .
.It Dv SMB_BREAD Ta
-The
.Em BlockRead
-command first sends the byte from the
+first sends the byte from
.Fa cmd
-field to the device, and then reads
-.Fa count
+to the device, then reads
+.Fa rcount
bytes of data that from the device.
-These data will be returned in the buffer pointed to by
-.Fa data.byte_ptr .
+This data is returned in the buffer pointed to by
+.Fa rbuf .
+.It Dv SMB_TRANS Ta
+.Em Trans
+sends an SMB roll-up transaction with flags that also allow it to
+be used for (mostly) I2C pass-through and with 10-bit addresses.
+This function can be utilized to roll up all of the above functions.
+It first sends the byte from
+.Fa cmd
+to the device, followed by
+.Fa wcount
+bytes of data that are taken from the buffer pointed to by
+.Fa wbuf ,
+then reads
+.Fa rcount
+bytes of data that from the device.
+This data is returned in the buffer pointed to by
+.Fa rbuf .
+.Pp
+The following flags are allowed in
+.Fa op :
+.Pp
+.Bd -literal -compact
+SMB_TRANS_NOSTOP Do not send STOP at end
+SMB_TRANS_NOCMD Ignore cmd field (do not tx)
+SMB_TRANS_NOCNT Do not tx or rx count field
+SMB_TRANS_7BIT Change address mode to 7-bit
+SMB_TRANS_10BIT Change address mode to 10-bit
+.Ed
.El
.Pp
The
@@ -201,4 +223,6 @@ manual page first appeared in
.Sh AUTHORS
This
manual page was written by
-.An Nicolas Souchu .
+.An Nicolas Souchu
+and extended by
+.An Michael Gmelin Aq freebsd@grem.de .
diff --git a/share/man/man4/urtwn.4 b/share/man/man4/urtwn.4
index 35463f481327..5a58200a81fe 100644
--- a/share/man/man4/urtwn.4
+++ b/share/man/man4/urtwn.4
@@ -52,7 +52,7 @@ The
driver supports USB 2.0 wireless network devices based on Realtek
RTL8188CUS, RTL8188CE-VAU, RTL8188EUS, RTL8188RU and RTL8192CU chipsets.
.Pp
-The RTL8188CUS and RTL8188EUS are highly integrated 802.11n adapter that
+The RTL8188CUS and RTL8188EUS are highly integrated 802.11n adapters that
combine a MAC, a 1T1R capable baseband and an RF in a single chip.
They operate in the 2GHz spectrum only.
The RTL8188RU is a high-power variant of the RTL8188CUS.
diff --git a/share/man/man4/xen.4 b/share/man/man4/xen.4
index 83b3d1226854..c2b1f5be2cbf 100644
--- a/share/man/man4/xen.4
+++ b/share/man/man4/xen.4
@@ -28,24 +28,16 @@
.\"
.\" $FreeBSD$
.\"
-.Dd December 17, 2010
+.Dd April 30, 2015
.Dt XEN 4
.Os
.Sh NAME
.Nm xen
.Nd Xen Hypervisor Guest (DomU) Support
.Sh SYNOPSIS
-To compile para-virtualized (PV) Xen guest support into an i386 kernel, place
-the following lines in your kernel configuration file:
-.Bd -ragged -offset indent
-.Cd "options PAE"
-.Cd "options XEN"
-.Cd "nooptions NATIVE"
-.Ed
-.Pp
To compile hardware-assisted virtualization (HVM) Xen guest support with
-para-virtualized drivers into an amd64 kernel, place the following lines in
-your kernel configuration file:
+para-virtualized drivers into an amd64 or i386 kernel,
+place the following lines in your kernel configuration file:
.Bd -ragged -offset indent
.Cd "options XENHVM"
.Cd "device xenpci"
@@ -69,34 +61,14 @@ and hence able to optimize certain behaviors to improve performance or
semantics.
.Pp
.Fx
-supports a fully para-virtualized (PV) kernel on the i386 architecture using
-.Cd "options XEN"
-and
-.Cd "nooptions NATIVE" ;
-currently, this requires use of a PAE kernel, enabled via
-.Cd "options PAE" .
-.Pp
-.Fx
-supports hardware-assisted virtualization (HVM) on both the i386 and amd64
-kernels; however, PV device drivers with an HVM kernel are only supported on
-the amd64 architecture, and require
-.Cd "options XENHVM"
-and
-.Cd "device xenpci" .
+supports hardware-assisted virtualization (HVM) on both i386 and amd64
+kernels.
.Pp
Para-virtualized device drivers are required in order to support certain
functionality, such as processing management requests, returning idle
physical memory pages to the hypervisor, etc.
.Ss Xen DomU device drivers
-Xen para-virtualized drivers are automatically added to the kernel if a PV
-kernel is compiled using
-.Cd "options XEN" ;
-for HVM environments,
-.Cd "options XENHVM"
-and
-.Cd "device xenpci"
-are required.
-The follow drivers are supported:
+These para-virtualized drivers are supported:
.Bl -hang -offset indent -width blkfront
.It Nm balloon
Allow physical memory pages to be returned to the hypervisor as a result of
@@ -148,8 +120,6 @@ It is recommended that adaptive locking be disabled when using Xen:
.Cd "options NO_ADAPTIVE_RWLOCKS"
.Cd "options NO_ADAPTIVE_SX"
.Ed
-.Sh SEE ALSO
-.Xr pae 4
.Sh HISTORY
Support for
.Nm
@@ -173,12 +143,6 @@ This manual page was written by
.Fx
is only able to run as a Xen guest (DomU) and not as a Xen host (Dom0).
.Pp
-A fully para-virtualized (PV) kernel is only supported on i386, and not
-amd64.
-.Pp
-Para-virtualized drivers under hardware-assisted virtualization (HVM) kernel
-are only supported on amd64, not i386.
-.Pp
As of this release, Xen PV DomU support is not heavily tested; instability
has been reported during VM migration of PV kernels.
.Pp
diff --git a/share/man/man9/BUS_BIND_INTR.9 b/share/man/man9/BUS_BIND_INTR.9
index 1c97897e51db..162a8b5a9e08 100644
--- a/share/man/man9/BUS_BIND_INTR.9
+++ b/share/man/man9/BUS_BIND_INTR.9
@@ -1,6 +1,6 @@
.\" -*- nroff -*-
.\"
-.\" Copyright (c) 2009 Advanced Computing Technologies LLC
+.\" Copyright (c) 2009 Hudson River Trading LLC
.\" Written by: John H. Baldwin <jhb@FreeBSD.org>
.\" All rights reserved.
.\"
diff --git a/share/man/man9/BUS_CHILD_DELETED.9 b/share/man/man9/BUS_CHILD_DELETED.9
index 4caa856fea75..4ab46bef0a44 100644
--- a/share/man/man9/BUS_CHILD_DELETED.9
+++ b/share/man/man9/BUS_CHILD_DELETED.9
@@ -1,6 +1,6 @@
.\" -*- nroff -*-
.\"
-.\" Copyright (c) 2012 Advanced Computing Technologies LLC
+.\" Copyright (c) 2012 Hudson River Trading LLC
.\" Written by: John H. Baldwin <jhb@FreeBSD.org>
.\" All rights reserved.
.\"
diff --git a/share/man/man9/BUS_CHILD_DETACHED.9 b/share/man/man9/BUS_CHILD_DETACHED.9
index 4e032d16a7ec..b79b9c412d1c 100644
--- a/share/man/man9/BUS_CHILD_DETACHED.9
+++ b/share/man/man9/BUS_CHILD_DETACHED.9
@@ -1,6 +1,6 @@
.\" -*- nroff -*-
.\"
-.\" Copyright (c) 2012 Advanced Computing Technologies LLC
+.\" Copyright (c) 2012 Hudson River Trading LLC
.\" Written by: John H. Baldwin <jhb@FreeBSD.org>
.\" All rights reserved.
.\"
diff --git a/share/man/man9/BUS_DESCRIBE_INTR.9 b/share/man/man9/BUS_DESCRIBE_INTR.9
index 10004551e76e..c340bb2d82ec 100644
--- a/share/man/man9/BUS_DESCRIBE_INTR.9
+++ b/share/man/man9/BUS_DESCRIBE_INTR.9
@@ -1,6 +1,6 @@
.\" -*- nroff -*-
.\"
-.\" Copyright (c) 2009 Advanced Computing Technologies LLC
+.\" Copyright (c) 2009 Hudson River Trading LLC
.\" Written by: John H. Baldwin <jhb@FreeBSD.org>
.\" All rights reserved.
.\"
diff --git a/share/man/man9/BUS_NEW_PASS.9 b/share/man/man9/BUS_NEW_PASS.9
index 4861ffd0d659..1da2f6706291 100644
--- a/share/man/man9/BUS_NEW_PASS.9
+++ b/share/man/man9/BUS_NEW_PASS.9
@@ -1,6 +1,6 @@
.\" -*- nroff -*-
.\"
-.\" Copyright (c) 2009 Advanced Computing Technologies LLC
+.\" Copyright (c) 2009 Hudson River Trading LLC
.\" Written by: John H. Baldwin <jhb@FreeBSD.org>
.\" All rights reserved.
.\"
diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile
index d8fd5855ff40..7f79156b4a6e 100644
--- a/share/man/man9/Makefile
+++ b/share/man/man9/Makefile
@@ -1135,6 +1135,7 @@ MLINKS+=osd.9 osd_call.9 \
osd.9 osd_get.9 \
osd.9 osd_register.9 \
osd.9 osd_set.9
+MLINKS+=panic.9 vpanic.9
MLINKS+=pbuf.9 getpbuf.9 \
pbuf.9 relpbuf.9 \
pbuf.9 trypbuf.9
diff --git a/share/man/man9/VOP_ADVISE.9 b/share/man/man9/VOP_ADVISE.9
index 250be5209ae6..50cd8606081d 100644
--- a/share/man/man9/VOP_ADVISE.9
+++ b/share/man/man9/VOP_ADVISE.9
@@ -1,6 +1,6 @@
.\" -*- nroff -*-
.\"
-.\" Copyright (c) 2013 Advanced Computing Technologies LLC
+.\" Copyright (c) 2013 Hudson River Trading LLC
.\" Written by: John H. Baldwin <jhb@FreeBSD.org>
.\" All rights reserved.
.\"
diff --git a/share/man/man9/VOP_ALLOCATE.9 b/share/man/man9/VOP_ALLOCATE.9
index 314410d3e689..6f1f54cc01fd 100644
--- a/share/man/man9/VOP_ALLOCATE.9
+++ b/share/man/man9/VOP_ALLOCATE.9
@@ -1,6 +1,6 @@
.\" -*- nroff -*-
.\"
-.\" Copyright (c) 2013 Advanced Computing Technologies LLC
+.\" Copyright (c) 2013 Hudson River Trading LLC
.\" Written by: John H. Baldwin <jhb@FreeBSD.org>
.\" All rights reserved.
.\"
diff --git a/share/man/man9/bus_adjust_resource.9 b/share/man/man9/bus_adjust_resource.9
index be4adaef3397..b7c477a8be23 100644
--- a/share/man/man9/bus_adjust_resource.9
+++ b/share/man/man9/bus_adjust_resource.9
@@ -1,6 +1,6 @@
.\" -*- nroff -*-
.\"
-.\" Copyright (c) 2011 Advanced Computing Technologies LLC
+.\" Copyright (c) 2011 Hudson River Trading LLC
.\" Written by: John H. Baldwin <jhb@FreeBSD.org>
.\" All rights reserved.
.\"
diff --git a/share/man/man9/bus_generic_new_pass.9 b/share/man/man9/bus_generic_new_pass.9
index de6422029c4f..b0b79b68a250 100644
--- a/share/man/man9/bus_generic_new_pass.9
+++ b/share/man/man9/bus_generic_new_pass.9
@@ -1,6 +1,6 @@
.\" -*- nroff -*-
.\"
-.\" Copyright (c) 2009 Advanced Computing Technologies LLC
+.\" Copyright (c) 2009 Hudson River Trading LLC
.\" Written by: John H. Baldwin <jhb@FreeBSD.org>
.\" All rights reserved.
.\"
diff --git a/share/man/man9/bus_set_pass.9 b/share/man/man9/bus_set_pass.9
index a28d833c04db..f59d03b04bcb 100644
--- a/share/man/man9/bus_set_pass.9
+++ b/share/man/man9/bus_set_pass.9
@@ -1,6 +1,6 @@
.\" -*- nroff -*-
.\"
-.\" Copyright (c) 2009 Advanced Computing Technologies LLC
+.\" Copyright (c) 2009 Hudson River Trading LLC
.\" Written by: John H. Baldwin <jhb@FreeBSD.org>
.\" All rights reserved.
.\"
diff --git a/share/man/man9/getenv.9 b/share/man/man9/getenv.9
index a20c5e81e310..a530ca4ee222 100644
--- a/share/man/man9/getenv.9
+++ b/share/man/man9/getenv.9
@@ -1,6 +1,6 @@
.\" -*- nroff -*-
.\"
-.\" Copyright (c) 2013 Advanced Computing Technologies LLC
+.\" Copyright (c) 2013 Hudson River Trading LLC
.\" Written by: John H. Baldwin <jhb@FreeBSD.org>
.\" All rights reserved.
.\"
diff --git a/share/man/man9/panic.9 b/share/man/man9/panic.9
index 44439dd913b0..c467b86dd5a1 100644
--- a/share/man/man9/panic.9
+++ b/share/man/man9/panic.9
@@ -31,7 +31,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd August 11, 1995
+.Dd April 23, 2015
.Dt PANIC 9
.Os
.Sh NAME
@@ -42,10 +42,14 @@
.In sys/systm.h
.Ft void
.Fn panic "const char *fmt" ...
+.Ft void
+.Fn vpanic "const char *fmt" "va_list ap"
.Sh DESCRIPTION
The
.Fn panic
-function terminates the running system.
+and
+.Fn vpanic
+functions terminate the running system.
The message
.Fa fmt
is a
diff --git a/share/man/man9/refcount.9 b/share/man/man9/refcount.9
index b3c8d7f61d3d..b435bab30641 100644
--- a/share/man/man9/refcount.9
+++ b/share/man/man9/refcount.9
@@ -1,5 +1,5 @@
.\"
-.\" Copyright (c) 2009 Advanced Computing Technologies LLC
+.\" Copyright (c) 2009 Hudson River Trading LLC
.\" Written by: John H. Baldwin <jhb@FreeBSD.org>
.\" All rights reserved.
.\"
diff --git a/share/man/man9/sglist.9 b/share/man/man9/sglist.9
index 280a9937e7e5..a9b34de63102 100644
--- a/share/man/man9/sglist.9
+++ b/share/man/man9/sglist.9
@@ -1,5 +1,5 @@
.\"
-.\" Copyright (c) 2009 Advanced Computing Technologies LLC
+.\" Copyright (c) 2009 Hudson River Trading LLC
.\" Written by: John H. Baldwin <jhb@FreeBSD.org>
.\" All rights reserved.
.\"
diff --git a/share/man/man9/shm_map.9 b/share/man/man9/shm_map.9
index 4ba822260f95..e2b57d526334 100644
--- a/share/man/man9/shm_map.9
+++ b/share/man/man9/shm_map.9
@@ -1,5 +1,5 @@
.\"
-.\" Copyright (c) 2011 Advanced Computing Technologies LLC
+.\" Copyright (c) 2011 Hudson River Trading LLC
.\" Written by: John H. Baldwin <jhb@FreeBSD.org>
.\" All rights reserved.
.\"
diff --git a/share/misc/committers-src.dot b/share/misc/committers-src.dot
index 98ea817d1591..9af30b7ccc4f 100644
--- a/share/misc/committers-src.dot
+++ b/share/misc/committers-src.dot
@@ -240,6 +240,7 @@ np [label="Navdeep Parhar\nnp@FreeBSD.org\n2009/06/05"]
nwhitehorn [label="Nathan Whitehorn\nnwhitehorn@FreeBSD.org\n2008/07/03"]
obrien [label="David E. O'Brien\nobrien@FreeBSD.org\n1996/10/29"]
olli [label="Oliver Fromme\nolli@FreeBSD.org\n2008/02/14"]
+oshogbo [label="Mariusz Zaborski\noshogbo@FreeBSD.org\n2015/04/15"]
peadar [label="Peter Edwards\npeadar@FreeBSD.org\n2004/03/08"]
peter [label="Peter Wemm\npeter@FreeBSD.org\n1995/07/04"]
peterj [label="Peter Jeremy\npeterj@FreeBSD.org\n2012/09/14"]
@@ -633,6 +634,7 @@ phk -> mux
pjd -> kib
pjd -> lulf
+pjd -> oshogbo
pjd -> smh
pjd -> trociny
diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk
index f98e19f74677..6e188747c002 100644
--- a/share/mk/src.opts.mk
+++ b/share/mk/src.opts.mk
@@ -233,7 +233,11 @@ __DEFAULT_YES_OPTIONS+=GCC GCC_BOOTSTRAP GNUCXX
__DEFAULT_NO_OPTIONS+=CLANG CLANG_BOOTSTRAP CLANG_FULL CLANG_IS_CC
.endif
.if ${__T} == "aarch64"
-BROKEN_OPTIONS+=BINUTILS BINUTILS_BOOTSTRAP GDB
+BROKEN_OPTIONS+=BINUTILS BINUTILS_BOOTSTRAP GCC GCC_BOOTSTRAP GDB
+.endif
+# LLVM lacks support for FreeBSD 64-bit atomic operations for ARMv4/ARMv5
+.if ${__T} == "arm" || ${__T} == "armeb"
+BROKEN_OPTIONS+=LLDB
.endif
.include <bsd.mkopt.mk>
diff --git a/sys/amd64/amd64/apic_vector.S b/sys/amd64/amd64/apic_vector.S
index c3aac336a506..4455cab0e787 100644
--- a/sys/amd64/amd64/apic_vector.S
+++ b/sys/amd64/amd64/apic_vector.S
@@ -174,6 +174,22 @@ IDTVEC(xen_intr_upcall)
jmp doreti
#endif
+#ifdef HYPERV
+/*
+ * This is the Hyper-V vmbus channel direct callback interrupt.
+ * Only used when it is running on Hyper-V.
+ */
+ .text
+ SUPERALIGN_TEXT
+IDTVEC(hv_vmbus_callback)
+ PUSH_FRAME
+ FAKE_MCOUNT(TF_RIP(%rsp))
+ movq %rsp, %rdi
+ call hv_vector_handler
+ MEXITCOUNT
+ jmp doreti
+#endif
+
#ifdef SMP
/*
* Global address space TLB shootdown.
diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c
index c81495a33a67..83ca54870bbe 100644
--- a/sys/amd64/amd64/mp_machdep.c
+++ b/sys/amd64/amd64/mp_machdep.c
@@ -81,28 +81,11 @@ __FBSDID("$FreeBSD$");
#define BIOS_RESET (0x0f)
#define BIOS_WARM (0x0a)
-/* lock region used by kernel profiling */
-int mcount_lock;
-
-int mp_naps; /* # of Applications processors */
-int boot_cpu_id = -1; /* designated BSP */
-
-extern struct pcpu __pcpu[];
-
-/* AP uses this during bootstrap. Do not staticize. */
-char *bootSTK;
-int bootAP;
-
-/* Free these after use */
-void *bootstacks[MAXCPU];
+extern struct pcpu __pcpu[];
/* Temporary variables for init_secondary() */
char *doublefault_stack;
char *nmi_stack;
-void *dpcpu;
-
-struct pcb stoppcbs[MAXCPU];
-struct susppcb **susppcbs;
/* Variables needed for SMP tlb shootdown. */
vm_offset_t smp_tlb_addr2;
@@ -112,309 +95,16 @@ uint64_t pcid_cr3;
pmap_t smp_tlb_pmap;
extern int invpcid_works;
-#ifdef COUNT_IPIS
-/* Interrupt counts. */
-static u_long *ipi_preempt_counts[MAXCPU];
-static u_long *ipi_ast_counts[MAXCPU];
-u_long *ipi_invltlb_counts[MAXCPU];
-u_long *ipi_invlrng_counts[MAXCPU];
-u_long *ipi_invlpg_counts[MAXCPU];
-u_long *ipi_invlcache_counts[MAXCPU];
-u_long *ipi_rendezvous_counts[MAXCPU];
-static u_long *ipi_hardclock_counts[MAXCPU];
-#endif
-
-/* Default cpu_ops implementation. */
-struct cpu_ops cpu_ops;
-
extern inthand_t IDTVEC(fast_syscall), IDTVEC(fast_syscall32);
-extern int pmap_pcid_enabled;
-
/*
* Local data and functions.
*/
-static volatile cpuset_t ipi_nmi_pending;
-
-/* used to hold the AP's until we are ready to release them */
-struct mtx ap_boot_mtx;
-
-/* Set to 1 once we're ready to let the APs out of the pen. */
-static volatile int aps_ready = 0;
-
-/*
- * Store data from cpu_add() until later in the boot when we actually setup
- * the APs.
- */
-struct cpu_info {
- int cpu_present:1;
- int cpu_bsp:1;
- int cpu_disabled:1;
- int cpu_hyperthread:1;
-} static cpu_info[MAX_APIC_ID + 1];
-int cpu_apic_ids[MAXCPU];
-int apic_cpuids[MAX_APIC_ID + 1];
-
-/* Holds pending bitmap based IPIs per CPU */
-volatile u_int cpu_ipi_pending[MAXCPU];
-
-static u_int boot_address;
-static int cpu_logical; /* logical cpus per core */
-static int cpu_cores; /* cores per package */
-
-static void assign_cpu_ids(void);
-static void set_interrupt_apic_ids(void);
static int start_ap(int apic_id);
-static void release_aps(void *dummy);
-static u_int hyperthreading_cpus; /* logical cpus sharing L1 cache */
-static int hyperthreading_allowed = 1;
static u_int bootMP_size;
-
-static void
-mem_range_AP_init(void)
-{
- if (mem_range_softc.mr_op && mem_range_softc.mr_op->initAP)
- mem_range_softc.mr_op->initAP(&mem_range_softc);
-}
-
-static void
-topo_probe_amd(void)
-{
- int core_id_bits;
- int id;
-
- /* AMD processors do not support HTT. */
- cpu_logical = 1;
-
- if ((amd_feature2 & AMDID2_CMP) == 0) {
- cpu_cores = 1;
- return;
- }
-
- core_id_bits = (cpu_procinfo2 & AMDID_COREID_SIZE) >>
- AMDID_COREID_SIZE_SHIFT;
- if (core_id_bits == 0) {
- cpu_cores = (cpu_procinfo2 & AMDID_CMP_CORES) + 1;
- return;
- }
-
- /* Fam 10h and newer should get here. */
- for (id = 0; id <= MAX_APIC_ID; id++) {
- /* Check logical CPU availability. */
- if (!cpu_info[id].cpu_present || cpu_info[id].cpu_disabled)
- continue;
- /* Check if logical CPU has the same package ID. */
- if ((id >> core_id_bits) != (boot_cpu_id >> core_id_bits))
- continue;
- cpu_cores++;
- }
-}
-
-/*
- * Round up to the next power of two, if necessary, and then
- * take log2.
- * Returns -1 if argument is zero.
- */
-static __inline int
-mask_width(u_int x)
-{
-
- return (fls(x << (1 - powerof2(x))) - 1);
-}
-
-static void
-topo_probe_0x4(void)
-{
- u_int p[4];
- int pkg_id_bits;
- int core_id_bits;
- int max_cores;
- int max_logical;
- int id;
-
- /* Both zero and one here mean one logical processor per package. */
- max_logical = (cpu_feature & CPUID_HTT) != 0 ?
- (cpu_procinfo & CPUID_HTT_CORES) >> 16 : 1;
- if (max_logical <= 1)
- return;
-
- /*
- * Because of uniformity assumption we examine only
- * those logical processors that belong to the same
- * package as BSP. Further, we count number of
- * logical processors that belong to the same core
- * as BSP thus deducing number of threads per core.
- */
- if (cpu_high >= 0x4) {
- cpuid_count(0x04, 0, p);
- max_cores = ((p[0] >> 26) & 0x3f) + 1;
- } else
- max_cores = 1;
- core_id_bits = mask_width(max_logical/max_cores);
- if (core_id_bits < 0)
- return;
- pkg_id_bits = core_id_bits + mask_width(max_cores);
-
- for (id = 0; id <= MAX_APIC_ID; id++) {
- /* Check logical CPU availability. */
- if (!cpu_info[id].cpu_present || cpu_info[id].cpu_disabled)
- continue;
- /* Check if logical CPU has the same package ID. */
- if ((id >> pkg_id_bits) != (boot_cpu_id >> pkg_id_bits))
- continue;
- cpu_cores++;
- /* Check if logical CPU has the same package and core IDs. */
- if ((id >> core_id_bits) == (boot_cpu_id >> core_id_bits))
- cpu_logical++;
- }
-
- KASSERT(cpu_cores >= 1 && cpu_logical >= 1,
- ("topo_probe_0x4 couldn't find BSP"));
-
- cpu_cores /= cpu_logical;
- hyperthreading_cpus = cpu_logical;
-}
-
-static void
-topo_probe_0xb(void)
-{
- u_int p[4];
- int bits;
- int cnt;
- int i;
- int logical;
- int type;
- int x;
-
- /* We only support three levels for now. */
- for (i = 0; i < 3; i++) {
- cpuid_count(0x0b, i, p);
-
- /* Fall back if CPU leaf 11 doesn't really exist. */
- if (i == 0 && p[1] == 0) {
- topo_probe_0x4();
- return;
- }
-
- bits = p[0] & 0x1f;
- logical = p[1] &= 0xffff;
- type = (p[2] >> 8) & 0xff;
- if (type == 0 || logical == 0)
- break;
- /*
- * Because of uniformity assumption we examine only
- * those logical processors that belong to the same
- * package as BSP.
- */
- for (cnt = 0, x = 0; x <= MAX_APIC_ID; x++) {
- if (!cpu_info[x].cpu_present ||
- cpu_info[x].cpu_disabled)
- continue;
- if (x >> bits == boot_cpu_id >> bits)
- cnt++;
- }
- if (type == CPUID_TYPE_SMT)
- cpu_logical = cnt;
- else if (type == CPUID_TYPE_CORE)
- cpu_cores = cnt;
- }
- if (cpu_logical == 0)
- cpu_logical = 1;
- cpu_cores /= cpu_logical;
-}
-
-/*
- * Both topology discovery code and code that consumes topology
- * information assume top-down uniformity of the topology.
- * That is, all physical packages must be identical and each
- * core in a package must have the same number of threads.
- * Topology information is queried only on BSP, on which this
- * code runs and for which it can query CPUID information.
- * Then topology is extrapolated on all packages using the
- * uniformity assumption.
- */
-static void
-topo_probe(void)
-{
- static int cpu_topo_probed = 0;
-
- if (cpu_topo_probed)
- return;
-
- CPU_ZERO(&logical_cpus_mask);
- if (mp_ncpus <= 1)
- cpu_cores = cpu_logical = 1;
- else if (cpu_vendor_id == CPU_VENDOR_AMD)
- topo_probe_amd();
- else if (cpu_vendor_id == CPU_VENDOR_INTEL) {
- /*
- * See Intel(R) 64 Architecture Processor
- * Topology Enumeration article for details.
- *
- * Note that 0x1 <= cpu_high < 4 case should be
- * compatible with topo_probe_0x4() logic when
- * CPUID.1:EBX[23:16] > 0 (cpu_cores will be 1)
- * or it should trigger the fallback otherwise.
- */
- if (cpu_high >= 0xb)
- topo_probe_0xb();
- else if (cpu_high >= 0x1)
- topo_probe_0x4();
- }
-
- /*
- * Fallback: assume each logical CPU is in separate
- * physical package. That is, no multi-core, no SMT.
- */
- if (cpu_cores == 0 || cpu_logical == 0)
- cpu_cores = cpu_logical = 1;
- cpu_topo_probed = 1;
-}
-
-struct cpu_group *
-cpu_topo(void)
-{
- int cg_flags;
-
- /*
- * Determine whether any threading flags are
- * necessry.
- */
- topo_probe();
- if (cpu_logical > 1 && hyperthreading_cpus)
- cg_flags = CG_FLAG_HTT;
- else if (cpu_logical > 1)
- cg_flags = CG_FLAG_SMT;
- else
- cg_flags = 0;
- if (mp_ncpus % (cpu_cores * cpu_logical) != 0) {
- printf("WARNING: Non-uniform processors.\n");
- printf("WARNING: Using suboptimal topology.\n");
- return (smp_topo_none());
- }
- /*
- * No multi-core or hyper-threaded.
- */
- if (cpu_logical * cpu_cores == 1)
- return (smp_topo_none());
- /*
- * Only HTT no multi-core.
- */
- if (cpu_logical > 1 && cpu_cores == 1)
- return (smp_topo_1level(CG_SHARE_L1, cpu_logical, cg_flags));
- /*
- * Only multi-core no HTT.
- */
- if (cpu_cores > 1 && cpu_logical == 1)
- return (smp_topo_1level(CG_SHARE_L2, cpu_cores, cg_flags));
- /*
- * Both HTT and multi-core.
- */
- return (smp_topo_2level(CG_SHARE_L2, cpu_cores,
- CG_SHARE_L1, cpu_logical, cg_flags));
-}
+static u_int boot_address;
/*
* Calculate usable address in base memory for AP trampoline code.
@@ -433,85 +123,6 @@ mp_bootaddress(u_int basemem)
return mptramp_pagetables;
}
-void
-cpu_add(u_int apic_id, char boot_cpu)
-{
-
- if (apic_id > MAX_APIC_ID) {
- panic("SMP: APIC ID %d too high", apic_id);
- return;
- }
- KASSERT(cpu_info[apic_id].cpu_present == 0, ("CPU %d added twice",
- apic_id));
- cpu_info[apic_id].cpu_present = 1;
- if (boot_cpu) {
- KASSERT(boot_cpu_id == -1,
- ("CPU %d claims to be BSP, but CPU %d already is", apic_id,
- boot_cpu_id));
- boot_cpu_id = apic_id;
- cpu_info[apic_id].cpu_bsp = 1;
- }
- if (mp_ncpus < MAXCPU) {
- mp_ncpus++;
- mp_maxid = mp_ncpus - 1;
- }
- if (bootverbose)
- printf("SMP: Added CPU %d (%s)\n", apic_id, boot_cpu ? "BSP" :
- "AP");
-}
-
-void
-cpu_mp_setmaxid(void)
-{
-
- /*
- * mp_maxid should be already set by calls to cpu_add().
- * Just sanity check its value here.
- */
- if (mp_ncpus == 0)
- KASSERT(mp_maxid == 0,
- ("%s: mp_ncpus is zero, but mp_maxid is not", __func__));
- else if (mp_ncpus == 1)
- mp_maxid = 0;
- else
- KASSERT(mp_maxid >= mp_ncpus - 1,
- ("%s: counters out of sync: max %d, count %d", __func__,
- mp_maxid, mp_ncpus));
-}
-
-int
-cpu_mp_probe(void)
-{
-
- /*
- * Always record BSP in CPU map so that the mbuf init code works
- * correctly.
- */
- CPU_SETOF(0, &all_cpus);
- if (mp_ncpus == 0) {
- /*
- * No CPUs were found, so this must be a UP system. Setup
- * the variables to represent a system with a single CPU
- * with an id of 0.
- */
- mp_ncpus = 1;
- return (0);
- }
-
- /* At least one CPU was found. */
- if (mp_ncpus == 1) {
- /*
- * One CPU was found, so this must be a UP system with
- * an I/O APIC.
- */
- mp_maxid = 0;
- return (0);
- }
-
- /* At least two CPUs were found. */
- return (1);
-}
-
/*
* Initialize the IPI handlers and start up the AP's.
*/
@@ -575,47 +186,6 @@ cpu_mp_start(void)
/*
- * Print various information about the SMP system hardware and setup.
- */
-void
-cpu_mp_announce(void)
-{
- const char *hyperthread;
- int i;
-
- printf("FreeBSD/SMP: %d package(s) x %d core(s)",
- mp_ncpus / (cpu_cores * cpu_logical), cpu_cores);
- if (hyperthreading_cpus > 1)
- printf(" x %d HTT threads", cpu_logical);
- else if (cpu_logical > 1)
- printf(" x %d SMT threads", cpu_logical);
- printf("\n");
-
- /* List active CPUs first. */
- printf(" cpu0 (BSP): APIC ID: %2d\n", boot_cpu_id);
- for (i = 1; i < mp_ncpus; i++) {
- if (cpu_info[cpu_apic_ids[i]].cpu_hyperthread)
- hyperthread = "/HT";
- else
- hyperthread = "";
- printf(" cpu%d (AP%s): APIC ID: %2d\n", i, hyperthread,
- cpu_apic_ids[i]);
- }
-
- /* List disabled CPUs last. */
- for (i = 0; i <= MAX_APIC_ID; i++) {
- if (!cpu_info[i].cpu_present || !cpu_info[i].cpu_disabled)
- continue;
- if (cpu_info[i].cpu_hyperthread)
- hyperthread = "/HT";
- else
- hyperthread = "";
- printf(" cpu (AP%s): APIC ID: %2d (disabled)\n", hyperthread,
- i);
- }
-}
-
-/*
* AP CPU's call this to initialize themselves.
*/
void
@@ -624,7 +194,6 @@ init_secondary(void)
struct pcpu *pc;
struct nmi_pcpu *np;
u_int64_t msr, cr0;
- u_int cpuid;
int cpu, gsel_tss, x;
struct region_descriptor ap_gdt;
@@ -712,94 +281,7 @@ init_secondary(void)
while (!aps_ready)
ia32_pause();
- /*
- * On real hardware, switch to x2apic mode if possible. Do it
- * after aps_ready was signalled, to avoid manipulating the
- * mode while BSP might still want to send some IPI to us
- * (second startup IPI is ignored on modern hardware etc).
- */
- lapic_xapic_mode();
-
- /* Initialize the PAT MSR. */
- pmap_init_pat();
-
- /* set up CPU registers and state */
- cpu_setregs();
-
- /* set up SSE/NX */
- initializecpu();
-
- /* set up FPU state on the AP */
- fpuinit();
-
- if (cpu_ops.cpu_init)
- cpu_ops.cpu_init();
-
- /* A quick check from sanity claus */
- cpuid = PCPU_GET(cpuid);
- if (PCPU_GET(apic_id) != lapic_id()) {
- printf("SMP: cpuid = %d\n", cpuid);
- printf("SMP: actual apic_id = %d\n", lapic_id());
- printf("SMP: correct apic_id = %d\n", PCPU_GET(apic_id));
- panic("cpuid mismatch! boom!!");
- }
-
- /* Initialize curthread. */
- KASSERT(PCPU_GET(idlethread) != NULL, ("no idle thread"));
- PCPU_SET(curthread, PCPU_GET(idlethread));
-
- mca_init();
-
- mtx_lock_spin(&ap_boot_mtx);
-
- /* Init local apic for irq's */
- lapic_setup(1);
-
- /* Set memory range attributes for this CPU to match the BSP */
- mem_range_AP_init();
-
- smp_cpus++;
-
- CTR1(KTR_SMP, "SMP: AP CPU #%d Launched", cpuid);
- printf("SMP: AP CPU #%d Launched!\n", cpuid);
-
- /* Determine if we are a logical CPU. */
- /* XXX Calculation depends on cpu_logical being a power of 2, e.g. 2 */
- if (cpu_logical > 1 && PCPU_GET(apic_id) % cpu_logical != 0)
- CPU_SET(cpuid, &logical_cpus_mask);
-
- if (bootverbose)
- lapic_dump("AP");
-
- if (smp_cpus == mp_ncpus) {
- /* enable IPI's, tlb shootdown, freezes etc */
- atomic_store_rel_int(&smp_started, 1);
- }
-
- /*
- * Enable global pages TLB extension
- * This also implicitly flushes the TLB
- */
-
- load_cr4(rcr4() | CR4_PGE);
- if (pmap_pcid_enabled)
- load_cr4(rcr4() | CR4_PCIDE);
- load_ds(_udatasel);
- load_es(_udatasel);
- load_fs(_ufssel);
- mtx_unlock_spin(&ap_boot_mtx);
-
- /* Wait until all the AP's are up. */
- while (smp_started == 0)
- ia32_pause();
-
- /* Start per-CPU event timers. */
- cpu_initclocks_ap();
-
- sched_throw(NULL);
-
- panic("scheduler returned us to %s", __func__);
- /* NOTREACHED */
+ init_secondary_tail();
}
/*******************************************************************
@@ -807,108 +289,6 @@ init_secondary(void)
*/
/*
- * We tell the I/O APIC code about all the CPUs we want to receive
- * interrupts. If we don't want certain CPUs to receive IRQs we
- * can simply not tell the I/O APIC code about them in this function.
- * We also do not tell it about the BSP since it tells itself about
- * the BSP internally to work with UP kernels and on UP machines.
- */
-static void
-set_interrupt_apic_ids(void)
-{
- u_int i, apic_id;
-
- for (i = 0; i < MAXCPU; i++) {
- apic_id = cpu_apic_ids[i];
- if (apic_id == -1)
- continue;
- if (cpu_info[apic_id].cpu_bsp)
- continue;
- if (cpu_info[apic_id].cpu_disabled)
- continue;
-
- /* Don't let hyperthreads service interrupts. */
- if (cpu_logical > 1 &&
- apic_id % cpu_logical != 0)
- continue;
-
- intr_add_cpu(i);
- }
-}
-
-/*
- * Assign logical CPU IDs to local APICs.
- */
-static void
-assign_cpu_ids(void)
-{
- u_int i;
-
- TUNABLE_INT_FETCH("machdep.hyperthreading_allowed",
- &hyperthreading_allowed);
-
- /* Check for explicitly disabled CPUs. */
- for (i = 0; i <= MAX_APIC_ID; i++) {
- if (!cpu_info[i].cpu_present || cpu_info[i].cpu_bsp)
- continue;
-
- if (hyperthreading_cpus > 1 && i % hyperthreading_cpus != 0) {
- cpu_info[i].cpu_hyperthread = 1;
-
- /*
- * Don't use HT CPU if it has been disabled by a
- * tunable.
- */
- if (hyperthreading_allowed == 0) {
- cpu_info[i].cpu_disabled = 1;
- continue;
- }
- }
-
- /* Don't use this CPU if it has been disabled by a tunable. */
- if (resource_disabled("lapic", i)) {
- cpu_info[i].cpu_disabled = 1;
- continue;
- }
- }
-
- if (hyperthreading_allowed == 0 && hyperthreading_cpus > 1) {
- hyperthreading_cpus = 0;
- cpu_logical = 1;
- }
-
- /*
- * Assign CPU IDs to local APIC IDs and disable any CPUs
- * beyond MAXCPU. CPU 0 is always assigned to the BSP.
- *
- * To minimize confusion for userland, we attempt to number
- * CPUs such that all threads and cores in a package are
- * grouped together. For now we assume that the BSP is always
- * the first thread in a package and just start adding APs
- * starting with the BSP's APIC ID.
- */
- mp_ncpus = 1;
- cpu_apic_ids[0] = boot_cpu_id;
- apic_cpuids[boot_cpu_id] = 0;
- for (i = boot_cpu_id + 1; i != boot_cpu_id;
- i == MAX_APIC_ID ? i = 0 : i++) {
- if (!cpu_info[i].cpu_present || cpu_info[i].cpu_bsp ||
- cpu_info[i].cpu_disabled)
- continue;
-
- if (mp_ncpus < MAXCPU) {
- cpu_apic_ids[mp_ncpus] = i;
- apic_cpuids[i] = mp_ncpus;
- mp_ncpus++;
- } else
- cpu_info[i].cpu_disabled = 1;
- }
- KASSERT(mp_maxid >= mp_ncpus - 1,
- ("%s: counters out of sync: max %d, count %d", __func__, mp_maxid,
- mp_ncpus));
-}
-
-/*
* start each AP in our list
*/
int
@@ -1026,129 +406,6 @@ start_ap(int apic_id)
return 0; /* return FAILURE */
}
-#ifdef COUNT_XINVLTLB_HITS
-u_int xhits_gbl[MAXCPU];
-u_int xhits_pg[MAXCPU];
-u_int xhits_rng[MAXCPU];
-static SYSCTL_NODE(_debug, OID_AUTO, xhits, CTLFLAG_RW, 0, "");
-SYSCTL_OPAQUE(_debug_xhits, OID_AUTO, global, CTLFLAG_RW, &xhits_gbl,
- sizeof(xhits_gbl), "IU", "");
-SYSCTL_OPAQUE(_debug_xhits, OID_AUTO, page, CTLFLAG_RW, &xhits_pg,
- sizeof(xhits_pg), "IU", "");
-SYSCTL_OPAQUE(_debug_xhits, OID_AUTO, range, CTLFLAG_RW, &xhits_rng,
- sizeof(xhits_rng), "IU", "");
-
-u_int ipi_global;
-u_int ipi_page;
-u_int ipi_range;
-u_int ipi_range_size;
-SYSCTL_UINT(_debug_xhits, OID_AUTO, ipi_global, CTLFLAG_RW, &ipi_global, 0, "");
-SYSCTL_UINT(_debug_xhits, OID_AUTO, ipi_page, CTLFLAG_RW, &ipi_page, 0, "");
-SYSCTL_UINT(_debug_xhits, OID_AUTO, ipi_range, CTLFLAG_RW, &ipi_range, 0, "");
-SYSCTL_UINT(_debug_xhits, OID_AUTO, ipi_range_size, CTLFLAG_RW,
- &ipi_range_size, 0, "");
-
-u_int ipi_masked_global;
-u_int ipi_masked_page;
-u_int ipi_masked_range;
-u_int ipi_masked_range_size;
-SYSCTL_UINT(_debug_xhits, OID_AUTO, ipi_masked_global, CTLFLAG_RW,
- &ipi_masked_global, 0, "");
-SYSCTL_UINT(_debug_xhits, OID_AUTO, ipi_masked_page, CTLFLAG_RW,
- &ipi_masked_page, 0, "");
-SYSCTL_UINT(_debug_xhits, OID_AUTO, ipi_masked_range, CTLFLAG_RW,
- &ipi_masked_range, 0, "");
-SYSCTL_UINT(_debug_xhits, OID_AUTO, ipi_masked_range_size, CTLFLAG_RW,
- &ipi_masked_range_size, 0, "");
-#endif /* COUNT_XINVLTLB_HITS */
-
-/*
- * Init and startup IPI.
- */
-void
-ipi_startup(int apic_id, int vector)
-{
-
- /*
- * This attempts to follow the algorithm described in the
- * Intel Multiprocessor Specification v1.4 in section B.4.
- * For each IPI, we allow the local APIC ~20us to deliver the
- * IPI. If that times out, we panic.
- */
-
- /*
- * first we do an INIT IPI: this INIT IPI might be run, resetting
- * and running the target CPU. OR this INIT IPI might be latched (P5
- * bug), CPU waiting for STARTUP IPI. OR this INIT IPI might be
- * ignored.
- */
- lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_LEVEL |
- APIC_LEVEL_ASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_INIT, apic_id);
- lapic_ipi_wait(100);
-
- /* Explicitly deassert the INIT IPI. */
- lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_LEVEL |
- APIC_LEVEL_DEASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_INIT,
- apic_id);
-
- DELAY(10000); /* wait ~10mS */
-
- /*
- * next we do a STARTUP IPI: the previous INIT IPI might still be
- * latched, (P5 bug) this 1st STARTUP would then terminate
- * immediately, and the previously started INIT IPI would continue. OR
- * the previous INIT IPI has already run. and this STARTUP IPI will
- * run. OR the previous INIT IPI was ignored. and this STARTUP IPI
- * will run.
- */
- lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_EDGE |
- APIC_LEVEL_ASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_STARTUP |
- vector, apic_id);
- if (!lapic_ipi_wait(100))
- panic("Failed to deliver first STARTUP IPI to APIC %d",
- apic_id);
- DELAY(200); /* wait ~200uS */
-
- /*
- * finally we do a 2nd STARTUP IPI: this 2nd STARTUP IPI should run IF
- * the previous STARTUP IPI was cancelled by a latched INIT IPI. OR
- * this STARTUP IPI will be ignored, as only ONE STARTUP IPI is
- * recognized after hardware RESET or INIT IPI.
- */
- lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_EDGE |
- APIC_LEVEL_ASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_STARTUP |
- vector, apic_id);
- if (!lapic_ipi_wait(100))
- panic("Failed to deliver second STARTUP IPI to APIC %d",
- apic_id);
-
- DELAY(200); /* wait ~200uS */
-}
-
-/*
- * Send an IPI to specified CPU handling the bitmap logic.
- */
-static void
-ipi_send_cpu(int cpu, u_int ipi)
-{
- u_int bitmap, old_pending, new_pending;
-
- KASSERT(cpu_apic_ids[cpu] != -1, ("IPI to non-existent CPU %d", cpu));
-
- if (IPI_IS_BITMAPED(ipi)) {
- bitmap = 1 << ipi;
- ipi = IPI_BITMAP_VECTOR;
- do {
- old_pending = cpu_ipi_pending[cpu];
- new_pending = old_pending | bitmap;
- } while (!atomic_cmpset_int(&cpu_ipi_pending[cpu],
- old_pending, new_pending));
- if (old_pending)
- return;
- }
- lapic_ipi_vectored(ipi, cpu_apic_ids[cpu]);
-}
-
/*
* Flush the TLB on all other CPU's
*/
@@ -1228,26 +485,6 @@ smp_targeted_tlb_shootdown(cpuset_t mask, u_int vector, pmap_t pmap,
}
void
-smp_cache_flush(void)
-{
-
- if (smp_started)
- smp_tlb_shootdown(IPI_INVLCACHE, NULL, 0, 0);
-}
-
-void
-smp_invltlb(pmap_t pmap)
-{
-
- if (smp_started) {
- smp_tlb_shootdown(IPI_INVLTLB, pmap, 0, 0);
-#ifdef COUNT_XINVLTLB_HITS
- ipi_global++;
-#endif
- }
-}
-
-void
smp_invlpg(pmap_t pmap, vm_offset_t addr)
{
@@ -1312,210 +549,23 @@ smp_masked_invlpg_range(cpuset_t mask, pmap_t pmap, vm_offset_t addr1,
}
void
-ipi_bitmap_handler(struct trapframe frame)
-{
- struct trapframe *oldframe;
- struct thread *td;
- int cpu = PCPU_GET(cpuid);
- u_int ipi_bitmap;
-
- critical_enter();
- td = curthread;
- td->td_intr_nesting_level++;
- oldframe = td->td_intr_frame;
- td->td_intr_frame = &frame;
- ipi_bitmap = atomic_readandclear_int(&cpu_ipi_pending[cpu]);
- if (ipi_bitmap & (1 << IPI_PREEMPT)) {
-#ifdef COUNT_IPIS
- (*ipi_preempt_counts[cpu])++;
-#endif
- sched_preempt(td);
- }
- if (ipi_bitmap & (1 << IPI_AST)) {
-#ifdef COUNT_IPIS
- (*ipi_ast_counts[cpu])++;
-#endif
- /* Nothing to do for AST */
- }
- if (ipi_bitmap & (1 << IPI_HARDCLOCK)) {
-#ifdef COUNT_IPIS
- (*ipi_hardclock_counts[cpu])++;
-#endif
- hardclockintr();
- }
- td->td_intr_frame = oldframe;
- td->td_intr_nesting_level--;
- critical_exit();
-}
-
-/*
- * send an IPI to a set of cpus.
- */
-void
-ipi_selected(cpuset_t cpus, u_int ipi)
-{
- int cpu;
-
- /*
- * IPI_STOP_HARD maps to a NMI and the trap handler needs a bit
- * of help in order to understand what is the source.
- * Set the mask of receiving CPUs for this purpose.
- */
- if (ipi == IPI_STOP_HARD)
- CPU_OR_ATOMIC(&ipi_nmi_pending, &cpus);
-
- while ((cpu = CPU_FFS(&cpus)) != 0) {
- cpu--;
- CPU_CLR(cpu, &cpus);
- CTR3(KTR_SMP, "%s: cpu: %d ipi: %x", __func__, cpu, ipi);
- ipi_send_cpu(cpu, ipi);
- }
-}
-
-/*
- * send an IPI to a specific CPU.
- */
-void
-ipi_cpu(int cpu, u_int ipi)
-{
-
- /*
- * IPI_STOP_HARD maps to a NMI and the trap handler needs a bit
- * of help in order to understand what is the source.
- * Set the mask of receiving CPUs for this purpose.
- */
- if (ipi == IPI_STOP_HARD)
- CPU_SET_ATOMIC(cpu, &ipi_nmi_pending);
-
- CTR3(KTR_SMP, "%s: cpu: %d ipi: %x", __func__, cpu, ipi);
- ipi_send_cpu(cpu, ipi);
-}
-
-/*
- * send an IPI to all CPUs EXCEPT myself
- */
-void
-ipi_all_but_self(u_int ipi)
+smp_cache_flush(void)
{
- cpuset_t other_cpus;
-
- other_cpus = all_cpus;
- CPU_CLR(PCPU_GET(cpuid), &other_cpus);
- if (IPI_IS_BITMAPED(ipi)) {
- ipi_selected(other_cpus, ipi);
- return;
- }
-
- /*
- * IPI_STOP_HARD maps to a NMI and the trap handler needs a bit
- * of help in order to understand what is the source.
- * Set the mask of receiving CPUs for this purpose.
- */
- if (ipi == IPI_STOP_HARD)
- CPU_OR_ATOMIC(&ipi_nmi_pending, &other_cpus);
-
- CTR2(KTR_SMP, "%s: ipi: %x", __func__, ipi);
- lapic_ipi_vectored(ipi, APIC_IPI_DEST_OTHERS);
+ if (smp_started)
+ smp_tlb_shootdown(IPI_INVLCACHE, NULL, 0, 0);
}
-int
-ipi_nmi_handler()
-{
- u_int cpuid;
-
- /*
- * As long as there is not a simple way to know about a NMI's
- * source, if the bitmask for the current CPU is present in
- * the global pending bitword an IPI_STOP_HARD has been issued
- * and should be handled.
- */
- cpuid = PCPU_GET(cpuid);
- if (!CPU_ISSET(cpuid, &ipi_nmi_pending))
- return (1);
-
- CPU_CLR_ATOMIC(cpuid, &ipi_nmi_pending);
- cpustop_handler();
- return (0);
-}
-
-/*
- * Handle an IPI_STOP by saving our current context and spinning until we
- * are resumed.
- */
void
-cpustop_handler(void)
-{
- u_int cpu;
-
- cpu = PCPU_GET(cpuid);
-
- savectx(&stoppcbs[cpu]);
-
- /* Indicate that we are stopped */
- CPU_SET_ATOMIC(cpu, &stopped_cpus);
-
- /* Wait for restart */
- while (!CPU_ISSET(cpu, &started_cpus))
- ia32_pause();
-
- CPU_CLR_ATOMIC(cpu, &started_cpus);
- CPU_CLR_ATOMIC(cpu, &stopped_cpus);
+smp_invltlb(pmap_t pmap)
+{
-#ifdef DDB
- amd64_db_resume_dbreg();
+ if (smp_started) {
+ smp_tlb_shootdown(IPI_INVLTLB, pmap, 0, 0);
+#ifdef COUNT_XINVLTLB_HITS
+ ipi_global++;
#endif
-
- if (cpu == 0 && cpustop_restartfunc != NULL) {
- cpustop_restartfunc();
- cpustop_restartfunc = NULL;
- }
-}
-
-/*
- * Handle an IPI_SUSPEND by saving our current context and spinning until we
- * are resumed.
- */
-void
-cpususpend_handler(void)
-{
- u_int cpu;
-
- mtx_assert(&smp_ipi_mtx, MA_NOTOWNED);
-
- cpu = PCPU_GET(cpuid);
- if (savectx(&susppcbs[cpu]->sp_pcb)) {
- fpususpend(susppcbs[cpu]->sp_fpususpend);
- wbinvd();
- CPU_SET_ATOMIC(cpu, &suspended_cpus);
- } else {
- fpuresume(susppcbs[cpu]->sp_fpususpend);
- pmap_init_pat();
- initializecpu();
- PCPU_SET(switchtime, 0);
- PCPU_SET(switchticks, ticks);
-
- /* Indicate that we are resumed */
- CPU_CLR_ATOMIC(cpu, &suspended_cpus);
}
-
- /* Wait for resume */
- while (!CPU_ISSET(cpu, &started_cpus))
- ia32_pause();
-
- if (cpu_ops.cpu_resume)
- cpu_ops.cpu_resume();
- if (vmm_resume_p)
- vmm_resume_p();
-
- /* Resume MCA and local APIC */
- lapic_xapic_mode();
- mca_resume();
- lapic_setup(0);
-
- CPU_CLR_ATOMIC(cpu, &started_cpus);
- /* Indicate that we are resumed */
- CPU_CLR_ATOMIC(cpu, &suspended_cpus);
}
/*
@@ -1678,63 +728,3 @@ invlrng_handler(void)
atomic_add_int(&smp_tlb_wait, 1);
}
-
-void
-invlcache_handler(void)
-{
-#ifdef COUNT_IPIS
- (*ipi_invlcache_counts[PCPU_GET(cpuid)])++;
-#endif /* COUNT_IPIS */
-
- wbinvd();
- atomic_add_int(&smp_tlb_wait, 1);
-}
-
-/*
- * This is called once the rest of the system is up and running and we're
- * ready to let the AP's out of the pen.
- */
-static void
-release_aps(void *dummy __unused)
-{
-
- if (mp_ncpus == 1)
- return;
- atomic_store_rel_int(&aps_ready, 1);
- while (smp_started == 0)
- ia32_pause();
-}
-SYSINIT(start_aps, SI_SUB_SMP, SI_ORDER_FIRST, release_aps, NULL);
-
-#ifdef COUNT_IPIS
-/*
- * Setup interrupt counters for IPI handlers.
- */
-static void
-mp_ipi_intrcnt(void *dummy)
-{
- char buf[64];
- int i;
-
- CPU_FOREACH(i) {
- snprintf(buf, sizeof(buf), "cpu%d:invltlb", i);
- intrcnt_add(buf, &ipi_invltlb_counts[i]);
- snprintf(buf, sizeof(buf), "cpu%d:invlrng", i);
- intrcnt_add(buf, &ipi_invlrng_counts[i]);
- snprintf(buf, sizeof(buf), "cpu%d:invlpg", i);
- intrcnt_add(buf, &ipi_invlpg_counts[i]);
- snprintf(buf, sizeof(buf), "cpu%d:invlcache", i);
- intrcnt_add(buf, &ipi_invlcache_counts[i]);
- snprintf(buf, sizeof(buf), "cpu%d:preempt", i);
- intrcnt_add(buf, &ipi_preempt_counts[i]);
- snprintf(buf, sizeof(buf), "cpu%d:ast", i);
- intrcnt_add(buf, &ipi_ast_counts[i]);
- snprintf(buf, sizeof(buf), "cpu%d:rendezvous", i);
- intrcnt_add(buf, &ipi_rendezvous_counts[i]);
- snprintf(buf, sizeof(buf), "cpu%d:hardclock", i);
- intrcnt_add(buf, &ipi_hardclock_counts[i]);
- }
-}
-SYSINIT(mp_ipi_intrcnt, SI_SUB_INTR, SI_ORDER_MIDDLE, mp_ipi_intrcnt, NULL);
-#endif
-
diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC
index bdaca33960f3..c24dd5ac918b 100644
--- a/sys/amd64/conf/GENERIC
+++ b/sys/amd64/conf/GENERIC
@@ -340,7 +340,9 @@ device virtio_blk # VirtIO Block device
device virtio_scsi # VirtIO SCSI device
device virtio_balloon # VirtIO Memory Balloon device
-# HyperV drivers
+# HyperV drivers and enchancement support
+# NOTE: HYPERV depends on hyperv. They must be added or removed together.
+options HYPERV # Hyper-V kernel infrastructure
device hyperv # HyperV drivers
# Xen HVM Guest Optimizations
diff --git a/sys/amd64/conf/NOTES b/sys/amd64/conf/NOTES
index 9b697f087e0d..e0fe46577fd7 100644
--- a/sys/amd64/conf/NOTES
+++ b/sys/amd64/conf/NOTES
@@ -494,6 +494,8 @@ device virtio_balloon # VirtIO Memory Balloon device
device virtio_random # VirtIO Entropy device
device virtio_console # VirtIO Console device
+# Microsoft Hyper-V enchancement support
+options HYPERV # Hyper-V kernel infrastructure
device hyperv # HyperV drivers
# Xen HVM Guest Optimizations
diff --git a/sys/amd64/include/smp.h b/sys/amd64/include/smp.h
index 3a4b6b329c94..034a693f9fec 100644
--- a/sys/amd64/include/smp.h
+++ b/sys/amd64/include/smp.h
@@ -35,6 +35,39 @@ extern int mp_naps;
extern int boot_cpu_id;
extern struct pcb stoppcbs[];
extern int cpu_apic_ids[];
+extern int bootAP;
+extern void *dpcpu;
+extern char *bootSTK;
+extern int bootAP;
+extern void *bootstacks[];
+extern volatile u_int cpu_ipi_pending[];
+extern volatile int aps_ready;
+extern struct mtx ap_boot_mtx;
+extern int cpu_logical;
+extern int cpu_cores;
+extern int pmap_pcid_enabled;
+extern u_int xhits_gbl[];
+extern u_int xhits_pg[];
+extern u_int xhits_rng[];
+extern u_int ipi_global;
+extern u_int ipi_page;
+extern u_int ipi_range;
+extern u_int ipi_range_size;
+extern u_int ipi_masked_global;
+extern u_int ipi_masked_page;
+extern u_int ipi_masked_range;
+extern u_int ipi_masked_range_size;
+
+extern volatile int smp_tlb_wait;
+
+struct cpu_info {
+ int cpu_present:1;
+ int cpu_bsp:1;
+ int cpu_disabled:1;
+ int cpu_hyperthread:1;
+};
+extern struct cpu_info cpu_info[];
+
#ifdef COUNT_IPIS
extern u_long *ipi_invltlb_counts[MAXCPU];
extern u_long *ipi_invlrng_counts[MAXCPU];
@@ -60,9 +93,11 @@ inthand_t
struct pmap;
/* functions in mp_machdep.c */
+void assign_cpu_ids(void);
void cpu_add(u_int apic_id, char boot_cpu);
void cpustop_handler(void);
void cpususpend_handler(void);
+void init_secondary_tail(void);
void invltlb_handler(void);
void invltlb_pcid_handler(void);
void invlpg_handler(void);
@@ -77,6 +112,7 @@ void ipi_cpu(int cpu, u_int ipi);
int ipi_nmi_handler(void);
void ipi_selected(cpuset_t cpus, u_int ipi);
u_int mp_bootaddress(u_int);
+void set_interrupt_apic_ids(void);
void smp_cache_flush(void);
void smp_invlpg(struct pmap *pmap, vm_offset_t addr);
void smp_masked_invlpg(cpuset_t mask, struct pmap *pmap, vm_offset_t addr);
@@ -87,6 +123,9 @@ void smp_masked_invlpg_range(cpuset_t mask, struct pmap *pmap,
void smp_invltlb(struct pmap *pmap);
void smp_masked_invltlb(cpuset_t mask, struct pmap *pmap);
int native_start_all_aps(void);
+void mem_range_AP_init(void);
+void topo_probe(void);
+void ipi_send_cpu(int cpu, u_int ipi);
#endif /* !LOCORE */
#endif /* SMP */
diff --git a/sys/amd64/include/vm.h b/sys/amd64/include/vm.h
index 6573e3784616..22d2ecafe211 100644
--- a/sys/amd64/include/vm.h
+++ b/sys/amd64/include/vm.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2009 Advanced Computing Technologies LLC
+ * Copyright (c) 2009 Hudson River Trading LLC
* Written by: John H. Baldwin <jhb@FreeBSD.org>
* All rights reserved.
*
diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h
index 52294bd8e29c..7c617bebdf0a 100644
--- a/sys/amd64/include/vmm.h
+++ b/sys/amd64/include/vmm.h
@@ -204,13 +204,12 @@ int vm_get_x2apic_state(struct vm *vm, int vcpu, enum x2apic_state *state);
int vm_set_x2apic_state(struct vm *vm, int vcpu, enum x2apic_state state);
int vm_apicid2vcpuid(struct vm *vm, int apicid);
int vm_activate_cpu(struct vm *vm, int vcpu);
-cpuset_t vm_active_cpus(struct vm *vm);
-cpuset_t vm_suspended_cpus(struct vm *vm);
struct vm_exit *vm_exitinfo(struct vm *vm, int vcpuid);
void vm_exit_suspended(struct vm *vm, int vcpuid, uint64_t rip);
void vm_exit_rendezvous(struct vm *vm, int vcpuid, uint64_t rip);
void vm_exit_astpending(struct vm *vm, int vcpuid, uint64_t rip);
+#ifdef _SYS__CPUSET_H_
/*
* Rendezvous all vcpus specified in 'dest' and execute 'func(arg)'.
* The rendezvous 'func(arg)' is not allowed to do anything that will
@@ -228,6 +227,9 @@ void vm_exit_astpending(struct vm *vm, int vcpuid, uint64_t rip);
typedef void (*vm_rendezvous_func_t)(struct vm *vm, int vcpuid, void *arg);
void vm_smp_rendezvous(struct vm *vm, int vcpuid, cpuset_t dest,
vm_rendezvous_func_t func, void *arg);
+cpuset_t vm_active_cpus(struct vm *vm);
+cpuset_t vm_suspended_cpus(struct vm *vm);
+#endif /* _SYS__CPUSET_H_ */
static __inline int
vcpu_rendezvous_pending(void *rendezvous_cookie)
diff --git a/sys/amd64/include/xen/xenfunc.h b/sys/amd64/include/xen/xenfunc.h
index d03d4f685e24..d8a6b5c5c99b 100644
--- a/sys/amd64/include/xen/xenfunc.h
+++ b/sys/amd64/include/xen/xenfunc.h
@@ -29,12 +29,7 @@
#ifndef _XEN_XENFUNC_H_
#define _XEN_XENFUNC_H_
-#ifdef XENHVM
#include <machine/xen/xenvar.h>
-#else
-#include <machine/xen/xenpmap.h>
-#include <machine/segments.h>
-#endif
#define BKPT __asm__("int3");
#define XPQ_CALL_DEPTH 5
@@ -64,10 +59,6 @@ void _xen_machphys_update(vm_paddr_t, vm_paddr_t, char *file, int line);
#define xen_machphys_update(a, b) _xen_machphys_update((a), (b), NULL, 0)
#endif
-#ifndef XENHVM
-void xen_update_descriptor(union descriptor *, union descriptor *);
-#endif
-
extern struct mtx balloon_lock;
#if 0
#define balloon_lock(__flags) mtx_lock_irqsave(&balloon_lock, __flags)
diff --git a/sys/amd64/include/xen/xenpmap.h b/sys/amd64/include/xen/xenpmap.h
deleted file mode 100644
index d768dad5f311..000000000000
--- a/sys/amd64/include/xen/xenpmap.h
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- *
- * Copyright (c) 2004 Christian Limpach.
- * Copyright (c) 2004,2005 Kip Macy
- * 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 Christian Limpach.
- * 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.
- */
-
-
-#ifndef _XEN_XENPMAP_H_
-#define _XEN_XENPMAP_H_
-
-#include <machine/xen/features.h>
-
-void _xen_queue_pt_update(vm_paddr_t, vm_paddr_t, char *, int);
-void xen_pt_switch(vm_paddr_t);
-void xen_set_ldt(vm_paddr_t, unsigned long);
-void xen_pgdpt_pin(vm_paddr_t);
-void xen_pgd_pin(vm_paddr_t);
-void xen_pgd_unpin(vm_paddr_t);
-void xen_pt_pin(vm_paddr_t);
-void xen_pt_unpin(vm_paddr_t);
-void xen_flush_queue(void);
-void xen_check_queue(void);
-#if 0
-void pmap_ref(pt_entry_t *pte, vm_paddr_t ma);
-#endif
-
-#ifdef INVARIANTS
-#define xen_queue_pt_update(a, b) _xen_queue_pt_update((a), (b), __FILE__, __LINE__)
-#else
-#define xen_queue_pt_update(a, b) _xen_queue_pt_update((a), (b), NULL, 0)
-#endif
-
-#ifdef PMAP_DEBUG
-#define PMAP_REF pmap_ref
-#define PMAP_DEC_REF_PAGE pmap_dec_ref_page
-#define PMAP_MARK_PRIV pmap_mark_privileged
-#define PMAP_MARK_UNPRIV pmap_mark_unprivileged
-#else
-#define PMAP_MARK_PRIV(a)
-#define PMAP_MARK_UNPRIV(a)
-#define PMAP_REF(a, b)
-#define PMAP_DEC_REF_PAGE(a)
-#endif
-
-#define ALWAYS_SYNC 0
-
-#ifdef PT_DEBUG
-#define PT_LOG() printk("WP PT_SET %s:%d\n", __FILE__, __LINE__)
-#else
-#define PT_LOG()
-#endif
-
-#define INVALID_P2M_ENTRY (~0UL)
-
-#define pmap_valid_entry(E) ((E) & PG_V) /* is PDE or PTE valid? */
-
-#define SH_PD_SET_VA 1
-#define SH_PD_SET_VA_MA 2
-#define SH_PD_SET_VA_CLEAR 3
-
-struct pmap;
-void pd_set(struct pmap *pmap, int ptepindex, vm_paddr_t val, int type);
-#ifdef notyet
-static vm_paddr_t
-vptetomachpte(vm_paddr_t *pte)
-{
- vm_offset_t offset, ppte;
- vm_paddr_t pgoffset, retval, *pdir_shadow_ptr;
- int pgindex;
-
- ppte = (vm_offset_t)pte;
- pgoffset = (ppte & PAGE_MASK);
- offset = ppte - (vm_offset_t)PTmap;
- pgindex = ppte >> PDRSHIFT;
-
- pdir_shadow_ptr = (vm_paddr_t *)PCPU_GET(pdir_shadow);
- retval = (pdir_shadow_ptr[pgindex] & ~PAGE_MASK) + pgoffset;
- return (retval);
-}
-#endif
-#define PT_GET(_ptp) \
- (pmap_valid_entry(*(_ptp)) ? xpmap_mtop(*(_ptp)) : (0))
-
-#ifdef WRITABLE_PAGETABLES
-
-#define PT_SET_VA(_ptp,_npte,sync) do { \
- PMAP_REF((_ptp), xpmap_ptom(_npte)); \
- PT_LOG(); \
- *(_ptp) = xpmap_ptom((_npte)); \
-} while (/*CONSTCOND*/0)
-#define PT_SET_VA_MA(_ptp,_npte,sync) do { \
- PMAP_REF((_ptp), (_npte)); \
- PT_LOG(); \
- *(_ptp) = (_npte); \
-} while (/*CONSTCOND*/0)
-#define PT_CLEAR_VA(_ptp, sync) do { \
- PMAP_REF((pt_entry_t *)(_ptp), 0); \
- PT_LOG(); \
- *(_ptp) = 0; \
-} while (/*CONSTCOND*/0)
-
-#define PD_SET_VA(_pmap, _ptp, _npte, sync) do { \
- PMAP_REF((_ptp), xpmap_ptom(_npte)); \
- pd_set((_pmap),(_ptp),(_npte), SH_PD_SET_VA); \
- if (sync || ALWAYS_SYNC) xen_flush_queue(); \
-} while (/*CONSTCOND*/0)
-#define PD_SET_VA_MA(_pmap, _ptp, _npte, sync) do { \
- PMAP_REF((_ptp), (_npte)); \
- pd_set((_pmap),(_ptp),(_npte), SH_PD_SET_VA_MA); \
- if (sync || ALWAYS_SYNC) xen_flush_queue(); \
-} while (/*CONSTCOND*/0)
-#define PD_CLEAR_VA(_pmap, _ptp, sync) do { \
- PMAP_REF((pt_entry_t *)(_ptp), 0); \
- pd_set((_pmap),(_ptp), 0, SH_PD_SET_VA_CLEAR); \
- if (sync || ALWAYS_SYNC) xen_flush_queue(); \
-} while (/*CONSTCOND*/0)
-
-#else /* !WRITABLE_PAGETABLES */
-
-#define PT_SET_VA(_ptp,_npte,sync) do { \
- PMAP_REF((_ptp), xpmap_ptom(_npte)); \
- xen_queue_pt_update(vtomach(_ptp), \
- xpmap_ptom(_npte)); \
- if (sync || ALWAYS_SYNC) xen_flush_queue(); \
-} while (/*CONSTCOND*/0)
-#define PT_SET_VA_MA(_ptp,_npte,sync) do { \
- PMAP_REF((_ptp), (_npte)); \
- xen_queue_pt_update(vtomach(_ptp), _npte); \
- if (sync || ALWAYS_SYNC) xen_flush_queue(); \
-} while (/*CONSTCOND*/0)
-#define PT_CLEAR_VA(_ptp, sync) do { \
- PMAP_REF((pt_entry_t *)(_ptp), 0); \
- xen_queue_pt_update(vtomach(_ptp), 0); \
- if (sync || ALWAYS_SYNC) \
- xen_flush_queue(); \
-} while (/*CONSTCOND*/0)
-
-#define PD_SET_VA(_pmap, _ptepindex,_npte,sync) do { \
- PMAP_REF((_ptp), xpmap_ptom(_npte)); \
- pd_set((_pmap),(_ptepindex),(_npte), SH_PD_SET_VA); \
- if (sync || ALWAYS_SYNC) xen_flush_queue(); \
-} while (/*CONSTCOND*/0)
-#define PD_SET_VA_MA(_pmap, _ptepindex,_npte,sync) do { \
- PMAP_REF((_ptp), (_npte)); \
- pd_set((_pmap),(_ptepindex),(_npte), SH_PD_SET_VA_MA); \
- if (sync || ALWAYS_SYNC) xen_flush_queue(); \
-} while (/*CONSTCOND*/0)
-#define PD_CLEAR_VA(_pmap, _ptepindex, sync) do { \
- PMAP_REF((pt_entry_t *)(_ptp), 0); \
- pd_set((_pmap),(_ptepindex), 0, SH_PD_SET_VA_CLEAR); \
- if (sync || ALWAYS_SYNC) xen_flush_queue(); \
-} while (/*CONSTCOND*/0)
-
-#endif
-
-#define PT_SET_MA(_va, _ma) \
-do { \
- PANIC_IF(HYPERVISOR_update_va_mapping(((unsigned long)(_va)),\
- (_ma), \
- UVMF_INVLPG| UVMF_ALL) < 0); \
-} while (/*CONSTCOND*/0)
-
-#define PT_UPDATES_FLUSH() do { \
- xen_flush_queue(); \
-} while (/*CONSTCOND*/0)
-
-static __inline vm_paddr_t
-xpmap_mtop(vm_paddr_t mpa)
-{
- vm_paddr_t tmp = (mpa & PG_FRAME);
-
- return machtophys(tmp) | (mpa & ~PG_FRAME);
-}
-
-static __inline vm_paddr_t
-xpmap_ptom(vm_paddr_t ppa)
-{
- vm_paddr_t tmp = (ppa & PG_FRAME);
-
- return phystomach(tmp) | (ppa & ~PG_FRAME);
-}
-
-static __inline void
-set_phys_to_machine(unsigned long pfn, unsigned long mfn)
-{
-#ifdef notyet
- PANIC_IF(max_mapnr && pfn >= max_mapnr);
-#endif
- if (xen_feature(XENFEAT_auto_translated_physmap)) {
-#ifdef notyet
- PANIC_IF((pfn != mfn && mfn != INVALID_P2M_ENTRY));
-#endif
- return;
- }
- xen_phys_machine[pfn] = mfn;
-}
-
-
-
-
-#endif /* _XEN_XENPMAP_H_ */
diff --git a/sys/amd64/include/xen/xenvar.h b/sys/amd64/include/xen/xenvar.h
index d9dbc5d9186a..110a351bac62 100644
--- a/sys/amd64/include/xen/xenvar.h
+++ b/sys/amd64/include/xen/xenvar.h
@@ -48,68 +48,7 @@ if (xendebug_flags & argflags) XENPRINTF("(file=%s, line=%d) " _f "\n", __FILE__
#define TRACE_DEBUG(argflags, _f, _a...)
#endif
-#ifdef XENHVM
-
-static inline vm_paddr_t
-phystomach(vm_paddr_t pa)
-{
-
- return (pa);
-}
-
-static inline vm_paddr_t
-machtophys(vm_paddr_t ma)
-{
-
- return (ma);
-}
-
#define vtomach(va) pmap_kextract((vm_offset_t) (va))
-#define PFNTOMFN(pa) (pa)
-#define MFNTOPFN(ma) (ma)
-
-#define set_phys_to_machine(pfn, mfn) ((void)0)
-#define phys_to_machine_mapping_valid(pfn) (TRUE)
-#define PT_UPDATES_FLUSH() ((void)0)
-
-#else
-
-extern xen_pfn_t *xen_phys_machine;
-
-
-extern xen_pfn_t *xen_machine_phys;
-/* Xen starts physical pages after the 4MB ISA hole -
- * FreeBSD doesn't
- */
-
-
-#undef ADD_ISA_HOLE /* XXX */
-
-#ifdef ADD_ISA_HOLE
-#define ISA_INDEX_OFFSET 1024
-#define ISA_PDR_OFFSET 1
-#else
-#define ISA_INDEX_OFFSET 0
-#define ISA_PDR_OFFSET 0
-#endif
-
-
-#define PFNTOMFN(i) (xen_phys_machine[(i)])
-#define MFNTOPFN(i) ((vm_paddr_t)xen_machine_phys[(i)])
-
-#define VTOP(x) ((((uintptr_t)(x))) - KERNBASE)
-#define PTOV(x) (((uintptr_t)(x)) + KERNBASE)
-
-#define VTOPFN(x) (VTOP(x) >> PAGE_SHIFT)
-#define PFNTOV(x) PTOV((vm_paddr_t)(x) << PAGE_SHIFT)
-
-#define VTOMFN(va) (vtomach(va) >> PAGE_SHIFT)
-#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
-
-#define phystomach(pa) (((vm_paddr_t)(PFNTOMFN((pa) >> PAGE_SHIFT))) << PAGE_SHIFT)
-#define machtophys(ma) (((vm_paddr_t)(MFNTOPFN((ma) >> PAGE_SHIFT))) << PAGE_SHIFT)
-
-#endif
void xpq_init(void);
diff --git a/sys/amd64/vmm/amd/amdv.c b/sys/amd64/vmm/amd/amdv.c
index acb3a3df7d37..3157e2120beb 100644
--- a/sys/amd64/vmm/amd/amdv.c
+++ b/sys/amd64/vmm/amd/amdv.c
@@ -32,7 +32,6 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/errno.h>
-#include <sys/smp.h>
#include <machine/vmm.h>
#include "io/iommu.h"
diff --git a/sys/amd64/vmm/amd/svm.c b/sys/amd64/vmm/amd/svm.c
index f505ea1ac453..7cc13ca3fcf9 100644
--- a/sys/amd64/vmm/amd/svm.c
+++ b/sys/amd64/vmm/amd/svm.c
@@ -802,6 +802,7 @@ svm_handle_inst_emul(struct vmcb *vmcb, uint64_t gpa, struct vm_exit *vmexit)
case CPU_MODE_REAL:
vmexit->u.inst_emul.cs_base = seg.base;
vmexit->u.inst_emul.cs_d = 0;
+ break;
case CPU_MODE_PROTECTED:
case CPU_MODE_COMPATIBILITY:
vmexit->u.inst_emul.cs_base = seg.base;
diff --git a/sys/amd64/vmm/amd/svm_msr.c b/sys/amd64/vmm/amd/svm_msr.c
index 100af4b34bd9..d3a6fe8ec7c8 100644
--- a/sys/amd64/vmm/amd/svm_msr.c
+++ b/sys/amd64/vmm/amd/svm_msr.c
@@ -27,12 +27,17 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include <sys/types.h>
+#include <sys/param.h>
#include <sys/errno.h>
+#include <sys/systm.h>
#include <machine/cpufunc.h>
#include <machine/specialreg.h>
+#include <machine/vmm.h>
+#include "svm.h"
+#include "vmcb.h"
+#include "svm_softc.h"
#include "svm_msr.h"
#ifndef MSR_AMDK8_IPM
@@ -105,6 +110,14 @@ svm_rdmsr(struct svm_softc *sc, int vcpu, u_int num, uint64_t *result,
int error = 0;
switch (num) {
+ case MSR_MTRRcap:
+ case MSR_MTRRdefType:
+ case MSR_MTRR4kBase ... MSR_MTRR4kBase + 8:
+ case MSR_MTRR16kBase ... MSR_MTRR16kBase + 1:
+ case MSR_MTRR64kBase:
+ case MSR_SYSCFG:
+ *result = 0;
+ break;
case MSR_AMDK8_IPM:
*result = 0;
break;
@@ -122,6 +135,15 @@ svm_wrmsr(struct svm_softc *sc, int vcpu, u_int num, uint64_t val, bool *retu)
int error = 0;
switch (num) {
+ case MSR_MTRRcap:
+ vm_inject_gp(sc->vm, vcpu);
+ break;
+ case MSR_MTRRdefType:
+ case MSR_MTRR4kBase ... MSR_MTRR4kBase + 8:
+ case MSR_MTRR16kBase ... MSR_MTRR16kBase + 1:
+ case MSR_MTRR64kBase:
+ case MSR_SYSCFG:
+ break; /* Ignore writes */
case MSR_AMDK8_IPM:
/*
* Ignore writes to the "Interrupt Pending Message" MSR.
diff --git a/sys/amd64/vmm/amd/vmcb.c b/sys/amd64/vmm/amd/vmcb.c
index fb4b2c89b9c9..d8601690c4d2 100644
--- a/sys/amd64/vmm/amd/vmcb.c
+++ b/sys/amd64/vmm/amd/vmcb.c
@@ -29,7 +29,6 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
-#include <sys/cpuset.h>
#include <machine/segments.h>
#include <machine/specialreg.h>
diff --git a/sys/amd64/vmm/intel/vmx_msr.c b/sys/amd64/vmm/intel/vmx_msr.c
index e5177786e4a4..526b0d1db2aa 100644
--- a/sys/amd64/vmm/intel/vmx_msr.c
+++ b/sys/amd64/vmm/intel/vmx_msr.c
@@ -31,7 +31,6 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
-#include <sys/cpuset.h>
#include <machine/clock.h>
#include <machine/cpufunc.h>
@@ -396,6 +395,13 @@ vmx_rdmsr(struct vmx *vmx, int vcpuid, u_int num, uint64_t *val, bool *retu)
error = 0;
switch (num) {
+ case MSR_MTRRcap:
+ case MSR_MTRRdefType:
+ case MSR_MTRR4kBase ... MSR_MTRR4kBase + 8:
+ case MSR_MTRR16kBase ... MSR_MTRR16kBase + 1:
+ case MSR_MTRR64kBase:
+ *val = 0;
+ break;
case MSR_IA32_MISC_ENABLE:
*val = misc_enable;
break;
@@ -427,6 +433,14 @@ vmx_wrmsr(struct vmx *vmx, int vcpuid, u_int num, uint64_t val, bool *retu)
error = 0;
switch (num) {
+ case MSR_MTRRcap:
+ vm_inject_gp(vmx->vm, vcpuid);
+ break;
+ case MSR_MTRRdefType:
+ case MSR_MTRR4kBase ... MSR_MTRR4kBase + 8:
+ case MSR_MTRR16kBase ... MSR_MTRR16kBase + 1:
+ case MSR_MTRR64kBase:
+ break; /* Ignore writes */
case MSR_IA32_MISC_ENABLE:
changed = val ^ misc_enable;
/*
diff --git a/sys/amd64/vmm/io/vatpic.c b/sys/amd64/vmm/io/vatpic.c
index 0df6e7c68081..6e94f5bd9a49 100644
--- a/sys/amd64/vmm/io/vatpic.c
+++ b/sys/amd64/vmm/io/vatpic.c
@@ -30,7 +30,6 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/types.h>
#include <sys/queue.h>
-#include <sys/cpuset.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
diff --git a/sys/amd64/vmm/io/vatpit.c b/sys/amd64/vmm/io/vatpit.c
index 842253dd55dc..173ef1fdd71b 100644
--- a/sys/amd64/vmm/io/vatpit.c
+++ b/sys/amd64/vmm/io/vatpit.c
@@ -31,7 +31,6 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/types.h>
#include <sys/queue.h>
-#include <sys/cpuset.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
diff --git a/sys/amd64/vmm/io/vhpet.c b/sys/amd64/vmm/io/vhpet.c
index a4c96cd19b31..1db1c512d73b 100644
--- a/sys/amd64/vmm/io/vhpet.c
+++ b/sys/amd64/vmm/io/vhpet.c
@@ -36,7 +36,6 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/systm.h>
-#include <sys/cpuset.h>
#include <dev/acpica/acpi_hpet.h>
diff --git a/sys/amd64/vmm/io/vioapic.c b/sys/amd64/vmm/io/vioapic.c
index 411887dd02e4..e6b8b5a64222 100644
--- a/sys/amd64/vmm/io/vioapic.c
+++ b/sys/amd64/vmm/io/vioapic.c
@@ -32,7 +32,6 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/queue.h>
-#include <sys/cpuset.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/systm.h>
diff --git a/sys/amd64/vmm/io/vlapic.c b/sys/amd64/vmm/io/vlapic.c
index 70972487753b..3451e1e7f23f 100644
--- a/sys/amd64/vmm/io/vlapic.c
+++ b/sys/amd64/vmm/io/vlapic.c
@@ -547,6 +547,8 @@ vlapic_update_ppr(struct vlapic *vlapic)
VLAPIC_CTR1(vlapic, "vlapic_update_ppr 0x%02x", ppr);
}
+static VMM_STAT(VLAPIC_GRATUITOUS_EOI, "EOI without any in-service interrupt");
+
static void
vlapic_process_eoi(struct vlapic *vlapic)
{
@@ -557,11 +559,7 @@ vlapic_process_eoi(struct vlapic *vlapic)
isrptr = &lapic->isr0;
tmrptr = &lapic->tmr0;
- /*
- * The x86 architecture reserves the the first 32 vectors for use
- * by the processor.
- */
- for (i = 7; i > 0; i--) {
+ for (i = 7; i >= 0; i--) {
idx = i * 4;
bitpos = fls(isrptr[idx]);
if (bitpos-- != 0) {
@@ -570,17 +568,21 @@ vlapic_process_eoi(struct vlapic *vlapic)
vlapic->isrvec_stk_top);
}
isrptr[idx] &= ~(1 << bitpos);
+ vector = i * 32 + bitpos;
+ VCPU_CTR1(vlapic->vm, vlapic->vcpuid, "EOI vector %d",
+ vector);
VLAPIC_CTR_ISR(vlapic, "vlapic_process_eoi");
vlapic->isrvec_stk_top--;
vlapic_update_ppr(vlapic);
if ((tmrptr[idx] & (1 << bitpos)) != 0) {
- vector = i * 32 + bitpos;
vioapic_process_eoi(vlapic->vm, vlapic->vcpuid,
vector);
}
return;
}
}
+ VCPU_CTR0(vlapic->vm, vlapic->vcpuid, "Gratuitous EOI");
+ vmm_stat_incr(vlapic->vm, vlapic->vcpuid, VLAPIC_GRATUITOUS_EOI, 1);
}
static __inline int
@@ -1092,11 +1094,7 @@ vlapic_pending_intr(struct vlapic *vlapic, int *vecptr)
irrptr = &lapic->irr0;
- /*
- * The x86 architecture reserves the the first 32 vectors for use
- * by the processor.
- */
- for (i = 7; i > 0; i--) {
+ for (i = 7; i >= 0; i--) {
idx = i * 4;
val = atomic_load_acq_int(&irrptr[idx]);
bitpos = fls(val);
diff --git a/sys/amd64/vmm/io/vpmtmr.c b/sys/amd64/vmm/io/vpmtmr.c
index 09f763fe5bf7..1e7bb93d7bcc 100644
--- a/sys/amd64/vmm/io/vpmtmr.c
+++ b/sys/amd64/vmm/io/vpmtmr.c
@@ -29,7 +29,6 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/queue.h>
-#include <sys/cpuset.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/systm.h>
diff --git a/sys/amd64/vmm/io/vrtc.c b/sys/amd64/vmm/io/vrtc.c
index ab9cabb78639..18ebc4b98f8a 100644
--- a/sys/amd64/vmm/io/vrtc.c
+++ b/sys/amd64/vmm/io/vrtc.c
@@ -30,7 +30,6 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/queue.h>
-#include <sys/cpuset.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/lock.h>
@@ -63,9 +62,12 @@ struct rtcdev {
uint8_t reg_b;
uint8_t reg_c;
uint8_t reg_d;
- uint8_t nvram[128 - 14];
+ uint8_t nvram[36];
+ uint8_t century;
+ uint8_t nvram2[128 - 51];
} __packed;
CTASSERT(sizeof(struct rtcdev) == 128);
+CTASSERT(offsetof(struct rtcdev, century) == RTC_CENTURY);
struct vrtc {
struct vm *vm;
@@ -139,20 +141,23 @@ update_enabled(struct vrtc *vrtc)
}
static time_t
-vrtc_curtime(struct vrtc *vrtc)
+vrtc_curtime(struct vrtc *vrtc, sbintime_t *basetime)
{
sbintime_t now, delta;
- time_t t;
+ time_t t, secs;
KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
t = vrtc->base_rtctime;
+ *basetime = vrtc->base_uptime;
if (update_enabled(vrtc)) {
now = sbinuptime();
delta = now - vrtc->base_uptime;
KASSERT(delta >= 0, ("vrtc_curtime: uptime went backwards: "
"%#lx to %#lx", vrtc->base_uptime, now));
- t += delta / SBT_1S;
+ secs = delta / SBT_1S;
+ t += secs;
+ *basetime += secs * SBT_1S;
}
return (t);
}
@@ -245,6 +250,7 @@ secs_to_rtc(time_t rtctime, struct vrtc *vrtc, int force_update)
rtc->day_of_month = rtcset(rtc, ct.day);
rtc->month = rtcset(rtc, ct.mon);
rtc->year = rtcset(rtc, ct.year % 100);
+ rtc->century = rtcset(rtc, ct.year / 100);
}
static int
@@ -274,7 +280,7 @@ rtc_to_secs(struct vrtc *vrtc)
struct timespec ts;
struct rtcdev *rtc;
struct vm *vm;
- int error, hour, pm, year;
+ int century, error, hour, pm, year;
KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
@@ -358,10 +364,14 @@ rtc_to_secs(struct vrtc *vrtc)
VM_CTR2(vm, "Invalid RTC year %#x/%d", rtc->year, year);
goto fail;
}
- if (year >= 70)
- ct.year = 1900 + year;
- else
- ct.year = 2000 + year;
+
+ error = rtcget(rtc, rtc->century, &century);
+ ct.year = century * 100 + year;
+ if (error || ct.year < POSIX_BASE_YEAR) {
+ VM_CTR2(vm, "Invalid RTC century %#x/%d", rtc->century,
+ ct.year);
+ goto fail;
+ }
error = clock_ct_to_ts(&ct, &ts);
if (error || ts.tv_sec < 0) {
@@ -373,13 +383,19 @@ rtc_to_secs(struct vrtc *vrtc)
}
return (ts.tv_sec); /* success */
fail:
- return (VRTC_BROKEN_TIME); /* failure */
+ /*
+ * Stop updating the RTC if the date/time fields programmed by
+ * the guest are invalid.
+ */
+ VM_CTR0(vrtc->vm, "Invalid RTC date/time programming detected");
+ return (VRTC_BROKEN_TIME);
}
static int
-vrtc_time_update(struct vrtc *vrtc, time_t newtime)
+vrtc_time_update(struct vrtc *vrtc, time_t newtime, sbintime_t newbase)
{
struct rtcdev *rtc;
+ sbintime_t oldbase;
time_t oldtime;
uint8_t alarm_sec, alarm_min, alarm_hour;
@@ -391,16 +407,21 @@ vrtc_time_update(struct vrtc *vrtc, time_t newtime)
alarm_hour = rtc->alarm_hour;
oldtime = vrtc->base_rtctime;
- VM_CTR2(vrtc->vm, "Updating RTC time from %#lx to %#lx",
+ VM_CTR2(vrtc->vm, "Updating RTC secs from %#lx to %#lx",
oldtime, newtime);
+ oldbase = vrtc->base_uptime;
+ VM_CTR2(vrtc->vm, "Updating RTC base uptime from %#lx to %#lx",
+ oldbase, newbase);
+ vrtc->base_uptime = newbase;
+
if (newtime == oldtime)
return (0);
/*
* If 'newtime' indicates that RTC updates are disabled then just
* record that and return. There is no need to do alarm interrupt
- * processing or update 'base_uptime' in this case.
+ * processing in this case.
*/
if (newtime == VRTC_BROKEN_TIME) {
vrtc->base_rtctime = VRTC_BROKEN_TIME;
@@ -446,8 +467,6 @@ vrtc_time_update(struct vrtc *vrtc, time_t newtime)
if (uintr_enabled(vrtc))
vrtc_set_reg_c(vrtc, rtc->reg_c | RTCIR_UPDATE);
- vrtc->base_uptime = sbinuptime();
-
return (0);
}
@@ -518,7 +537,7 @@ static void
vrtc_callout_handler(void *arg)
{
struct vrtc *vrtc = arg;
- sbintime_t freqsbt;
+ sbintime_t freqsbt, basetime;
time_t rtctime;
int error;
@@ -540,8 +559,8 @@ vrtc_callout_handler(void *arg)
vrtc_set_reg_c(vrtc, vrtc->rtcdev.reg_c | RTCIR_PERIOD);
if (aintr_enabled(vrtc) || uintr_enabled(vrtc)) {
- rtctime = vrtc_curtime(vrtc);
- error = vrtc_time_update(vrtc, rtctime);
+ rtctime = vrtc_curtime(vrtc, &basetime);
+ error = vrtc_time_update(vrtc, rtctime, basetime);
KASSERT(error == 0, ("%s: vrtc_time_update error %d",
__func__, error));
}
@@ -606,7 +625,7 @@ static int
vrtc_set_reg_b(struct vrtc *vrtc, uint8_t newval)
{
struct rtcdev *rtc;
- sbintime_t oldfreq, newfreq;
+ sbintime_t oldfreq, newfreq, basetime;
time_t curtime, rtctime;
int error;
uint8_t oldval, changed;
@@ -627,19 +646,13 @@ vrtc_set_reg_b(struct vrtc *vrtc, uint8_t newval)
if (changed & RTCSB_HALT) {
if ((newval & RTCSB_HALT) == 0) {
rtctime = rtc_to_secs(vrtc);
+ basetime = sbinuptime();
if (rtctime == VRTC_BROKEN_TIME) {
- /*
- * Stop updating the RTC if the date/time
- * programmed by the guest is not correct.
- */
- VM_CTR0(vrtc->vm, "Invalid RTC date/time "
- "programming detected");
-
if (rtc_flag_broken_time)
return (-1);
}
} else {
- curtime = vrtc_curtime(vrtc);
+ curtime = vrtc_curtime(vrtc, &basetime);
KASSERT(curtime == vrtc->base_rtctime, ("%s: mismatch "
"between vrtc basetime (%#lx) and curtime (%#lx)",
__func__, vrtc->base_rtctime, curtime));
@@ -658,7 +671,7 @@ vrtc_set_reg_b(struct vrtc *vrtc, uint8_t newval)
rtctime = VRTC_BROKEN_TIME;
rtc->reg_b &= ~RTCSB_UINTR;
}
- error = vrtc_time_update(vrtc, rtctime);
+ error = vrtc_time_update(vrtc, rtctime, basetime);
KASSERT(error == 0, ("vrtc_time_update error %d", error));
}
@@ -738,7 +751,7 @@ vrtc_set_time(struct vm *vm, time_t secs)
vrtc = vm_rtc(vm);
VRTC_LOCK(vrtc);
- error = vrtc_time_update(vrtc, secs);
+ error = vrtc_time_update(vrtc, secs, sbinuptime());
VRTC_UNLOCK(vrtc);
if (error) {
@@ -755,11 +768,12 @@ time_t
vrtc_get_time(struct vm *vm)
{
struct vrtc *vrtc;
+ sbintime_t basetime;
time_t t;
vrtc = vm_rtc(vm);
VRTC_LOCK(vrtc);
- t = vrtc_curtime(vrtc);
+ t = vrtc_curtime(vrtc, &basetime);
VRTC_UNLOCK(vrtc);
return (t);
@@ -777,7 +791,7 @@ vrtc_nvram_write(struct vm *vm, int offset, uint8_t value)
* Don't allow writes to RTC control registers or the date/time fields.
*/
if (offset < offsetof(struct rtcdev, nvram[0]) ||
- offset >= sizeof(struct rtcdev)) {
+ offset == RTC_CENTURY || offset >= sizeof(struct rtcdev)) {
VM_CTR1(vrtc->vm, "RTC nvram write to invalid offset %d",
offset);
return (EINVAL);
@@ -796,6 +810,7 @@ int
vrtc_nvram_read(struct vm *vm, int offset, uint8_t *retval)
{
struct vrtc *vrtc;
+ sbintime_t basetime;
time_t curtime;
uint8_t *ptr;
@@ -811,8 +826,8 @@ vrtc_nvram_read(struct vm *vm, int offset, uint8_t *retval)
/*
* Update RTC date/time fields if necessary.
*/
- if (offset < 10) {
- curtime = vrtc_curtime(vrtc);
+ if (offset < 10 || offset == RTC_CENTURY) {
+ curtime = vrtc_curtime(vrtc, &basetime);
secs_to_rtc(curtime, vrtc, 0);
}
@@ -852,6 +867,7 @@ vrtc_data_handler(struct vm *vm, int vcpuid, bool in, int port, int bytes,
{
struct vrtc *vrtc;
struct rtcdev *rtc;
+ sbintime_t basetime;
time_t curtime;
int error, offset;
@@ -869,16 +885,20 @@ vrtc_data_handler(struct vm *vm, int vcpuid, bool in, int port, int bytes,
}
error = 0;
- curtime = vrtc_curtime(vrtc);
- vrtc_time_update(vrtc, curtime);
+ curtime = vrtc_curtime(vrtc, &basetime);
+ vrtc_time_update(vrtc, curtime, basetime);
- if (in) {
- /*
- * Update RTC date/time fields if necessary.
- */
- if (offset < 10)
- secs_to_rtc(curtime, vrtc, 0);
+ /*
+ * Update RTC date/time fields if necessary.
+ *
+ * This is not just for reads of the RTC. The side-effect of writing
+ * the century byte requires other RTC date/time fields (e.g. sec)
+ * to be updated here.
+ */
+ if (offset < 10 || offset == RTC_CENTURY)
+ secs_to_rtc(curtime, vrtc, 0);
+ if (in) {
if (offset == 12) {
/*
* XXX
@@ -922,6 +942,18 @@ vrtc_data_handler(struct vm *vm, int vcpuid, bool in, int port, int bytes,
*((uint8_t *)rtc + offset) = *val;
break;
}
+
+ /*
+ * XXX some guests (e.g. OpenBSD) write the century byte
+ * outside of RTCSB_HALT so re-calculate the RTC date/time.
+ */
+ if (offset == RTC_CENTURY && !rtc_halted(vrtc)) {
+ curtime = rtc_to_secs(vrtc);
+ error = vrtc_time_update(vrtc, curtime, sbinuptime());
+ KASSERT(!error, ("vrtc_time_update error %d", error));
+ if (curtime == VRTC_BROKEN_TIME && rtc_flag_broken_time)
+ error = -1;
+ }
}
VRTC_UNLOCK(vrtc);
return (error);
@@ -971,7 +1003,7 @@ vrtc_init(struct vm *vm)
VRTC_LOCK(vrtc);
vrtc->base_rtctime = VRTC_BROKEN_TIME;
- vrtc_time_update(vrtc, curtime);
+ vrtc_time_update(vrtc, curtime, sbinuptime());
secs_to_rtc(curtime, vrtc, 0);
VRTC_UNLOCK(vrtc);
diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c
index 6bd5bce1f05b..bca9b98adc7e 100644
--- a/sys/amd64/vmm/vmm.c
+++ b/sys/amd64/vmm/vmm.c
@@ -1293,8 +1293,12 @@ vm_handle_inst_emul(struct vm *vm, int vcpuid, bool *retu)
else if (error != 0)
panic("%s: vmm_fetch_instruction error %d", __func__, error);
- if (vmm_decode_instruction(vm, vcpuid, gla, cpu_mode, cs_d, vie) != 0)
- return (EFAULT);
+ if (vmm_decode_instruction(vm, vcpuid, gla, cpu_mode, cs_d, vie) != 0) {
+ VCPU_CTR1(vm, vcpuid, "Error decoding instruction at %#lx",
+ vme->rip + cs_base);
+ *retu = true; /* dump instruction bytes in userspace */
+ return (0);
+ }
/*
* If the instruction length was not specified then update it now
diff --git a/sys/amd64/vmm/vmm_instruction_emul.c b/sys/amd64/vmm/vmm_instruction_emul.c
index 0b50e923239e..71723654d54f 100644
--- a/sys/amd64/vmm/vmm_instruction_emul.c
+++ b/sys/amd64/vmm/vmm_instruction_emul.c
@@ -72,6 +72,8 @@ enum {
VIE_OP_TYPE_POP,
VIE_OP_TYPE_MOVS,
VIE_OP_TYPE_GROUP1,
+ VIE_OP_TYPE_STOS,
+ VIE_OP_TYPE_BITTEST,
VIE_OP_TYPE_LAST
};
@@ -91,6 +93,11 @@ static const struct vie_op two_byte_opcodes[256] = {
.op_byte = 0xB7,
.op_type = VIE_OP_TYPE_MOVZX,
},
+ [0xBA] = {
+ .op_byte = 0xBA,
+ .op_type = VIE_OP_TYPE_BITTEST,
+ .op_flags = VIE_OP_F_IMM8,
+ },
[0xBE] = {
.op_byte = 0xBE,
.op_type = VIE_OP_TYPE_MOVSX,
@@ -146,6 +153,16 @@ static const struct vie_op one_byte_opcodes[256] = {
.op_type = VIE_OP_TYPE_MOVS,
.op_flags = VIE_OP_F_NO_MODRM | VIE_OP_F_NO_GLA_VERIFICATION
},
+ [0xAA] = {
+ .op_byte = 0xAA,
+ .op_type = VIE_OP_TYPE_STOS,
+ .op_flags = VIE_OP_F_NO_MODRM | VIE_OP_F_NO_GLA_VERIFICATION
+ },
+ [0xAB] = {
+ .op_byte = 0xAB,
+ .op_type = VIE_OP_TYPE_STOS,
+ .op_flags = VIE_OP_F_NO_MODRM | VIE_OP_F_NO_GLA_VERIFICATION
+ },
[0xC6] = {
/* XXX Group 11 extended opcode - not just MOV */
.op_byte = 0xC6,
@@ -803,6 +820,68 @@ done:
}
static int
+emulate_stos(void *vm, int vcpuid, uint64_t gpa, struct vie *vie,
+ struct vm_guest_paging *paging, mem_region_read_t memread,
+ mem_region_write_t memwrite, void *arg)
+{
+ int error, opsize, repeat;
+ uint64_t val;
+ uint64_t rcx, rdi, rflags;
+
+ opsize = (vie->op.op_byte == 0xAA) ? 1 : vie->opsize;
+ repeat = vie->repz_present | vie->repnz_present;
+
+ if (repeat) {
+ error = vie_read_register(vm, vcpuid, VM_REG_GUEST_RCX, &rcx);
+ KASSERT(!error, ("%s: error %d getting rcx", __func__, error));
+
+ /*
+ * The count register is %rcx, %ecx or %cx depending on the
+ * address size of the instruction.
+ */
+ if ((rcx & vie_size2mask(vie->addrsize)) == 0)
+ return (0);
+ }
+
+ error = vie_read_register(vm, vcpuid, VM_REG_GUEST_RAX, &val);
+ KASSERT(!error, ("%s: error %d getting rax", __func__, error));
+
+ error = memwrite(vm, vcpuid, gpa, val, opsize, arg);
+ if (error)
+ return (error);
+
+ error = vie_read_register(vm, vcpuid, VM_REG_GUEST_RDI, &rdi);
+ KASSERT(error == 0, ("%s: error %d getting rdi", __func__, error));
+
+ error = vie_read_register(vm, vcpuid, VM_REG_GUEST_RFLAGS, &rflags);
+ KASSERT(error == 0, ("%s: error %d getting rflags", __func__, error));
+
+ if (rflags & PSL_D)
+ rdi -= opsize;
+ else
+ rdi += opsize;
+
+ error = vie_update_register(vm, vcpuid, VM_REG_GUEST_RDI, rdi,
+ vie->addrsize);
+ KASSERT(error == 0, ("%s: error %d updating rdi", __func__, error));
+
+ if (repeat) {
+ rcx = rcx - 1;
+ error = vie_update_register(vm, vcpuid, VM_REG_GUEST_RCX,
+ rcx, vie->addrsize);
+ KASSERT(!error, ("%s: error %d updating rcx", __func__, error));
+
+ /*
+ * Repeat the instruction if the count register is not zero.
+ */
+ if ((rcx & vie_size2mask(vie->addrsize)) != 0)
+ vm_restart_instruction(vm, vcpuid);
+ }
+
+ return (0);
+}
+
+static int
emulate_and(void *vm, int vcpuid, uint64_t gpa, struct vie *vie,
mem_region_read_t memread, mem_region_write_t memwrite, void *arg)
{
@@ -1262,6 +1341,48 @@ emulate_group1(void *vm, int vcpuid, uint64_t gpa, struct vie *vie,
return (error);
}
+static int
+emulate_bittest(void *vm, int vcpuid, uint64_t gpa, struct vie *vie,
+ mem_region_read_t memread, mem_region_write_t memwrite, void *memarg)
+{
+ uint64_t val, rflags;
+ int error, bitmask, bitoff;
+
+ /*
+ * 0F BA is a Group 8 extended opcode.
+ *
+ * Currently we only emulate the 'Bit Test' instruction which is
+ * identified by a ModR/M:reg encoding of 100b.
+ */
+ if ((vie->reg & 7) != 4)
+ return (EINVAL);
+
+ error = vie_read_register(vm, vcpuid, VM_REG_GUEST_RFLAGS, &rflags);
+ KASSERT(error == 0, ("%s: error %d getting rflags", __func__, error));
+
+ error = memread(vm, vcpuid, gpa, &val, vie->opsize, memarg);
+ if (error)
+ return (error);
+
+ /*
+ * Intel SDM, Vol 2, Table 3-2:
+ * "Range of Bit Positions Specified by Bit Offset Operands"
+ */
+ bitmask = vie->opsize * 8 - 1;
+ bitoff = vie->immediate & bitmask;
+
+ /* Copy the bit into the Carry flag in %rflags */
+ if (val & (1UL << bitoff))
+ rflags |= PSL_C;
+ else
+ rflags &= ~PSL_C;
+
+ error = vie_update_register(vm, vcpuid, VM_REG_GUEST_RFLAGS, rflags, 8);
+ KASSERT(error == 0, ("%s: error %d updating rflags", __func__, error));
+
+ return (0);
+}
+
int
vmm_emulate_instruction(void *vm, int vcpuid, uint64_t gpa, struct vie *vie,
struct vm_guest_paging *paging, mem_region_read_t memread,
@@ -1302,6 +1423,10 @@ vmm_emulate_instruction(void *vm, int vcpuid, uint64_t gpa, struct vie *vie,
error = emulate_movs(vm, vcpuid, gpa, vie, paging, memread,
memwrite, memarg);
break;
+ case VIE_OP_TYPE_STOS:
+ error = emulate_stos(vm, vcpuid, gpa, vie, paging, memread,
+ memwrite, memarg);
+ break;
case VIE_OP_TYPE_AND:
error = emulate_and(vm, vcpuid, gpa, vie,
memread, memwrite, memarg);
@@ -1314,6 +1439,10 @@ vmm_emulate_instruction(void *vm, int vcpuid, uint64_t gpa, struct vie *vie,
error = emulate_sub(vm, vcpuid, gpa, vie,
memread, memwrite, memarg);
break;
+ case VIE_OP_TYPE_BITTEST:
+ error = emulate_bittest(vm, vcpuid, gpa, vie,
+ memread, memwrite, memarg);
+ break;
default:
error = EINVAL;
break;
diff --git a/sys/amd64/vmm/vmm_ioport.c b/sys/amd64/vmm/vmm_ioport.c
index fc68a6160739..63044e81402f 100644
--- a/sys/amd64/vmm/vmm_ioport.c
+++ b/sys/amd64/vmm/vmm_ioport.c
@@ -28,16 +28,10 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/cpuset.h>
#include <sys/systm.h>
-#include <vm/vm.h>
-
#include <machine/vmm.h>
#include <machine/vmm_instruction_emul.h>
-#include <x86/psl.h>
#include "vatpic.h"
#include "vatpit.h"
diff --git a/sys/amd64/vmm/vmm_stat.c b/sys/amd64/vmm/vmm_stat.c
index 9ecf9afd8a81..4ae5fb9132cc 100644
--- a/sys/amd64/vmm/vmm_stat.c
+++ b/sys/amd64/vmm/vmm_stat.c
@@ -33,7 +33,6 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/malloc.h>
-#include <sys/smp.h>
#include <machine/vmm.h>
#include "vmm_util.h"
diff --git a/sys/amd64/vmm/x86.c b/sys/amd64/vmm/x86.c
index c37d21c6e1bb..45e08b562ced 100644
--- a/sys/amd64/vmm/x86.c
+++ b/sys/amd64/vmm/x86.c
@@ -32,7 +32,6 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/pcpu.h>
#include <sys/systm.h>
-#include <sys/cpuset.h>
#include <sys/sysctl.h>
#include <machine/clock.h>
@@ -289,9 +288,8 @@ x86_emulate_cpuid(struct vm *vm, int vcpu_id,
/*
* Machine check handling is done in the host.
- * Hide MTRR capability.
*/
- regs[3] &= ~(CPUID_MCA | CPUID_MCE | CPUID_MTRR);
+ regs[3] &= ~(CPUID_MCA | CPUID_MCE);
/*
* Hide the debug store capability.
diff --git a/sys/arm/allwinner/std.a10 b/sys/arm/allwinner/std.a10
index 0084c41ee70c..da5d895352aa 100644
--- a/sys/arm/allwinner/std.a10
+++ b/sys/arm/allwinner/std.a10
@@ -17,5 +17,7 @@ options KERNPHYSADDR=0x40200000
makeoptions KERNVIRTADDR=0xc0200000
options KERNVIRTADDR=0xc0200000
+options ARM_L2_PIPT
+
files "../allwinner/files.allwinner"
files "../allwinner/files.a10"
diff --git a/sys/arm/amlogic/aml8726/aml8726_mmc.c b/sys/arm/amlogic/aml8726/aml8726_mmc.c
index 167d3a3311c3..7d1ef4ea0d67 100644
--- a/sys/arm/amlogic/aml8726/aml8726_mmc.c
+++ b/sys/arm/amlogic/aml8726/aml8726_mmc.c
@@ -70,6 +70,7 @@ struct aml8726_mmc_softc {
device_t dev;
struct resource *res[2];
struct mtx mtx;
+ struct callout ch;
uint32_t port;
unsigned int ref_freq;
struct aml8726_mmc_gpio pwr_en;
@@ -81,7 +82,7 @@ struct aml8726_mmc_softc {
struct mmc_host host;
int bus_busy;
struct mmc_command *cmd;
- unsigned int timeout_remaining;
+ uint32_t stop_timeout;
};
static struct resource_spec aml8726_mmc_spec[] = {
@@ -92,6 +93,7 @@ static struct resource_spec aml8726_mmc_spec[] = {
#define AML_MMC_LOCK(sc) mtx_lock(&(sc)->mtx)
#define AML_MMC_UNLOCK(sc) mtx_unlock(&(sc)->mtx)
+#define AML_MMC_LOCK_ASSERT(sc) mtx_assert(&(sc)->mtx, MA_OWNED)
#define AML_MMC_LOCK_INIT(sc) \
mtx_init(&(sc)->mtx, device_get_nameunit((sc)->dev), \
"mmc", MTX_DEF)
@@ -107,6 +109,10 @@ static struct resource_spec aml8726_mmc_spec[] = {
#define PWR_OFF_FLAG(pol) ((pol) == 0 ? GPIO_PIN_HIGH : \
GPIO_PIN_LOW)
+#define MSECS_TO_TICKS(ms) (((ms)*hz)/1000 + 1)
+
+static void aml8726_mmc_timeout(void *arg);
+
static unsigned int
aml8726_mmc_clk(phandle_t node)
{
@@ -126,6 +132,37 @@ aml8726_mmc_clk(phandle_t node)
return ((unsigned int)prop);
}
+static uint32_t
+aml8726_mmc_freq(struct aml8726_mmc_softc *sc, uint32_t divisor)
+{
+
+ return (sc->ref_freq / ((divisor + 1) * 2));
+}
+
+static uint32_t
+aml8726_mmc_div(struct aml8726_mmc_softc *sc, uint32_t desired_freq)
+{
+ uint32_t divisor;
+
+ divisor = sc->ref_freq / (desired_freq * 2);
+
+ if (divisor == 0)
+ divisor = 1;
+
+ divisor -= 1;
+
+ if (aml8726_mmc_freq(sc, divisor) > desired_freq)
+ divisor += 1;
+
+ if (divisor > (AML_MMC_CONFIG_CMD_CLK_DIV_MASK >>
+ AML_MMC_CONFIG_CMD_CLK_DIV_SHIFT)) {
+ divisor = AML_MMC_CONFIG_CMD_CLK_DIV_MASK >>
+ AML_MMC_CONFIG_CMD_CLK_DIV_SHIFT;
+ }
+
+ return (divisor);
+}
+
static void
aml8726_mmc_mapmem(void *arg, bus_dma_segment_t *segs, int nseg, int error)
{
@@ -162,25 +199,18 @@ aml8726_mmc_power_on(struct aml8726_mmc_softc *sc)
PWR_ON_FLAG(sc->pwr_en.pol)));
}
-static int
-aml8726_mmc_restart_timer(struct aml8726_mmc_softc *sc)
+static void
+aml8726_mmc_soft_reset(struct aml8726_mmc_softc *sc, boolean_t enable_irq)
{
- uint32_t count;
- uint32_t isr;
-
- if (sc->cmd == NULL || sc->timeout_remaining == 0)
- return (0);
-
- count = (sc->timeout_remaining > 0x1fff) ? 0x1fff :
- sc->timeout_remaining;
- sc->timeout_remaining -= count;
+ uint32_t icr;
- isr = (count << AML_MMC_IRQ_STATUS_TIMER_CNT_SHIFT) |
- AML_MMC_IRQ_STATUS_TIMER_EN | AML_MMC_IRQ_STATUS_TIMEOUT_IRQ;
+ icr = AML_MMC_IRQ_CONFIG_SOFT_RESET;
- CSR_WRITE_4(sc, AML_MMC_IRQ_STATUS_REG, isr);
+ if (enable_irq == true)
+ icr |= AML_MMC_IRQ_CONFIG_CMD_DONE_EN;
- return (1);
+ CSR_WRITE_4(sc, AML_MMC_IRQ_CONFIG_REG, icr);
+ CSR_BARRIER(sc, AML_MMC_IRQ_CONFIG_REG);
}
static int
@@ -191,7 +221,6 @@ aml8726_mmc_start_command(struct aml8726_mmc_softc *sc, struct mmc_command *cmd)
uint32_t block_size;
uint32_t bus_width;
uint32_t cmdr;
- uint32_t cycles_per_msec;
uint32_t extr;
uint32_t mcfgr;
uint32_t nbits_per_pkg;
@@ -203,14 +232,9 @@ aml8726_mmc_start_command(struct aml8726_mmc_softc *sc, struct mmc_command *cmd)
return (MMC_ERR_INVALID);
/*
- * Ensure the hardware state machine is in a known state,
- * the command done interrupt is enabled, and previous
- * IRQ status bits have been cleared.
+ * Ensure the hardware state machine is in a known state.
*/
- CSR_WRITE_4(sc, AML_MMC_IRQ_CONFIG_REG,
- (AML_MMC_IRQ_CONFIG_SOFT_RESET | AML_MMC_IRQ_CONFIG_CMD_DONE_EN));
- CSR_BARRIER(sc, AML_MMC_IRQ_CONFIG_REG);
- CSR_WRITE_4(sc, AML_MMC_IRQ_STATUS_REG, AML_MMC_IRQ_STATUS_CLEAR_IRQ);
+ aml8726_mmc_soft_reset(sc, true);
/*
* Start and transmission bits are per section 4.7.2 of the:
@@ -225,6 +249,13 @@ aml8726_mmc_start_command(struct aml8726_mmc_softc *sc, struct mmc_command *cmd)
mcfgr = sc->port;
timeout = AML_MMC_CMD_TIMEOUT;
+ /*
+ * If this is a linked command, then use the previous timeout.
+ */
+ if (cmd == cmd->mrq->stop && sc->stop_timeout)
+ timeout = sc->stop_timeout;
+ sc->stop_timeout = 0;
+
if ((cmd->flags & MMC_RSP_136) != 0) {
cmdr |= AML_MMC_CMD_RESP_CRC7_FROM_8;
cmdr |= (133 << AML_MMC_CMD_RESP_BITS_SHIFT);
@@ -291,32 +322,24 @@ aml8726_mmc_start_command(struct aml8726_mmc_softc *sc, struct mmc_command *cmd)
timeout = AML_MMC_WRITE_TIMEOUT *
(data->len / block_size);
}
+
+ /*
+ * Stop terminates a multiblock read / write and thus
+ * can take as long to execute as an actual read / write.
+ */
+ if (cmd->mrq->stop != NULL)
+ sc->stop_timeout = timeout;
}
sc->cmd = cmd;
cmd->error = MMC_ERR_NONE;
- /*
- * Round up while calculating the number of cycles which
- * correspond to a millisecond. Use that to determine
- * the count from the desired timeout in milliseconds.
- *
- * The counter has a limited range which is not sufficient
- * for directly implementing worst case timeouts at high clock
- * rates so a 32 bit counter is implemented in software.
- *
- * The documentation isn't clear on when the timer starts
- * so add 48 cycles for the command and 136 cycles for the
- * response (the values are from the previously mentioned
- * standard).
- */
if (timeout > AML_MMC_MAX_TIMEOUT)
timeout = AML_MMC_MAX_TIMEOUT;
- cycles_per_msec = (ios->clock + 1000 - 1) / 1000;
- sc->timeout_remaining = 48 + 136 + timeout * cycles_per_msec;
- aml8726_mmc_restart_timer(sc);
+ callout_reset(&sc->ch, MSECS_TO_TICKS(timeout),
+ aml8726_mmc_timeout, sc);
CSR_WRITE_4(sc, AML_MMC_CMD_ARGUMENT_REG, cmd->arg);
CSR_WRITE_4(sc, AML_MMC_MULT_CONFIG_REG, mcfgr);
@@ -330,20 +353,96 @@ aml8726_mmc_start_command(struct aml8726_mmc_softc *sc, struct mmc_command *cmd)
}
static void
-aml8726_mmc_intr(void *arg)
+aml8726_mmc_finish_command(struct aml8726_mmc_softc *sc, int mmc_error)
{
- struct aml8726_mmc_softc *sc = (struct aml8726_mmc_softc *)arg;
+ int mmc_stop_error;
struct mmc_command *cmd;
struct mmc_command *stop_cmd;
struct mmc_data *data;
+
+ AML_MMC_LOCK_ASSERT(sc);
+
+ /* Clear all interrupts since the request is no longer in flight. */
+ CSR_WRITE_4(sc, AML_MMC_IRQ_STATUS_REG, AML_MMC_IRQ_STATUS_CLEAR_IRQ);
+ CSR_BARRIER(sc, AML_MMC_IRQ_STATUS_REG);
+
+ /* In some cases (e.g. finish called via timeout) this is a NOP. */
+ callout_stop(&sc->ch);
+
+ cmd = sc->cmd;
+ sc->cmd = NULL;
+
+ cmd->error = mmc_error;
+
+ data = cmd->data;
+
+ if (data && data->len &&
+ (data->flags & (MMC_DATA_READ | MMC_DATA_WRITE)) != 0) {
+ if ((data->flags & MMC_DATA_READ) != 0)
+ bus_dmamap_sync(sc->dmatag, sc->dmamap,
+ BUS_DMASYNC_POSTREAD);
+ else
+ bus_dmamap_sync(sc->dmatag, sc->dmamap,
+ BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(sc->dmatag, sc->dmamap);
+ }
+
+ /*
+ * If there's a linked stop command, then start the stop command.
+ * In order to establish a known state attempt the stop command
+ * even if the original request encountered an error.
+ */
+
+ stop_cmd = (cmd->mrq->stop != cmd) ? cmd->mrq->stop : NULL;
+
+ if (stop_cmd != NULL) {
+ mmc_stop_error = aml8726_mmc_start_command(sc, stop_cmd);
+ if (mmc_stop_error == MMC_ERR_NONE) {
+ AML_MMC_UNLOCK(sc);
+ return;
+ }
+ stop_cmd->error = mmc_stop_error;
+ }
+
+ AML_MMC_UNLOCK(sc);
+
+ /* Execute the callback after dropping the lock. */
+ if (cmd->mrq)
+ cmd->mrq->done(cmd->mrq);
+}
+
+static void
+aml8726_mmc_timeout(void *arg)
+{
+ struct aml8726_mmc_softc *sc = (struct aml8726_mmc_softc *)arg;
+
+ /*
+ * The command failed to complete in time so forcefully
+ * terminate it.
+ */
+ aml8726_mmc_soft_reset(sc, false);
+
+ /*
+ * Ensure the command has terminated before continuing on
+ * to things such as bus_dmamap_sync / bus_dmamap_unload.
+ */
+ while ((CSR_READ_4(sc, AML_MMC_IRQ_STATUS_REG) &
+ AML_MMC_IRQ_STATUS_CMD_BUSY) != 0)
+ cpu_spinwait();
+
+ aml8726_mmc_finish_command(sc, MMC_ERR_TIMEOUT);
+}
+
+static void
+aml8726_mmc_intr(void *arg)
+{
+ struct aml8726_mmc_softc *sc = (struct aml8726_mmc_softc *)arg;
uint32_t cmdr;
- uint32_t icr;
uint32_t isr;
uint32_t mcfgr;
uint32_t previous_byte;
uint32_t resp;
int mmc_error;
- int mmc_stop_error;
unsigned int i;
AML_MMC_LOCK(sc);
@@ -367,12 +466,6 @@ aml8726_mmc_intr(void *arg)
if ((cmdr & AML_MMC_CMD_CMD_HAS_DATA) != 0 &&
(isr & AML_MMC_IRQ_STATUS_WR_CRC16_OK) == 0)
mmc_error = MMC_ERR_BADCRC;
- } else if ((isr & AML_MMC_IRQ_STATUS_TIMEOUT_IRQ) != 0) {
- if (aml8726_mmc_restart_timer(sc) != 0) {
- AML_MMC_UNLOCK(sc);
- return;
- }
- mmc_error = MMC_ERR_TIMEOUT;
} else {
spurious:
@@ -389,49 +482,12 @@ spurious:
return;
}
- if ((isr & AML_MMC_IRQ_STATUS_CMD_BUSY) != 0 &&
- /*
- * A multiblock operation may keep the hardware
- * busy until stop transmission is executed.
- */
- (isr & AML_MMC_IRQ_STATUS_CMD_DONE_IRQ) == 0) {
- if (mmc_error == MMC_ERR_NONE)
- mmc_error = MMC_ERR_FAILED;
-
- /*
- * Issue a soft reset (while leaving the command complete
- * interrupt enabled) to terminate the command.
- *
- * Ensure the command has terminated before continuing on
- * to things such as bus_dmamap_sync / bus_dmamap_unload.
- */
-
- icr = AML_MMC_IRQ_CONFIG_SOFT_RESET |
- AML_MMC_IRQ_CONFIG_CMD_DONE_EN;
-
- CSR_WRITE_4(sc, AML_MMC_IRQ_CONFIG_REG, icr);
-
- while ((CSR_READ_4(sc, AML_MMC_IRQ_STATUS_REG) &
- AML_MMC_IRQ_STATUS_CMD_BUSY) != 0)
- cpu_spinwait();
- }
-
- /* Clear all interrupts since the request is no longer in flight. */
- CSR_WRITE_4(sc, AML_MMC_IRQ_STATUS_REG, AML_MMC_IRQ_STATUS_CLEAR_IRQ);
- CSR_BARRIER(sc, AML_MMC_IRQ_STATUS_REG);
-
- cmd = sc->cmd;
- sc->cmd = NULL;
-
- cmd->error = mmc_error;
-
- if ((cmd->flags & MMC_RSP_PRESENT) != 0 &&
- mmc_error == MMC_ERR_NONE) {
+ if ((cmdr & AML_MMC_CMD_RESP_BITS_MASK) != 0) {
mcfgr = sc->port;
mcfgr |= AML_MMC_MULT_CONFIG_RESP_READOUT_EN;
CSR_WRITE_4(sc, AML_MMC_MULT_CONFIG_REG, mcfgr);
- if ((cmd->flags & MMC_RSP_136) != 0) {
+ if ((cmdr & AML_MMC_CMD_RESP_CRC7_FROM_8) != 0) {
/*
* Controller supplies 135:8 instead of
@@ -444,48 +500,39 @@ spurious:
for (i = 0; i < 4; i++) {
resp = CSR_READ_4(sc, AML_MMC_CMD_ARGUMENT_REG);
- cmd->resp[3 - i] = (resp << 8) | previous_byte;
+ sc->cmd->resp[3 - i] = (resp << 8) |
+ previous_byte;
previous_byte = (resp >> 24) & 0xff;
}
} else
- cmd->resp[0] = CSR_READ_4(sc, AML_MMC_CMD_ARGUMENT_REG);
+ sc->cmd->resp[0] = CSR_READ_4(sc,
+ AML_MMC_CMD_ARGUMENT_REG);
}
- data = cmd->data;
-
- if (data && data->len &&
- (data->flags & (MMC_DATA_READ | MMC_DATA_WRITE)) != 0) {
- if ((data->flags & MMC_DATA_READ) != 0)
- bus_dmamap_sync(sc->dmatag, sc->dmamap,
- BUS_DMASYNC_POSTREAD);
- else
- bus_dmamap_sync(sc->dmatag, sc->dmamap,
- BUS_DMASYNC_POSTWRITE);
- bus_dmamap_unload(sc->dmatag, sc->dmamap);
- }
+ if ((isr & AML_MMC_IRQ_STATUS_CMD_BUSY) != 0 &&
+ /*
+ * A multiblock operation may keep the hardware
+ * busy until stop transmission is executed.
+ */
+ (isr & AML_MMC_IRQ_STATUS_CMD_DONE_IRQ) == 0) {
+ if (mmc_error == MMC_ERR_NONE)
+ mmc_error = MMC_ERR_FAILED;
- /*
- * If there's a linked stop command, then start the stop command.
- * In order to establish a known state attempt the stop command
- * even if the original request encountered an error.
- */
+ /*
+ * Issue a soft reset to terminate the command.
+ *
+ * Ensure the command has terminated before continuing on
+ * to things such as bus_dmamap_sync / bus_dmamap_unload.
+ */
- stop_cmd = (cmd->mrq->stop != cmd) ? cmd->mrq->stop : NULL;
+ aml8726_mmc_soft_reset(sc, false);
- if (stop_cmd != NULL) {
- mmc_stop_error = aml8726_mmc_start_command(sc, stop_cmd);
- if (mmc_stop_error == MMC_ERR_NONE) {
- AML_MMC_UNLOCK(sc);
- return;
- }
- stop_cmd->error = mmc_stop_error;
+ while ((CSR_READ_4(sc, AML_MMC_IRQ_STATUS_REG) &
+ AML_MMC_IRQ_STATUS_CMD_BUSY) != 0)
+ cpu_spinwait();
}
- AML_MMC_UNLOCK(sc);
-
- /* Execute the callback after dropping the lock. */
- if (cmd->mrq)
- cmd->mrq->done(cmd->mrq);
+ aml8726_mmc_finish_command(sc, mmc_error);
}
static int
@@ -698,8 +745,10 @@ aml8726_mmc_attach(device_t dev)
goto fail;
}
- sc->host.f_min = 200000;
- sc->host.f_max = 50000000;
+ callout_init_mtx(&sc->ch, &sc->mtx, CALLOUT_RETURNUNLOCKED);
+
+ sc->host.f_min = aml8726_mmc_freq(sc, aml8726_mmc_div(sc, 200000));
+ sc->host.f_max = aml8726_mmc_freq(sc, aml8726_mmc_div(sc, 50000000));
sc->host.host_ocr = sc->voltages[0] | sc->voltages[1];
sc->host.caps = MMC_CAP_4_BIT_DATA | MMC_CAP_HSPEED;
@@ -756,10 +805,12 @@ aml8726_mmc_detach(device_t dev)
* disable the interrupts, and clear the interrupts.
*/
(void)aml8726_mmc_power_off(sc);
- CSR_WRITE_4(sc, AML_MMC_IRQ_CONFIG_REG, AML_MMC_IRQ_CONFIG_SOFT_RESET);
- CSR_BARRIER(sc, AML_MMC_IRQ_CONFIG_REG);
+ aml8726_mmc_soft_reset(sc, false);
CSR_WRITE_4(sc, AML_MMC_IRQ_STATUS_REG, AML_MMC_IRQ_STATUS_CLEAR_IRQ);
+ /* This should be a NOP since no command was in flight. */
+ callout_stop(&sc->ch);
+
AML_MMC_UNLOCK(sc);
bus_generic_detach(dev);
@@ -787,8 +838,7 @@ aml8726_mmc_shutdown(device_t dev)
* disable the interrupts, and clear the interrupts.
*/
(void)aml8726_mmc_power_off(sc);
- CSR_WRITE_4(sc, AML_MMC_IRQ_CONFIG_REG, AML_MMC_IRQ_CONFIG_SOFT_RESET);
- CSR_BARRIER(sc, AML_MMC_IRQ_CONFIG_REG);
+ aml8726_mmc_soft_reset(sc, false);
CSR_WRITE_4(sc, AML_MMC_IRQ_STATUS_REG, AML_MMC_IRQ_STATUS_CLEAR_IRQ);
return (0);
@@ -799,7 +849,6 @@ aml8726_mmc_update_ios(device_t bus, device_t child)
{
struct aml8726_mmc_softc *sc = device_get_softc(bus);
struct mmc_ios *ios = &sc->host.ios;
- unsigned int divisor;
int error;
int i;
uint32_t cfgr;
@@ -820,15 +869,8 @@ aml8726_mmc_update_ios(device_t bus, device_t child)
return (EINVAL);
}
- divisor = sc->ref_freq / (ios->clock * 2) - 1;
- if (divisor == 0 || divisor == -1)
- divisor = 1;
- if ((sc->ref_freq / ((divisor + 1) * 2)) > ios->clock)
- divisor += 1;
- if (divisor > 0x3ff)
- divisor = 0x3ff;
-
- cfgr |= divisor;
+ cfgr |= aml8726_mmc_div(sc, ios->clock) <<
+ AML_MMC_CONFIG_CMD_CLK_DIV_SHIFT;
CSR_WRITE_4(sc, AML_MMC_CONFIG_REG, cfgr);
diff --git a/sys/arm/amlogic/aml8726/aml8726_mmc.h b/sys/arm/amlogic/aml8726/aml8726_mmc.h
index 0370943e6cf5..64e3baefaf72 100644
--- a/sys/arm/amlogic/aml8726/aml8726_mmc.h
+++ b/sys/arm/amlogic/aml8726/aml8726_mmc.h
@@ -47,20 +47,6 @@
#define AML_MMC_WRITE_TIMEOUT 500
#define AML_MMC_MAX_TIMEOUT 5000
-/*
- * Internally the timeout is implemented by counting clock cycles.
- *
- * Since the hardware implements timeouts by counting cycles
- * the minimum read / write timeout (assuming the minimum
- * conversion factor of 1 cycle per usec) is:
- *
- * (8 bits * 512 bytes per block + 16 bits CRC) = 4112 usec
- */
-#if ((AML_MMC_READ_TIMEOUT * 1000) < 4112 || \
- (AML_MMC_WRITE_TIMEOUT * 1000) < 4112)
-#error "Single block timeout is smaller than supported"
-#endif
-
#define AML_MMC_CMD_ARGUMENT_REG 0
#define AML_MMC_CMD_SEND_REG 4
diff --git a/sys/arm/amlogic/aml8726/files.aml8726 b/sys/arm/amlogic/aml8726/files.aml8726
index b32ebcdf449f..ca058a519ed6 100644
--- a/sys/arm/amlogic/aml8726/files.aml8726
+++ b/sys/arm/amlogic/aml8726/files.aml8726
@@ -4,12 +4,13 @@ kern/kern_clocksource.c standard
arm/arm/bus_space_base.c standard
arm/arm/bus_space_generic.c standard
-arm/arm/bus_space_asm_generic.S standard
+arm/arm/gic.c standard
arm/arm/pl310.c standard
arm/amlogic/aml8726/aml8726_l2cache.c standard
arm/amlogic/aml8726/aml8726_machdep.c standard
+arm/amlogic/aml8726/aml8726_mp.c optional smp
arm/amlogic/aml8726/aml8726_identsoc.c standard
arm/amlogic/aml8726/aml8726_ccm.c standard
arm/amlogic/aml8726/aml8726_clkmsr.c standard
diff --git a/sys/arm/amlogic/aml8726/files.smp b/sys/arm/amlogic/aml8726/files.smp
deleted file mode 100644
index 9b6c6ab07427..000000000000
--- a/sys/arm/amlogic/aml8726/files.smp
+++ /dev/null
@@ -1,4 +0,0 @@
-#$FreeBSD$
-
-arm/arm/gic.c standard
-arm/amlogic/aml8726/aml8726_mp.c standard
diff --git a/sys/arm/amlogic/aml8726/std.aml8726 b/sys/arm/amlogic/aml8726/std.aml8726
index 073f02cd2449..61b515f75f9c 100644
--- a/sys/arm/amlogic/aml8726/std.aml8726
+++ b/sys/arm/amlogic/aml8726/std.aml8726
@@ -4,6 +4,15 @@ cpu CPU_CORTEXA
machine arm armv6
makeoptions CONF_CFLAGS="-march=armv7a"
+# Physical memory starts at 0x80000000. We assume the kernel is loaded
+# at 0x80100000 by u-boot (which doesn't support ubldr since it's missing
+# CONFIG_API). The kernel must be supplied as a binary since u-boot is
+# also missing CONFIG_CMD_ELF.
+#
+#
+options KERNVIRTADDR=0xc0100000 # Used in ldscript.arm
+makeoptions KERNVIRTADDR=0xc0100000
+
device fdt_pinctrl
files "../amlogic/aml8726/files.aml8726"
diff --git a/sys/arm/amlogic/aml8726/std.odroidc1 b/sys/arm/amlogic/aml8726/std.odroidc1
deleted file mode 100644
index 441c135b21c1..000000000000
--- a/sys/arm/amlogic/aml8726/std.odroidc1
+++ /dev/null
@@ -1,17 +0,0 @@
-# $FreeBSD$
-
-include "../amlogic/aml8726/std.aml8726"
-
-makeoptions FDT_DTS_FILE=odroidc1.dts
-
-options SMP # Enable multiple cores
-files "../amlogic/aml8726/files.smp"
-
-# Physical memory starts at 0x00000000. We assume the kernel is loaded
-# at 0x00100000 by u-boot (which doesn't support ubldr since it's missing
-# CONFIG_API). The kernel must be supplied as a binary since u-boot is
-# also missing CONFIG_CMD_ELF.
-#
-#
-options KERNVIRTADDR=0xc0100000 # Used in ldscript.arm
-makeoptions KERNVIRTADDR=0xc0100000
diff --git a/sys/arm/amlogic/aml8726/std.vsatv102-m6 b/sys/arm/amlogic/aml8726/std.vsatv102-m6
deleted file mode 100644
index e0014a48c459..000000000000
--- a/sys/arm/amlogic/aml8726/std.vsatv102-m6
+++ /dev/null
@@ -1,17 +0,0 @@
-# $FreeBSD$
-
-include "../amlogic/aml8726/std.aml8726"
-
-makeoptions FDT_DTS_FILE=vsatv102-m6.dts
-
-options SMP # Enable multiple cores
-files "../amlogic/aml8726/files.smp"
-
-# Physical memory starts at 0x80000000. We assume the kernel is loaded
-# at 0x80100000 by u-boot (which doesn't support ubldr since it's missing
-# CONFIG_API). The kernel must be supplied as a binary since u-boot is
-# also missing CONFIG_CMD_ELF.
-#
-#
-options KERNVIRTADDR=0xc0100000 # Used in ldscript.arm
-makeoptions KERNVIRTADDR=0xc0100000
diff --git a/sys/arm/arm/busdma_machdep-v6.c b/sys/arm/arm/busdma_machdep-v6.c
index ed501c50af32..7236c5a54c1f 100644
--- a/sys/arm/arm/busdma_machdep-v6.c
+++ b/sys/arm/arm/busdma_machdep-v6.c
@@ -1685,8 +1685,8 @@ add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr,
if (dmat->flags & BUS_DMA_KEEP_PG_OFFSET) {
/* Page offset needs to be preserved. */
- bpage->vaddr |= vaddr & PAGE_MASK;
- bpage->busaddr |= vaddr & PAGE_MASK;
+ bpage->vaddr |= addr & PAGE_MASK;
+ bpage->busaddr |= addr & PAGE_MASK;
}
bpage->datavaddr = vaddr;
bpage->dataaddr = addr;
diff --git a/sys/arm/arm/busdma_machdep.c b/sys/arm/arm/busdma_machdep.c
index 265292d20494..acd8f81ec128 100644
--- a/sys/arm/arm/busdma_machdep.c
+++ b/sys/arm/arm/busdma_machdep.c
@@ -1441,8 +1441,8 @@ add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr,
if (dmat->flags & BUS_DMA_KEEP_PG_OFFSET) {
/* Page offset needs to be preserved. */
- bpage->vaddr |= vaddr & PAGE_MASK;
- bpage->busaddr |= vaddr & PAGE_MASK;
+ bpage->vaddr |= addr & PAGE_MASK;
+ bpage->busaddr |= addr & PAGE_MASK;
}
bpage->datavaddr = vaddr;
bpage->dataaddr = addr;
diff --git a/sys/arm/arm/cpufunc.c b/sys/arm/arm/cpufunc.c
index f98e91aa57cc..a3c82395124d 100644
--- a/sys/arm/arm/cpufunc.c
+++ b/sys/arm/arm/cpufunc.c
@@ -1186,7 +1186,8 @@ arm11x6_setup(void)
CPU_CONTROL_32BD_ENABLE |
CPU_CONTROL_LABT_ENABLE |
CPU_CONTROL_SYST_ENABLE |
- CPU_CONTROL_IC_ENABLE;
+ CPU_CONTROL_IC_ENABLE |
+ CPU_CONTROL_UNAL_ENABLE;
/*
* "write as existing" bits
diff --git a/sys/arm/arm/locore-v4.S b/sys/arm/arm/locore-v4.S
index 8ef53e93fa00..d798e97d7ff7 100644
--- a/sys/arm/arm/locore-v4.S
+++ b/sys/arm/arm/locore-v4.S
@@ -116,7 +116,7 @@ ASENTRY_NP(_start)
* If we're running with MMU disabled, test against the
* physical address instead.
*/
- mrc p15, 0, r2, c1, c0, 0
+ mrc p15, 0, r2, c1, c0, 0
ands r2, r2, #CPU_CONTROL_MMU_ENABLE
ldreq r6, =PHYSADDR
ldrne r6, =LOADERRAMADDR
@@ -125,7 +125,7 @@ ASENTRY_NP(_start)
cmp r7, pc
bhi from_ram
b do_copy
-
+
flash_lower:
cmp r6, pc
bls from_ram
@@ -148,12 +148,12 @@ from_ram:
disable_mmu:
/* Disable MMU for a while */
- mrc p15, 0, r2, c1, c0, 0
+ mrc p15, 0, r2, c1, c0, 0
bic r2, r2, #(CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE |\
CPU_CONTROL_WBUF_ENABLE)
bic r2, r2, #(CPU_CONTROL_IC_ENABLE)
bic r2, r2, #(CPU_CONTROL_BPRD_ENABLE)
- mcr p15, 0, r2, c1, c0, 0
+ mcr p15, 0, r2, c1, c0, 0
nop
nop
@@ -169,36 +169,16 @@ Lunmapped:
adr r0, Lpagetable
bl translate_va_to_pa
-#ifndef _ARM_ARCH_6
/*
* Some of the older ports (the various XScale, mostly) assume
* that the memory before the kernel is mapped, and use it for
- * the various stacks, page tables, etc. For those CPUs, map the
- * 64 first MB of RAM, as it used to be.
+ * the various stacks, page tables, etc. For those CPUs, map the
+ * 64 first MB of RAM, as it used to be.
*/
/*
* Map PA == VA
- */
- ldr r5, =PHYSADDR
- mov r1, r5
- mov r2, r5
- /* Map 64MiB, preserved over calls to build_pagetables */
- mov r3, #64
- bl build_pagetables
-
- /* Create the kernel map to jump to */
- mov r1, r5
- ldr r2, =(KERNBASE)
- bl build_pagetables
- ldr r5, =(KERNPHYSADDR)
-#else
- /*
- * Map PA == VA
- */
- /* Find the start kernels load address */
- adr r5, _start
- ldr r2, =(L1_S_OFFSET)
- bic r5, r2
+ */
+ ldr r5, =PHYSADDR
mov r1, r5
mov r2, r5
/* Map 64MiB, preserved over calls to build_pagetables */
@@ -207,10 +187,10 @@ Lunmapped:
/* Create the kernel map to jump to */
mov r1, r5
- ldr r2, =(KERNVIRTADDR)
+ ldr r2, =(KERNBASE)
bl build_pagetables
-#endif
-
+ ldr r5, =(KERNPHYSADDR)
+
#if defined(SOCDEV_PA) && defined(SOCDEV_VA)
/* Create the custom map */
ldr r1, =SOCDEV_PA
@@ -221,26 +201,16 @@ Lunmapped:
mcr p15, 0, r0, c2, c0, 0 /* Set TTB */
mcr p15, 0, r0, c8, c7, 0 /* Flush TLB */
-#if defined(CPU_ARM1136) || defined(CPU_ARM1176) || defined(CPU_CORTEXA) || defined(CPU_MV_PJ4B) || defined(CPU_KRAIT)
- mov r0, #0
- mcr p15, 0, r0, c13, c0, 1 /* Set ASID to 0 */
-#endif
-
/* Set the Domain Access register. Very important! */
- mov r0, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT)
+ mov r0, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT)
mcr p15, 0, r0, c3, c0, 0
- /*
+ /*
* Enable MMU.
* On armv6 enable extended page tables, and set alignment checking
* to modulo-4 (CPU_CONTROL_UNAL_ENABLE) for the ldrd/strd
* instructions emitted by clang.
*/
mrc p15, 0, r0, c1, c0, 0
-#ifdef _ARM_ARCH_6
- orr r0, r0, #(CPU_CONTROL_V6_EXTPAGE | CPU_CONTROL_UNAL_ENABLE)
- orr r0, r0, #(CPU_CONTROL_AFLT_ENABLE)
- orr r0, r0, #(CPU_CONTROL_AF_ENABLE)
-#endif
orr r0, r0, #(CPU_CONTROL_MMU_ENABLE)
mcr p15, 0, r0, c1, c0, 0
nop
@@ -280,7 +250,7 @@ virt_done:
/* init arm will return the new stack pointer. */
mov sp, r0
- bl _C_LABEL(mi_startup) /* call mi_startup()! */
+ bl _C_LABEL(mi_startup) /* call mi_startup()! */
adr r0, .Lmainreturned
b _C_LABEL(panic)
@@ -389,11 +359,11 @@ pagetable:
.word _C_LABEL(cpufuncs)
ENTRY_NP(cpu_halt)
- mrs r2, cpsr
+ mrs r2, cpsr
bic r2, r2, #(PSR_MODE)
- orr r2, r2, #(PSR_SVC32_MODE)
+ orr r2, r2, #(PSR_SVC32_MODE)
orr r2, r2, #(PSR_I | PSR_F)
- msr cpsr_fsxc, r2
+ msr cpsr_fsxc, r2
ldr r4, .Lcpu_reset_address
ldr r4, [r4]
@@ -419,9 +389,9 @@ ENTRY_NP(cpu_halt)
* Hurl ourselves into the ROM
*/
mov r0, #(CPU_CONTROL_32BP_ENABLE | CPU_CONTROL_32BD_ENABLE)
- mcr p15, 0, r0, c1, c0, 0
- mcrne p15, 0, r2, c8, c7, 0 /* nail I+D TLB on ARMv4 and greater */
- mov pc, r4
+ mcr p15, 0, r0, c1, c0, 0
+ mcrne p15, 0, r2, c8, c7, 0 /* nail I+D TLB on ARMv4 and greater */
+ mov pc, r4
/*
* _cpu_reset_address contains the address to branch to, to complete
@@ -458,7 +428,7 @@ ENTRY(longjmp)
END(longjmp)
.data
- .global _C_LABEL(esym)
+ .global _C_LABEL(esym)
_C_LABEL(esym): .word _C_LABEL(end)
ENTRY_NP(abort)
@@ -471,7 +441,7 @@ ENTRY_NP(sigcode)
/*
* Call the sigreturn system call.
- *
+ *
* We have to load r7 manually rather than using
* "ldr r7, =SYS_sigreturn" to ensure the value of szsigcode is
* correct. Using the alternative places esigcode at the address
diff --git a/sys/arm/arm/locore-v6.S b/sys/arm/arm/locore-v6.S
index 55b4311fb935..7d5ba9704ae7 100644
--- a/sys/arm/arm/locore-v6.S
+++ b/sys/arm/arm/locore-v6.S
@@ -39,7 +39,7 @@
__FBSDID("$FreeBSD$");
-#ifndef ARM_NEW_PMAP
+#ifndef ARM_NEW_PMAP
#define PTE1_OFFSET L1_S_OFFSET
#define PTE1_SHIFT L1_S_SHIFT
#define PTE1_SIZE L1_S_SIZE
@@ -52,13 +52,13 @@ __FBSDID("$FreeBSD$");
.align 2
/*
- * On entry for FreeBSD boot ABI:
- * r0 - metadata pointer or 0 (boothowto on AT91's boot2)
- * r1 - if (r0 == 0) then metadata pointer
- * On entry for Linux boot ABI:
+ * On entry for FreeBSD boot ABI:
+ * r0 - metadata pointer or 0 (boothowto on AT91's boot2)
+ * r1 - if (r0 == 0) then metadata pointer
+ * On entry for Linux boot ABI:
* r0 - 0
* r1 - machine type (passed as arg2 to initarm)
- * r2 - Pointer to a tagged list or dtb image (phys addr) (passed as arg1 initarm)
+ * r2 - Pointer to a tagged list or dtb image (phys addr) (passed as arg1 initarm)
*
* For both types of boot we gather up the args, put them in a struct arm_boot_params
* structure and pass that to initarm.
@@ -66,17 +66,17 @@ __FBSDID("$FreeBSD$");
.globl btext
btext:
ASENTRY_NP(_start)
- STOP_UNWINDING /* Can't unwind into the bootloader! */
+ STOP_UNWINDING /* Can't unwind into the bootloader! */
- /* Make sure interrupts are disabled. */
+ /* Make sure interrupts are disabled. */
cpsid ifa
- mov r8, r0 /* 0 or boot mode from boot2 */
- mov r9, r1 /* Save Machine type */
- mov r10, r2 /* Save meta data */
+ mov r8, r0 /* 0 or boot mode from boot2 */
+ mov r9, r1 /* Save Machine type */
+ mov r10, r2 /* Save meta data */
mov r11, r3 /* Future expansion */
- /*
+ /*
* Check whether data cache is enabled. If it is, then we know
* current tags are valid (not power-on garbage values) and there
* might be dirty lines that need cleaning. Disable cache to prevent
@@ -93,7 +93,7 @@ ASENTRY_NP(_start)
* valid. Disable all caches and the MMU, and invalidate everything
* before setting up new page tables and re-enabling the mmu.
*/
-1:
+1:
bic r7, #CPU_CONTROL_DC_ENABLE
bic r7, #CPU_CONTROL_MMU_ENABLE
bic r7, #CPU_CONTROL_IC_ENABLE
@@ -119,13 +119,13 @@ ASENTRY_NP(_start)
/*
* Map PA == VA
*/
- /* Find the start kernels load address */
+ /* Find the start kernels load address */
adr r5, _start
ldr r2, =(PTE1_OFFSET)
bic r5, r2
mov r1, r5
mov r2, r5
- /* Map 64MiB, preserved over calls to build_pagetables */
+ /* Map 64MiB, preserved over calls to build_pagetables */
mov r3, #64
bl build_pagetables
@@ -142,41 +142,41 @@ ASENTRY_NP(_start)
#endif
bl init_mmu
- /* Switch to virtual addresses. */
+ /* Switch to virtual addresses. */
ldr pc, =1f
1:
- /* Setup stack, clear BSS */
+ /* Setup stack, clear BSS */
ldr r1, =.Lstart
ldmia r1, {r1, r2, sp} /* Set initial stack and */
add sp, sp, #INIT_ARM_STACK_SIZE
- sub r2, r2, r1 /* get zero init data */
+ sub r2, r2, r1 /* get zero init data */
mov r3, #0
2:
str r3, [r1], #0x0004 /* get zero init data */
- subs r2, r2, #4
+ subs r2, r2, #4
bgt 2b
- mov r1, #28 /* loader info size is 28 bytes also second arg */
- subs sp, sp, r1 /* allocate arm_boot_params struct on stack */
- mov r0, sp /* loader info pointer is first arg */
- bic sp, sp, #7 /* align stack to 8 bytes */
- str r1, [r0] /* Store length of loader info */
+ mov r1, #28 /* loader info size is 28 bytes also second arg */
+ subs sp, sp, r1 /* allocate arm_boot_params struct on stack */
+ mov r0, sp /* loader info pointer is first arg */
+ bic sp, sp, #7 /* align stack to 8 bytes */
+ str r1, [r0] /* Store length of loader info */
str r8, [r0, #4] /* Store r0 from boot loader */
str r9, [r0, #8] /* Store r1 from boot loader */
str r10, [r0, #12] /* store r2 from boot loader */
str r11, [r0, #16] /* store r3 from boot loader */
str r5, [r0, #20] /* store the physical address */
- adr r4, Lpagetable /* load the pagetable address */
+ adr r4, Lpagetable /* load the pagetable address */
ldr r5, [r4, #4]
str r5, [r0, #24] /* store the pagetable address */
mov fp, #0 /* trace back starts here */
bl _C_LABEL(initarm) /* Off we go */
- /* init arm will return the new stack pointer. */
+ /* init arm will return the new stack pointer. */
mov sp, r0
- bl _C_LABEL(mi_startup) /* call mi_startup()! */
+ bl _C_LABEL(mi_startup) /* call mi_startup()! */
ldr r0, =.Lmainreturned
b _C_LABEL(panic)
@@ -219,8 +219,8 @@ translate_va_to_pa:
mov pc, lr
/*
- * Init MMU
- * r0 - The table base address
+ * Init MMU
+ * r0 - the table base address
*/
ASENTRY_NP(init_mmu)
@@ -267,11 +267,11 @@ END(init_mmu)
/*
- * Init SMP coherent mode, enable caching and switch to final MMU table.
- * Called with disabled caches
- * r0 - The table base address
- * r1 - clear bits for aux register
- * r2 - set bits for aux register
+ * Init SMP coherent mode, enable caching and switch to final MMU table.
+ * Called with disabled caches
+ * r0 - The table base address
+ * r1 - clear bits for aux register
+ * r2 - set bits for aux register
*/
ASENTRY_NP(reinit_mmu)
push {r4-r11, lr}
@@ -331,11 +331,11 @@ END(reinit_mmu)
/*
* Builds the page table
- * r0 - The table base address
- * r1 - The physical address (trashed)
- * r2 - The virtual address (trashed)
- * r3 - The number of 1MiB sections
- * r4 - Trashed
+ * r0 - The table base address
+ * r1 - The physical address (trashed)
+ * r2 - The virtual address (trashed)
+ * r3 - The number of 1MiB sections
+ * r4 - Trashed
*
* Addresses must be 1MiB aligned
*/
@@ -350,15 +350,15 @@ build_pagetables:
#endif
orr r1, r4
- /* Move the virtual address to the correct bit location */
+ /* Move the virtual address to the correct bit location */
lsr r2, #(PTE1_SHIFT - 2)
mov r4, r3
1:
str r1, [r0, r2]
- add r2, r2, #4
- add r1, r1, #(PTE1_SIZE)
- adds r4, r4, #-1
+ add r2, r2, #4
+ add r1, r1, #(PTE1_SIZE)
+ adds r4, r4, #-1
bhi 1b
mov pc, lr
@@ -372,7 +372,7 @@ VA_TO_PA_POINTER(Lpagetable, boot_pt1)
.word svcstk /* must remain in order together. */
.Lmainreturned:
- .asciz "main() returned"
+ .asciz "main() returned"
.align 2
.bss
@@ -380,8 +380,8 @@ svcstk:
.space INIT_ARM_STACK_SIZE * MAXCPU
/*
- * Memory for the initial pagetable. We are unable to place this in
- * the bss as this will be cleared after the table is loaded.
+ * Memory for the initial pagetable. We are unable to place this in
+ * the bss as this will be cleared after the table is loaded.
*/
.section ".init_pagetable"
.align 14 /* 16KiB aligned */
@@ -398,7 +398,7 @@ boot_pt1:
#if defined(SMP)
ASENTRY_NP(mpentry)
- /* Make sure interrupts are disabled. */
+ /* Make sure interrupts are disabled. */
cpsid ifa
/* Setup core, disable all caches. */
@@ -419,10 +419,10 @@ ASENTRY_NP(mpentry)
mcr CP15_ICIALLU
ISB
- /* Find the delta between VA and PA */
+ /* Find the delta between VA and PA */
adr r0, Lpagetable
bl translate_va_to_pa
-
+
bl init_mmu
adr r1, .Lstart+8 /* Get initstack pointer from */
@@ -433,7 +433,7 @@ ASENTRY_NP(mpentry)
mul r2, r1, r0 /* Point sp to initstack */
add sp, sp, r2 /* area for this processor. */
- /* Switch to virtual addresses. */
+ /* Switch to virtual addresses. */
ldr pc, =1f
1:
mov fp, #0 /* trace back starts here */
@@ -459,14 +459,14 @@ ENTRY_NP(cpu_halt)
ldr r4, [r4]
teq r4, #0
movne pc, r4
-1:
+1:
WFI
b 1b
/*
* _cpu_reset_address contains the address to branch to, to complete
* the cpu reset after turning the MMU off
- * This variable is provided by the hardware specific code
+ * This variable is provided by the hardware specific code
*/
.Lcpu_reset_address:
.word _C_LABEL(cpu_reset_address)
@@ -498,38 +498,37 @@ END(abort)
ENTRY_NP(sigcode)
mov r0, sp
- add r0, r0, #SIGF_UC
+ add r0, r0, #SIGF_UC
/*
- * Call the sigreturn system call.
+ * Call the sigreturn system call.
*
* We have to load r7 manually rather than using
- * "ldr r7, =SYS_sigreturn" to ensure the value of szsigcode is
+ * "ldr r7, =SYS_sigreturn" to ensure the value of szsigcode is
* correct. Using the alternative places esigcode at the address
- * of the data rather than the address one past the data.
+ * of the data rather than the address one past the data.
*/
- ldr r7, [pc, #12] /* Load SYS_sigreturn */
+ ldr r7, [pc, #12] /* Load SYS_sigreturn */
swi SYS_sigreturn
- /* Well if that failed we better exit quick ! */
+ /* Well if that failed we better exit quick ! */
- ldr r7, [pc, #8] /* Load SYS_exit */
+ ldr r7, [pc, #8] /* Load SYS_exit */
swi SYS_exit
- /* Branch back to retry SYS_sigreturn */
+ /* Branch back to retry SYS_sigreturn */
b . - 16
END(sigcode)
-
.word SYS_sigreturn
.word SYS_exit
.align 2
- .global _C_LABEL(esigcode)
+ .global _C_LABEL(esigcode)
_C_LABEL(esigcode):
.data
- .global szsigcode
+ .global szsigcode
szsigcode:
.long esigcode-sigcode
diff --git a/sys/arm/arm/pmap-v6-new.c b/sys/arm/arm/pmap-v6-new.c
index 53896d4ea5df..f4042141aec6 100644
--- a/sys/arm/arm/pmap-v6-new.c
+++ b/sys/arm/arm/pmap-v6-new.c
@@ -6094,13 +6094,13 @@ pmap_set_pcb_pagedir(pmap_t pmap, struct pcb *pcb)
/*
- * Clean L1 data cache range on a single page, which is not mapped yet.
+ * Clean L1 data cache range by physical address.
+ * The range must be within a single page.
*/
static void
pmap_dcache_wb_pou(vm_paddr_t pa, vm_size_t size, vm_memattr_t ma)
{
struct sysmaps *sysmaps;
- vm_offset_t va;
KASSERT(((pa & PAGE_MASK) + size) <= PAGE_SIZE,
("%s: not on single page", __func__));
@@ -6111,9 +6111,8 @@ pmap_dcache_wb_pou(vm_paddr_t pa, vm_size_t size, vm_memattr_t ma)
if (*sysmaps->CMAP3)
panic("%s: CMAP3 busy", __func__);
pte2_store(sysmaps->CMAP3, PTE2_KERN_NG(pa, PTE2_AP_KRW, ma));
- va = (vm_offset_t)sysmaps->CADDR3;
- tlb_flush_local(va);
- dcache_wb_pou(va, size);
+ tlb_flush_local((vm_offset_t)sysmaps->CADDR3);
+ dcache_wb_pou((vm_offset_t)sysmaps->CADDR3 + (pa & PAGE_MASK), size);
pte2_clear(sysmaps->CMAP3);
sched_unpin();
mtx_unlock(&sysmaps->lock);
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_mbox.c b/sys/arm/broadcom/bcm2835/bcm2835_mbox.c
index 2ab7ebf91a20..af600cac3448 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_mbox.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_mbox.c
@@ -306,8 +306,7 @@ bcm2835_mbox_init_dma(device_t dev, size_t len, bus_dma_tag_t *tag,
return (NULL);
}
- err = bus_dmamap_load(*tag, *map, buf,
- sizeof(struct msg_set_power_state), bcm2835_mbox_dma_cb,
+ err = bus_dmamap_load(*tag, *map, buf, len, bcm2835_mbox_dma_cb,
phys, 0);
if (err != 0) {
bus_dmamem_free(*tag, buf, *map);
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c b/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c
index 19eeb7170cf1..1024a48e7fa2 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c
@@ -181,17 +181,16 @@ bcm_sdhci_attach(device_t dev)
if (err == 0) {
/* Convert to MHz */
default_freq /= 1000000;
- if (bootverbose)
- device_printf(dev, "default frequency: %dMHz\n",
- default_freq);
+ }
+ if (default_freq == 0) {
+ node = ofw_bus_get_node(sc->sc_dev);
+ if ((OF_getencprop(node, "clock-frequency", &cell,
+ sizeof(cell))) > 0)
+ default_freq = cell / 1000000;
}
if (default_freq == 0)
default_freq = BCM2835_DEFAULT_SDHCI_FREQ;
- node = ofw_bus_get_node(sc->sc_dev);
- if ((OF_getprop(node, "clock-frequency", &cell, sizeof(cell))) > 0)
- default_freq = fdt32_to_cpu(cell)/1000000;
-
if (bootverbose)
device_printf(dev, "SDHCI frequency: %dMHz\n", default_freq);
diff --git a/sys/arm/broadcom/bcm2835/std.bcm2836 b/sys/arm/broadcom/bcm2835/std.bcm2836
index 874083fd3e03..bb112bec424d 100644
--- a/sys/arm/broadcom/bcm2835/std.bcm2836
+++ b/sys/arm/broadcom/bcm2835/std.bcm2836
@@ -5,6 +5,8 @@ cpu CPU_CORTEXA
makeoptions CONF_CFLAGS="-march=armv7a"
options SOC_BCM2836
+options ARM_L2_PIPT
+
files "../broadcom/bcm2835/files.bcm2836"
files "../broadcom/bcm2835/files.bcm283x"
diff --git a/sys/arm/conf/AML8726 b/sys/arm/conf/AML8726
new file mode 100644
index 000000000000..7272db4b08a2
--- /dev/null
+++ b/sys/arm/conf/AML8726
@@ -0,0 +1,143 @@
+#
+# Kernel configuration for Amlogic aml8726 boards.
+#
+# For more information on this file, please read the config(5) manual page,
+# and/or the handbook section on Kernel Configuration Files:
+#
+# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
+#
+# The handbook is also available locally in /usr/share/doc/handbook
+# if you've installed the doc distribution, otherwise always see the
+# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the
+# latest information.
+#
+# An exhaustive list of options and more detailed explanations of the
+# device lines is also present in the ../../conf/NOTES and NOTES files.
+# If you are in doubt as to the purpose or necessity of a line, check first
+# in NOTES.
+#
+# $FreeBSD$
+
+ident AML8726
+include "../amlogic/aml8726/std.aml8726"
+
+options HZ=100
+options SCHED_ULE # ULE scheduler
+options PREEMPTION # Enable kernel thread preemption
+options INET # InterNETworking
+options INET6 # IPv6 communications protocols
+options SCTP # Stream Control Transmission Protocol
+options FFS # Berkeley Fast Filesystem
+options SOFTUPDATES # Enable FFS soft updates support
+options UFS_ACL # Support for access control lists
+options UFS_DIRHASH # Improve performance on big directories
+options UFS_GJOURNAL # Enable gjournal-based UFS journaling
+options QUOTA # Enable disk quotas for UFS
+options NFSCL # Network Filesystem Client
+options NFSLOCKD # Network Lock Manager
+options NFS_ROOT # NFS usable as /, requires NFSCL
+options MSDOSFS # MSDOS Filesystem
+options CD9660 # ISO 9660 Filesystem
+options PROCFS # Process filesystem (requires PSEUDOFS)
+options PSEUDOFS # Pseudo-filesystem framework
+options TMPFS # Efficient memory filesystem
+options GEOM_PART_GPT # GUID Partition Tables
+options GEOM_PART_BSD # BSD partition scheme
+options GEOM_PART_MBR # MBR partition scheme
+options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!]
+options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
+options KTRACE # ktrace(1) support
+options SYSVSHM # SYSV-style shared memory
+options SYSVMSG # SYSV-style message queues
+options SYSVSEM # SYSV-style semaphores
+options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options PRINTF_BUFR_SIZE=128 # Prevent printf output being interspersed.
+options KBD_INSTALL_CDEV # install a CDEV entry in /dev
+options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
+options LINUX_BOOT_ABI
+options VFP # Enable floating point hardware support
+options SMP # Enable multiple cores
+
+# Debugging
+makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
+options ALT_BREAK_TO_DEBUGGER
+#options VERBOSE_SYSINIT # Enable verbose sysinit messages
+options BOOTVERBOSE=1
+options KDB # Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+#options KDB_TRACE # Print a stack trace for a panic
+# For full debugger support use this instead:
+options DDB # Enable the kernel debugger
+options INVARIANTS # Enable calls of extra sanity checking
+options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
+options WITNESS # Enable checks to detect deadlocks and cycles
+options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
+#options DIAGNOSTIC
+
+# NFS root from boopt/dhcp
+#options BOOTP
+#options BOOTP_NFSROOT
+#options BOOTP_COMPAT
+#options BOOTP_NFSV3
+#options BOOTP_WIRED_TO=axe0
+
+# MMC/SD/SDIO Card slot support
+device mmc # mmc/sd bus
+device mmcsd # mmc/sd flash cards
+
+# Boot device is 2nd slice on MMC/SD card
+options ROOTDEVNAME=\"ufs:mmcsd0s2\"
+
+# GPIO
+device gpio
+device gpioled
+
+# I2C support
+device iicbus
+device iicbb
+device iic
+
+# vt is the default console driver, resembling an SCO console
+device vt
+#device kbdmux
+
+# Serial (COM) ports
+device uart # Generic UART driver
+
+# Pseudo devices.
+device loop # Network loopback
+device random # Entropy device
+device ether # Ethernet support
+device pty # BSD-style compatibility pseudo ttys
+
+# The `bpf' device enables the Berkeley Packet Filter.
+# Be aware of the administrative consequences of enabling this!
+# Note that 'bpf' is required for DHCP.
+device bpf # Berkeley packet filter
+
+# USB support
+device usb # General USB code (mandatory for USB)
+device dwcotg # DWC OTG controller
+options USB_HOST_ALIGN=64 # Align usb buffers to cache line size.
+options USB_DEBUG
+#options USB_REQ_DEBUG
+#options USB_VERBOSE
+
+#device ukbd # USB keyboard
+#device ums # USB mouse
+
+device scbus # SCSI bus (required for ATA/SCSI)
+device da # Direct Access (disks)
+device umass # Disks/Mass storage - Requires scbus and da
+
+# Ethernet support
+device miibus # MII bus support
+
+# SoC Ethernet, requires miibus
+device dwc
+
+# USB Ethernet support, requires miibus
+device axe # ASIX Electronics USB Ethernet
+
+# Flattened Device Tree
+options FDT # Configure using FDT/DTB data
diff --git a/sys/arm/conf/EFIKA_MX b/sys/arm/conf/EFIKA_MX
index 6ea9d8a1286b..a4690f6964fc 100644
--- a/sys/arm/conf/EFIKA_MX
+++ b/sys/arm/conf/EFIKA_MX
@@ -24,6 +24,8 @@ include "../freescale/imx/std.imx51"
makeoptions WITHOUT_MODULES="ahc"
+options SOC_IMX51
+
options SCHED_4BSD # 4BSD scheduler
options PREEMPTION # Enable kernel thread preemption
options INET # InterNETworking
diff --git a/sys/arm/conf/IMX53 b/sys/arm/conf/IMX53
index d627c25b9043..9f78f303d76a 100644
--- a/sys/arm/conf/IMX53
+++ b/sys/arm/conf/IMX53
@@ -22,6 +22,8 @@ ident IMX53
include "../freescale/imx/std.imx53"
+options SOC_IMX53
+
options SCHED_4BSD # 4BSD scheduler
options PREEMPTION # Enable kernel thread preemption
options INET # InterNETworking
diff --git a/sys/arm/conf/IMX6 b/sys/arm/conf/IMX6
index ada4eeaab463..f1baf296667b 100644
--- a/sys/arm/conf/IMX6
+++ b/sys/arm/conf/IMX6
@@ -21,6 +21,8 @@
ident IMX6
include "../freescale/imx/std.imx6"
+options SOC_IMX6
+
options HZ=500 # Scheduling quantum is 2 milliseconds.
options SCHED_ULE # ULE scheduler
options PREEMPTION # Enable kernel thread preemption
diff --git a/sys/arm/conf/ODROIDC1 b/sys/arm/conf/ODROIDC1
index 7d70fa4ec334..7bb7b565f883 100644
--- a/sys/arm/conf/ODROIDC1
+++ b/sys/arm/conf/ODROIDC1
@@ -1,7 +1,7 @@
# ODROIDC1 -- Custom configuration for the HardKernel ODROID-C1 SBC
#
-# For more information on this file, please read the handbook section on
-# Kernel Configuration Files:
+# For more information on this file, please read the config(5) manual page,
+# and/or the handbook section on Kernel Configuration Files:
#
# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
#
@@ -17,117 +17,10 @@
#
# $FreeBSD$
-ident ODROIDC1
-
-include "../amlogic/aml8726/std.odroidc1"
-
-options HZ=100
-options SCHED_ULE # ULE scheduler
-options PREEMPTION # Enable kernel thread preemption
-options INET # InterNETworking
-options INET6 # IPv6 communications protocols
-options FFS # Berkeley Fast Filesystem
-options SOFTUPDATES # Enable FFS soft updates support
-options UFS_ACL # Support for access control lists
-options UFS_DIRHASH # Improve performance on big directories
-options PROCFS # Process filesystem (requires PSEUDOFS)
-options PSEUDOFS # Pseudo-filesystem framework
-options GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
-options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
-options KTRACE # ktrace(1) support
-options SYSVSHM # SYSV-style shared memory
-options SYSVMSG # SYSV-style message queues
-options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
-options PRINTF_BUFR_SIZE=128 # Prevent printf output being interspersed.
-options KBD_INSTALL_CDEV # install a CDEV entry in /dev
-options LINUX_BOOT_ABI
-options VFP # vfp/neon
-
-# Debugging
-makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
-options ALT_BREAK_TO_DEBUGGER
-#options VERBOSE_SYSINIT # Enable verbose sysinit messages
-options BOOTVERBOSE=1
-options KDB
-options DDB # Enable the kernel debugger
-options INVARIANTS # Enable calls of extra sanity checking
-options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
-options WITNESS # Enable checks to detect deadlocks and cycles
-options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
-#options DIAGNOSTIC
-
-# NFS support
-#options NFSCL # New Network Filesystem Client
-#options NFSLOCKD # Network Lock Manager
-#options NFS_ROOT # NFS usable as /, requires NFSCL
-
-# NFS root from boopt/dhcp
-#options BOOTP
-#options BOOTP_NFSROOT
-#options BOOTP_COMPAT
-#options BOOTP_NFSV3
-#options BOOTP_WIRED_TO=axe0
-
-# MMC/SD/SDIO card slot support
-device mmc # mmc/sd bus
-device mmcsd # mmc/sd flash cards
-
-# Boot device is 2nd slice on MMC/SD card
-options ROOTDEVNAME=\"ufs:mmcsd0s2\"
-
-# GPIO
-device gpio
-device gpioled
-
-# I2C support
-device iicbus
-device iicbb
-device iic
+#NO_UNIVERSE
-# vt is the default console driver, resembling an SCO console
-device vt
-#device kbdmux
-
-# Serial (COM) ports
-device uart # Generic UART driver
-
-# Pseudo devices.
-device loop # Network loopback
-device random # Entropy device
-device ether # Ethernet support
-device pty # BSD-style compatibility pseudo ttys
-
-# The `bpf' device enables the Berkeley Packet Filter.
-# Be aware of the administrative consequences of enabling this!
-# Note that 'bpf' is required for DHCP.
-device bpf # Berkeley packet filter
-
-# USB support
-device usb # General USB code (mandatory for USB)
-device dwcotg # DWC OTG controller
-options USB_HOST_ALIGN=64 # Cacheline size is 64
-options USB_DEBUG
-#options USB_REQ_DEBUG
-#options USB_VERBOSE
-
-#device ukbd # USB keyboard
-#device ums # USB mouse
-
-device scbus # SCSI bus (required for ATA/SCSI)
-device da # Direct Access (disks)
-device umass # Disks/Mass storage - Requires scbus and da
-
-# Ethernet support
-device miibus # MII bus support
-
-# SoC Ethernet, requires miibus
-device dwc
-
-# USB Ethernet, requires miibus
-device axe # ASIX Electronics USB Ethernet
+include "AML8726"
+ident ODROIDC1
-# Flattened Device Tree
-options FDT
-options FDT_DTB_STATIC
+options FDT_DTB_STATIC
+makeoptions FDT_DTS_FILE=odroidc1.dts
diff --git a/sys/arm/conf/RK3188 b/sys/arm/conf/RK3188
index 2aba68e184d3..64065d30d70a 100644
--- a/sys/arm/conf/RK3188
+++ b/sys/arm/conf/RK3188
@@ -72,8 +72,8 @@ options WITNESS # Enable checks to detect deadlocks and cycles
options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
options DIAGNOSTIC
-# Boot device is 2nd slice on USB
-options ROOTDEVNAME=\"ufs:/dev/da0s2\"
+# Root mount from MMC/SD card
+options ROOTDEVNAME=\"ufs:/dev/mmcsd0\"
# MMC/SD/SDIO Card slot support
device mmc # mmc/sd bus
diff --git a/sys/arm/conf/RPI2 b/sys/arm/conf/RPI2
index 02f386970ef1..18d97d7ae21d 100644
--- a/sys/arm/conf/RPI2
+++ b/sys/arm/conf/RPI2
@@ -137,6 +137,6 @@ device bcm2835_spi
options FDT # Configure using FDT/DTB data
# Note: DTB is normally loaded and modified by RPi boot loader, then
# handed to kernel via U-Boot and ubldr.
-options FDT_DTB_STATIC
-makeoptions FDT_DTS_FILE=rpi2.dts
+#options FDT_DTB_STATIC
+#makeoptions FDT_DTS_FILE=rpi2.dts
makeoptions MODULES_EXTRA=dtb/rpi
diff --git a/sys/arm/conf/VSATV102 b/sys/arm/conf/VSATV102
index a3df9fa6e060..b5de5f9a3cbf 100644
--- a/sys/arm/conf/VSATV102
+++ b/sys/arm/conf/VSATV102
@@ -1,7 +1,7 @@
# VSATV102 -- Custom configuration for the Visson ATV-102 media player
#
-# For more information on this file, please read the handbook section on
-# Kernel Configuration Files:
+# For more information on this file, please read the config(5) manual page,
+# and/or the handbook section on Kernel Configuration Files:
#
# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
#
@@ -17,117 +17,10 @@
#
# $FreeBSD$
-ident VSATV102
-
-include "../amlogic/aml8726/std.vsatv102-m6"
-
-options HZ=100
-options SCHED_ULE # ULE scheduler
-options PREEMPTION # Enable kernel thread preemption
-options INET # InterNETworking
-options INET6 # IPv6 communications protocols
-options FFS # Berkeley Fast Filesystem
-options SOFTUPDATES # Enable FFS soft updates support
-options UFS_ACL # Support for access control lists
-options UFS_DIRHASH # Improve performance on big directories
-options PROCFS # Process filesystem (requires PSEUDOFS)
-options PSEUDOFS # Pseudo-filesystem framework
-options GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
-options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
-options KTRACE # ktrace(1) support
-options SYSVSHM # SYSV-style shared memory
-options SYSVMSG # SYSV-style message queues
-options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
-options PRINTF_BUFR_SIZE=128 # Prevent printf output being interspersed.
-options KBD_INSTALL_CDEV # install a CDEV entry in /dev
-options LINUX_BOOT_ABI
-options VFP # vfp/neon
-
-# Debugging
-makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
-options ALT_BREAK_TO_DEBUGGER
-#options VERBOSE_SYSINIT # Enable verbose sysinit messages
-options BOOTVERBOSE=1
-options KDB
-options DDB # Enable the kernel debugger
-options INVARIANTS # Enable calls of extra sanity checking
-options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
-options WITNESS # Enable checks to detect deadlocks and cycles
-options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
-#options DIAGNOSTIC
-
-# NFS support
-#options NFSCL # New Network Filesystem Client
-#options NFSLOCKD # Network Lock Manager
-#options NFS_ROOT # NFS usable as /, requires NFSCL
-
-# NFS root from boopt/dhcp
-#options BOOTP
-#options BOOTP_NFSROOT
-#options BOOTP_COMPAT
-#options BOOTP_NFSV3
-#options BOOTP_WIRED_TO=axe0
-
-# MMC/SD/SDIO card slot support
-device mmc # mmc/sd bus
-device mmcsd # mmc/sd flash cards
-
-# Boot device is 2nd slice on MMC/SD card
-options ROOTDEVNAME=\"ufs:mmcsd0s2\"
-
-# GPIO
-device gpio
-device gpioled
-
-# I2C support
-device iicbus
-device iicbb
-device iic
+#NO_UNIVERSE
-# vt is the default console driver, resembling an SCO console
-device vt
-#device kbdmux
-
-# Serial (COM) ports
-device uart # Generic UART driver
-
-# Pseudo devices.
-device loop # Network loopback
-device random # Entropy device
-device ether # Ethernet support
-device pty # BSD-style compatibility pseudo ttys
-
-# The `bpf' device enables the Berkeley Packet Filter.
-# Be aware of the administrative consequences of enabling this!
-# Note that 'bpf' is required for DHCP.
-device bpf # Berkeley packet filter
-
-# USB support
-device usb # General USB code (mandatory for USB)
-device dwcotg # DWC OTG controller
-options USB_HOST_ALIGN=64 # Cacheline size is 64
-options USB_DEBUG
-#options USB_REQ_DEBUG
-#options USB_VERBOSE
-
-#device ukbd # USB keyboard
-#device ums # USB mouse
-
-device scbus # SCSI bus (required for ATA/SCSI)
-device da # Direct Access (disks)
-device umass # Disks/Mass storage - Requires scbus and da
-
-# Ethernet support
-device miibus # MII bus support
-
-# SoC Ethernet, requires miibus
-device dwc
-
-# USB Ethernet, requires miibus
-device axe # ASIX Electronics USB Ethernet
+include "AML8726"
+ident VSATV102
-# Flattened Device Tree
-options FDT
-options FDT_DTB_STATIC
+options FDT_DTB_STATIC
+makeoptions FDT_DTS_FILE=vsatv102-m6.dts
diff --git a/sys/arm/freescale/imx/files.imx53 b/sys/arm/freescale/imx/files.imx5
index 6ca4ffdb0007..58e925b25934 100644
--- a/sys/arm/freescale/imx/files.imx53
+++ b/sys/arm/freescale/imx/files.imx5
@@ -6,14 +6,15 @@ kern/kern_clocksource.c standard
# Init
arm/freescale/imx/imx_common.c standard
arm/freescale/imx/imx_machdep.c standard
-arm/freescale/imx/imx53_machdep.c standard
+arm/freescale/imx/imx51_machdep.c optional soc_imx51
+arm/freescale/imx/imx53_machdep.c optional soc_imx53
arm/arm/bus_space_base.c standard
# Special serial console for debuging early boot code
#arm/freescale/imx/console.c standard
# UART driver (includes serial console support)
-dev/uart/uart_dev_imx.c optional uart
+dev/uart/uart_dev_imx.c optional uart
# TrustZone Interrupt Controller
arm/freescale/imx/tzic.c standard
diff --git a/sys/arm/freescale/imx/files.imx51 b/sys/arm/freescale/imx/files.imx51
deleted file mode 100644
index b779ee29f2a5..000000000000
--- a/sys/arm/freescale/imx/files.imx51
+++ /dev/null
@@ -1,49 +0,0 @@
-# $FreeBSD$
-arm/arm/bus_space_asm_generic.S standard
-arm/arm/bus_space_generic.c standard
-kern/kern_clocksource.c standard
-
-# Init
-arm/freescale/imx/imx_common.c standard
-arm/freescale/imx/imx_machdep.c standard
-arm/freescale/imx/imx51_machdep.c standard
-arm/arm/bus_space_base.c standard
-
-# Dummy serial console
-#arm/freescale/imx/console.c standard
-
-# TrustZone Interrupt Controller
-arm/freescale/imx/tzic.c standard
-
-# IOMUX - external pins multiplexor
-arm/freescale/imx/imx_iomux.c standard
-
-# GPIO
-arm/freescale/imx/imx_gpio.c optional gpio
-
-# Generic Periodic Timer
-arm/freescale/imx/imx_gpt.c standard
-
-# Clock Configuration Manager
-arm/freescale/imx/imx51_ccm.c standard
-
-# i.MX5xx PATA controller
-dev/ata/chipsets/ata-fsl.c optional imxata
-
-# UART driver
-dev/uart/uart_dev_imx.c optional uart
-
-# USB OH3 controller (1 OTG, 3 EHCI)
-arm/freescale/imx/imx_nop_usbphy.c optional ehci
-dev/usb/controller/ehci_imx.c optional ehci
-
-# Watchdog
-arm/freescale/imx/imx_wdog.c optional imxwdt
-
-# i2c
-arm/freescale/imx/imx_i2c.c optional fsliic
-
-# IPU - Image Processing Unit (frame buffer also)
-arm/freescale/imx/imx51_ipuv3.c optional sc
-arm/freescale/imx/imx51_ipuv3_fbd.c optional vt
-dev/vt/hw/fb/vt_early_fb.c optional vt
diff --git a/sys/arm/freescale/imx/std.imx51 b/sys/arm/freescale/imx/std.imx51
index fbc134968ee5..eca33c263962 100644
--- a/sys/arm/freescale/imx/std.imx51
+++ b/sys/arm/freescale/imx/std.imx51
@@ -13,5 +13,4 @@ options PHYSADDR=0x90000000
device fdt_pinctrl
-files "../freescale/imx/files.imx51"
-
+files "../freescale/imx/files.imx5"
diff --git a/sys/arm/freescale/imx/std.imx53 b/sys/arm/freescale/imx/std.imx53
index cbef21aedb96..1da484ceebde 100644
--- a/sys/arm/freescale/imx/std.imx53
+++ b/sys/arm/freescale/imx/std.imx53
@@ -13,5 +13,4 @@ options PHYSADDR=0x70000000
device fdt_pinctrl
-files "../freescale/imx/files.imx53"
-
+files "../freescale/imx/files.imx5"
diff --git a/sys/arm64/arm64/bus_machdep.c b/sys/arm64/arm64/bus_machdep.c
index d8e66465c332..25a675eb4bad 100644
--- a/sys/arm64/arm64/bus_machdep.c
+++ b/sys/arm64/arm64/bus_machdep.c
@@ -169,10 +169,10 @@ struct bus_space memmap_bus = {
.bs_r_8_s = NULL,
/* read multiple stream */
- .bs_rm_1_s = NULL,
- .bs_rm_2_s = NULL,
- .bs_rm_4_s = NULL,
- .bs_rm_8_s = NULL,
+ .bs_rm_1_s = generic_bs_rm_1,
+ .bs_rm_2_s = generic_bs_rm_2,
+ .bs_rm_4_s = generic_bs_rm_4,
+ .bs_rm_8_s = generic_bs_rm_8,
/* read region stream */
.bs_rr_1_s = NULL,
@@ -187,10 +187,10 @@ struct bus_space memmap_bus = {
.bs_w_8_s = NULL,
/* write multiple stream */
- .bs_wm_1_s = NULL,
- .bs_wm_2_s = NULL,
- .bs_wm_4_s = NULL,
- .bs_wm_8_s = NULL,
+ .bs_wm_1_s = generic_bs_wm_1,
+ .bs_wm_2_s = generic_bs_wm_2,
+ .bs_wm_4_s = generic_bs_wm_4,
+ .bs_wm_8_s = generic_bs_wm_8,
/* write region stream */
.bs_wr_1_s = NULL,
diff --git a/sys/arm64/arm64/bus_space_asm.S b/sys/arm64/arm64/bus_space_asm.S
index 52ad5dddd129..20d4128b79ec 100644
--- a/sys/arm64/arm64/bus_space_asm.S
+++ b/sys/arm64/arm64/bus_space_asm.S
@@ -63,7 +63,7 @@ ENTRY(generic_bs_rm_1)
/* Read the data. */
1: ldrb w1, [x0]
- strb w1, [x3], #2
+ strb w1, [x3], #1
subs x4, x4, #1
b.ne 1b
@@ -105,7 +105,7 @@ ENTRY(generic_bs_rm_4)
/* Read the data. */
1: ldr w1, [x0]
- str w1, [x3], #2
+ str w1, [x3], #4
subs x4, x4, #1
b.ne 1b
@@ -126,7 +126,7 @@ ENTRY(generic_bs_rm_8)
/* Read the data. */
1: ldr x1, [x0]
- str x1, [x3], #2
+ str x1, [x3], #8
subs x4, x4, #1
b.ne 1b
diff --git a/sys/arm64/arm64/db_disasm.c b/sys/arm64/arm64/db_disasm.c
new file mode 100644
index 000000000000..ec943a4d4669
--- /dev/null
+++ b/sys/arm64/arm64/db_disasm.c
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 2015 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under
+ * the sponsorship of the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#include <sys/param.h>
+#include <ddb/ddb.h>
+
+vm_offset_t
+db_disasm(vm_offset_t loc, boolean_t altfmt)
+{
+ return 0;
+}
+
+/* End of db_disasm.c */
diff --git a/sys/arm64/arm64/db_interface.c b/sys/arm64/arm64/db_interface.c
new file mode 100644
index 000000000000..38834af19d1c
--- /dev/null
+++ b/sys/arm64/arm64/db_interface.c
@@ -0,0 +1,168 @@
+/*-
+ * Copyright (c) 2015 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under
+ * the sponsorship of the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
+
+#ifdef KDB
+#include <sys/kdb.h>
+#endif
+
+#include <ddb/ddb.h>
+#include <ddb/db_variables.h>
+
+#include <machine/cpu.h>
+#include <machine/pcb.h>
+#include <machine/vmparam.h>
+
+static int
+db_frame(struct db_variable *vp, db_expr_t *valuep, int op)
+{
+ long *reg;
+
+ if (kdb_frame == NULL)
+ return (0);
+
+ reg = (long *)((uintptr_t)kdb_frame + (db_expr_t)vp->valuep);
+ if (op == DB_VAR_GET)
+ *valuep = *reg;
+ else
+ *reg = *valuep;
+ return (1);
+}
+
+#define DB_OFFSET(x) (db_expr_t *)offsetof(struct trapframe, x)
+struct db_variable db_regs[] = {
+ { "spsr", DB_OFFSET(tf_spsr), db_frame },
+ { "x0", DB_OFFSET(tf_x[0]), db_frame },
+ { "x1", DB_OFFSET(tf_x[1]), db_frame },
+ { "x2", DB_OFFSET(tf_x[2]), db_frame },
+ { "x3", DB_OFFSET(tf_x[3]), db_frame },
+ { "x4", DB_OFFSET(tf_x[4]), db_frame },
+ { "x5", DB_OFFSET(tf_x[5]), db_frame },
+ { "x6", DB_OFFSET(tf_x[6]), db_frame },
+ { "x7", DB_OFFSET(tf_x[7]), db_frame },
+ { "x8", DB_OFFSET(tf_x[8]), db_frame },
+ { "x9", DB_OFFSET(tf_x[9]), db_frame },
+ { "x10", DB_OFFSET(tf_x[10]), db_frame },
+ { "x11", DB_OFFSET(tf_x[11]), db_frame },
+ { "x12", DB_OFFSET(tf_x[12]), db_frame },
+ { "x13", DB_OFFSET(tf_x[13]), db_frame },
+ { "x14", DB_OFFSET(tf_x[14]), db_frame },
+ { "x15", DB_OFFSET(tf_x[15]), db_frame },
+ { "x16", DB_OFFSET(tf_x[16]), db_frame },
+ { "x17", DB_OFFSET(tf_x[17]), db_frame },
+ { "x18", DB_OFFSET(tf_x[18]), db_frame },
+ { "x19", DB_OFFSET(tf_x[19]), db_frame },
+ { "x20", DB_OFFSET(tf_x[20]), db_frame },
+ { "x21", DB_OFFSET(tf_x[21]), db_frame },
+ { "x22", DB_OFFSET(tf_x[22]), db_frame },
+ { "x23", DB_OFFSET(tf_x[23]), db_frame },
+ { "x24", DB_OFFSET(tf_x[24]), db_frame },
+ { "x25", DB_OFFSET(tf_x[25]), db_frame },
+ { "x26", DB_OFFSET(tf_x[26]), db_frame },
+ { "x27", DB_OFFSET(tf_x[27]), db_frame },
+ { "x28", DB_OFFSET(tf_x[28]), db_frame },
+ { "x29", DB_OFFSET(tf_x[29]), db_frame },
+ { "lr", DB_OFFSET(tf_lr), db_frame },
+ { "elr", DB_OFFSET(tf_elr), db_frame },
+ { "sp", DB_OFFSET(tf_sp), db_frame },
+};
+
+struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
+
+void
+db_show_mdpcpu(struct pcpu *pc)
+{
+}
+
+static int
+db_validate_address(vm_offset_t addr)
+{
+ struct proc *p = curproc;
+ struct pmap *pmap;
+
+ if (!p || !p->p_vmspace || !p->p_vmspace->vm_map.pmap ||
+ addr >= VM_MAXUSER_ADDRESS)
+ pmap = pmap_kernel();
+ else
+ pmap = p->p_vmspace->vm_map.pmap;
+
+ return (pmap_extract(pmap, addr) == FALSE);
+}
+
+/*
+ * Read bytes from kernel address space for debugger.
+ */
+int
+db_read_bytes(vm_offset_t addr, size_t size, char *data)
+{
+ const char *src = (const char *)addr;
+
+ while (size-- > 0) {
+ if (db_validate_address((vm_offset_t)src)) {
+ db_printf("address %p is invalid\n", src);
+ return (-1);
+ }
+ *data++ = *src++;
+ }
+ return (0);
+}
+
+/*
+ * Write bytes to kernel address space for debugger.
+ */
+int
+db_write_bytes(vm_offset_t addr, size_t size, char *data)
+{
+ char *dst;
+
+ dst = (char *)addr;
+ while (size-- > 0) {
+ if (db_validate_address((vm_offset_t)dst)) {
+ db_printf("address %p is invalid\n", dst);
+ return (-1);
+ }
+ *dst++ = *data++;
+ }
+
+ dsb();
+ /* Clean D-cache and invalidate I-cache */
+ cpu_dcache_wb_range(addr, (vm_size_t)size);
+ cpu_icache_sync_range(addr, (vm_size_t)size);
+ dsb();
+ isb();
+
+ return (0);
+}
diff --git a/sys/arm64/arm64/db_trace.c b/sys/arm64/arm64/db_trace.c
new file mode 100644
index 000000000000..1e89bac78b76
--- /dev/null
+++ b/sys/arm64/arm64/db_trace.c
@@ -0,0 +1,152 @@
+/*-
+ * Copyright (c) 2015 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under
+ * the sponsorship of the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/kdb.h>
+#include <machine/pcb.h>
+#include <ddb/ddb.h>
+#include <ddb/db_sym.h>
+
+#include <machine/armreg.h>
+#include <machine/debug_monitor.h>
+
+struct unwind_state {
+ uint64_t fp;
+ uint64_t sp;
+ uint64_t pc;
+};
+
+void
+db_md_list_watchpoints()
+{
+
+ dbg_show_watchpoint();
+}
+
+int
+db_md_clr_watchpoint(db_expr_t addr, db_expr_t size)
+{
+
+ return (dbg_remove_watchpoint(addr, size, DBG_FROM_EL1));
+}
+
+int
+db_md_set_watchpoint(db_expr_t addr, db_expr_t size)
+{
+
+ return (dbg_setup_watchpoint(addr, size, DBG_FROM_EL1,
+ HW_BREAKPOINT_RW));
+}
+
+static int
+db_unwind_frame(struct unwind_state *frame)
+{
+ uint64_t fp = frame->fp;
+
+ if (fp == 0)
+ return -1;
+
+ frame->sp = fp + 0x10;
+ /* FP to previous frame (X29) */
+ frame->fp = *(uint64_t *)(fp);
+ /* LR (X30) */
+ frame->pc = *(uint64_t *)(fp + 8) - 4;
+ return (0);
+}
+
+static void
+db_stack_trace_cmd(struct unwind_state *frame)
+{
+ c_db_sym_t sym;
+ const char *name;
+ db_expr_t value;
+ db_expr_t offset;
+
+ while (1) {
+ uint64_t pc = frame->pc;
+ int ret;
+
+ ret = db_unwind_frame(frame);
+ if (ret < 0)
+ break;
+
+ sym = db_search_symbol(pc, DB_STGY_ANY, &offset);
+ if (sym == C_DB_SYM_NULL) {
+ value = 0;
+ name = "(null)";
+ } else
+ db_symbol_values(sym, &name, &value);
+
+ db_printf("%s() at ", name);
+ db_printsym(frame->pc, DB_STGY_PROC);
+ db_printf("\n");
+
+ db_printf("\t pc = 0x%016lx lr = 0x%016lx\n", pc,
+ frame->pc);
+ db_printf("\t sp = 0x%016lx fp = 0x%016lx\n", frame->sp,
+ frame->fp);
+ /* TODO: Show some more registers */
+ db_printf("\n");
+ }
+}
+
+int
+db_trace_thread(struct thread *thr, int count)
+{
+ struct unwind_state frame;
+ struct pcb *ctx;
+
+ if (thr != curthread) {
+ ctx = kdb_thr_ctx(thr);
+
+ frame.sp = (uint64_t)ctx->pcb_sp;
+ frame.fp = (uint64_t)ctx->pcb_x[29];
+ frame.pc = (uint64_t)ctx->pcb_x[30];
+ db_stack_trace_cmd(&frame);
+ } else
+ db_trace_self();
+ return (0);
+}
+
+void
+db_trace_self(void)
+{
+ struct unwind_state frame;
+ uint64_t sp;
+
+ __asm __volatile("mov %0, sp" : "=&r" (sp));
+
+ frame.sp = sp;
+ frame.fp = (uint64_t)__builtin_frame_address(0);
+ frame.pc = (uint64_t)db_trace_self;
+ db_stack_trace_cmd(&frame);
+}
diff --git a/sys/arm64/arm64/debug_monitor.c b/sys/arm64/arm64/debug_monitor.c
new file mode 100644
index 000000000000..50d663da4b09
--- /dev/null
+++ b/sys/arm64/arm64/debug_monitor.c
@@ -0,0 +1,487 @@
+/*-
+ * Copyright (c) 2014 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under
+ * the sponsorship of the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/kdb.h>
+#include <sys/pcpu.h>
+#include <sys/systm.h>
+
+#include <machine/armreg.h>
+#include <machine/cpu.h>
+#include <machine/debug_monitor.h>
+#include <machine/kdb.h>
+#include <machine/param.h>
+
+#include <ddb/ddb.h>
+#include <ddb/db_sym.h>
+
+enum dbg_t {
+ DBG_TYPE_BREAKPOINT = 0,
+ DBG_TYPE_WATCHPOINT = 1,
+};
+
+static int dbg_watchpoint_num;
+static int dbg_breakpoint_num;
+static int dbg_ref_count_mde[MAXCPU];
+static int dbg_ref_count_kde[MAXCPU];
+
+/* Watchpoints/breakpoints control register bitfields */
+#define DBG_WATCH_CTRL_LEN_1 (0x1 << 5)
+#define DBG_WATCH_CTRL_LEN_2 (0x3 << 5)
+#define DBG_WATCH_CTRL_LEN_4 (0xf << 5)
+#define DBG_WATCH_CTRL_LEN_8 (0xff << 5)
+#define DBG_WATCH_CTRL_LEN_MASK(x) ((x) & (0xff << 5))
+#define DBG_WATCH_CTRL_EXEC (0x0 << 3)
+#define DBG_WATCH_CTRL_LOAD (0x1 << 3)
+#define DBG_WATCH_CTRL_STORE (0x2 << 3)
+#define DBG_WATCH_CTRL_ACCESS_MASK(x) ((x) & (0x3 << 3))
+
+/* Common for breakpoint and watchpoint */
+#define DBG_WB_CTRL_EL1 (0x1 << 1)
+#define DBG_WB_CTRL_EL0 (0x2 << 1)
+#define DBG_WB_CTRL_ELX_MASK(x) ((x) & (0x3 << 1))
+#define DBG_WB_CTRL_E (0x1 << 0)
+
+#define DBG_REG_BASE_BVR 0
+#define DBG_REG_BASE_BCR (DBG_REG_BASE_BVR + 16)
+#define DBG_REG_BASE_WVR (DBG_REG_BASE_BCR + 16)
+#define DBG_REG_BASE_WCR (DBG_REG_BASE_WVR + 16)
+
+/* Watchpoint/breakpoint helpers */
+#define DBG_WB_WVR "wvr"
+#define DBG_WB_WCR "wcr"
+#define DBG_WB_BVR "bvr"
+#define DBG_WB_BCR "bcr"
+
+#define DBG_WB_READ(reg, num, val) do { \
+ __asm __volatile("mrs %0, dbg" reg #num "_el1" : "=r" (val)); \
+} while (0)
+
+#define DBG_WB_WRITE(reg, num, val) do { \
+ __asm __volatile("msr dbg" reg #num "_el1, %0" :: "r" (val)); \
+} while (0)
+
+#define READ_WB_REG_CASE(reg, num, offset, val) \
+ case (num + offset): \
+ DBG_WB_READ(reg, num, val); \
+ break
+
+#define WRITE_WB_REG_CASE(reg, num, offset, val) \
+ case (num + offset): \
+ DBG_WB_WRITE(reg, num, val); \
+ break
+
+#define SWITCH_CASES_READ_WB_REG(reg, offset, val) \
+ READ_WB_REG_CASE(reg, 0, offset, val); \
+ READ_WB_REG_CASE(reg, 1, offset, val); \
+ READ_WB_REG_CASE(reg, 2, offset, val); \
+ READ_WB_REG_CASE(reg, 3, offset, val); \
+ READ_WB_REG_CASE(reg, 4, offset, val); \
+ READ_WB_REG_CASE(reg, 5, offset, val); \
+ READ_WB_REG_CASE(reg, 6, offset, val); \
+ READ_WB_REG_CASE(reg, 7, offset, val); \
+ READ_WB_REG_CASE(reg, 8, offset, val); \
+ READ_WB_REG_CASE(reg, 9, offset, val); \
+ READ_WB_REG_CASE(reg, 10, offset, val); \
+ READ_WB_REG_CASE(reg, 11, offset, val); \
+ READ_WB_REG_CASE(reg, 12, offset, val); \
+ READ_WB_REG_CASE(reg, 13, offset, val); \
+ READ_WB_REG_CASE(reg, 14, offset, val); \
+ READ_WB_REG_CASE(reg, 15, offset, val)
+
+#define SWITCH_CASES_WRITE_WB_REG(reg, offset, val) \
+ WRITE_WB_REG_CASE(reg, 0, offset, val); \
+ WRITE_WB_REG_CASE(reg, 1, offset, val); \
+ WRITE_WB_REG_CASE(reg, 2, offset, val); \
+ WRITE_WB_REG_CASE(reg, 3, offset, val); \
+ WRITE_WB_REG_CASE(reg, 4, offset, val); \
+ WRITE_WB_REG_CASE(reg, 5, offset, val); \
+ WRITE_WB_REG_CASE(reg, 6, offset, val); \
+ WRITE_WB_REG_CASE(reg, 7, offset, val); \
+ WRITE_WB_REG_CASE(reg, 8, offset, val); \
+ WRITE_WB_REG_CASE(reg, 9, offset, val); \
+ WRITE_WB_REG_CASE(reg, 10, offset, val); \
+ WRITE_WB_REG_CASE(reg, 11, offset, val); \
+ WRITE_WB_REG_CASE(reg, 12, offset, val); \
+ WRITE_WB_REG_CASE(reg, 13, offset, val); \
+ WRITE_WB_REG_CASE(reg, 14, offset, val); \
+ WRITE_WB_REG_CASE(reg, 15, offset, val)
+
+static uint64_t
+dbg_wb_read_reg(int reg, int n)
+{
+ uint64_t val = 0;
+
+ switch (reg + n) {
+ SWITCH_CASES_READ_WB_REG(DBG_WB_WVR, DBG_REG_BASE_WVR, val);
+ SWITCH_CASES_READ_WB_REG(DBG_WB_WCR, DBG_REG_BASE_WCR, val);
+ SWITCH_CASES_READ_WB_REG(DBG_WB_BVR, DBG_REG_BASE_BVR, val);
+ SWITCH_CASES_READ_WB_REG(DBG_WB_BCR, DBG_REG_BASE_BCR, val);
+ default:
+ db_printf("trying to read from wrong debug register %d\n", n);
+ }
+
+ return val;
+}
+
+static void
+dbg_wb_write_reg(int reg, int n, uint64_t val)
+{
+ switch (reg + n) {
+ SWITCH_CASES_WRITE_WB_REG(DBG_WB_WVR, DBG_REG_BASE_WVR, val);
+ SWITCH_CASES_WRITE_WB_REG(DBG_WB_WCR, DBG_REG_BASE_WCR, val);
+ SWITCH_CASES_WRITE_WB_REG(DBG_WB_BVR, DBG_REG_BASE_BVR, val);
+ SWITCH_CASES_WRITE_WB_REG(DBG_WB_BCR, DBG_REG_BASE_BCR, val);
+ default:
+ db_printf("trying to write to wrong debug register %d\n", n);
+ }
+ isb();
+}
+
+void
+kdb_cpu_set_singlestep(void)
+{
+
+ kdb_frame->tf_spsr |= DBG_SPSR_SS;
+ WRITE_SPECIALREG(MDSCR_EL1, READ_SPECIALREG(MDSCR_EL1) |
+ DBG_MDSCR_SS | DBG_MDSCR_KDE);
+
+ /*
+ * Disable breakpoints and watchpoints, e.g. stepping
+ * over watched instruction will trigger break exception instead of
+ * single-step exception and locks CPU on that instruction for ever.
+ */
+ if (dbg_ref_count_mde[PCPU_GET(cpuid)] > 0) {
+ WRITE_SPECIALREG(MDSCR_EL1,
+ READ_SPECIALREG(MDSCR_EL1) & ~DBG_MDSCR_MDE);
+ }
+}
+
+void
+kdb_cpu_clear_singlestep(void)
+{
+
+ WRITE_SPECIALREG(MDSCR_EL1, READ_SPECIALREG(MDSCR_EL1) &
+ ~(DBG_MDSCR_SS | DBG_MDSCR_KDE));
+
+ /* Restore breakpoints and watchpoints */
+ if (dbg_ref_count_mde[PCPU_GET(cpuid)] > 0) {
+ WRITE_SPECIALREG(MDSCR_EL1,
+ READ_SPECIALREG(MDSCR_EL1) | DBG_MDSCR_MDE);
+ }
+
+ if (dbg_ref_count_kde[PCPU_GET(cpuid)] > 0) {
+ WRITE_SPECIALREG(MDSCR_EL1,
+ READ_SPECIALREG(MDSCR_EL1) | DBG_MDSCR_KDE);
+ }
+}
+
+static const char *
+dbg_watchtype_str(uint32_t type)
+{
+ switch (type) {
+ case DBG_WATCH_CTRL_EXEC:
+ return ("execute");
+ case DBG_WATCH_CTRL_STORE:
+ return ("write");
+ case DBG_WATCH_CTRL_LOAD:
+ return ("read");
+ case DBG_WATCH_CTRL_LOAD | DBG_WATCH_CTRL_STORE:
+ return ("read/write");
+ default:
+ return ("invalid");
+ }
+}
+
+static int
+dbg_watchtype_len(uint32_t len)
+{
+ switch (len) {
+ case DBG_WATCH_CTRL_LEN_1:
+ return (1);
+ case DBG_WATCH_CTRL_LEN_2:
+ return (2);
+ case DBG_WATCH_CTRL_LEN_4:
+ return (4);
+ case DBG_WATCH_CTRL_LEN_8:
+ return (8);
+ default:
+ return (0);
+ }
+}
+
+void
+dbg_show_watchpoint(void)
+{
+ uint32_t wcr, len, type;
+ uint64_t addr;
+ int i;
+
+ db_printf("\nhardware watchpoints:\n");
+ db_printf(" watch status type len address symbol\n");
+ db_printf(" ----- -------- ---------- --- ------------------ ------------------\n");
+ for (i = 0; i < dbg_watchpoint_num; i++) {
+ wcr = dbg_wb_read_reg(DBG_REG_BASE_WCR, i);
+ if ((wcr & DBG_WB_CTRL_E) != 0) {
+ type = DBG_WATCH_CTRL_ACCESS_MASK(wcr);
+ len = DBG_WATCH_CTRL_LEN_MASK(wcr);
+ addr = dbg_wb_read_reg(DBG_REG_BASE_WVR, i);
+ db_printf(" %-5d %-8s %10s %3d 0x%16lx ",
+ i, "enabled", dbg_watchtype_str(type),
+ dbg_watchtype_len(len), addr);
+ db_printsym((db_addr_t)addr, DB_STGY_ANY);
+ db_printf("\n");
+ } else {
+ db_printf(" %-5d disabled\n", i);
+ }
+ }
+}
+
+
+static int
+dbg_find_free_slot(enum dbg_t type)
+{
+ u_int max, reg, i;
+
+ switch(type) {
+ case DBG_TYPE_BREAKPOINT:
+ max = dbg_breakpoint_num;
+ reg = DBG_REG_BASE_BCR;
+
+ break;
+ case DBG_TYPE_WATCHPOINT:
+ max = dbg_watchpoint_num;
+ reg = DBG_REG_BASE_WCR;
+ break;
+ default:
+ db_printf("Unsupported debug type\n");
+ return (i);
+ }
+
+ for (i = 0; i < max; i++) {
+ if ((dbg_wb_read_reg(reg, i) & DBG_WB_CTRL_E) == 0)
+ return (i);
+ }
+
+ return (-1);
+}
+
+static int
+dbg_find_slot(enum dbg_t type, db_expr_t addr)
+{
+ u_int max, reg_addr, reg_ctrl, i;
+
+ switch(type) {
+ case DBG_TYPE_BREAKPOINT:
+ max = dbg_breakpoint_num;
+ reg_addr = DBG_REG_BASE_BVR;
+ reg_ctrl = DBG_REG_BASE_BCR;
+ break;
+ case DBG_TYPE_WATCHPOINT:
+ max = dbg_watchpoint_num;
+ reg_addr = DBG_REG_BASE_WVR;
+ reg_ctrl = DBG_REG_BASE_WCR;
+ break;
+ default:
+ db_printf("Unsupported debug type\n");
+ return (i);
+ }
+
+ for (i = 0; i < max; i++) {
+ if ((dbg_wb_read_reg(reg_addr, i) == addr) &&
+ ((dbg_wb_read_reg(reg_ctrl, i) & DBG_WB_CTRL_E) != 0))
+ return (i);
+ }
+
+ return (-1);
+}
+
+static void
+dbg_enable_monitor(enum dbg_el_t el)
+{
+ uint64_t reg_mdcr = 0;
+
+ /*
+ * There is no need to have debug monitor on permanently, thus we are
+ * refcounting and turn it on only if any of CPU is going to use that.
+ */
+ if (atomic_fetchadd_int(&dbg_ref_count_mde[PCPU_GET(cpuid)], 1) == 0)
+ reg_mdcr = DBG_MDSCR_MDE;
+
+ if ((el == DBG_FROM_EL1) &&
+ atomic_fetchadd_int(&dbg_ref_count_kde[PCPU_GET(cpuid)], 1) == 0)
+ reg_mdcr |= DBG_MDSCR_KDE;
+
+ if (reg_mdcr)
+ WRITE_SPECIALREG(MDSCR_EL1, READ_SPECIALREG(MDSCR_EL1) | reg_mdcr);
+}
+
+static void
+dbg_disable_monitor(enum dbg_el_t el)
+{
+ uint64_t reg_mdcr = 0;
+
+ if (atomic_fetchadd_int(&dbg_ref_count_mde[PCPU_GET(cpuid)], -1) == 1)
+ reg_mdcr = DBG_MDSCR_MDE;
+
+ if ((el == DBG_FROM_EL1) &&
+ atomic_fetchadd_int(&dbg_ref_count_kde[PCPU_GET(cpuid)], -1) == 1)
+ reg_mdcr |= DBG_MDSCR_KDE;
+
+ if (reg_mdcr)
+ WRITE_SPECIALREG(MDSCR_EL1, READ_SPECIALREG(MDSCR_EL1) & ~reg_mdcr);
+}
+
+int
+dbg_setup_watchpoint(db_expr_t addr, db_expr_t size, enum dbg_el_t el,
+ enum dbg_access_t access)
+{
+ uint64_t wcr_size, wcr_priv, wcr_access;
+ u_int i;
+
+ i = dbg_find_free_slot(DBG_TYPE_WATCHPOINT);
+ if (i == -1) {
+ db_printf("Can not find slot for watchpoint, max %d"
+ " watchpoints supported\n", dbg_watchpoint_num);
+ return (i);
+ }
+
+ switch(size) {
+ case 1:
+ wcr_size = DBG_WATCH_CTRL_LEN_1;
+ break;
+ case 2:
+ wcr_size = DBG_WATCH_CTRL_LEN_2;
+ break;
+ case 4:
+ wcr_size = DBG_WATCH_CTRL_LEN_4;
+ break;
+ case 8:
+ wcr_size = DBG_WATCH_CTRL_LEN_8;
+ break;
+ default:
+ db_printf("Unsupported address size for watchpoint\n");
+ return (-1);
+ }
+
+ switch(el) {
+ case DBG_FROM_EL0:
+ wcr_priv = DBG_WB_CTRL_EL0;
+ break;
+ case DBG_FROM_EL1:
+ wcr_priv = DBG_WB_CTRL_EL1;
+ break;
+ default:
+ db_printf("Unsupported exception level for watchpoint\n");
+ return (-1);
+ }
+
+ switch(access) {
+ case HW_BREAKPOINT_X:
+ wcr_access = DBG_WATCH_CTRL_EXEC;
+ break;
+ case HW_BREAKPOINT_R:
+ wcr_access = DBG_WATCH_CTRL_LOAD;
+ break;
+ case HW_BREAKPOINT_W:
+ wcr_access = DBG_WATCH_CTRL_STORE;
+ break;
+ case HW_BREAKPOINT_RW:
+ wcr_access = DBG_WATCH_CTRL_LOAD | DBG_WATCH_CTRL_STORE;
+ break;
+ default:
+ db_printf("Unsupported exception level for watchpoint\n");
+ return (-1);
+ }
+
+ dbg_wb_write_reg(DBG_REG_BASE_WVR, i, addr);
+ dbg_wb_write_reg(DBG_REG_BASE_WCR, i, wcr_size | wcr_access | wcr_priv |
+ DBG_WB_CTRL_E);
+ dbg_enable_monitor(el);
+ return (0);
+}
+
+int
+dbg_remove_watchpoint(db_expr_t addr, db_expr_t size, enum dbg_el_t el)
+{
+ u_int i;
+
+ i = dbg_find_slot(DBG_TYPE_WATCHPOINT, addr);
+ if (i == -1) {
+ db_printf("Can not find watchpoint for address 0%lx\n", addr);
+ return (i);
+ }
+
+ dbg_wb_write_reg(DBG_REG_BASE_WCR, i, 0);
+ dbg_disable_monitor(el);
+ return (0);
+}
+
+void
+dbg_monitor_init(void)
+{
+ u_int i;
+
+ /* Clear OS lock */
+ WRITE_SPECIALREG(OSLAR_EL1, 0);
+
+ /* Find out many breakpoints and watchpoints we can use */
+ dbg_watchpoint_num = ((READ_SPECIALREG(ID_AA64DFR0_EL1) >> 20) & 0xf) + 1;
+ dbg_breakpoint_num = ((READ_SPECIALREG(ID_AA64DFR0_EL1) >> 12) & 0xf) + 1;
+
+ if (bootverbose && PCPU_GET(cpuid) == 0) {
+ db_printf("%d watchpoints and %d breakpoints supported\n",
+ dbg_watchpoint_num, dbg_breakpoint_num);
+ }
+
+ /*
+ * We have limited number of {watch,break}points, each consists of
+ * two registers:
+ * - wcr/bcr regsiter configurates corresponding {watch,break}point
+ * behaviour
+ * - wvr/bvr register keeps address we are hunting for
+ *
+ * Reset all breakpoints and watchpoints.
+ */
+ for (i = 0; i < dbg_watchpoint_num; ++i) {
+ dbg_wb_write_reg(DBG_REG_BASE_WCR, i, 0);
+ dbg_wb_write_reg(DBG_REG_BASE_WVR, i, 0);
+ }
+
+ for (i = 0; i < dbg_breakpoint_num; ++i) {
+ dbg_wb_write_reg(DBG_REG_BASE_BCR, i, 0);
+ dbg_wb_write_reg(DBG_REG_BASE_BVR, i, 0);
+ }
+
+ dbg_enable();
+}
diff --git a/sys/arm64/arm64/nexus.c b/sys/arm64/arm64/nexus.c
index 15b18b50383a..bc3833036a10 100644
--- a/sys/arm64/arm64/nexus.c
+++ b/sys/arm64/arm64/nexus.c
@@ -208,12 +208,12 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
break;
default:
- return (0);
+ return (NULL);
}
rv = rman_reserve_resource(rm, start, end, count, flags, child);
if (rv == 0)
- return (0);
+ return (NULL);
rman_set_rid(rv, *rid);
rman_set_bushandle(rv, rman_get_start(rv));
@@ -221,7 +221,7 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
if (needactivate) {
if (bus_activate_resource(child, type, *rid, rv)) {
rman_release_resource(rv);
- return (0);
+ return (NULL);
}
}
diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c
index 174b023e0729..c192fa637cc6 100644
--- a/sys/arm64/arm64/pmap.c
+++ b/sys/arm64/arm64/pmap.c
@@ -2936,6 +2936,18 @@ pmap_clear_modify(vm_page_t m)
/* TODO: We lack support for tracking if a page is modified */
}
+void *
+pmap_mapbios(vm_paddr_t pa, vm_size_t size)
+{
+
+ return ((void *)PHYS_TO_DMAP(pa));
+}
+
+void
+pmap_unmapbios(vm_paddr_t pa, vm_size_t size)
+{
+}
+
/*
* Sets the memory attribute for the specified page.
*/
diff --git a/sys/arm64/include/pmap.h b/sys/arm64/include/pmap.h
index e5401ef86759..63ae34c81c13 100644
--- a/sys/arm64/include/pmap.h
+++ b/sys/arm64/include/pmap.h
@@ -142,7 +142,9 @@ void pmap_kremove(vm_offset_t);
void pmap_kremove_device(vm_offset_t, vm_size_t);
void *pmap_mapdev(vm_offset_t, vm_size_t);
+void *pmap_mapbios(vm_paddr_t, vm_size_t);
void pmap_unmapdev(vm_offset_t, vm_size_t);
+void pmap_unmapbios(vm_offset_t, vm_size_t);
boolean_t pmap_map_io_transient(vm_page_t *, vm_offset_t *, int, boolean_t);
void pmap_unmap_io_transient(vm_page_t *, vm_offset_t *, int, boolean_t);
diff --git a/sys/boot/common/md.c b/sys/boot/common/md.c
index 6d2d2b455748..a8f092b92baf 100644
--- a/sys/boot/common/md.c
+++ b/sys/boot/common/md.c
@@ -27,11 +27,11 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <stand.h>
#include <sys/param.h>
#include <sys/endian.h>
#include <sys/queue.h>
#include <machine/stdarg.h>
-#include <stand.h>
#include "bootstrap.h"
diff --git a/sys/boot/fdt/dts/arm/bcm2836.dtsi b/sys/boot/fdt/dts/arm/bcm2836.dtsi
index 7fdaecfa49e3..bd75c843ca48 100644
--- a/sys/boot/fdt/dts/arm/bcm2836.dtsi
+++ b/sys/boot/fdt/dts/arm/bcm2836.dtsi
@@ -101,6 +101,12 @@
*/
};
+ watchdog0 {
+ compatible = "broadcom,bcm2835-wdt",
+ "broadcom,bcm2708-wdt";
+ reg = <0x10001c 0x0c>; /* 0x1c, 0x20, 0x24 */
+ };
+
gpio: gpio {
compatible = "broadcom,bcm2835-gpio",
"broadcom,bcm2708-gpio";
@@ -125,11 +131,11 @@
pinctrl-names = "default";
pinctrl-0 = <&pins_reserved>;
- /* Pins that can short 3.3V to GND in output mode: 46-47
+ /* Pins that can short 3.3V to GND in output mode: 46
* Pins used by VideoCore: 48-53
*/
- broadcom,read-only = <46>, <47>, <48>, <49>, <50>,
- <51>, <52>, <53>;
+ broadcom,read-only = <46>, <48>, <49>, <50>,
+ <51>, <52>, <53>;
/* BSC0 */
pins_bsc0_a: bsc0_a {
@@ -431,7 +437,7 @@
interrupts = <70>;
interrupt-parent = <&intc>;
- clock-frequency = <2500000000>; /* Set by VideoCore */
+ clock-frequency = <250000000>; /* Set by VideoCore */
};
uart0: uart0 {
diff --git a/sys/boot/fdt/dts/arm/rpi2.dts b/sys/boot/fdt/dts/arm/rpi2.dts
index 59974f148ba7..1c8c559b4daa 100644
--- a/sys/boot/fdt/dts/arm/rpi2.dts
+++ b/sys/boot/fdt/dts/arm/rpi2.dts
@@ -322,18 +322,14 @@
leds {
compatible = "gpio-leds";
- ok {
- label = "ok";
- gpios = <&gpio 16 1>;
-
- /* Don't change this - it configures
- * how the led driver determines if
- * the led is on or off when it loads.
- */
- default-state = "keep";
-
- /* This is the real default state. */
- linux,default-trigger = "default-on";
+ pwr {
+ label = "pwr";
+ gpios = <&gpio 35 0>;
+ };
+
+ act {
+ label = "act";
+ gpios = <&gpio 47 0>;
};
};
diff --git a/sys/boot/forth/loader.conf b/sys/boot/forth/loader.conf
index 275a58bf60f8..240e4033b188 100644
--- a/sys/boot/forth/loader.conf
+++ b/sys/boot/forth/loader.conf
@@ -48,6 +48,16 @@ entropy_cache_type="/boot/entropy"
#kern.random.sys.seeded="0" # Set this to 1 to start /dev/random
# without waiting for a (re)seed.
+##############################################################
+### RAM Blacklist configuration #############################
+##############################################################
+
+ram_blacklist_load="NO" # Set this to YES to load a file
+ # containing a list of addresses to
+ # exclude from the running system.
+ram_blacklist_name="/boot/blacklist.txt" # Set this to the name of the file
+ram_blacklist_type="ram_blacklist" # Required for the kernel to find
+ # the blacklist module
##############################################################
### Loader settings ########################################
diff --git a/sys/boot/i386/common/edd.h b/sys/boot/i386/common/edd.h
index 4a204f7006cf..7d1f45020f9d 100644
--- a/sys/boot/i386/common/edd.h
+++ b/sys/boot/i386/common/edd.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2011 Advanced Computing Technologies LLC
+ * Copyright (c) 2011 Hudson River Trading LLC
* Written by: John H. Baldwin <jhb@FreeBSD.org>
* All rights reserved.
*
diff --git a/sys/boot/libstand32/Makefile b/sys/boot/libstand32/Makefile
index a08a8e938739..c41dc21f6c50 100644
--- a/sys/boot/libstand32/Makefile
+++ b/sys/boot/libstand32/Makefile
@@ -11,9 +11,10 @@ MAN=
.include <src.opts.mk>
MK_SSP= no
-S= ${.CURDIR}/../../../lib/libstand
+LIBSTAND_SRC= ${.CURDIR}/../../../lib/libstand
+LIBC_SRC= ${LIBSTAND_SRC}/../libc
-.PATH: ${S}
+.PATH: ${LIBSTAND_SRC}
LIB= stand
INTERNALLIB=
MK_PROFILE= no
@@ -22,7 +23,7 @@ NO_PIC=
WARNS?= 0
CFLAGS+= -ffreestanding -Wformat
-CFLAGS+= -I${S}
+CFLAGS+= -I${LIBSTAND_SRC}
.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
CFLAGS.gcc+= -mpreferred-stack-boundary=2
@@ -52,56 +53,54 @@ SRCS+= gzguts.h zutil.h __main.c assert.c bcd.c bswap.c environment.c getopt.c g
# private (pruned) versions of libc string functions
SRCS+= strcasecmp.c
-LIBC= ${S}/../libc
-
-.PATH: ${LIBC}/net
+.PATH: ${LIBC_SRC}/net
SRCS+= ntoh.c
# string functions from libc
-.PATH: ${LIBC}/string
+.PATH: ${LIBC_SRC}/string
SRCS+= bcmp.c bcopy.c bzero.c ffs.c memccpy.c memchr.c memcmp.c memcpy.c \
memmove.c memset.c qdivrem.c strcat.c strchr.c strcmp.c strcpy.c \
strcspn.c strlen.c strncat.c strncmp.c strncpy.c strpbrk.c \
strrchr.c strsep.c strspn.c strstr.c strtok.c swab.c
.if ${MACHINE_CPUARCH} == "arm"
-.PATH: ${LIBC}/arm/gen
+.PATH: ${LIBC_SRC}/arm/gen
# Compiler support functions
-.PATH: ${.CURDIR}/../../../contrib/compiler-rt/lib/builtins/
+.PATH: ${LIBSTAND_SRC}/../../contrib/compiler-rt/lib/builtins/
# __clzsi2 and ctzsi2 for various builtin functions
SRCS+= clzsi2.c ctzsi2.c
# Divide and modulus functions called by the compiler
SRCS+= divmoddi4.c divmodsi4.c divdi3.c divsi3.c moddi3.c modsi3.c
SRCS+= udivmoddi4.c udivmodsi4.c udivdi3.c udivsi3.c umoddi3.c umodsi3.c
-.PATH: ${.CURDIR}/../../../contrib/compiler-rt/lib/builtins/arm/
+.PATH: ${LIBSTAND_SRC}/../../contrib/compiler-rt/lib/builtins/arm/
SRCS+= aeabi_idivmod.S aeabi_ldivmod.S aeabi_uidivmod.S aeabi_uldivmod.S
SRCS+= aeabi_memcmp.S aeabi_memcpy.S aeabi_memmove.S aeabi_memset.S
.endif
.if ${MACHINE_CPUARCH} == "powerpc"
-.PATH: ${LIBC}/quad
+.PATH: ${LIBC_SRC}/quad
SRCS+= ashldi3.c ashrdi3.c
SRCS+= syncicache.c
.endif
# uuid functions from libc
-.PATH: ${LIBC}/uuid
+.PATH: ${LIBC_SRC}/uuid
SRCS+= uuid_equal.c uuid_is_nil.c
# _setjmp/_longjmp
.if ${MACHINE_CPUARCH} == "amd64"
-.PATH: ${S}/i386
+.PATH: ${LIBSTAND_SRC}/i386
.else
-.PATH: ${S}/${MACHINE_CPUARCH}
+.PATH: ${LIBSTAND_SRC}/${MACHINE_CPUARCH}
.endif
SRCS+= _setjmp.S
# decompression functionality from libbz2
# NOTE: to actually test this functionality after libbz2 upgrade compile
# loader(8) with LOADER_BZIP2_SUPPORT defined
-.PATH: ${.CURDIR}/../../../contrib/bzip2
+.PATH: ${LIBSTAND_SRC}/../../contrib/bzip2
CFLAGS+= -DBZ_NO_STDIO -DBZ_NO_COMPRESS
SRCS+= libstand_bzlib_private.h
@@ -110,7 +109,8 @@ SRCS+= _${file}
CLEANFILES+= _${file}
_${file}: ${file}
- sed "s|bzlib_private\.h|libstand_bzlib_private.h|" ${.ALLSRC} > ${.TARGET}
+ sed "s|bzlib_private\.h|libstand_bzlib_private.h|" \
+ ${.ALLSRC} > ${.TARGET}
.endfor
CLEANFILES+= libstand_bzlib_private.h
@@ -119,8 +119,8 @@ libstand_bzlib_private.h: bzlib_private.h
${.ALLSRC} > ${.TARGET}
# decompression functionality from libz
-.PATH: ${S}/../libz
-CFLAGS+=-DHAVE_MEMCPY -I${S}/../libz
+.PATH: ${LIBSTAND_SRC}/../libz
+CFLAGS+=-DHAVE_MEMCPY -I${LIBSTAND_SRC}/../libz
SRCS+= adler32.c crc32.c libstand_zutil.h libstand_gzguts.h
.for file in infback.c inffast.c inflate.c inftrees.c zutil.c
diff --git a/sys/boot/userboot/libstand/Makefile b/sys/boot/userboot/libstand/Makefile
index 35903fc40864..88eb98f44e0b 100644
--- a/sys/boot/userboot/libstand/Makefile
+++ b/sys/boot/userboot/libstand/Makefile
@@ -11,9 +11,10 @@ MAN=
.include <bsd.own.mk>
MK_SSP= no
-S= ${.CURDIR}/../../../../lib/libstand
+LIBSTAND_SRC= ${.CURDIR}/../../../../lib/libstand
+LIBC_SRC= ${LIBSTAND_SRC}/../libc
-.PATH: ${S}
+.PATH: ${LIBSTAND_SRC}
LIB= stand
INTERNALLIB=
MK_PROFILE= no
@@ -22,7 +23,7 @@ NO_PIC=
WARNS?= 0
CFLAGS+= -ffreestanding -Wformat -fPIC
-CFLAGS+= -I${.CURDIR}/../../../../lib/libstand
+CFLAGS+= -I${LIBSTAND_SRC}
.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
CFLAGS+= -mno-mmx -mno-3dnow -mno-sse -mno-sse2
@@ -49,14 +50,12 @@ SRCS+= gzguts.h zutil.h __main.c assert.c bcd.c bswap.c environment.c getopt.c g
# private (pruned) versions of libc string functions
SRCS+= strcasecmp.c
-LIBC= ${.CURDIR}/../../../../lib/libc
-
-.PATH: ${LIBC}/net
+.PATH: ${LIBC_SRC}/net
SRCS+= ntoh.c
# string functions from libc
-.PATH: ${LIBC}/string
+.PATH: ${LIBC_SRC}/string
.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "powerpc" || \
${MACHINE_CPUARCH} == "sparc64" || ${MACHINE_CPUARCH} == "amd64" || \
${MACHINE_CPUARCH} == "arm"
@@ -66,34 +65,34 @@ SRCS+= bcmp.c bcopy.c bzero.c ffs.c memccpy.c memchr.c memcmp.c memcpy.c \
strrchr.c strsep.c strspn.c strstr.c strtok.c swab.c
.endif
.if ${MACHINE_CPUARCH} == "arm"
-.PATH: ${LIBC}/arm/gen
+.PATH: ${LIBC_SRC}/arm/gen
SRCS+= divsi3.S
.endif
.if ${MACHINE_CPUARCH} == "powerpc"
-.PATH: ${LIBC}/libc/quad
+.PATH: ${LIBC_SRC}/quad
SRCS+= ashldi3.c ashrdi3.c
-.PATH: ${LIBC}/powerpc/gen
+.PATH: ${LIBC_SRC}/powerpc/gen
SRCS+= syncicache.c
.endif
# uuid functions from libc
-.PATH: ${LIBC}/uuid
+.PATH: ${LIBC_SRC}/uuid
SRCS+= uuid_equal.c uuid_is_nil.c
# _setjmp/_longjmp
.if ${MACHINE_CPUARCH} == "amd64"
-.PATH: ${S}/amd64
+.PATH: ${LIBSTAND_SRC}/amd64
.elif ${MACHINE_ARCH} == "powerpc64"
-.PATH: ${S}/powerpc
+.PATH: ${LIBSTAND_SRC}/powerpc
.else
-.PATH: ${S}/${MACHINE_CPUARCH}
+.PATH: ${LIBSTAND_SRC}/${MACHINE_CPUARCH}
.endif
SRCS+= _setjmp.S
# decompression functionality from libbz2
# NOTE: to actually test this functionality after libbz2 upgrade compile
# loader(8) with LOADER_BZIP2_SUPPORT defined
-.PATH: ${.CURDIR}/../../../../contrib/bzip2
+.PATH: ${LIBSTAND_SRC}/../../contrib/bzip2
CFLAGS+= -DBZ_NO_STDIO -DBZ_NO_COMPRESS
SRCS+= libstand_bzlib_private.h
@@ -102,7 +101,8 @@ SRCS+= _${file}
CLEANFILES+= _${file}
_${file}: ${file}
- sed "s|bzlib_private\.h|libstand_bzlib_private.h|" ${.ALLSRC} > ${.TARGET}
+ sed "s|bzlib_private\.h|libstand_bzlib_private.h|" \
+ ${.ALLSRC} > ${.TARGET}
.endfor
CLEANFILES+= libstand_bzlib_private.h
@@ -111,8 +111,8 @@ libstand_bzlib_private.h: bzlib_private.h
${.ALLSRC} > ${.TARGET}
# decompression functionality from libz
-.PATH: ${.CURDIR}/../../../../lib/libz
-CFLAGS+=-DHAVE_MEMCPY -I${.CURDIR}/../../../../lib/libz
+.PATH: ${LIBSTAND_SRC}/../libz
+CFLAGS+=-DHAVE_MEMCPY -I${LIBSTAND_SRC}/../libz
SRCS+= adler32.c crc32.c libstand_zutil.h libstand_gzguts.h
.for file in infback.c inffast.c inflate.c inftrees.c zutil.c
@@ -121,7 +121,8 @@ CLEANFILES+= _${file}
_${file}: ${file}
sed -e "s|zutil\.h|libstand_zutil.h|" \
- -e "s|gzguts\.h|libstand_gzguts.h|" ${.ALLSRC} > ${.TARGET}
+ -e "s|gzguts\.h|libstand_gzguts.h|" \
+ ${.ALLSRC} > ${.TARGET}
.endfor
# depend on stand.h being able to be included multiple times
diff --git a/sys/cddl/contrib/opensolaris/common/nvpair/nvpair.c b/sys/cddl/contrib/opensolaris/common/nvpair/nvpair.c
index 53ed5f28f19b..cd6af4e0de8f 100644
--- a/sys/cddl/contrib/opensolaris/common/nvpair/nvpair.c
+++ b/sys/cddl/contrib/opensolaris/common/nvpair/nvpair.c
@@ -1227,6 +1227,7 @@ nvpair_type_is_array(nvpair_t *nvp)
data_type_t type = NVP_TYPE(nvp);
if ((type == DATA_TYPE_BYTE_ARRAY) ||
+ (type == DATA_TYPE_INT8_ARRAY) ||
(type == DATA_TYPE_UINT8_ARRAY) ||
(type == DATA_TYPE_INT16_ARRAY) ||
(type == DATA_TYPE_UINT16_ARRAY) ||
diff --git a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
index dc7c283fdd7f..b31e8bb68c6c 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
@@ -611,7 +611,11 @@ dtrace_panic(const char *format, ...)
va_list alist;
va_start(alist, format);
+#ifdef __FreeBSD__
+ vpanic(format, alist);
+#else
dtrace_vpanic(format, alist);
+#endif
va_end(alist);
}
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c
index 36ac27a5e0de..fb9c8a1a955d 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c
@@ -23,6 +23,7 @@
* Copyright (c) 2012, 2014 by Delphix. All rights reserved.
* Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
/* Portions Copyright 2010 Robert Milkowski */
@@ -879,11 +880,7 @@ dmu_objset_clone_check(void *arg, dmu_tx_t *tx)
dsl_dir_rele(pdd, FTAG);
return (SET_ERROR(EEXIST));
}
- /* You can't clone across pools. */
- if (pdd->dd_pool != dp) {
- dsl_dir_rele(pdd, FTAG);
- return (SET_ERROR(EXDEV));
- }
+
error = dsl_fs_ss_limit_check(pdd, 1, ZFS_PROP_FILESYSTEM_LIMIT, NULL,
doca->doca_cred);
if (error != 0) {
@@ -896,12 +893,6 @@ dmu_objset_clone_check(void *arg, dmu_tx_t *tx)
if (error != 0)
return (error);
- /* You can't clone across pools. */
- if (origin->ds_dir->dd_pool != dp) {
- dsl_dataset_rele(origin, FTAG);
- return (SET_ERROR(EXDEV));
- }
-
/* You can only clone snapshots, not the head datasets. */
if (!dsl_dataset_is_snapshot(origin)) {
dsl_dataset_rele(origin, FTAG);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c
index 7b1d6befa6ae..faa6d0ce0d4c 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c
@@ -306,21 +306,22 @@ traverse_visitbp(traverse_data_t *td, const dnode_phys_t *dnp,
arc_flags_t flags = ARC_FLAG_WAIT;
int i;
int epb = BP_GET_LSIZE(bp) >> DNODE_SHIFT;
+ dnode_phys_t *cdnp;
err = arc_read(NULL, td->td_spa, bp, arc_getbuf_func, &buf,
ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL, &flags, zb);
if (err != 0)
goto post;
- dnp = buf->b_data;
+ cdnp = buf->b_data;
for (i = 0; i < epb; i++) {
- prefetch_dnode_metadata(td, &dnp[i], zb->zb_objset,
+ prefetch_dnode_metadata(td, &cdnp[i], zb->zb_objset,
zb->zb_blkid * epb + i);
}
/* recursively visitbp() blocks below this */
for (i = 0; i < epb; i++) {
- err = traverse_dnode(td, &dnp[i], zb->zb_objset,
+ err = traverse_dnode(td, &cdnp[i], zb->zb_objset,
zb->zb_blkid * epb + i);
if (err != 0)
break;
@@ -328,7 +329,7 @@ traverse_visitbp(traverse_data_t *td, const dnode_phys_t *dnp,
} else if (BP_GET_TYPE(bp) == DMU_OT_OBJSET) {
arc_flags_t flags = ARC_FLAG_WAIT;
objset_phys_t *osp;
- dnode_phys_t *dnp;
+ dnode_phys_t *mdnp, *gdnp, *udnp;
err = arc_read(NULL, td->td_spa, bp, arc_getbuf_func, &buf,
ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL, &flags, zb);
@@ -336,26 +337,27 @@ traverse_visitbp(traverse_data_t *td, const dnode_phys_t *dnp,
goto post;
osp = buf->b_data;
- dnp = &osp->os_meta_dnode;
- prefetch_dnode_metadata(td, dnp, zb->zb_objset,
+ mdnp = &osp->os_meta_dnode;
+ gdnp = &osp->os_groupused_dnode;
+ udnp = &osp->os_userused_dnode;
+
+ prefetch_dnode_metadata(td, mdnp, zb->zb_objset,
DMU_META_DNODE_OBJECT);
if (arc_buf_size(buf) >= sizeof (objset_phys_t)) {
- prefetch_dnode_metadata(td, &osp->os_groupused_dnode,
- zb->zb_objset, DMU_GROUPUSED_OBJECT);
- prefetch_dnode_metadata(td, &osp->os_userused_dnode,
- zb->zb_objset, DMU_USERUSED_OBJECT);
+ prefetch_dnode_metadata(td, gdnp, zb->zb_objset,
+ DMU_GROUPUSED_OBJECT);
+ prefetch_dnode_metadata(td, udnp, zb->zb_objset,
+ DMU_USERUSED_OBJECT);
}
- err = traverse_dnode(td, dnp, zb->zb_objset,
+ err = traverse_dnode(td, mdnp, zb->zb_objset,
DMU_META_DNODE_OBJECT);
if (err == 0 && arc_buf_size(buf) >= sizeof (objset_phys_t)) {
- dnp = &osp->os_groupused_dnode;
- err = traverse_dnode(td, dnp, zb->zb_objset,
+ err = traverse_dnode(td, gdnp, zb->zb_objset,
DMU_GROUPUSED_OBJECT);
}
if (err == 0 && arc_buf_size(buf) >= sizeof (objset_phys_t)) {
- dnp = &osp->os_userused_dnode;
- err = traverse_dnode(td, dnp, zb->zb_objset,
+ err = traverse_dnode(td, udnp, zb->zb_objset,
DMU_USERUSED_OBJECT);
}
}
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
index ce22f4efb52f..58db4ddb71c2 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
@@ -413,7 +413,8 @@ dsl_dataset_hold_obj(dsl_pool_t *dp, uint64_t dsobj, void *tag,
offsetof(dmu_sendarg_t, dsa_link));
if (doi.doi_type == DMU_OTN_ZAP_METADATA) {
- int zaperr = zap_contains(mos, dsobj, DS_FIELD_LARGE_BLOCKS);
+ int zaperr = zap_contains(mos, dsobj,
+ DS_FIELD_LARGE_BLOCKS);
if (zaperr != ENOENT) {
VERIFY0(zaperr);
ds->ds_large_blocks = B_TRUE;
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c
index 1862f8cb8d7c..26f5c2da4c6b 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c
@@ -24,6 +24,7 @@
* All rights reserved.
* Copyright (c) 2012, 2014 by Delphix. All rights reserved.
* Copyright (c) 2014 Joyent, Inc. All rights reserved.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/dmu.h>
@@ -408,7 +409,7 @@ dsl_dir_hold(dsl_pool_t *dp, const char *name, void *tag,
/* Make sure the name is in the specified pool. */
spaname = spa_name(dp->dp_spa);
if (strcmp(buf, spaname) != 0)
- return (SET_ERROR(EINVAL));
+ return (SET_ERROR(EXDEV));
ASSERT(dsl_pool_config_held(dp));
@@ -1706,7 +1707,7 @@ dsl_dir_rename_check(void *arg, dmu_tx_t *tx)
if (dd->dd_pool != newparent->dd_pool) {
dsl_dir_rele(newparent, FTAG);
dsl_dir_rele(dd, FTAG);
- return (SET_ERROR(ENXIO));
+ return (SET_ERROR(EXDEV));
}
/* new name should not already exist */
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_onexit.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_onexit.c
index 6a90b9cf2028..fe023996dd89 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_onexit.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_onexit.c
@@ -137,7 +137,7 @@ zfs_onexit_fd_hold(int fd, minor_t *minorp)
*minorp = (minor_t)(uintptr_t)data;
curthread->td_fpop = tmpfp;
if (error != 0)
- return (error);
+ return (SET_ERROR(EBADF));
return (zfs_onexit_minor_to_state(*minorp, &zo));
}
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
index d92571293325..e3b314fef954 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
@@ -1320,15 +1320,25 @@ zfs_rezget(znode_t *zp)
}
/*
- * XXXPJD: Not sure how is that possible, but under heavy
- * zfs recv -F load it happens that z_gen is the same, but
- * vnode type is different than znode type. This would mean
- * that for example regular file was replaced with directory
- * which has the same object number.
+ * It is highly improbable but still quite possible that two
+ * objects in different datasets are created with the same
+ * object numbers and in transaction groups with the same
+ * numbers. znodes corresponding to those objects would
+ * have the same z_id and z_gen, but their other attributes
+ * may be different.
+ * zfs recv -F may replace one of such objects with the other.
+ * As a result file properties recorded in the replaced
+ * object's vnode may no longer match the received object's
+ * properties. At present the only cached property is the
+ * files type recorded in v_type.
+ * So, handle this case by leaving the old vnode and znode
+ * disassociated from the actual object. A new vnode and a
+ * znode will be created if the object is accessed
+ * (e.g. via a look-up). The old vnode and znode will be
+ * recycled when the last vnode reference is dropped.
*/
vp = ZTOV(zp);
- if (vp != NULL &&
- vp->v_type != IFTOVT((mode_t)zp->z_mode)) {
+ if (vp != NULL && vp->v_type != IFTOVT((mode_t)zp->z_mode)) {
zfs_znode_dmu_fini(zp);
ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num);
return (EIO);
diff --git a/sys/cddl/dev/dtrace/amd64/dtrace_asm.S b/sys/cddl/dev/dtrace/amd64/dtrace_asm.S
index cf8314c6dceb..a6c079ee6773 100644
--- a/sys/cddl/dev/dtrace/amd64/dtrace_asm.S
+++ b/sys/cddl/dev/dtrace/amd64/dtrace_asm.S
@@ -363,211 +363,3 @@ dtrace_interrupt_enable(dtrace_icookie_t cookie)
popfq
ret
END(dtrace_interrupt_enable)
-
-/*
- * The panic() and cmn_err() functions invoke vpanic() as a common entry point
- * into the panic code implemented in panicsys(). vpanic() is responsible
- * for passing through the format string and arguments, and constructing a
- * regs structure on the stack into which it saves the current register
- * values. If we are not dying due to a fatal trap, these registers will
- * then be preserved in panicbuf as the current processor state. Before
- * invoking panicsys(), vpanic() activates the first panic trigger (see
- * common/os/panic.c) and switches to the panic_stack if successful. Note that
- * DTrace takes a slightly different panic path if it must panic from probe
- * context. Instead of calling panic, it calls into dtrace_vpanic(), which
- * sets up the initial stack as vpanic does, calls dtrace_panic_trigger(), and
- * branches back into vpanic().
- */
-
-/*
-void
-vpanic(const char *format, va_list alist)
-*/
- ENTRY(vpanic) /* Initial stack layout: */
-
- pushq %rbp /* | %rip | 0x60 */
- movq %rsp, %rbp /* | %rbp | 0x58 */
- pushfq /* | rfl | 0x50 */
- pushq %r11 /* | %r11 | 0x48 */
- pushq %r10 /* | %r10 | 0x40 */
- pushq %rbx /* | %rbx | 0x38 */
- pushq %rax /* | %rax | 0x30 */
- pushq %r9 /* | %r9 | 0x28 */
- pushq %r8 /* | %r8 | 0x20 */
- pushq %rcx /* | %rcx | 0x18 */
- pushq %rdx /* | %rdx | 0x10 */
- pushq %rsi /* | %rsi | 0x8 alist */
- pushq %rdi /* | %rdi | 0x0 format */
-
- movq %rsp, %rbx /* %rbx = current %rsp */
-
- leaq panic_quiesce(%rip), %rdi /* %rdi = &panic_quiesce */
- call panic_trigger /* %eax = panic_trigger() */
-
-vpanic_common:
- /*
- * The panic_trigger result is in %eax from the call above, and
- * dtrace_panic places it in %eax before branching here.
- * The rdmsr instructions that follow below will clobber %eax so
- * we stash the panic_trigger result in %r11d.
- */
- movl %eax, %r11d
- cmpl $0, %r11d
- je 0f
-
- /*
- * If panic_trigger() was successful, we are the first to initiate a
- * panic: we now switch to the reserved panic_stack before continuing.
- */
- leaq panic_stack(%rip), %rsp
- addq $PANICSTKSIZE, %rsp
-0: subq $REGSIZE, %rsp
- /*
- * Now that we've got everything set up, store the register values as
- * they were when we entered vpanic() to the designated location in
- * the regs structure we allocated on the stack.
- */
-#ifdef notyet
- movq 0x0(%rbx), %rcx
- movq %rcx, REGOFF_RDI(%rsp)
- movq 0x8(%rbx), %rcx
- movq %rcx, REGOFF_RSI(%rsp)
- movq 0x10(%rbx), %rcx
- movq %rcx, REGOFF_RDX(%rsp)
- movq 0x18(%rbx), %rcx
- movq %rcx, REGOFF_RCX(%rsp)
- movq 0x20(%rbx), %rcx
-
- movq %rcx, REGOFF_R8(%rsp)
- movq 0x28(%rbx), %rcx
- movq %rcx, REGOFF_R9(%rsp)
- movq 0x30(%rbx), %rcx
- movq %rcx, REGOFF_RAX(%rsp)
- movq 0x38(%rbx), %rcx
- movq %rcx, REGOFF_RBX(%rsp)
- movq 0x58(%rbx), %rcx
-
- movq %rcx, REGOFF_RBP(%rsp)
- movq 0x40(%rbx), %rcx
- movq %rcx, REGOFF_R10(%rsp)
- movq 0x48(%rbx), %rcx
- movq %rcx, REGOFF_R11(%rsp)
- movq %r12, REGOFF_R12(%rsp)
-
- movq %r13, REGOFF_R13(%rsp)
- movq %r14, REGOFF_R14(%rsp)
- movq %r15, REGOFF_R15(%rsp)
-
- xorl %ecx, %ecx
- movw %ds, %cx
- movq %rcx, REGOFF_DS(%rsp)
- movw %es, %cx
- movq %rcx, REGOFF_ES(%rsp)
- movw %fs, %cx
- movq %rcx, REGOFF_FS(%rsp)
- movw %gs, %cx
- movq %rcx, REGOFF_GS(%rsp)
-
- movq $0, REGOFF_TRAPNO(%rsp)
-
- movq $0, REGOFF_ERR(%rsp)
- leaq vpanic(%rip), %rcx
- movq %rcx, REGOFF_RIP(%rsp)
- movw %cs, %cx
- movzwq %cx, %rcx
- movq %rcx, REGOFF_CS(%rsp)
- movq 0x50(%rbx), %rcx
- movq %rcx, REGOFF_RFL(%rsp)
- movq %rbx, %rcx
- addq $0x60, %rcx
- movq %rcx, REGOFF_RSP(%rsp)
- movw %ss, %cx
- movzwq %cx, %rcx
- movq %rcx, REGOFF_SS(%rsp)
-
- /*
- * panicsys(format, alist, rp, on_panic_stack)
- */
- movq REGOFF_RDI(%rsp), %rdi /* format */
- movq REGOFF_RSI(%rsp), %rsi /* alist */
- movq %rsp, %rdx /* struct regs */
- movl %r11d, %ecx /* on_panic_stack */
- call panicsys
- addq $REGSIZE, %rsp
-#endif
- popq %rdi
- popq %rsi
- popq %rdx
- popq %rcx
- popq %r8
- popq %r9
- popq %rax
- popq %rbx
- popq %r10
- popq %r11
- popfq
- leave
- ret
- END(vpanic)
-
-/*
-void
-dtrace_vpanic(const char *format, va_list alist)
-*/
- ENTRY(dtrace_vpanic) /* Initial stack layout: */
-
- pushq %rbp /* | %rip | 0x60 */
- movq %rsp, %rbp /* | %rbp | 0x58 */
- pushfq /* | rfl | 0x50 */
- pushq %r11 /* | %r11 | 0x48 */
- pushq %r10 /* | %r10 | 0x40 */
- pushq %rbx /* | %rbx | 0x38 */
- pushq %rax /* | %rax | 0x30 */
- pushq %r9 /* | %r9 | 0x28 */
- pushq %r8 /* | %r8 | 0x20 */
- pushq %rcx /* | %rcx | 0x18 */
- pushq %rdx /* | %rdx | 0x10 */
- pushq %rsi /* | %rsi | 0x8 alist */
- pushq %rdi /* | %rdi | 0x0 format */
-
- movq %rsp, %rbx /* %rbx = current %rsp */
-
- leaq panic_quiesce(%rip), %rdi /* %rdi = &panic_quiesce */
- call dtrace_panic_trigger /* %eax = dtrace_panic_trigger() */
- jmp vpanic_common
-
- END(dtrace_vpanic)
-
-/*
-int
-panic_trigger(int *tp)
-*/
- ENTRY(panic_trigger)
- xorl %eax, %eax
- movl $0xdefacedd, %edx
- lock
- xchgl %edx, (%rdi)
- cmpl $0, %edx
- je 0f
- movl $0, %eax
- ret
-0: movl $1, %eax
- ret
- END(panic_trigger)
-
-/*
-int
-dtrace_panic_trigger(int *tp)
-*/
- ENTRY(dtrace_panic_trigger)
- xorl %eax, %eax
- movl $0xdefacedd, %edx
- lock
- xchgl %edx, (%rdi)
- cmpl $0, %edx
- je 0f
- movl $0, %eax
- ret
-0: movl $1, %eax
- ret
- END(dtrace_panic_trigger)
diff --git a/sys/cddl/dev/dtrace/arm/dtrace_asm.S b/sys/cddl/dev/dtrace/arm/dtrace_asm.S
index ce27b1410c6e..06e91d2bd756 100644
--- a/sys/cddl/dev/dtrace/arm/dtrace_asm.S
+++ b/sys/cddl/dev/dtrace/arm/dtrace_asm.S
@@ -170,24 +170,6 @@ ENTRY(dtrace_copystr)
END(dtrace_copystr)
/*
-void
-vpanic(const char *format, va_list alist)
-*/
-ENTRY(vpanic) /* Initial stack layout: */
-vpanic_common:
- RET
-END(vpanic)
-
-/*
-void
-dtrace_vpanic(const char *format, va_list alist)
-*/
-ENTRY(dtrace_vpanic) /* Initial stack layout: */
- b vpanic
- RET
-END(dtrace_vpanic) /* Initial stack layout: */
-
-/*
uintptr_t
dtrace_caller(int aframes)
*/
diff --git a/sys/cddl/dev/dtrace/dtrace_hacks.c b/sys/cddl/dev/dtrace/dtrace_hacks.c
index 21da9f82e703..3f8997382c75 100644
--- a/sys/cddl/dev/dtrace/dtrace_hacks.c
+++ b/sys/cddl/dev/dtrace/dtrace_hacks.c
@@ -3,9 +3,6 @@
dtrace_cacheid_t dtrace_predcache_id;
-int panic_quiesce;
-char panic_stack[PANICSTKSIZE];
-
boolean_t
priv_policy_only(const cred_t *a, int b, boolean_t c)
{
diff --git a/sys/cddl/dev/dtrace/i386/dtrace_asm.S b/sys/cddl/dev/dtrace/i386/dtrace_asm.S
index 6338719bf968..d44f6c3fdf81 100644
--- a/sys/cddl/dev/dtrace/i386/dtrace_asm.S
+++ b/sys/cddl/dev/dtrace/i386/dtrace_asm.S
@@ -355,167 +355,3 @@ void dtrace_interrupt_enable(dtrace_icookie_t cookie)
popfl
ret
END(dtrace_interrupt_enable)
-
-/*
- * The panic() and cmn_err() functions invoke vpanic() as a common entry point
- * into the panic code implemented in panicsys(). vpanic() is responsible
- * for passing through the format string and arguments, and constructing a
- * regs structure on the stack into which it saves the current register
- * values. If we are not dying due to a fatal trap, these registers will
- * then be preserved in panicbuf as the current processor state. Before
- * invoking panicsys(), vpanic() activates the first panic trigger (see
- * common/os/panic.c) and switches to the panic_stack if successful. Note that
- * DTrace takes a slightly different panic path if it must panic from probe
- * context. Instead of calling panic, it calls into dtrace_vpanic(), which
- * sets up the initial stack as vpanic does, calls dtrace_panic_trigger(), and
- * branches back into vpanic().
- */
-/*
-void vpanic(const char *format, va_list alist)
-*/
- ENTRY(vpanic) /* Initial stack layout: */
-
- pushl %ebp /* | %eip | 20 */
- movl %esp, %ebp /* | %ebp | 16 */
- pushl %eax /* | %eax | 12 */
- pushl %ebx /* | %ebx | 8 */
- pushl %ecx /* | %ecx | 4 */
- pushl %edx /* | %edx | 0 */
-
- movl %esp, %ebx /* %ebx = current stack pointer */
-
- lea panic_quiesce, %eax /* %eax = &panic_quiesce */
- pushl %eax /* push &panic_quiesce */
- call panic_trigger /* %eax = panic_trigger() */
- addl $4, %esp /* reset stack pointer */
-
-vpanic_common:
- cmpl $0, %eax /* if (%eax == 0) */
- je 0f /* goto 0f; */
-
- /*
- * If panic_trigger() was successful, we are the first to initiate a
- * panic: we now switch to the reserved panic_stack before continuing.
- */
- lea panic_stack, %esp /* %esp = panic_stack */
- addl $PANICSTKSIZE, %esp /* %esp += PANICSTKSIZE */
-
-0: subl $REGSIZE, %esp /* allocate struct regs */
-
- /*
- * Now that we've got everything set up, store the register values as
- * they were when we entered vpanic() to the designated location in
- * the regs structure we allocated on the stack.
- */
-#ifdef notyet
- mov %gs, %edx
- mov %edx, REGOFF_GS(%esp)
- mov %fs, %edx
- mov %edx, REGOFF_FS(%esp)
- mov %es, %edx
- mov %edx, REGOFF_ES(%esp)
- mov %ds, %edx
- mov %edx, REGOFF_DS(%esp)
- movl %edi, REGOFF_EDI(%esp)
- movl %esi, REGOFF_ESI(%esp)
- movl 16(%ebx), %ecx
- movl %ecx, REGOFF_EBP(%esp)
- movl %ebx, %ecx
- addl $20, %ecx
- movl %ecx, REGOFF_ESP(%esp)
- movl 8(%ebx), %ecx
- movl %ecx, REGOFF_EBX(%esp)
- movl 0(%ebx), %ecx
- movl %ecx, REGOFF_EDX(%esp)
- movl 4(%ebx), %ecx
- movl %ecx, REGOFF_ECX(%esp)
- movl 12(%ebx), %ecx
- movl %ecx, REGOFF_EAX(%esp)
- movl $0, REGOFF_TRAPNO(%esp)
- movl $0, REGOFF_ERR(%esp)
- lea vpanic, %ecx
- movl %ecx, REGOFF_EIP(%esp)
- mov %cs, %edx
- movl %edx, REGOFF_CS(%esp)
- pushfl
- popl %ecx
- movl %ecx, REGOFF_EFL(%esp)
- movl $0, REGOFF_UESP(%esp)
- mov %ss, %edx
- movl %edx, REGOFF_SS(%esp)
-
- movl %esp, %ecx /* %ecx = &regs */
- pushl %eax /* push on_panic_stack */
- pushl %ecx /* push &regs */
- movl 12(%ebp), %ecx /* %ecx = alist */
- pushl %ecx /* push alist */
- movl 8(%ebp), %ecx /* %ecx = format */
- pushl %ecx /* push format */
- call panicsys /* panicsys(); */
- addl $16, %esp /* pop arguments */
-
- addl $REGSIZE, %esp
-#endif
- popl %edx
- popl %ecx
- popl %ebx
- popl %eax
- leave
- ret
- END(vpanic)
-
-/*
-void dtrace_vpanic(const char *format, va_list alist)
-*/
- ENTRY(dtrace_vpanic) /* Initial stack layout: */
-
- pushl %ebp /* | %eip | 20 */
- movl %esp, %ebp /* | %ebp | 16 */
- pushl %eax /* | %eax | 12 */
- pushl %ebx /* | %ebx | 8 */
- pushl %ecx /* | %ecx | 4 */
- pushl %edx /* | %edx | 0 */
-
- movl %esp, %ebx /* %ebx = current stack pointer */
-
- lea panic_quiesce, %eax /* %eax = &panic_quiesce */
- pushl %eax /* push &panic_quiesce */
- call dtrace_panic_trigger /* %eax = dtrace_panic_trigger() */
- addl $4, %esp /* reset stack pointer */
- jmp vpanic_common /* jump back to common code */
-
- END(dtrace_vpanic)
-
-/*
-int
-panic_trigger(int *tp)
-*/
- ENTRY(panic_trigger)
- xorl %eax, %eax
- movl $0xdefacedd, %edx
- lock
- xchgl %edx, (%edi)
- cmpl $0, %edx
- je 0f
- movl $0, %eax
- ret
-0: movl $1, %eax
- ret
- END(panic_trigger)
-
-/*
-int
-dtrace_panic_trigger(int *tp)
-*/
- ENTRY(dtrace_panic_trigger)
- xorl %eax, %eax
- movl $0xdefacedd, %edx
- lock
- xchgl %edx, (%edi)
- cmpl $0, %edx
- je 0f
- movl $0, %eax
- ret
-0: movl $1, %eax
- ret
- END(dtrace_panic_trigger)
diff --git a/sys/cddl/dev/dtrace/mips/dtrace_asm.S b/sys/cddl/dev/dtrace/mips/dtrace_asm.S
index 50f6c5418c34..199d16be5b6f 100644
--- a/sys/cddl/dev/dtrace/mips/dtrace_asm.S
+++ b/sys/cddl/dev/dtrace/mips/dtrace_asm.S
@@ -249,49 +249,6 @@ LEAF(dtrace_invop_uninit)
END(dtrace_invop_uninit)
/*
- * The panic() and cmn_err() functions invoke vpanic() as a common entry point
- * into the panic code implemented in panicsys(). vpanic() is responsible
- * for passing through the format string and arguments, and constructing a
- * regs structure on the stack into which it saves the current register
- * values. If we are not dying due to a fatal trap, these registers will
- * then be preserved in panicbuf as the current processor state. Before
- * invoking panicsys(), vpanic() activates the first panic trigger (see
- * common/os/panic.c) and switches to the panic_stack if successful. Note that
- * DTrace takes a slightly different panic path if it must panic from probe
- * context. Instead of calling panic, it calls into dtrace_vpanic(), which
- * sets up the initial stack as vpanic does, calls dtrace_panic_trigger(), and
- * branches back into vpanic().
- */
-
-/*
-void
-vpanic(const char *format, va_list alist)
-*/
-LEAF(vpanic) /* Initial stack layout: */
-
-vpanic_common:
- j ra
- nop
-END(vpanic)
-
-
-
-/*
-void
-dtrace_vpanic(const char *format, va_list alist)
-*/
-LEAF(dtrace_vpanic) /* Initial stack layout: */
-
-#if 0
- jal dtrace_panic_trigger /* %eax = dtrace_panic_trigger() */
- nop
-#endif
- j vpanic_common
- nop
-
-END(dtrace_vpanic)
-
-/*
uintptr_t
dtrace_caller(int aframes)
*/
@@ -300,4 +257,3 @@ LEAF(dtrace_caller)
j ra
nop
END(dtrace_caller)
-
diff --git a/sys/cddl/dev/dtrace/powerpc/dtrace_asm.S b/sys/cddl/dev/dtrace/powerpc/dtrace_asm.S
index 5676360e089f..3adfbe38cd7f 100644
--- a/sys/cddl/dev/dtrace/powerpc/dtrace_asm.S
+++ b/sys/cddl/dev/dtrace/powerpc/dtrace_asm.S
@@ -161,45 +161,6 @@ ASENTRY_NOPROF(dtrace_copystr)
END(dtrace_copystr)
/*
- * The panic() and cmn_err() functions invoke vpanic() as a common entry point
- * into the panic code implemented in panicsys(). vpanic() is responsible
- * for passing through the format string and arguments, and constructing a
- * regs structure on the stack into which it saves the current register
- * values. If we are not dying due to a fatal trap, these registers will
- * then be preserved in panicbuf as the current processor state. Before
- * invoking panicsys(), vpanic() activates the first panic trigger (see
- * common/os/panic.c) and switches to the panic_stack if successful. Note that
- * DTrace takes a slightly different panic path if it must panic from probe
- * context. Instead of calling panic, it calls into dtrace_vpanic(), which
- * sets up the initial stack as vpanic does, calls dtrace_panic_trigger(), and
- * branches back into vpanic().
- */
-
-/*
-void
-vpanic(const char *format, va_list alist)
-*/
-ASENTRY_NOPROF(vpanic) /* Initial stack layout: */
-
-vpanic_common:
- blr
-END(vpanic)
-
-
-
-/*
-void
-dtrace_vpanic(const char *format, va_list alist)
-*/
-ASENTRY_NOPROF(dtrace_vpanic) /* Initial stack layout: */
-
-#if 0
- bl dtrace_panic_trigger /* %eax = dtrace_panic_trigger() */
-#endif
- b vpanic_common
-END(dtrace_vpanic)
-
-/*
uintptr_t
dtrace_caller(int aframes)
*/
@@ -207,4 +168,3 @@ ASENTRY_NOPROF(dtrace_caller)
li %r3, -1
blr
END(dtrace_caller)
-
diff --git a/sys/cddl/dev/profile/profile.c b/sys/cddl/dev/profile/profile.c
index 338a95843913..d31d5c81077e 100644
--- a/sys/cddl/dev/profile/profile.c
+++ b/sys/cddl/dev/profile/profile.c
@@ -134,8 +134,10 @@ struct profile_probe_percpu;
#endif
#ifdef __arm__
-/* bogus */
-#define PROF_ARTIFICIAL_FRAMES 9
+/*
+ * At least on ARMv7, this appears to work quite well.
+ */
+#define PROF_ARTIFICIAL_FRAMES 10
#endif
typedef struct profile_probe {
diff --git a/sys/compat/linux/linux_getcwd.c b/sys/compat/linux/linux_getcwd.c
index 7c0b9ba5fa92..ebcf97008bf7 100644
--- a/sys/compat/linux/linux_getcwd.c
+++ b/sys/compat/linux/linux_getcwd.c
@@ -2,11 +2,15 @@
/* $NetBSD: vfs_getcwd.c,v 1.3.2.3 1999/07/11 10:24:09 sommerfeld Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * Copyright (c) 2015 The FreeBSD Foundation
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Bill Sommerfeld.
*
+ * Portions of this software were developed by Edward Tomasz Napierala
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -36,19 +40,9 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
-#include <sys/namei.h>
-#include <sys/filedesc.h>
-#include <sys/kernel.h>
-#include <sys/file.h>
-#include <sys/stat.h>
#include <sys/syscallsubr.h>
-#include <sys/vnode.h>
-#include <sys/mount.h>
#include <sys/proc.h>
-#include <sys/uio.h>
#include <sys/malloc.h>
-#include <sys/dirent.h>
-#include <ufs/ufs/dir.h> /* XXX only for DIRBLKSIZ */
#ifdef COMPAT_LINUX32
#include <machine/../linux32/linux.h>
@@ -60,408 +54,37 @@ __FBSDID("$FreeBSD$");
#include <compat/linux/linux_misc.h>
#include <compat/linux/linux_util.h>
-#include <security/mac/mac_framework.h>
-
-static int
-linux_getcwd_scandir(struct vnode **, struct vnode **,
- char **, char *, struct thread *);
-static int
-linux_getcwd_common(struct vnode *, struct vnode *,
- char **, char *, int, int, struct thread *);
-
-#define DIRENT_MINSIZE (sizeof(struct dirent) - (MAXNAMLEN+1) + 4)
-
-/*
- * Vnode variable naming conventions in this file:
- *
- * rvp: the current root we're aiming towards.
- * lvp, *lvpp: the "lower" vnode
- * uvp, *uvpp: the "upper" vnode.
- *
- * Since all the vnodes we're dealing with are directories, and the
- * lookups are going *up* in the filesystem rather than *down*, the
- * usual "pvp" (parent) or "dvp" (directory) naming conventions are
- * too confusing.
- */
-
-/*
- * XXX Will infinite loop in certain cases if a directory read reliably
- * returns EINVAL on last block.
- * XXX is EINVAL the right thing to return if a directory is malformed?
- */
-
-/*
- * XXX Untested vs. mount -o union; probably does the wrong thing.
- */
-
-/*
- * Find parent vnode of *lvpp, return in *uvpp
- *
- * If we care about the name, scan it looking for name of directory
- * entry pointing at lvp.
- *
- * Place the name in the buffer which starts at bufp, immediately
- * before *bpp, and move bpp backwards to point at the start of it.
- *
- * On entry, *lvpp is a locked vnode reference; on exit, it is vput and NULL'ed
- * On exit, *uvpp is either NULL or is a locked vnode reference.
- */
-static int
-linux_getcwd_scandir(lvpp, uvpp, bpp, bufp, td)
- struct vnode **lvpp;
- struct vnode **uvpp;
- char **bpp;
- char *bufp;
- struct thread *td;
-{
- int error = 0;
- int eofflag;
- off_t off;
- int tries;
- struct uio uio;
- struct iovec iov;
- char *dirbuf = NULL;
- int dirbuflen;
- ino_t fileno;
- struct vattr va;
- struct vnode *uvp = NULL;
- struct vnode *lvp = *lvpp;
- struct componentname cn;
- int len, reclen;
- tries = 0;
-
- /*
- * If we want the filename, get some info we need while the
- * current directory is still locked.
- */
- if (bufp != NULL) {
- error = VOP_GETATTR(lvp, &va, td->td_ucred);
- if (error) {
- vput(lvp);
- *lvpp = NULL;
- *uvpp = NULL;
- return error;
- }
- }
-
- /*
- * Ok, we have to do it the hard way..
- * Next, get parent vnode using lookup of ..
- */
- cn.cn_nameiop = LOOKUP;
- cn.cn_flags = ISLASTCN | ISDOTDOT | RDONLY;
- cn.cn_thread = td;
- cn.cn_cred = td->td_ucred;
- cn.cn_pnbuf = NULL;
- cn.cn_nameptr = "..";
- cn.cn_namelen = 2;
- cn.cn_consume = 0;
- cn.cn_lkflags = LK_SHARED;
-
- /*
- * At this point, lvp is locked and will be unlocked by the lookup.
- * On successful return, *uvpp will be locked
- */
-#ifdef MAC
- error = mac_vnode_check_lookup(td->td_ucred, lvp, &cn);
- if (error == 0)
-#endif
- error = VOP_LOOKUP(lvp, uvpp, &cn);
- if (error) {
- vput(lvp);
- *lvpp = NULL;
- *uvpp = NULL;
- return error;
- }
- uvp = *uvpp;
-
- /* If we don't care about the pathname, we're done */
- if (bufp == NULL) {
- vput(lvp);
- *lvpp = NULL;
- return 0;
- }
-
- fileno = va.va_fileid;
-
- dirbuflen = DIRBLKSIZ;
- if (dirbuflen < va.va_blocksize)
- dirbuflen = va.va_blocksize;
- dirbuf = malloc(dirbuflen, M_TEMP, M_WAITOK);
-
-#if 0
-unionread:
-#endif
- off = 0;
- do {
- /* call VOP_READDIR of parent */
- iov.iov_base = dirbuf;
- iov.iov_len = dirbuflen;
-
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- uio.uio_offset = off;
- uio.uio_resid = dirbuflen;
- uio.uio_segflg = UIO_SYSSPACE;
- uio.uio_rw = UIO_READ;
- uio.uio_td = td;
-
- eofflag = 0;
-
-#ifdef MAC
- error = mac_vnode_check_readdir(td->td_ucred, uvp);
- if (error == 0)
-#endif /* MAC */
- error = VOP_READDIR(uvp, &uio, td->td_ucred, &eofflag,
- 0, 0);
-
- off = uio.uio_offset;
-
- /*
- * Try again if NFS tosses its cookies.
- * XXX this can still loop forever if the directory is busted
- * such that the second or subsequent page of it always
- * returns EINVAL
- */
- if ((error == EINVAL) && (tries < 3)) {
- off = 0;
- tries++;
- continue; /* once more, with feeling */
- }
-
- if (!error) {
- char *cpos;
- struct dirent *dp;
-
- cpos = dirbuf;
- tries = 0;
-
- /* scan directory page looking for matching vnode */
- for (len = (dirbuflen - uio.uio_resid); len > 0; len -= reclen) {
- dp = (struct dirent *) cpos;
- reclen = dp->d_reclen;
-
- /* check for malformed directory.. */
- if (reclen < DIRENT_MINSIZE) {
- error = EINVAL;
- goto out;
- }
- /*
- * XXX should perhaps do VOP_LOOKUP to
- * check that we got back to the right place,
- * but getting the locking games for that
- * right would be heinous.
- */
- if ((dp->d_type != DT_WHT) &&
- (dp->d_fileno == fileno)) {
- char *bp = *bpp;
- bp -= dp->d_namlen;
-
- if (bp <= bufp) {
- error = ERANGE;
- goto out;
- }
- bcopy(dp->d_name, bp, dp->d_namlen);
- error = 0;
- *bpp = bp;
- goto out;
- }
- cpos += reclen;
- }
- }
- } while (!eofflag);
- error = ENOENT;
-
-out:
- vput(lvp);
- *lvpp = NULL;
- free(dirbuf, M_TEMP);
- return error;
-}
-
-
-/*
- * common routine shared by sys___getcwd() and linux_vn_isunder()
- */
-
-#define GETCWD_CHECK_ACCESS 0x0001
-
-static int
-linux_getcwd_common (lvp, rvp, bpp, bufp, limit, flags, td)
- struct vnode *lvp;
- struct vnode *rvp;
- char **bpp;
- char *bufp;
- int limit;
- int flags;
- struct thread *td;
-{
- struct filedesc *fdp = td->td_proc->p_fd;
- struct vnode *uvp = NULL;
- char *bp = NULL;
- int error;
- accmode_t accmode = VEXEC;
-
- if (rvp == NULL) {
- rvp = fdp->fd_rdir;
- if (rvp == NULL)
- rvp = rootvnode;
- }
-
- VREF(rvp);
- VREF(lvp);
-
- /*
- * Error handling invariant:
- * Before a `goto out':
- * lvp is either NULL, or locked and held.
- * uvp is either NULL, or locked and held.
- */
-
- error = vn_lock(lvp, LK_EXCLUSIVE | LK_RETRY);
- if (error != 0)
- panic("vn_lock LK_RETRY returned error %d", error);
- if (bufp)
- bp = *bpp;
- /*
- * this loop will terminate when one of the following happens:
- * - we hit the root
- * - getdirentries or lookup fails
- * - we run out of space in the buffer.
- */
- if (lvp == rvp) {
- if (bp)
- *(--bp) = '/';
- goto out;
- }
- do {
- if (lvp->v_type != VDIR) {
- error = ENOTDIR;
- goto out;
- }
-
- /*
- * access check here is optional, depending on
- * whether or not caller cares.
- */
- if (flags & GETCWD_CHECK_ACCESS) {
- error = VOP_ACCESS(lvp, accmode, td->td_ucred, td);
- if (error)
- goto out;
- accmode = VEXEC|VREAD;
- }
-
- /*
- * step up if we're a covered vnode..
- */
- while (lvp->v_vflag & VV_ROOT) {
- struct vnode *tvp;
-
- if (lvp == rvp)
- goto out;
-
- tvp = lvp;
- lvp = lvp->v_mount->mnt_vnodecovered;
- vput(tvp);
- /*
- * hodie natus est radici frater
- */
- if (lvp == NULL) {
- error = ENOENT;
- goto out;
- }
- VREF(lvp);
- error = vn_lock(lvp, LK_EXCLUSIVE | LK_RETRY);
- if (error != 0)
- panic("vn_lock LK_RETRY returned %d", error);
- }
- error = linux_getcwd_scandir(&lvp, &uvp, &bp, bufp, td);
- if (error)
- goto out;
-#ifdef DIAGNOSTIC
- if (lvp != NULL)
- panic("getcwd: oops, forgot to null lvp");
- if (bufp && (bp <= bufp)) {
- panic("getcwd: oops, went back too far");
- }
-#endif
- if (bp)
- *(--bp) = '/';
- lvp = uvp;
- uvp = NULL;
- limit--;
- } while ((lvp != rvp) && (limit > 0));
-
-out:
- if (bpp)
- *bpp = bp;
- if (uvp)
- vput(uvp);
- if (lvp)
- vput(lvp);
- vrele(rvp);
- return error;
-}
-
-
/*
* Find pathname of process's current directory.
- *
- * Use vfs vnode-to-name reverse cache; if that fails, fall back
- * to reading directory contents.
*/
-
int
linux_getcwd(struct thread *td, struct linux_getcwd_args *args)
{
- char *bp, *bend, *path;
- int error, len, lenused;
+ char *path;
+ int error, lenused;
#ifdef DEBUG
if (ldebug(getcwd))
printf(ARGS(getcwd, "%p, %ld"), args->buf, (long)args->bufsize);
#endif
- len = args->bufsize;
-
- if (len > LINUX_PATH_MAX)
- len = LINUX_PATH_MAX;
- else if (len < 2)
- return ERANGE;
+ /*
+ * Linux returns ERANGE instead of EINVAL.
+ */
+ if (args->bufsize < 2)
+ return (ERANGE);
- path = malloc(len, M_TEMP, M_WAITOK);
+ path = malloc(LINUX_PATH_MAX, M_TEMP, M_WAITOK);
- error = kern___getcwd(td, path, UIO_SYSSPACE, len, LINUX_PATH_MAX);
- if (!error) {
+ error = kern___getcwd(td, path, UIO_SYSSPACE, args->bufsize,
+ LINUX_PATH_MAX);
+ if (error == 0) {
lenused = strlen(path) + 1;
- if (lenused <= args->bufsize) {
+ error = copyout(path, args->buf, lenused);
+ if (error == 0)
td->td_retval[0] = lenused;
- error = copyout(path, args->buf, lenused);
- }
- else
- error = ERANGE;
- } else {
- bp = &path[len];
- bend = bp;
- *(--bp) = '\0';
-
- /*
- * 5th argument here is "max number of vnodes to traverse".
- * Since each entry takes up at least 2 bytes in the output buffer,
- * limit it to N/2 vnodes for an N byte buffer.
- */
-
- error = linux_getcwd_common (td->td_proc->p_fd->fd_cdir, NULL,
- &bp, path, len/2, GETCWD_CHECK_ACCESS, td);
- if (error)
- goto out;
- lenused = bend - bp;
- td->td_retval[0] = lenused;
- /* put the result into user buffer */
- error = copyout(bp, args->buf, lenused);
}
-out:
+
free(path, M_TEMP);
return (error);
}
-
diff --git a/sys/conf/files b/sys/conf/files
index ce28fa17de06..caaed94e76b9 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -584,7 +584,6 @@ dev/acpica/acpi_button.c optional acpi
dev/acpica/acpi_cmbat.c optional acpi
dev/acpica/acpi_cpu.c optional acpi
dev/acpica/acpi_ec.c optional acpi
-dev/acpica/acpi_hpet.c optional acpi
dev/acpica/acpi_isab.c optional acpi isa
dev/acpica/acpi_lid.c optional acpi
dev/acpica/acpi_package.c optional acpi
@@ -1780,6 +1779,8 @@ dev/ixgbe/ixgbe_82599.c optional ix ixv inet \
compile-with "${NORMAL_C} -I$S/dev/ixgbe"
dev/ixgbe/ixgbe_x540.c optional ix ixv inet \
compile-with "${NORMAL_C} -I$S/dev/ixgbe"
+dev/ixgbe/ixgbe_x550.c optional ix ixv inet \
+ compile-with "${NORMAL_C} -I$S/dev/ixgbe"
dev/ixgbe/ixgbe_dcb.c optional ix ixv inet \
compile-with "${NORMAL_C} -I$S/dev/ixgbe"
dev/ixgbe/ixgbe_dcb_82598.c optional ix ixv inet \
@@ -2677,24 +2678,24 @@ wpi.fw optional wpifw \
clean "wpi.fw"
dev/xe/if_xe.c optional xe
dev/xe/if_xe_pccard.c optional xe pccard
-dev/xen/balloon/balloon.c optional xen | xenhvm
-dev/xen/blkfront/blkfront.c optional xen | xenhvm
-dev/xen/blkback/blkback.c optional xen | xenhvm
-dev/xen/console/console.c optional xen | xenhvm
-dev/xen/console/xencons_ring.c optional xen | xenhvm
-dev/xen/control/control.c optional xen | xenhvm
-dev/xen/grant_table/grant_table.c optional xen | xenhvm
-dev/xen/netback/netback.c optional xen | xenhvm
-dev/xen/netfront/netfront.c optional xen | xenhvm
+dev/xen/balloon/balloon.c optional xenhvm
+dev/xen/blkfront/blkfront.c optional xenhvm
+dev/xen/blkback/blkback.c optional xenhvm
+dev/xen/console/console.c optional xenhvm
+dev/xen/console/xencons_ring.c optional xenhvm
+dev/xen/control/control.c optional xenhvm
+dev/xen/grant_table/grant_table.c optional xenhvm
+dev/xen/netback/netback.c optional xenhvm
+dev/xen/netfront/netfront.c optional xenhvm
dev/xen/xenpci/xenpci.c optional xenpci
-dev/xen/timer/timer.c optional xen | xenhvm
-dev/xen/pvcpu/pvcpu.c optional xen | xenhvm
-dev/xen/xenstore/xenstore.c optional xen | xenhvm
-dev/xen/xenstore/xenstore_dev.c optional xen | xenhvm
-dev/xen/xenstore/xenstored_dev.c optional xen | xenhvm
-dev/xen/evtchn/evtchn_dev.c optional xen | xenhvm
-dev/xen/privcmd/privcmd.c optional xen | xenhvm
-dev/xen/debug/debug.c optional xen | xenhvm
+dev/xen/timer/timer.c optional xenhvm
+dev/xen/pvcpu/pvcpu.c optional xenhvm
+dev/xen/xenstore/xenstore.c optional xenhvm
+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/debug/debug.c optional xenhvm
dev/xl/if_xl.c optional xl pci
dev/xl/xlphy.c optional xl pci
fs/autofs/autofs.c optional autofs
@@ -3262,6 +3263,9 @@ libkern/strtoul.c standard
libkern/strtouq.c standard
libkern/strvalid.c standard
libkern/timingsafe_bcmp.c standard
+libkern/zlib.c optional crypto | geom_uzip | ipsec | \
+ mxge | netgraph_deflate | \
+ ddb_ctf | gzio | geom_uncompress
net/altq/altq_cbq.c optional altq
net/altq/altq_cdnr.c optional altq
net/altq/altq_hfsc.c optional altq
@@ -3324,9 +3328,6 @@ net/slcompress.c optional netgraph_vjc | sppp | \
netgraph_sppp
net/toeplitz.c optional inet rss | inet6 rss
net/vnet.c optional vimage
-net/zlib.c optional crypto | geom_uzip | ipsec | \
- mxge | netgraph_deflate | \
- ddb_ctf | gzio | geom_uncompress
net80211/ieee80211.c optional wlan
net80211/ieee80211_acl.c optional wlan wlan_acl
net80211/ieee80211_action.c optional wlan
@@ -3503,6 +3504,7 @@ netinet/sctp_sysctl.c optional inet sctp | inet6 sctp
netinet/sctp_timer.c optional inet sctp | inet6 sctp
netinet/sctp_usrreq.c optional inet sctp | inet6 sctp
netinet/sctputil.c optional inet sctp | inet6 sctp
+netinet/siftr.c optional inet siftr alq | inet6 siftr alq
netinet/tcp_debug.c optional tcpdebug
netinet/tcp_hostcache.c optional inet | inet6
netinet/tcp_input.c optional inet | inet6
@@ -4043,13 +4045,13 @@ vm/vm_reserv.c standard
vm/vm_unix.c standard
vm/vm_zeroidle.c standard
vm/vnode_pager.c standard
-xen/features.c optional xen | xenhvm
-xen/xenbus/xenbus_if.m optional xen | xenhvm
-xen/xenbus/xenbus.c optional xen | xenhvm
-xen/xenbus/xenbusb_if.m optional xen | xenhvm
-xen/xenbus/xenbusb.c optional xen | xenhvm
-xen/xenbus/xenbusb_front.c optional xen | xenhvm
-xen/xenbus/xenbusb_back.c optional xen | xenhvm
+xen/features.c optional xenhvm
+xen/xenbus/xenbus_if.m optional xenhvm
+xen/xenbus/xenbus.c optional xenhvm
+xen/xenbus/xenbusb_if.m optional xenhvm
+xen/xenbus/xenbusb.c optional xenhvm
+xen/xenbus/xenbusb_front.c optional xenhvm
+xen/xenbus/xenbusb_back.c optional xenhvm
xdr/xdr.c optional krpc | nfslockd | nfscl | nfsd
xdr/xdr_array.c optional krpc | nfslockd | nfscl | nfsd
xdr/xdr_mbuf.c optional krpc | nfslockd | nfscl | nfsd
diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64
index ae71c396efa5..8aadcf5fba2f 100644
--- a/sys/conf/files.amd64
+++ b/sys/conf/files.amd64
@@ -145,6 +145,7 @@ crypto/via/padlock.c optional padlock
crypto/via/padlock_cipher.c optional padlock
crypto/via/padlock_hash.c optional padlock
dev/acpica/acpi_if.m standard
+dev/acpica/acpi_hpet.c optional acpi
dev/acpi_support/acpi_wmi_if.m standard
dev/agp/agp_amd64.c optional agp
dev/agp/agp_i810.c optional agp
@@ -513,10 +514,10 @@ compat/ndis/winx64_wrap.S optional ndisapi pci
libkern/memmove.c standard
libkern/memset.c standard
#
-# x86 real mode BIOS emulator, required by atkbdc/dpms/pci/vesa
+# x86 real mode BIOS emulator, required by dpms/pci/vesa
#
-compat/x86bios/x86bios.c optional x86bios | atkbd | dpms | pci | vesa
-contrib/x86emu/x86emu.c optional x86bios | atkbd | dpms | pci | vesa
+compat/x86bios/x86bios.c optional x86bios | dpms | pci | vesa
+contrib/x86emu/x86emu.c optional x86bios | dpms | pci | vesa
#
# bvm console
#
@@ -569,13 +570,14 @@ x86/x86/local_apic.c standard
x86/x86/mca.c standard
x86/x86/mptable.c optional mptable
x86/x86/mptable_pci.c optional mptable pci
+x86/x86/mp_x86.c optional smp
x86/x86/msi.c optional pci
x86/x86/nexus.c standard
x86/x86/pvclock.c standard
x86/x86/tsc.c standard
x86/x86/delay.c standard
x86/xen/hvm.c optional xenhvm
-x86/xen/xen_intr.c optional xen | xenhvm
+x86/xen/xen_intr.c optional xenhvm
x86/xen/pv.c optional xenhvm
x86/xen/pvcpu_enum.c optional xenhvm
x86/xen/xen_apic.c optional xenhvm
diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64
index 758c9a6fa0ce..f80fecd7c811 100644
--- a/sys/conf/files.arm64
+++ b/sys/conf/files.arm64
@@ -10,6 +10,10 @@ arm64/arm64/clock.c standard
arm64/arm64/copyinout.S standard
arm64/arm64/copystr.c standard
arm64/arm64/cpufunc_asm.S standard
+arm64/arm64/db_disasm.c optional ddb
+arm64/arm64/db_interface.c optional ddb
+arm64/arm64/db_trace.c optional ddb
+arm64/arm64/debug_monitor.c optional kdb
arm64/arm64/dump_machdep.c standard
arm64/arm64/elf_machdep.c standard
arm64/arm64/exception.S standard
diff --git a/sys/conf/files.i386 b/sys/conf/files.i386
index f072247b7870..68dd6a9aea4e 100644
--- a/sys/conf/files.i386
+++ b/sys/conf/files.i386
@@ -285,6 +285,7 @@ dev/uart/uart_cpu_x86.c optional uart
dev/viawd/viawd.c optional viawd
dev/vmware/vmxnet3/if_vmx.c optional vmx
dev/acpica/acpi_if.m standard
+dev/acpica/acpi_hpet.c optional acpi
dev/acpi_support/acpi_wmi_if.m standard
dev/wbwd/wbwd.c optional wbwd
dev/wpi/if_wpi.c optional wpi
@@ -427,16 +428,15 @@ i386/bios/smapi_bios.S optional smapi
i386/i386/atomic.c standard \
compile-with "${CC} -c ${CFLAGS} ${DEFINED_PROF:S/^$/-fomit-frame-pointer/} ${.IMPSRC}"
i386/i386/autoconf.c standard
-i386/i386/bios.c optional native
-i386/i386/bioscall.s optional native
+i386/i386/bios.c standard
+i386/i386/bioscall.s standard
i386/i386/bpf_jit_machdep.c optional bpf_jitter
i386/i386/db_disasm.c optional ddb
i386/i386/db_interface.c optional ddb
i386/i386/db_trace.c optional ddb
i386/i386/elan-mmcr.c optional cpu_elan | cpu_soekris
i386/i386/elf_machdep.c standard
-i386/i386/exception.s optional native
-i386/xen/exception.s optional xen
+i386/i386/exception.s standard
i386/i386/gdb_machdep.c optional gdb
i386/i386/geode.c optional cpu_geode
i386/i386/i686_mem.c optional mem
@@ -444,22 +444,17 @@ i386/i386/in_cksum.c optional inet | inet6
i386/i386/initcpu.c standard
i386/i386/io.c optional io
i386/i386/k6_mem.c optional mem
-i386/i386/locore.s optional native no-obj
-i386/xen/locore.s optional xen no-obj
+i386/i386/locore.s standard no-obj
i386/i386/longrun.c optional cpu_enable_longrun
i386/i386/machdep.c standard
-i386/xen/xen_machdep.c optional xen
i386/i386/mem.c optional mem
i386/i386/minidump_machdep.c standard
i386/i386/mp_clock.c optional smp
-i386/i386/mp_machdep.c optional native smp
-i386/xen/mp_machdep.c optional xen smp
+i386/i386/mp_machdep.c optional smp
i386/i386/mp_watchdog.c optional mp_watchdog smp
-i386/i386/mpboot.s optional smp native
-i386/xen/mptable.c optional apic xen
+i386/i386/mpboot.s optional smp
i386/i386/perfmon.c optional perfmon
-i386/i386/pmap.c optional native
-i386/xen/pmap.c optional xen
+i386/i386/pmap.c standard
i386/i386/ptrace_machdep.c standard
i386/i386/stack_machdep.c optional ddb | stack
i386/i386/support.s standard
@@ -488,7 +483,6 @@ i386/ibcs2/ibcs2_util.c optional ibcs2
i386/ibcs2/ibcs2_xenix.c optional ibcs2
i386/ibcs2/ibcs2_xenix_sysent.c optional ibcs2
i386/ibcs2/imgact_coff.c optional ibcs2
-i386/xen/clock.c optional xen
i386/isa/elink.c optional ep | ie
i386/isa/npx.c optional npx
i386/isa/pmtimer.c optional pmtimer
@@ -531,9 +525,9 @@ i386/xbox/xboxfb.c optional xboxfb
dev/fb/boot_font.c optional xboxfb
i386/xbox/pic16l.s optional xbox
#
-# x86 real mode BIOS support, required by atkbdc/dpms/pci/vesa
+# x86 real mode BIOS support, required by dpms/pci/vesa
#
-compat/x86bios/x86bios.c optional x86bios | atkbd | dpms | pci | vesa
+compat/x86bios/x86bios.c optional x86bios | dpms | pci | vesa
#
# bvm console
#
@@ -565,9 +559,9 @@ x86/iommu/intel_qi.c optional acpi acpi_dmar pci
x86/iommu/intel_quirks.c optional acpi acpi_dmar pci
x86/iommu/intel_utils.c optional acpi acpi_dmar pci
x86/isa/atpic.c optional atpic
-x86/isa/atrtc.c optional native
-x86/isa/clock.c optional native
-x86/isa/elcr.c optional atpic | apic native
+x86/isa/atrtc.c standard
+x86/isa/clock.c standard
+x86/isa/elcr.c optional atpic | apic
x86/isa/isa.c optional isa
x86/isa/isa_dma.c optional isa
x86/isa/nmi.c standard
@@ -582,19 +576,20 @@ x86/x86/fdt_machdep.c optional fdt
x86/x86/identcpu.c standard
x86/x86/intr_machdep.c standard
x86/x86/io_apic.c optional apic
-x86/x86/legacy.c optional native
+x86/x86/legacy.c standard
x86/x86/local_apic.c optional apic
x86/x86/mca.c standard
-x86/x86/mptable.c optional apic native
-x86/x86/mptable_pci.c optional apic native pci
+x86/x86/mptable.c optional apic
+x86/x86/mptable_pci.c optional apic pci
+x86/x86/mp_x86.c optional smp
x86/x86/msi.c optional apic pci
x86/x86/nexus.c standard
x86/x86/tsc.c standard
x86/x86/pvclock.c standard
x86/x86/delay.c standard
x86/xen/hvm.c optional xenhvm
-x86/xen/xen_intr.c optional xen | xenhvm
+x86/xen/xen_intr.c optional xenhvm
x86/xen/xen_apic.c optional xenhvm
-x86/xen/xenpv.c optional xen | xenhvm
-x86/xen/xen_nexus.c optional xen | xenhvm
-x86/xen/xen_msi.c optional xen | xenhvm
+x86/xen/xenpv.c optional xenhvm
+x86/xen/xen_nexus.c optional xenhvm
+x86/xen/xen_msi.c optional xenhvm
diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98
index f95d0bb681cc..ae165fcd3b85 100644
--- a/sys/conf/files.pc98
+++ b/sys/conf/files.pc98
@@ -256,6 +256,7 @@ x86/x86/io_apic.c optional apic
x86/x86/legacy.c standard
x86/x86/local_apic.c optional apic
x86/x86/mca.c standard
+x86/x86/mp_x86.c optional smp
x86/x86/mptable.c optional apic
x86/x86/mptable_pci.c optional apic pci
x86/x86/msi.c optional apic pci
diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc
index ab585b067f83..92f41019b427 100644
--- a/sys/conf/files.powerpc
+++ b/sys/conf/files.powerpc
@@ -97,17 +97,16 @@ libkern/udivdi3.c optional powerpc
libkern/umoddi3.c optional powerpc
powerpc/aim/interrupt.c optional aim
powerpc/aim/locore.S optional aim no-obj
-powerpc/aim/machdep.c optional aim
+powerpc/aim/aim_machdep.c optional aim
powerpc/aim/mmu_oea.c optional aim powerpc
powerpc/aim/mmu_oea64.c optional aim
powerpc/aim/moea64_if.m optional aim
powerpc/aim/moea64_native.c optional aim
powerpc/aim/mp_cpudep.c optional aim
powerpc/aim/slb.c optional aim powerpc64
-powerpc/aim/uma_machdep.c optional aim
powerpc/booke/interrupt.c optional booke
powerpc/booke/locore.S optional booke no-obj
-powerpc/booke/machdep.c optional booke
+powerpc/booke/booke_machdep.c optional booke
powerpc/booke/machdep_e500.c optional booke_e500
powerpc/booke/mp_cpudep.c optional booke smp
powerpc/booke/platform_bare.c optional booke
@@ -195,6 +194,7 @@ powerpc/powerpc/gdb_machdep.c optional gdb
powerpc/powerpc/in_cksum.c optional inet | inet6
powerpc/powerpc/intr_machdep.c standard
powerpc/powerpc/iommu_if.m standard
+powerpc/powerpc/machdep.c standard
powerpc/powerpc/mem.c optional mem
powerpc/powerpc/mmu_if.m standard
powerpc/powerpc/mp_machdep.c optional smp
@@ -217,6 +217,7 @@ powerpc/powerpc/syncicache.c standard
powerpc/powerpc/sys_machdep.c standard
powerpc/powerpc/trap.c standard
powerpc/powerpc/uio_machdep.c standard
+powerpc/powerpc/uma_machdep.c standard
powerpc/powerpc/vm_machdep.c standard
powerpc/ps3/ehci_ps3.c optional ps3 ehci
powerpc/ps3/ohci_ps3.c optional ps3 ohci
diff --git a/sys/conf/kern.mk b/sys/conf/kern.mk
index 9a7ad618b515..8e76268354b2 100644
--- a/sys/conf/kern.mk
+++ b/sys/conf/kern.mk
@@ -187,7 +187,7 @@ CFLAGS+= -fstack-protector
CFLAGS+= -gdwarf-2
.endif
-CFLAGS+= ${CWARNEXTRA} ${CWARNFLAGS} ${CWARNFLAGS.${.IMPSRC:T}}
+CFLAGS+= ${CWARNFLAGS} ${CWARNFLAGS.${.IMPSRC:T}}
CFLAGS+= ${CFLAGS.${COMPILER_TYPE}} ${CFLAGS.${.IMPSRC:T}}
# Tell bmake not to mistake standard targets for things to be searched for
diff --git a/sys/conf/kern.pre.mk b/sys/conf/kern.pre.mk
index 99ada0508294..8c3b9c6e942f 100644
--- a/sys/conf/kern.pre.mk
+++ b/sys/conf/kern.pre.mk
@@ -87,7 +87,7 @@ INCLUDES+= -I$S/dev/cxgb -I$S/dev/cxgbe
.endif
-CFLAGS= ${COPTFLAGS} ${DEBUG} ${CWARNFLAGS}
+CFLAGS= ${COPTFLAGS} ${DEBUG}
CFLAGS+= ${INCLUDES} -D_KERNEL -DHAVE_KERNEL_OPTION_HEADERS -include opt_global.h
CFLAGS_PARAM_INLINE_UNIT_GROWTH?=100
CFLAGS_PARAM_LARGE_FUNCTION_GROWTH?=1000
diff --git a/sys/conf/options b/sys/conf/options
index 2405442a5fbe..b6987173e6fc 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -432,6 +432,7 @@ ROUTETABLES opt_route.h
RSS opt_rss.h
SLIP_IFF_OPTS opt_slip.h
TCPDEBUG
+SIFTR
TCP_OFFLOAD opt_inet.h # Enable code to dispatch TCP offloading
TCP_SIGNATURE opt_inet.h
VLAN_ARRAY opt_vlan.h
@@ -928,6 +929,7 @@ IPOIB_CM opt_ofed.h
# Resource Accounting
RACCT opt_global.h
+RACCT_DISABLED opt_global.h
# Resource Limits
RCTL opt_global.h
diff --git a/sys/conf/options.amd64 b/sys/conf/options.amd64
index f1d4b4a57e48..0e591878dece 100644
--- a/sys/conf/options.amd64
+++ b/sys/conf/options.amd64
@@ -63,5 +63,7 @@ BPF_JITTER opt_bpf.h
XENHVM opt_global.h
+HYPERV opt_global.h
+
# options for the Intel C600 SAS driver (isci)
ISCI_LOGGING opt_isci.h
diff --git a/sys/conf/options.arm b/sys/conf/options.arm
index 239be2a73e69..b712b02fec5a 100644
--- a/sys/conf/options.arm
+++ b/sys/conf/options.arm
@@ -40,6 +40,9 @@ PV_STATS opt_pmap.h
QEMU_WORKAROUNDS opt_global.h
SOC_BCM2835 opt_global.h
SOC_BCM2836 opt_global.h
+SOC_IMX51 opt_global.h
+SOC_IMX53 opt_global.h
+SOC_IMX6 opt_global.h
SOC_MV_ARMADAXP opt_global.h
SOC_MV_DISCOVERY opt_global.h
SOC_MV_DOVE opt_global.h
diff --git a/sys/conf/options.arm64 b/sys/conf/options.arm64
index fff47abaa13e..1dfcbec11ffe 100644
--- a/sys/conf/options.arm64
+++ b/sys/conf/options.arm64
@@ -1,4 +1,6 @@
# $FreeBSD$
ARM64 opt_global.h
+SOCDEV_PA opt_global.h
+SOCDEV_VA opt_global.h
VFP opt_global.h
diff --git a/sys/conf/options.i386 b/sys/conf/options.i386
index 0a1a52f21991..69eb7e374a21 100644
--- a/sys/conf/options.i386
+++ b/sys/conf/options.i386
@@ -121,9 +121,9 @@ NPX_DEBUG opt_npx.h
# BPF just-in-time compiler
BPF_JITTER opt_bpf.h
-NATIVE opt_global.h
-XEN opt_global.h
XENHVM opt_global.h
+HYPERV opt_global.h
+
# options for the Intel C600 SAS driver (isci)
ISCI_LOGGING opt_isci.h
diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
index 47bc79153dad..7796fbe39ef6 100644
--- a/sys/dev/acpica/acpi.c
+++ b/sys/dev/acpica/acpi.c
@@ -606,7 +606,7 @@ acpi_attach(device_t dev)
sc->acpi_handle_reboot = 1;
/* Only enable S4BIOS by default if the FACS says it is available. */
- if (AcpiGbl_FACS->Flags & ACPI_FACS_S4_BIOS_PRESENT)
+ if (AcpiGbl_FACS != NULL && AcpiGbl_FACS->Flags & ACPI_FACS_S4_BIOS_PRESENT)
sc->acpi_s4bios = 1;
/* Probe all supported sleep states. */
diff --git a/sys/dev/atkbdc/atkbd.c b/sys/dev/atkbdc/atkbd.c
index d93c1c6da01b..a90f5d203db7 100644
--- a/sys/dev/atkbdc/atkbd.c
+++ b/sys/dev/atkbdc/atkbd.c
@@ -44,19 +44,6 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/resource.h>
-#if defined(__i386__) || defined(__amd64__)
-#include <machine/md_var.h>
-#include <machine/psl.h>
-#include <compat/x86bios/x86bios.h>
-#include <machine/pc/bios.h>
-
-#include <vm/vm.h>
-#include <vm/pmap.h>
-#include <vm/vm_param.h>
-
-#include <isa/isareg.h>
-#endif /* __i386__ || __amd64__ */
-
#include <sys/kbio.h>
#include <dev/kbd/kbdreg.h>
#include <dev/atkbdc/atkbdreg.h>
@@ -82,6 +69,9 @@ static int atkbd_reset(KBDC kbdc, int flags, int c);
#define HAS_QUIRK(p, q) (((atkbdc_softc_t *)(p))->quirks & q)
#define ALLOW_DISABLE_KBD(kbdc) !HAS_QUIRK(kbdc, KBDC_QUIRK_KEEP_ACTIVATED)
+#define DEFAULT_DELAY 0x1 /* 500ms */
+#define DEFAULT_RATE 0x10 /* 14Hz */
+
int
atkbd_probe_unit(device_t dev, int irq, int flags)
{
@@ -249,7 +239,7 @@ static keyboard_switch_t atkbdsw = {
KEYBOARD_DRIVER(atkbd, atkbdsw, atkbd_configure);
/* local functions */
-static int get_typematic(keyboard_t *kbd);
+static int set_typematic(keyboard_t *kbd);
static int setup_kbd_port(KBDC kbdc, int port, int intr);
static int get_kbd_echo(KBDC kbdc);
static int probe_keyboard(KBDC kbdc, int flags);
@@ -443,7 +433,7 @@ atkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
goto bad;
}
atkbd_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state);
- get_typematic(kbd);
+ set_typematic(kbd);
delay[0] = kbd->kb_delay1;
delay[1] = kbd->kb_delay2;
atkbd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
@@ -503,7 +493,7 @@ atkbd_intr(keyboard_t *kbd, void *arg)
init_keyboard(state->kbdc, &kbd->kb_type, kbd->kb_config);
KBD_FOUND_DEVICE(kbd);
atkbd_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state);
- get_typematic(kbd);
+ set_typematic(kbd);
delay[0] = kbd->kb_delay1;
delay[1] = kbd->kb_delay2;
atkbd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
@@ -1135,57 +1125,19 @@ atkbd_reset(KBDC kbdc, int flags, int c)
/* local functions */
static int
-get_typematic(keyboard_t *kbd)
+set_typematic(keyboard_t *kbd)
{
-#if defined(__i386__) || defined(__amd64__)
- /*
- * Only some systems allow us to retrieve the keyboard repeat
- * rate previously set via the BIOS...
- */
- x86regs_t regs;
- uint8_t *p;
+ int val, error;
+ atkbd_state_t *state = kbd->kb_data;
- /*
- * Traditional entry points of int 0x15 and 0x16 are fixed
- * and later BIOSes follow them. (U)EFI CSM specification
- * also mandates these fixed entry points.
- *
- * Validate the entry points here before we proceed further.
- * It's known that some recent laptops does not have the
- * same entry point and hang on boot if we call it.
- */
- if (x86bios_get_intr(0x15) != 0xf000f859 ||
- x86bios_get_intr(0x16) != 0xf000e82e)
- return (ENODEV);
-
- /* Is BIOS system configuration table supported? */
- x86bios_init_regs(&regs);
- regs.R_AH = 0xc0;
- x86bios_intr(&regs, 0x15);
- if ((regs.R_FLG & PSL_C) != 0 || regs.R_AH != 0)
- return (ENODEV);
-
- /* Is int 0x16, function 0x09 supported? */
- p = x86bios_offset((regs.R_ES << 4) + regs.R_BX);
- if (readw(p) < 5 || (readb(p + 6) & 0x40) == 0)
- return (ENODEV);
-
- /* Is int 0x16, function 0x0306 supported? */
- x86bios_init_regs(&regs);
- regs.R_AH = 0x09;
- x86bios_intr(&regs, 0x16);
- if ((regs.R_AL & 0x08) == 0)
- return (ENODEV);
-
- x86bios_init_regs(&regs);
- regs.R_AX = 0x0306;
- x86bios_intr(&regs, 0x16);
- kbd->kb_delay1 = typematic_delay(regs.R_BH << 5);
- kbd->kb_delay2 = typematic_rate(regs.R_BL);
- return (0);
-#else
- return (ENODEV);
-#endif /* __i386__ || __amd64__ */
+ val = typematic(DEFAULT_DELAY, DEFAULT_RATE);
+ error = write_kbd(state->kbdc, KBDC_SET_TYPEMATIC, val);
+ if (error == 0) {
+ kbd->kb_delay1 = typematic_delay(val);
+ kbd->kb_delay2 = typematic_rate(val);
+ }
+
+ return (error);
}
static int
diff --git a/sys/dev/bxe/bxe.h b/sys/dev/bxe/bxe.h
index f37b93f56e73..eb695d045211 100644
--- a/sys/dev/bxe/bxe.h
+++ b/sys/dev/bxe/bxe.h
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
#include <sys/limits.h>
#include <sys/queue.h>
#include <sys/taskqueue.h>
+#include <sys/zlib.h>
#include <net/if.h>
#include <net/if_types.h>
@@ -60,7 +61,6 @@ __FBSDID("$FreeBSD$");
#include <net/if_var.h>
#include <net/if_media.h>
#include <net/if_vlan_var.h>
-#include <net/zlib.h>
#include <net/bpf.h>
#include <netinet/in.h>
diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c
index 40098b89500c..4bbb55ed5d0b 100644
--- a/sys/dev/cxgbe/t4_main.c
+++ b/sys/dev/cxgbe/t4_main.c
@@ -1571,9 +1571,6 @@ cxgbe_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
struct ifmedia *media = NULL;
struct ifmedia_entry *cur;
int speed = pi->link_cfg.speed;
-#ifdef INVARIANTS
- int data = (pi->port_type << 8) | pi->mod_type;
-#endif
if (ifp == pi->ifp)
media = &pi->media;
@@ -1584,7 +1581,6 @@ cxgbe_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
MPASS(media != NULL);
cur = media->ifm_cur;
- MPASS(cur->ifm_data == data);
ifmr->ifm_status = IFM_AVALID;
if (!pi->link_cfg.link_ok)
@@ -2884,30 +2880,29 @@ t4_set_desc(struct adapter *sc)
static void
build_medialist(struct port_info *pi, struct ifmedia *media)
{
- int data, m;
+ int m;
PORT_LOCK(pi);
ifmedia_removeall(media);
m = IFM_ETHER | IFM_FDX;
- data = (pi->port_type << 8) | pi->mod_type;
switch(pi->port_type) {
case FW_PORT_TYPE_BT_XFI:
case FW_PORT_TYPE_BT_XAUI:
- ifmedia_add(media, m | IFM_10G_T, data, NULL);
+ ifmedia_add(media, m | IFM_10G_T, 0, NULL);
/* fall through */
case FW_PORT_TYPE_BT_SGMII:
- ifmedia_add(media, m | IFM_1000_T, data, NULL);
- ifmedia_add(media, m | IFM_100_TX, data, NULL);
- ifmedia_add(media, IFM_ETHER | IFM_AUTO, data, NULL);
+ ifmedia_add(media, m | IFM_1000_T, 0, NULL);
+ ifmedia_add(media, m | IFM_100_TX, 0, NULL);
+ ifmedia_add(media, IFM_ETHER | IFM_AUTO, 0, NULL);
ifmedia_set(media, IFM_ETHER | IFM_AUTO);
break;
case FW_PORT_TYPE_CX4:
- ifmedia_add(media, m | IFM_10G_CX4, data, NULL);
+ ifmedia_add(media, m | IFM_10G_CX4, 0, NULL);
ifmedia_set(media, m | IFM_10G_CX4);
break;
@@ -2918,29 +2913,29 @@ build_medialist(struct port_info *pi, struct ifmedia *media)
switch (pi->mod_type) {
case FW_PORT_MOD_TYPE_LR:
- ifmedia_add(media, m | IFM_10G_LR, data, NULL);
+ ifmedia_add(media, m | IFM_10G_LR, 0, NULL);
ifmedia_set(media, m | IFM_10G_LR);
break;
case FW_PORT_MOD_TYPE_SR:
- ifmedia_add(media, m | IFM_10G_SR, data, NULL);
+ ifmedia_add(media, m | IFM_10G_SR, 0, NULL);
ifmedia_set(media, m | IFM_10G_SR);
break;
case FW_PORT_MOD_TYPE_LRM:
- ifmedia_add(media, m | IFM_10G_LRM, data, NULL);
+ ifmedia_add(media, m | IFM_10G_LRM, 0, NULL);
ifmedia_set(media, m | IFM_10G_LRM);
break;
case FW_PORT_MOD_TYPE_TWINAX_PASSIVE:
case FW_PORT_MOD_TYPE_TWINAX_ACTIVE:
- ifmedia_add(media, m | IFM_10G_TWINAX, data, NULL);
+ ifmedia_add(media, m | IFM_10G_TWINAX, 0, NULL);
ifmedia_set(media, m | IFM_10G_TWINAX);
break;
case FW_PORT_MOD_TYPE_NONE:
m &= ~IFM_FDX;
- ifmedia_add(media, m | IFM_NONE, data, NULL);
+ ifmedia_add(media, m | IFM_NONE, 0, NULL);
ifmedia_set(media, m | IFM_NONE);
break;
@@ -2950,7 +2945,7 @@ build_medialist(struct port_info *pi, struct ifmedia *media)
device_printf(pi->dev,
"unknown port_type (%d), mod_type (%d)\n",
pi->port_type, pi->mod_type);
- ifmedia_add(media, m | IFM_UNKNOWN, data, NULL);
+ ifmedia_add(media, m | IFM_UNKNOWN, 0, NULL);
ifmedia_set(media, m | IFM_UNKNOWN);
break;
}
@@ -2960,24 +2955,24 @@ build_medialist(struct port_info *pi, struct ifmedia *media)
switch (pi->mod_type) {
case FW_PORT_MOD_TYPE_LR:
- ifmedia_add(media, m | IFM_40G_LR4, data, NULL);
+ ifmedia_add(media, m | IFM_40G_LR4, 0, NULL);
ifmedia_set(media, m | IFM_40G_LR4);
break;
case FW_PORT_MOD_TYPE_SR:
- ifmedia_add(media, m | IFM_40G_SR4, data, NULL);
+ ifmedia_add(media, m | IFM_40G_SR4, 0, NULL);
ifmedia_set(media, m | IFM_40G_SR4);
break;
case FW_PORT_MOD_TYPE_TWINAX_PASSIVE:
case FW_PORT_MOD_TYPE_TWINAX_ACTIVE:
- ifmedia_add(media, m | IFM_40G_CR4, data, NULL);
+ ifmedia_add(media, m | IFM_40G_CR4, 0, NULL);
ifmedia_set(media, m | IFM_40G_CR4);
break;
case FW_PORT_MOD_TYPE_NONE:
m &= ~IFM_FDX;
- ifmedia_add(media, m | IFM_NONE, data, NULL);
+ ifmedia_add(media, m | IFM_NONE, 0, NULL);
ifmedia_set(media, m | IFM_NONE);
break;
@@ -2985,7 +2980,7 @@ build_medialist(struct port_info *pi, struct ifmedia *media)
device_printf(pi->dev,
"unknown port_type (%d), mod_type (%d)\n",
pi->port_type, pi->mod_type);
- ifmedia_add(media, m | IFM_UNKNOWN, data, NULL);
+ ifmedia_add(media, m | IFM_UNKNOWN, 0, NULL);
ifmedia_set(media, m | IFM_UNKNOWN);
break;
}
@@ -2995,7 +2990,7 @@ build_medialist(struct port_info *pi, struct ifmedia *media)
device_printf(pi->dev,
"unknown port_type (%d), mod_type (%d)\n", pi->port_type,
pi->mod_type);
- ifmedia_add(media, m | IFM_UNKNOWN, data, NULL);
+ ifmedia_add(media, m | IFM_UNKNOWN, 0, NULL);
ifmedia_set(media, m | IFM_UNKNOWN);
break;
}
diff --git a/sys/dev/e1000/if_igb.c b/sys/dev/e1000/if_igb.c
index 49cc16a1d9dd..6ac6eb63c987 100644
--- a/sys/dev/e1000/if_igb.c
+++ b/sys/dev/e1000/if_igb.c
@@ -1046,8 +1046,7 @@ igb_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr)
}
drbr_advance(ifp, txr->br);
enq++;
- if_inc_counter(ifp, IFCOUNTER_OBYTES, next->m_pkthdr.len);
- if (next->m_flags & M_MCAST)
+ if (next->m_flags & M_MCAST && adapter->vf_ifp)
if_inc_counter(ifp, IFCOUNTER_OMCASTS, 1);
ETHER_BPF_MTAP(ifp, next);
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
@@ -4055,7 +4054,9 @@ static bool
igb_txeof(struct tx_ring *txr)
{
struct adapter *adapter = txr->adapter;
+#ifdef DEV_NETMAP
struct ifnet *ifp = adapter->ifp;
+#endif /* DEV_NETMAP */
u32 work, processed = 0;
u16 limit = txr->process_limit;
struct igb_tx_buf *buf;
@@ -4130,7 +4131,6 @@ igb_txeof(struct tx_ring *txr)
}
++txr->packets;
++processed;
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
txr->watchdog_time = ticks;
/* Try the next packet */
@@ -5127,7 +5127,6 @@ igb_rxeof(struct igb_queue *que, int count, int *done)
if (eop) {
rxr->fmp->m_pkthdr.rcvif = ifp;
- if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
rxr->rx_packets++;
/* capture data for AIM */
rxr->packets++;
@@ -5560,24 +5559,94 @@ igb_led_func(void *arg, int onoff)
}
static uint64_t
+igb_get_vf_counter(if_t ifp, ift_counter cnt)
+{
+ struct adapter *adapter;
+ struct e1000_vf_stats *stats;
+#ifndef IGB_LEGACY_TX
+ struct tx_ring *txr;
+ uint64_t rv;
+#endif
+
+ adapter = if_getsoftc(ifp);
+ stats = (struct e1000_vf_stats *)adapter->stats;
+
+ switch (cnt) {
+ case IFCOUNTER_IPACKETS:
+ return (stats->gprc);
+ case IFCOUNTER_OPACKETS:
+ return (stats->gptc);
+ case IFCOUNTER_IBYTES:
+ return (stats->gorc);
+ case IFCOUNTER_OBYTES:
+ return (stats->gotc);
+ case IFCOUNTER_IMCASTS:
+ return (stats->mprc);
+ case IFCOUNTER_IERRORS:
+ return (adapter->dropped_pkts);
+ case IFCOUNTER_OERRORS:
+ return (adapter->watchdog_events);
+#ifndef IGB_LEGACY_TX
+ case IFCOUNTER_OQDROPS:
+ rv = 0;
+ txr = adapter->tx_rings;
+ for (int i = 0; i < adapter->num_queues; i++, txr++)
+ rv += txr->br->br_drops;
+ return (rv);
+#endif
+ default:
+ return (if_get_counter_default(ifp, cnt));
+ }
+}
+
+static uint64_t
igb_get_counter(if_t ifp, ift_counter cnt)
{
struct adapter *adapter;
struct e1000_hw_stats *stats;
+#ifndef IGB_LEGACY_TX
+ struct tx_ring *txr;
+ uint64_t rv;
+#endif
adapter = if_getsoftc(ifp);
+ if (adapter->vf_ifp)
+ return (igb_get_vf_counter(ifp, cnt));
+
stats = (struct e1000_hw_stats *)adapter->stats;
switch (cnt) {
+ case IFCOUNTER_IPACKETS:
+ return (stats->gprc);
+ case IFCOUNTER_OPACKETS:
+ return (stats->gptc);
+ case IFCOUNTER_IBYTES:
+ return (stats->gorc);
+ case IFCOUNTER_OBYTES:
+ return (stats->gotc);
+ case IFCOUNTER_IMCASTS:
+ return (stats->mprc);
+ case IFCOUNTER_OMCASTS:
+ return (stats->mptc);
case IFCOUNTER_IERRORS:
return (adapter->dropped_pkts + stats->rxerrc +
stats->crcerrs + stats->algnerrc +
- stats->ruc + stats->roc + stats->mpc + stats->cexterr);
+ stats->ruc + stats->roc + stats->cexterr);
case IFCOUNTER_OERRORS:
return (stats->ecol + stats->latecol +
adapter->watchdog_events);
case IFCOUNTER_COLLISIONS:
return (stats->colc);
+ case IFCOUNTER_IQDROPS:
+ return (stats->mpc);
+#ifndef IGB_LEGACY_TX
+ case IFCOUNTER_OQDROPS:
+ rv = 0;
+ txr = adapter->tx_rings;
+ for (int i = 0; i < adapter->num_queues; i++, txr++)
+ rv += txr->br->br_drops;
+ return (rv);
+#endif
default:
return (if_get_counter_default(ifp, cnt));
}
diff --git a/sys/dev/hyperv/include/hyperv.h b/sys/dev/hyperv/include/hyperv.h
index 8a45d89cd063..5360b7c160b9 100644
--- a/sys/dev/hyperv/include/hyperv.h
+++ b/sys/dev/hyperv/include/hyperv.h
@@ -46,6 +46,7 @@
#include <sys/systm.h>
#include <sys/lock.h>
#include <sys/sema.h>
+#include <sys/smp.h>
#include <sys/mutex.h>
#include <sys/bus.h>
#include <vm/vm.h>
@@ -63,11 +64,22 @@ typedef uint8_t hv_bool_uint8_t;
#define HV_ERROR_MACHINE_LOCKED 0x800704F7
/*
- * A revision number of vmbus that is used for ensuring both ends on a
- * partition are using compatible versions.
+ * VMBUS version is 32 bit, upper 16 bit for major_number and lower
+ * 16 bit for minor_number.
+ *
+ * 0.13 -- Windows Server 2008
+ * 1.1 -- Windows 7
+ * 2.4 -- Windows 8
+ * 3.0 -- Windows 8.1
*/
+#define HV_VMBUS_VERSION_WS2008 ((0 << 16) | (13))
+#define HV_VMBUS_VERSION_WIN7 ((1 << 16) | (1))
+#define HV_VMBUS_VERSION_WIN8 ((2 << 16) | (4))
+#define HV_VMBUS_VERSION_WIN8_1 ((3 << 16) | (0))
+
+#define HV_VMBUS_VERSION_INVALID -1
-#define HV_VMBUS_REVISION_NUMBER 13
+#define HV_VMBUS_VERSION_CURRENT HV_VMBUS_VERSION_WIN8_1
/*
* Make maximum size of pipe payload of 16K
@@ -112,6 +124,18 @@ typedef struct hv_guid {
unsigned char data[16];
} __packed hv_guid;
+#define HV_NIC_GUID \
+ .data = {0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46, \
+ 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E}
+
+#define HV_IDE_GUID \
+ .data = {0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, \
+ 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5}
+
+#define HV_SCSI_GUID \
+ .data = {0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, \
+ 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f}
+
/*
* At the center of the Channel Management library is
* the Channel Offer. This struct contains the
@@ -147,7 +171,11 @@ typedef struct hv_vmbus_channel_offer {
} __packed pipe;
} u;
- uint32_t padding;
+ /*
+ * Sub_channel_index, newly added in Win8.
+ */
+ uint16_t sub_channel_index;
+ uint16_t padding;
} __packed hv_vmbus_channel_offer;
@@ -344,7 +372,25 @@ typedef struct {
hv_vmbus_channel_offer offer;
uint32_t child_rel_id;
uint8_t monitor_id;
- hv_bool_uint8_t monitor_allocated;
+ /*
+ * This field has been split into a bit field on Win7
+ * and higher.
+ */
+ uint8_t monitor_allocated:1;
+ uint8_t reserved:7;
+ /*
+ * Following fields were added in win7 and higher.
+ * Make sure to check the version before accessing these fields.
+ *
+ * If "is_dedicated_interrupt" is set, we must not set the
+ * associated bit in the channel bitmap while sending the
+ * interrupt to the host.
+ *
+ * connection_id is used in signaling the host.
+ */
+ uint16_t is_dedicated_interrupt:1;
+ uint16_t reserved1:15;
+ uint32_t connection_id;
} __packed hv_vmbus_channel_offer_channel;
/*
@@ -394,9 +440,11 @@ typedef struct
hv_gpadl_handle ring_buffer_gpadl_handle;
/*
- * GPADL for the channel's server context save area.
+ * Before win8, all incoming channel interrupts are only
+ * delivered on cpu 0. Setting this value to 0 would
+ * preserve the earlier behavior.
*/
- hv_gpadl_handle server_context_area_gpadl_handle;
+ uint32_t target_vcpu;
/*
* The upstream ring buffer begins at offset zero in the memory described
@@ -646,14 +694,42 @@ typedef struct {
} hv_vmbus_ring_buffer_info;
typedef void (*hv_vmbus_pfn_channel_callback)(void *context);
+typedef void (*hv_vmbus_sc_creation_callback)(void *context);
typedef enum {
HV_CHANNEL_OFFER_STATE,
HV_CHANNEL_OPENING_STATE,
HV_CHANNEL_OPEN_STATE,
+ HV_CHANNEL_OPENED_STATE,
HV_CHANNEL_CLOSING_NONDESTRUCTIVE_STATE,
} hv_vmbus_channel_state;
+/*
+ * Connection identifier type
+ */
+typedef union {
+ uint32_t as_uint32_t;
+ struct {
+ uint32_t id:24;
+ uint32_t reserved:8;
+ } u;
+
+} __packed hv_vmbus_connection_id;
+
+/*
+ * Definition of the hv_vmbus_signal_event hypercall input structure
+ */
+typedef struct {
+ hv_vmbus_connection_id connection_id;
+ uint16_t flag_number;
+ uint16_t rsvd_z;
+} __packed hv_vmbus_input_signal_event;
+
+typedef struct {
+ uint64_t align8;
+ hv_vmbus_input_signal_event event;
+} __packed hv_vmbus_input_signal_event_buffer;
+
typedef struct hv_vmbus_channel {
TAILQ_ENTRY(hv_vmbus_channel) list_entry;
struct hv_device* device;
@@ -688,8 +764,82 @@ typedef struct hv_vmbus_channel {
hv_vmbus_pfn_channel_callback on_channel_callback;
void* channel_callback_context;
+ /*
+ * If batched_reading is set to "true", mask the interrupt
+ * and read until the channel is empty.
+ * If batched_reading is set to "false", the channel is not
+ * going to perform batched reading.
+ *
+ * Batched reading is enabled by default; specific
+ * drivers that don't want this behavior can turn it off.
+ */
+ boolean_t batched_reading;
+
+ boolean_t is_dedicated_interrupt;
+
+ /*
+ * Used as an input param for HV_CALL_SIGNAL_EVENT hypercall.
+ */
+ hv_vmbus_input_signal_event_buffer signal_event_buffer;
+ /*
+ * 8-bytes aligned of the buffer above
+ */
+ hv_vmbus_input_signal_event *signal_event_param;
+
+ /*
+ * From Win8, this field specifies the target virtual process
+ * on which to deliver the interupt from the host to guest.
+ * Before Win8, all channel interrupts would only be
+ * delivered on cpu 0. Setting this value to 0 would preserve
+ * the earlier behavior.
+ */
+ uint32_t target_vcpu;
+ /* The corresponding CPUID in the guest */
+ uint32_t target_cpu;
+
+ /*
+ * Support for multi-channels.
+ * The initial offer is considered the primary channel and this
+ * offer message will indicate if the host supports multi-channels.
+ * The guest is free to ask for multi-channels to be offerred and can
+ * open these multi-channels as a normal "primary" channel. However,
+ * all multi-channels will have the same type and instance guids as the
+ * primary channel. Requests sent on a given channel will result in a
+ * response on the same channel.
+ */
+
+ /*
+ * Multi-channel creation callback. This callback will be called in
+ * process context when a Multi-channel offer is received from the host.
+ * The guest can open the Multi-channel in the context of this callback.
+ */
+ hv_vmbus_sc_creation_callback sc_creation_callback;
+
+ struct mtx sc_lock;
+
+ /*
+ * Link list of all the multi-channels if this is a primary channel
+ */
+ TAILQ_HEAD(, hv_vmbus_channel) sc_list_anchor;
+ TAILQ_ENTRY(hv_vmbus_channel) sc_list_entry;
+
+ /*
+ * The primary channel this sub-channle belongs to.
+ * This will be NULL for the primary channel.
+ */
+ struct hv_vmbus_channel *primary_channel;
+ /*
+ * Support per channel state for use by vmbus drivers.
+ */
+ void *per_channel_state;
} hv_vmbus_channel;
+static inline void
+hv_set_channel_read_state(hv_vmbus_channel* channel, boolean_t state)
+{
+ channel->batched_reading = state;
+}
+
typedef struct hv_device {
hv_guid class_id;
hv_guid device_id;
@@ -760,6 +910,8 @@ int hv_vmbus_channel_teardown_gpdal(
hv_vmbus_channel* channel,
uint32_t gpadl_handle);
+struct hv_vmbus_channel* vmbus_select_outgoing_channel(struct hv_vmbus_channel *promary);
+
/*
* Work abstraction defines
*/
@@ -819,6 +971,7 @@ typedef struct hv_vmbus_service {
extern uint8_t* receive_buffer[];
extern hv_vmbus_service service_table[];
+extern uint32_t hv_vmbus_protocal_version;
void hv_kvp_callback(void *context);
int hv_kvp_init(hv_vmbus_service *serv);
diff --git a/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c b/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c
index d00d279285ad..f8a871b285a9 100644
--- a/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c
+++ b/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/condvar.h>
+#include <sys/time.h>
#include <sys/systm.h>
#include <sys/sockio.h>
#include <sys/mbuf.h>
@@ -53,8 +54,12 @@ __FBSDID("$FreeBSD$");
#include <sys/callout.h>
#include <vm/vm.h>
#include <vm/pmap.h>
+#include <vm/uma.h>
#include <sys/lock.h>
#include <sys/sema.h>
+#include <sys/sglist.h>
+#include <machine/bus.h>
+#include <sys/bus_dma.h>
#include <cam/cam.h>
#include <cam/cam_ccb.h>
@@ -66,7 +71,6 @@ __FBSDID("$FreeBSD$");
#include <cam/scsi/scsi_all.h>
#include <cam/scsi/scsi_message.h>
-
#include <dev/hyperv/include/hyperv.h>
#include "hv_vstorage.h"
@@ -77,8 +81,29 @@ __FBSDID("$FreeBSD$");
#define BLKVSC_MAX_IO_REQUESTS STORVSC_MAX_IO_REQUESTS
#define STORVSC_MAX_TARGETS (2)
+#define STORVSC_WIN7_MAJOR 4
+#define STORVSC_WIN7_MINOR 2
+
+#define STORVSC_WIN8_MAJOR 5
+#define STORVSC_WIN8_MINOR 1
+
+#define HV_ALIGN(x, a) roundup2(x, a)
+
struct storvsc_softc;
+struct hv_sgl_node {
+ LIST_ENTRY(hv_sgl_node) link;
+ struct sglist *sgl_data;
+};
+
+struct hv_sgl_page_pool{
+ LIST_HEAD(, hv_sgl_node) in_use_sgl_list;
+ LIST_HEAD(, hv_sgl_node) free_sgl_list;
+ boolean_t is_init;
+} g_hv_sgl_page_pool;
+
+#define STORVSC_MAX_SG_PAGE_CNT STORVSC_MAX_IO_REQUESTS * HV_MAX_MULTIPAGE_BUFFER_COUNT
+
enum storvsc_request_type {
WRITE_TYPE,
READ_TYPE,
@@ -96,20 +121,24 @@ struct hv_storvsc_request {
struct storvsc_softc *softc;
struct callout callout;
struct sema synch_sema; /*Synchronize the request/response if needed */
+ struct sglist *bounce_sgl;
+ unsigned int bounce_sgl_count;
+ uint64_t not_aligned_seg_bits;
};
struct storvsc_softc {
struct hv_device *hs_dev;
- LIST_HEAD(, hv_storvsc_request) hs_free_list;
- struct mtx hs_lock;
- struct storvsc_driver_props *hs_drv_props;
- int hs_unit;
- uint32_t hs_frozen;
- struct cam_sim *hs_sim;
- struct cam_path *hs_path;
+ LIST_HEAD(, hv_storvsc_request) hs_free_list;
+ struct mtx hs_lock;
+ struct storvsc_driver_props *hs_drv_props;
+ int hs_unit;
+ uint32_t hs_frozen;
+ struct cam_sim *hs_sim;
+ struct cam_path *hs_path;
uint32_t hs_num_out_reqs;
boolean_t hs_destroy;
boolean_t hs_drain_notify;
+ boolean_t hs_open_multi_channel;
struct sema hs_drain_sema;
struct hv_storvsc_request hs_init_req;
struct hv_storvsc_request hs_reset_req;
@@ -124,7 +153,7 @@ struct storvsc_softc {
* The first can be tested by "sg_senddiag -vv /dev/daX",
* and the second and third can be done by
* "sg_wr_mode -v -p 08 -c 0,1a -m 0,ff /dev/daX".
- */
+ */
#define HVS_TIMEOUT_TEST 0
/*
@@ -138,7 +167,7 @@ struct storvsc_driver_props {
char *drv_name;
char *drv_desc;
uint8_t drv_max_luns_per_target;
- uint8_t drv_max_ios_per_target;
+ uint8_t drv_max_ios_per_target;
uint32_t drv_ringbuffer_size;
};
@@ -150,6 +179,8 @@ enum hv_storage_type {
#define HS_MAX_ADAPTERS 10
+#define HV_STORAGE_SUPPORTS_MULTI_CHANNEL 0x1
+
/* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */
static const hv_guid gStorVscDeviceType={
.data = {0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d,
@@ -171,13 +202,16 @@ static struct storvsc_driver_props g_drv_props_table[] = {
STORVSC_RINGBUFFER_SIZE}
};
+static int storvsc_current_major;
+static int storvsc_current_minor;
+
/* static functions */
static int storvsc_probe(device_t dev);
static int storvsc_attach(device_t dev);
static int storvsc_detach(device_t dev);
static void storvsc_poll(struct cam_sim * sim);
static void storvsc_action(struct cam_sim * sim, union ccb * ccb);
-static void create_storvsc_request(union ccb *ccb, struct hv_storvsc_request *reqp);
+static int create_storvsc_request(union ccb *ccb, struct hv_storvsc_request *reqp);
static void storvsc_free_request(struct storvsc_softc *sc, struct hv_storvsc_request *reqp);
static enum hv_storage_type storvsc_get_storage_type(device_t dev);
static void hv_storvsc_on_channel_callback(void *context);
@@ -186,6 +220,14 @@ static void hv_storvsc_on_iocompletion( struct storvsc_softc *sc,
struct hv_storvsc_request *request);
static int hv_storvsc_connect_vsp(struct hv_device *device);
static void storvsc_io_done(struct hv_storvsc_request *reqp);
+static void storvsc_copy_sgl_to_bounce_buf(struct sglist *bounce_sgl,
+ bus_dma_segment_t *orig_sgl,
+ unsigned int orig_sgl_count,
+ uint64_t seg_bits);
+void storvsc_copy_from_bounce_buf_to_sgl(bus_dma_segment_t *dest_sgl,
+ unsigned int dest_sgl_count,
+ struct sglist* src_sgl,
+ uint64_t seg_bits);
static device_method_t storvsc_methods[] = {
/* Device interface */
@@ -207,7 +249,7 @@ MODULE_DEPEND(storvsc, vmbus, 1, 1, 1);
/**
- * The host is capable of sending messages to us that are
+ * The host is capable of sending messages to us that are
* completely unsolicited. So, we need to address the race
* condition where we may be in the process of unloading the
* driver when the host may send us an unsolicited message.
@@ -223,7 +265,7 @@ MODULE_DEPEND(storvsc, vmbus, 1, 1, 1);
* destroyed.
*
* 3. Once the device is marked as being destroyed, we only
- * permit incoming traffic to properly account for
+ * permit incoming traffic to properly account for
* packets already sent out.
*/
static inline struct storvsc_softc *
@@ -260,6 +302,113 @@ get_stor_device(struct hv_device *device,
}
/**
+ * @brief Callback handler, will be invoked when receive mutil-channel offer
+ *
+ * @param context new multi-channel
+ */
+static void
+storvsc_handle_sc_creation(void *context)
+{
+ hv_vmbus_channel *new_channel;
+ struct hv_device *device;
+ struct storvsc_softc *sc;
+ struct vmstor_chan_props props;
+ int ret = 0;
+
+ new_channel = (hv_vmbus_channel *)context;
+ device = new_channel->primary_channel->device;
+ sc = get_stor_device(device, TRUE);
+ if (sc == NULL)
+ return;
+
+ if (FALSE == sc->hs_open_multi_channel)
+ return;
+
+ memset(&props, 0, sizeof(props));
+
+ ret = hv_vmbus_channel_open(new_channel,
+ sc->hs_drv_props->drv_ringbuffer_size,
+ sc->hs_drv_props->drv_ringbuffer_size,
+ (void *)&props,
+ sizeof(struct vmstor_chan_props),
+ hv_storvsc_on_channel_callback,
+ new_channel);
+
+ return;
+}
+
+/**
+ * @brief Send multi-channel creation request to host
+ *
+ * @param device a Hyper-V device pointer
+ * @param max_chans the max channels supported by vmbus
+ */
+static void
+storvsc_send_multichannel_request(struct hv_device *dev, int max_chans)
+{
+ struct storvsc_softc *sc;
+ struct hv_storvsc_request *request;
+ struct vstor_packet *vstor_packet;
+ int request_channels_cnt = 0;
+ int ret;
+
+ /* get multichannels count that need to create */
+ request_channels_cnt = MIN(max_chans, mp_ncpus);
+
+ sc = get_stor_device(dev, TRUE);
+ if (sc == NULL) {
+ printf("Storvsc_error: get sc failed while send mutilchannel "
+ "request\n");
+ return;
+ }
+
+ request = &sc->hs_init_req;
+
+ /* Establish a handler for multi-channel */
+ dev->channel->sc_creation_callback = storvsc_handle_sc_creation;
+
+ /* request the host to create multi-channel */
+ memset(request, 0, sizeof(struct hv_storvsc_request));
+
+ sema_init(&request->synch_sema, 0, ("stor_synch_sema"));
+
+ vstor_packet = &request->vstor_packet;
+
+ vstor_packet->operation = VSTOR_OPERATION_CREATE_MULTI_CHANNELS;
+ vstor_packet->flags = REQUEST_COMPLETION_FLAG;
+ vstor_packet->u.multi_channels_cnt = request_channels_cnt;
+
+ ret = hv_vmbus_channel_send_packet(
+ dev->channel,
+ vstor_packet,
+ sizeof(struct vstor_packet),
+ (uint64_t)(uintptr_t)request,
+ HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
+ HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+
+ /* wait for 5 seconds */
+ ret = sema_timedwait(&request->synch_sema, 5 * hz);
+ if (ret != 0) {
+ printf("Storvsc_error: create multi-channel timeout, %d\n",
+ ret);
+ return;
+ }
+
+ if (vstor_packet->operation != VSTOR_OPERATION_COMPLETEIO ||
+ vstor_packet->status != 0) {
+ printf("Storvsc_error: create multi-channel invalid operation "
+ "(%d) or statue (%u)\n",
+ vstor_packet->operation, vstor_packet->status);
+ return;
+ }
+
+ sc->hs_open_multi_channel = TRUE;
+
+ if (bootverbose)
+ printf("Storvsc create multi-channel success!\n");
+}
+
+/**
* @brief initialize channel connection to parent partition
*
* @param dev a Hyper-V device pointer
@@ -272,11 +421,15 @@ hv_storvsc_channel_init(struct hv_device *dev)
struct hv_storvsc_request *request;
struct vstor_packet *vstor_packet;
struct storvsc_softc *sc;
+ uint16_t max_chans = 0;
+ boolean_t support_multichannel = FALSE;
+
+ max_chans = 0;
+ support_multichannel = FALSE;
sc = get_stor_device(dev, TRUE);
- if (sc == NULL) {
- return ENODEV;
- }
+ if (sc == NULL)
+ return (ENODEV);
request = &sc->hs_init_req;
memset(request, 0, sizeof(struct hv_storvsc_request));
@@ -300,15 +453,13 @@ hv_storvsc_channel_init(struct hv_device *dev)
HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
- if (ret != 0) {
+ if (ret != 0)
goto cleanup;
- }
-
- ret = sema_timedwait(&request->synch_sema, 500); /* KYS 5 seconds */
- if (ret != 0) {
+ /* wait 5 seconds */
+ ret = sema_timedwait(&request->synch_sema, 5 * hz);
+ if (ret != 0)
goto cleanup;
- }
if (vstor_packet->operation != VSTOR_OPERATION_COMPLETEIO ||
vstor_packet->status != 0) {
@@ -321,7 +472,8 @@ hv_storvsc_channel_init(struct hv_device *dev)
vstor_packet->operation = VSTOR_OPERATION_QUERYPROTOCOLVERSION;
vstor_packet->flags = REQUEST_COMPLETION_FLAG;
- vstor_packet->u.version.major_minor = VMSTOR_PROTOCOL_VERSION_CURRENT;
+ vstor_packet->u.version.major_minor =
+ VMSTOR_PROTOCOL_VERSION(storvsc_current_major, storvsc_current_minor);
/* revision is only significant for Windows guests */
vstor_packet->u.version.revision = 0;
@@ -334,21 +486,19 @@ hv_storvsc_channel_init(struct hv_device *dev)
HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
- if (ret != 0) {
+ if (ret != 0)
goto cleanup;
- }
- ret = sema_timedwait(&request->synch_sema, 500); /* KYS 5 seconds */
+ /* wait 5 seconds */
+ ret = sema_timedwait(&request->synch_sema, 5 * hz);
- if (ret) {
+ if (ret)
goto cleanup;
- }
/* TODO: Check returned version */
if (vstor_packet->operation != VSTOR_OPERATION_COMPLETEIO ||
- vstor_packet->status != 0) {
+ vstor_packet->status != 0)
goto cleanup;
- }
/**
* Query channel properties
@@ -365,22 +515,30 @@ hv_storvsc_channel_init(struct hv_device *dev)
HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
- if ( ret != 0) {
+ if ( ret != 0)
goto cleanup;
- }
- ret = sema_timedwait(&request->synch_sema, 500); /* KYS 5 seconds */
+ /* wait 5 seconds */
+ ret = sema_timedwait(&request->synch_sema, 5 * hz);
- if (ret != 0) {
+ if (ret != 0)
goto cleanup;
- }
/* TODO: Check returned version */
if (vstor_packet->operation != VSTOR_OPERATION_COMPLETEIO ||
- vstor_packet->status != 0) {
+ vstor_packet->status != 0) {
goto cleanup;
}
+ /* multi-channels feature is supported by WIN8 and above version */
+ max_chans = vstor_packet->u.chan_props.max_channel_cnt;
+ if ((hv_vmbus_protocal_version != HV_VMBUS_VERSION_WIN7) &&
+ (hv_vmbus_protocal_version != HV_VMBUS_VERSION_WS2008) &&
+ (vstor_packet->u.chan_props.flags &
+ HV_STORAGE_SUPPORTS_MULTI_CHANNEL)) {
+ support_multichannel = TRUE;
+ }
+
memset(vstor_packet, 0, sizeof(struct vstor_packet));
vstor_packet->operation = VSTOR_OPERATION_ENDINITIALIZATION;
vstor_packet->flags = REQUEST_COMPLETION_FLAG;
@@ -397,16 +555,22 @@ hv_storvsc_channel_init(struct hv_device *dev)
goto cleanup;
}
- ret = sema_timedwait(&request->synch_sema, 500); /* KYS 5 seconds */
+ /* wait 5 seconds */
+ ret = sema_timedwait(&request->synch_sema, 5 * hz);
- if (ret != 0) {
+ if (ret != 0)
goto cleanup;
- }
if (vstor_packet->operation != VSTOR_OPERATION_COMPLETEIO ||
- vstor_packet->status != 0) {
+ vstor_packet->status != 0)
goto cleanup;
- }
+
+ /*
+ * If multi-channel is supported, send multichannel create
+ * request to host.
+ */
+ if (support_multichannel)
+ storvsc_send_multichannel_request(dev, max_chans);
cleanup:
sema_destroy(&request->synch_sema);
@@ -443,8 +607,7 @@ hv_storvsc_connect_vsp(struct hv_device *dev)
(void *)&props,
sizeof(struct vmstor_chan_props),
hv_storvsc_on_channel_callback,
- dev);
-
+ dev->channel);
if (ret != 0) {
return ret;
@@ -490,7 +653,7 @@ hv_storvsc_host_reset(struct hv_device *dev)
goto cleanup;
}
- ret = sema_timedwait(&request->synch_sema, 500); /* KYS 5 seconds */
+ ret = sema_timedwait(&request->synch_sema, 5 * hz); /* KYS 5 seconds */
if (ret) {
goto cleanup;
@@ -498,7 +661,7 @@ hv_storvsc_host_reset(struct hv_device *dev)
/*
- * At this point, all outstanding requests in the adapter
+ * At this point, all outstanding requests in the adapter
* should have been flushed out and return to us
*/
@@ -521,6 +684,7 @@ hv_storvsc_io_request(struct hv_device *device,
{
struct storvsc_softc *sc;
struct vstor_packet *vstor_packet = &request->vstor_packet;
+ struct hv_vmbus_channel* outgoing_channel = NULL;
int ret = 0;
sc = get_stor_device(device, TRUE);
@@ -539,19 +703,20 @@ hv_storvsc_io_request(struct hv_device *device,
vstor_packet->operation = VSTOR_OPERATION_EXECUTESRB;
+ outgoing_channel = vmbus_select_outgoing_channel(device->channel);
mtx_unlock(&request->softc->hs_lock);
if (request->data_buf.length) {
ret = hv_vmbus_channel_send_packet_multipagebuffer(
- device->channel,
+ outgoing_channel,
&request->data_buf,
- vstor_packet,
- sizeof(struct vstor_packet),
+ vstor_packet,
+ sizeof(struct vstor_packet),
(uint64_t)(uintptr_t)request);
} else {
ret = hv_vmbus_channel_send_packet(
- device->channel,
+ outgoing_channel,
vstor_packet,
sizeof(struct vstor_packet),
(uint64_t)(uintptr_t)request,
@@ -610,7 +775,8 @@ static void
hv_storvsc_on_channel_callback(void *context)
{
int ret = 0;
- struct hv_device *device = (struct hv_device *)context;
+ hv_vmbus_channel *channel = (hv_vmbus_channel *)context;
+ struct hv_device *device = NULL;
struct storvsc_softc *sc;
uint32_t bytes_recvd;
uint64_t request_id;
@@ -618,15 +784,22 @@ hv_storvsc_on_channel_callback(void *context)
struct hv_storvsc_request *request;
struct vstor_packet *vstor_packet;
+ if (channel->primary_channel != NULL){
+ device = channel->primary_channel->device;
+ } else {
+ device = channel->device;
+ }
+
+ KASSERT(device, ("device is NULL"));
+
sc = get_stor_device(device, FALSE);
if (sc == NULL) {
+ printf("Storvsc_error: get stor device failed.\n");
return;
}
- KASSERT(device, ("device"));
-
ret = hv_vmbus_channel_recv_packet(
- device->channel,
+ channel,
packet,
roundup2(sizeof(struct vstor_packet), 8),
&bytes_recvd,
@@ -634,21 +807,28 @@ hv_storvsc_on_channel_callback(void *context)
while ((ret == 0) && (bytes_recvd > 0)) {
request = (struct hv_storvsc_request *)(uintptr_t)request_id;
- KASSERT(request, ("request"));
if ((request == &sc->hs_init_req) ||
(request == &sc->hs_reset_req)) {
memcpy(&request->vstor_packet, packet,
sizeof(struct vstor_packet));
- sema_post(&request->synch_sema);
+ sema_post(&request->synch_sema);
} else {
vstor_packet = (struct vstor_packet *)packet;
switch(vstor_packet->operation) {
case VSTOR_OPERATION_COMPLETEIO:
+ if (request == NULL)
+ panic("VMBUS: storvsc received a "
+ "packet with NULL request id in "
+ "COMPLETEIO operation.");
+
hv_storvsc_on_iocompletion(sc,
vstor_packet, request);
break;
case VSTOR_OPERATION_REMOVEDEVICE:
+ case VSTOR_OPERATION_ENUMERATE_BUS:
+ printf("VMBUS: storvsc operation %d not "
+ "implemented.\n", vstor_packet->operation);
/* TODO: implement */
break;
default:
@@ -656,7 +836,7 @@ hv_storvsc_on_channel_callback(void *context)
}
}
ret = hv_vmbus_channel_recv_packet(
- device->channel,
+ channel,
packet,
roundup2(sizeof(struct vstor_packet), 8),
&bytes_recvd,
@@ -680,7 +860,16 @@ storvsc_probe(device_t dev)
{
int ata_disk_enable = 0;
int ret = ENXIO;
-
+
+ if ((HV_VMBUS_VERSION_WIN8 == hv_vmbus_protocal_version) ||
+ (HV_VMBUS_VERSION_WIN8_1 == hv_vmbus_protocal_version)){
+ storvsc_current_major = STORVSC_WIN8_MAJOR;
+ storvsc_current_minor = STORVSC_WIN8_MINOR;
+ } else {
+ storvsc_current_major = STORVSC_WIN7_MAJOR;
+ storvsc_current_minor = STORVSC_WIN7_MINOR;
+ }
+
switch (storvsc_get_storage_type(dev)) {
case DRIVER_BLKVSC:
if(bootverbose)
@@ -721,9 +910,11 @@ storvsc_attach(device_t dev)
enum hv_storage_type stor_type;
struct storvsc_softc *sc;
struct cam_devq *devq;
- int ret, i;
+ int ret, i, j;
struct hv_storvsc_request *reqp;
struct root_hold_token *root_mount_token = NULL;
+ struct hv_sgl_node *sgl_node = NULL;
+ void *tmp_buff = NULL;
/*
* We need to serialize storvsc attach calls.
@@ -764,8 +955,41 @@ storvsc_attach(device_t dev)
LIST_INSERT_HEAD(&sc->hs_free_list, reqp, link);
}
+ /* create sg-list page pool */
+ if (FALSE == g_hv_sgl_page_pool.is_init) {
+ g_hv_sgl_page_pool.is_init = TRUE;
+ LIST_INIT(&g_hv_sgl_page_pool.in_use_sgl_list);
+ LIST_INIT(&g_hv_sgl_page_pool.free_sgl_list);
+
+ /*
+ * Pre-create SG list, each SG list with
+ * HV_MAX_MULTIPAGE_BUFFER_COUNT segments, each
+ * segment has one page buffer
+ */
+ for (i = 0; i < STORVSC_MAX_IO_REQUESTS; i++) {
+ sgl_node = malloc(sizeof(struct hv_sgl_node),
+ M_DEVBUF, M_WAITOK|M_ZERO);
+
+ sgl_node->sgl_data =
+ sglist_alloc(HV_MAX_MULTIPAGE_BUFFER_COUNT,
+ M_WAITOK|M_ZERO);
+
+ for (j = 0; j < HV_MAX_MULTIPAGE_BUFFER_COUNT; j++) {
+ tmp_buff = malloc(PAGE_SIZE,
+ M_DEVBUF, M_WAITOK|M_ZERO);
+
+ sgl_node->sgl_data->sg_segs[j].ss_paddr =
+ (vm_paddr_t)tmp_buff;
+ }
+
+ LIST_INSERT_HEAD(&g_hv_sgl_page_pool.free_sgl_list,
+ sgl_node, link);
+ }
+ }
+
sc->hs_destroy = FALSE;
sc->hs_drain_notify = FALSE;
+ sc->hs_open_multi_channel = FALSE;
sema_init(&sc->hs_drain_sema, 0, "Store Drain Sema");
ret = hv_storvsc_connect_vsp(hv_dev);
@@ -834,6 +1058,20 @@ cleanup:
LIST_REMOVE(reqp, link);
free(reqp, M_DEVBUF);
}
+
+ while (!LIST_EMPTY(&g_hv_sgl_page_pool.free_sgl_list)) {
+ sgl_node = LIST_FIRST(&g_hv_sgl_page_pool.free_sgl_list);
+ LIST_REMOVE(sgl_node, link);
+ for (j = 0; j < HV_MAX_MULTIPAGE_BUFFER_COUNT; j++) {
+ if (NULL !=
+ (void*)sgl_node->sgl_data->sg_segs[j].ss_paddr) {
+ free((void*)sgl_node->sgl_data->sg_segs[j].ss_paddr, M_DEVBUF);
+ }
+ }
+ sglist_free(sgl_node->sgl_data);
+ free(sgl_node, M_DEVBUF);
+ }
+
return (ret);
}
@@ -853,6 +1091,8 @@ storvsc_detach(device_t dev)
struct storvsc_softc *sc = device_get_softc(dev);
struct hv_storvsc_request *reqp = NULL;
struct hv_device *hv_device = vmbus_get_devctx(dev);
+ struct hv_sgl_node *sgl_node = NULL;
+ int j = 0;
mtx_lock(&hv_device->channel->inbound_lock);
sc->hs_destroy = TRUE;
@@ -884,6 +1124,20 @@ storvsc_detach(device_t dev)
free(reqp, M_DEVBUF);
}
mtx_unlock(&sc->hs_lock);
+
+ while (!LIST_EMPTY(&g_hv_sgl_page_pool.free_sgl_list)) {
+ sgl_node = LIST_FIRST(&g_hv_sgl_page_pool.free_sgl_list);
+ LIST_REMOVE(sgl_node, link);
+ for (j = 0; j < HV_MAX_MULTIPAGE_BUFFER_COUNT; j++){
+ if (NULL !=
+ (void*)sgl_node->sgl_data->sg_segs[j].ss_paddr) {
+ free((void*)sgl_node->sgl_data->sg_segs[j].ss_paddr, M_DEVBUF);
+ }
+ }
+ sglist_free(sgl_node->sgl_data);
+ free(sgl_node, M_DEVBUF);
+ }
+
return (0);
}
@@ -939,7 +1193,7 @@ storvsc_timeout_test(struct hv_storvsc_request *reqp,
ticks, __func__, (ret == 0)?
"IO return detected" :
"IO return not detected");
- /*
+ /*
* Now both the timer handler and io done are running
* simultaneously. We want to confirm the io done always
* finishes after the timer handler exits. So reqp used by
@@ -1023,7 +1277,7 @@ storvsc_poll(struct cam_sim *sim)
mtx_assert(&sc->hs_lock, MA_OWNED);
mtx_unlock(&sc->hs_lock);
- hv_storvsc_on_channel_callback(sc->hs_dev);
+ hv_storvsc_on_channel_callback(sc->hs_dev->channel);
mtx_lock(&sc->hs_lock);
}
@@ -1151,9 +1405,13 @@ storvsc_action(struct cam_sim *sim, union ccb *ccb)
bzero(reqp, sizeof(struct hv_storvsc_request));
reqp->softc = sc;
-
- ccb->ccb_h.status |= CAM_SIM_QUEUED;
- create_storvsc_request(ccb, reqp);
+
+ ccb->ccb_h.status |= CAM_SIM_QUEUED;
+ if ((res = create_storvsc_request(ccb, reqp)) != 0) {
+ ccb->ccb_h.status = CAM_REQ_INVALID;
+ xpt_done(ccb);
+ return;
+ }
if (ccb->ccb_h.timeout != CAM_TIME_INFINITY) {
callout_init(&reqp->callout, CALLOUT_MPSAFE);
@@ -1194,6 +1452,212 @@ storvsc_action(struct cam_sim *sim, union ccb *ccb)
}
/**
+ * @brief destroy bounce buffer
+ *
+ * This function is responsible for destroy a Scatter/Gather list
+ * that create by storvsc_create_bounce_buffer()
+ *
+ * @param sgl- the Scatter/Gather need be destroy
+ * @param sg_count- page count of the SG list.
+ *
+ */
+static void
+storvsc_destroy_bounce_buffer(struct sglist *sgl)
+{
+ struct hv_sgl_node *sgl_node = NULL;
+
+ sgl_node = LIST_FIRST(&g_hv_sgl_page_pool.in_use_sgl_list);
+ LIST_REMOVE(sgl_node, link);
+ if (NULL == sgl_node) {
+ printf("storvsc error: not enough in use sgl\n");
+ return;
+ }
+ sgl_node->sgl_data = sgl;
+ LIST_INSERT_HEAD(&g_hv_sgl_page_pool.free_sgl_list, sgl_node, link);
+}
+
+/**
+ * @brief create bounce buffer
+ *
+ * This function is responsible for create a Scatter/Gather list,
+ * which hold several pages that can be aligned with page size.
+ *
+ * @param seg_count- SG-list segments count
+ * @param write - if WRITE_TYPE, set SG list page used size to 0,
+ * otherwise set used size to page size.
+ *
+ * return NULL if create failed
+ */
+static struct sglist *
+storvsc_create_bounce_buffer(uint16_t seg_count, int write)
+{
+ int i = 0;
+ struct sglist *bounce_sgl = NULL;
+ unsigned int buf_len = ((write == WRITE_TYPE) ? 0 : PAGE_SIZE);
+ struct hv_sgl_node *sgl_node = NULL;
+
+ /* get struct sglist from free_sgl_list */
+ sgl_node = LIST_FIRST(&g_hv_sgl_page_pool.free_sgl_list);
+ LIST_REMOVE(sgl_node, link);
+ if (NULL == sgl_node) {
+ printf("storvsc error: not enough free sgl\n");
+ return NULL;
+ }
+ bounce_sgl = sgl_node->sgl_data;
+ LIST_INSERT_HEAD(&g_hv_sgl_page_pool.in_use_sgl_list, sgl_node, link);
+
+ bounce_sgl->sg_maxseg = seg_count;
+
+ if (write == WRITE_TYPE)
+ bounce_sgl->sg_nseg = 0;
+ else
+ bounce_sgl->sg_nseg = seg_count;
+
+ for (i = 0; i < seg_count; i++)
+ bounce_sgl->sg_segs[i].ss_len = buf_len;
+
+ return bounce_sgl;
+}
+
+/**
+ * @brief copy data from SG list to bounce buffer
+ *
+ * This function is responsible for copy data from one SG list's segments
+ * to another SG list which used as bounce buffer.
+ *
+ * @param bounce_sgl - the destination SG list
+ * @param orig_sgl - the segment of the source SG list.
+ * @param orig_sgl_count - the count of segments.
+ * @param orig_sgl_count - indicate which segment need bounce buffer,
+ * set 1 means need.
+ *
+ */
+static void
+storvsc_copy_sgl_to_bounce_buf(struct sglist *bounce_sgl,
+ bus_dma_segment_t *orig_sgl,
+ unsigned int orig_sgl_count,
+ uint64_t seg_bits)
+{
+ int src_sgl_idx = 0;
+
+ for (src_sgl_idx = 0; src_sgl_idx < orig_sgl_count; src_sgl_idx++) {
+ if (seg_bits & (1 << src_sgl_idx)) {
+ memcpy((void*)bounce_sgl->sg_segs[src_sgl_idx].ss_paddr,
+ (void*)orig_sgl[src_sgl_idx].ds_addr,
+ orig_sgl[src_sgl_idx].ds_len);
+
+ bounce_sgl->sg_segs[src_sgl_idx].ss_len =
+ orig_sgl[src_sgl_idx].ds_len;
+ }
+ }
+}
+
+/**
+ * @brief copy data from SG list which used as bounce to another SG list
+ *
+ * This function is responsible for copy data from one SG list with bounce
+ * buffer to another SG list's segments.
+ *
+ * @param dest_sgl - the destination SG list's segments
+ * @param dest_sgl_count - the count of destination SG list's segment.
+ * @param src_sgl - the source SG list.
+ * @param seg_bits - indicate which segment used bounce buffer of src SG-list.
+ *
+ */
+void
+storvsc_copy_from_bounce_buf_to_sgl(bus_dma_segment_t *dest_sgl,
+ unsigned int dest_sgl_count,
+ struct sglist* src_sgl,
+ uint64_t seg_bits)
+{
+ int sgl_idx = 0;
+
+ for (sgl_idx = 0; sgl_idx < dest_sgl_count; sgl_idx++) {
+ if (seg_bits & (1 << sgl_idx)) {
+ memcpy((void*)(dest_sgl[sgl_idx].ds_addr),
+ (void*)(src_sgl->sg_segs[sgl_idx].ss_paddr),
+ src_sgl->sg_segs[sgl_idx].ss_len);
+ }
+ }
+}
+
+/**
+ * @brief check SG list with bounce buffer or not
+ *
+ * This function is responsible for check if need bounce buffer for SG list.
+ *
+ * @param sgl - the SG list's segments
+ * @param sg_count - the count of SG list's segment.
+ * @param bits - segmengs number that need bounce buffer
+ *
+ * return -1 if SG list needless bounce buffer
+ */
+static int
+storvsc_check_bounce_buffer_sgl(bus_dma_segment_t *sgl,
+ unsigned int sg_count,
+ uint64_t *bits)
+{
+ int i = 0;
+ int offset = 0;
+ uint64_t phys_addr = 0;
+ uint64_t tmp_bits = 0;
+ boolean_t found_hole = FALSE;
+ boolean_t pre_aligned = TRUE;
+
+ if (sg_count < 2){
+ return -1;
+ }
+
+ *bits = 0;
+
+ phys_addr = vtophys(sgl[0].ds_addr);
+ offset = phys_addr - trunc_page(phys_addr);
+
+ if (offset != 0) {
+ pre_aligned = FALSE;
+ tmp_bits |= 1;
+ }
+
+ for (i = 1; i < sg_count; i++) {
+ phys_addr = vtophys(sgl[i].ds_addr);
+ offset = phys_addr - trunc_page(phys_addr);
+
+ if (offset == 0) {
+ if (FALSE == pre_aligned){
+ /*
+ * This segment is aligned, if the previous
+ * one is not aligned, find a hole
+ */
+ found_hole = TRUE;
+ }
+ pre_aligned = TRUE;
+ } else {
+ tmp_bits |= 1 << i;
+ if (!pre_aligned) {
+ if (phys_addr != vtophys(sgl[i-1].ds_addr +
+ sgl[i-1].ds_len)) {
+ /*
+ * Check whether connect to previous
+ * segment,if not, find the hole
+ */
+ found_hole = TRUE;
+ }
+ } else {
+ found_hole = TRUE;
+ }
+ pre_aligned = FALSE;
+ }
+ }
+
+ if (!found_hole) {
+ return (-1);
+ } else {
+ *bits = tmp_bits;
+ return 0;
+ }
+}
+
+/**
* @brief Fill in a request structure based on a CAM control block
*
* Fills in a request structure based on the contents of a CAM control
@@ -1203,7 +1667,7 @@ storvsc_action(struct cam_sim *sim, union ccb *ccb)
* @param ccb pointer to a CAM contorl block
* @param reqp pointer to a request structure
*/
-static void
+static int
create_storvsc_request(union ccb *ccb, struct hv_storvsc_request *reqp)
{
struct ccb_scsiio *csio = &ccb->csio;
@@ -1211,6 +1675,7 @@ create_storvsc_request(union ccb *ccb, struct hv_storvsc_request *reqp)
uint32_t bytes_to_copy = 0;
uint32_t pfn_num = 0;
uint32_t pfn;
+ uint64_t not_aligned_seg_bits = 0;
/* refer to struct vmscsi_req for meanings of these two fields */
reqp->vstor_packet.u.vm_srb.port =
@@ -1231,48 +1696,172 @@ create_storvsc_request(union ccb *ccb, struct hv_storvsc_request *reqp)
}
switch (ccb->ccb_h.flags & CAM_DIR_MASK) {
- case CAM_DIR_OUT:
- reqp->vstor_packet.u.vm_srb.data_in = WRITE_TYPE;
- break;
- case CAM_DIR_IN:
- reqp->vstor_packet.u.vm_srb.data_in = READ_TYPE;
- break;
- case CAM_DIR_NONE:
- reqp->vstor_packet.u.vm_srb.data_in = UNKNOWN_TYPE;
- break;
- default:
- reqp->vstor_packet.u.vm_srb.data_in = UNKNOWN_TYPE;
- break;
+ case CAM_DIR_OUT:
+ reqp->vstor_packet.u.vm_srb.data_in = WRITE_TYPE;
+ break;
+ case CAM_DIR_IN:
+ reqp->vstor_packet.u.vm_srb.data_in = READ_TYPE;
+ break;
+ case CAM_DIR_NONE:
+ reqp->vstor_packet.u.vm_srb.data_in = UNKNOWN_TYPE;
+ break;
+ default:
+ reqp->vstor_packet.u.vm_srb.data_in = UNKNOWN_TYPE;
+ break;
}
reqp->sense_data = &csio->sense_data;
reqp->sense_info_len = csio->sense_len;
reqp->ccb = ccb;
- /*
- KASSERT((ccb->ccb_h.flags & CAM_SCATTER_VALID) == 0,
- ("ccb is scatter gather valid\n"));
- */
- if (csio->dxfer_len != 0) {
- reqp->data_buf.length = csio->dxfer_len;
+
+ if (0 == csio->dxfer_len) {
+ return (0);
+ }
+
+ reqp->data_buf.length = csio->dxfer_len;
+
+ switch (ccb->ccb_h.flags & CAM_DATA_MASK) {
+ case CAM_DATA_VADDR:
+ {
bytes_to_copy = csio->dxfer_len;
phys_addr = vtophys(csio->data_ptr);
- reqp->data_buf.offset = phys_addr - trunc_page(phys_addr);
+ reqp->data_buf.offset = phys_addr & PAGE_MASK;
+
+ while (bytes_to_copy != 0) {
+ int bytes, page_offset;
+ phys_addr =
+ vtophys(&csio->data_ptr[reqp->data_buf.length -
+ bytes_to_copy]);
+ pfn = phys_addr >> PAGE_SHIFT;
+ reqp->data_buf.pfn_array[pfn_num] = pfn;
+ page_offset = phys_addr & PAGE_MASK;
+
+ bytes = min(PAGE_SIZE - page_offset, bytes_to_copy);
+
+ bytes_to_copy -= bytes;
+ pfn_num++;
+ }
+ break;
}
- while (bytes_to_copy != 0) {
- int bytes, page_offset;
- phys_addr = vtophys(&csio->data_ptr[reqp->data_buf.length -
- bytes_to_copy]);
- pfn = phys_addr >> PAGE_SHIFT;
- reqp->data_buf.pfn_array[pfn_num] = pfn;
- page_offset = phys_addr - trunc_page(phys_addr);
+ case CAM_DATA_SG:
+ {
+ int i = 0;
+ int offset = 0;
+ int ret;
+
+ bus_dma_segment_t *storvsc_sglist =
+ (bus_dma_segment_t *)ccb->csio.data_ptr;
+ u_int16_t storvsc_sg_count = ccb->csio.sglist_cnt;
+
+ printf("Storvsc: get SG I/O operation, %d\n",
+ reqp->vstor_packet.u.vm_srb.data_in);
+
+ if (storvsc_sg_count > HV_MAX_MULTIPAGE_BUFFER_COUNT){
+ printf("Storvsc: %d segments is too much, "
+ "only support %d segments\n",
+ storvsc_sg_count, HV_MAX_MULTIPAGE_BUFFER_COUNT);
+ return (EINVAL);
+ }
+
+ /*
+ * We create our own bounce buffer function currently. Idealy
+ * we should use BUS_DMA(9) framework. But with current BUS_DMA
+ * code there is no callback API to check the page alignment of
+ * middle segments before busdma can decide if a bounce buffer
+ * is needed for particular segment. There is callback,
+ * "bus_dma_filter_t *filter", but the parrameters are not
+ * sufficient for storvsc driver.
+ * TODO:
+ * Add page alignment check in BUS_DMA(9) callback. Once
+ * this is complete, switch the following code to use
+ * BUS_DMA(9) for storvsc bounce buffer support.
+ */
+ /* check if we need to create bounce buffer */
+ ret = storvsc_check_bounce_buffer_sgl(storvsc_sglist,
+ storvsc_sg_count, &not_aligned_seg_bits);
+ if (ret != -1) {
+ reqp->bounce_sgl =
+ storvsc_create_bounce_buffer(storvsc_sg_count,
+ reqp->vstor_packet.u.vm_srb.data_in);
+ if (NULL == reqp->bounce_sgl) {
+ printf("Storvsc_error: "
+ "create bounce buffer failed.\n");
+ return (ENOMEM);
+ }
+
+ reqp->bounce_sgl_count = storvsc_sg_count;
+ reqp->not_aligned_seg_bits = not_aligned_seg_bits;
+
+ /*
+ * if it is write, we need copy the original data
+ *to bounce buffer
+ */
+ if (WRITE_TYPE == reqp->vstor_packet.u.vm_srb.data_in) {
+ storvsc_copy_sgl_to_bounce_buf(
+ reqp->bounce_sgl,
+ storvsc_sglist,
+ storvsc_sg_count,
+ reqp->not_aligned_seg_bits);
+ }
+
+ /* transfer virtual address to physical frame number */
+ if (reqp->not_aligned_seg_bits & 0x1){
+ phys_addr =
+ vtophys(reqp->bounce_sgl->sg_segs[0].ss_paddr);
+ }else{
+ phys_addr =
+ vtophys(storvsc_sglist[0].ds_addr);
+ }
+ reqp->data_buf.offset = phys_addr & PAGE_MASK;
+
+ pfn = phys_addr >> PAGE_SHIFT;
+ reqp->data_buf.pfn_array[0] = pfn;
+
+ for (i = 1; i < storvsc_sg_count; i++) {
+ if (reqp->not_aligned_seg_bits & (1 << i)) {
+ phys_addr =
+ vtophys(reqp->bounce_sgl->sg_segs[i].ss_paddr);
+ } else {
+ phys_addr =
+ vtophys(storvsc_sglist[i].ds_addr);
+ }
+
+ pfn = phys_addr >> PAGE_SHIFT;
+ reqp->data_buf.pfn_array[i] = pfn;
+ }
+ } else {
+ phys_addr = vtophys(storvsc_sglist[0].ds_addr);
+
+ reqp->data_buf.offset = phys_addr & PAGE_MASK;
- bytes = min(PAGE_SIZE - page_offset, bytes_to_copy);
+ for (i = 0; i < storvsc_sg_count; i++) {
+ phys_addr = vtophys(storvsc_sglist[i].ds_addr);
+ pfn = phys_addr >> PAGE_SHIFT;
+ reqp->data_buf.pfn_array[i] = pfn;
+ }
- bytes_to_copy -= bytes;
- pfn_num++;
+ /* check the last segment cross boundary or not */
+ offset = phys_addr & PAGE_MASK;
+ if (offset) {
+ phys_addr =
+ vtophys(storvsc_sglist[i-1].ds_addr +
+ PAGE_SIZE - offset);
+ pfn = phys_addr >> PAGE_SHIFT;
+ reqp->data_buf.pfn_array[i] = pfn;
+ }
+
+ reqp->bounce_sgl_count = 0;
+ }
+ break;
+ }
+ default:
+ printf("Unknow flags: %d\n", ccb->ccb_h.flags);
+ return(EINVAL);
}
+
+ return(0);
}
/**
@@ -1291,7 +1880,29 @@ storvsc_io_done(struct hv_storvsc_request *reqp)
struct ccb_scsiio *csio = &ccb->csio;
struct storvsc_softc *sc = reqp->softc;
struct vmscsi_req *vm_srb = &reqp->vstor_packet.u.vm_srb;
-
+ bus_dma_segment_t *ori_sglist = NULL;
+ int ori_sg_count = 0;
+
+ /* destroy bounce buffer if it is used */
+ if (reqp->bounce_sgl_count) {
+ ori_sglist = (bus_dma_segment_t *)ccb->csio.data_ptr;
+ ori_sg_count = ccb->csio.sglist_cnt;
+
+ /*
+ * If it is READ operation, we should copy back the data
+ * to original SG list.
+ */
+ if (READ_TYPE == reqp->vstor_packet.u.vm_srb.data_in) {
+ storvsc_copy_from_bounce_buf_to_sgl(ori_sglist,
+ ori_sg_count,
+ reqp->bounce_sgl,
+ reqp->not_aligned_seg_bits);
+ }
+
+ storvsc_destroy_bounce_buffer(reqp->bounce_sgl);
+ reqp->bounce_sgl_count = 0;
+ }
+
if (reqp->retries > 0) {
mtx_lock(&sc->hs_lock);
#if HVS_TIMEOUT_TEST
@@ -1309,7 +1920,7 @@ storvsc_io_done(struct hv_storvsc_request *reqp)
mtx_unlock(&sc->hs_lock);
}
- /*
+ /*
* callout_drain() will wait for the timer handler to finish
* if it is running. So we don't need any lock to synchronize
* between this routine and the timer handler.
diff --git a/sys/dev/hyperv/storvsc/hv_vstorage.h b/sys/dev/hyperv/storvsc/hv_vstorage.h
index 2632676160ce..deb918303d60 100644
--- a/sys/dev/hyperv/storvsc/hv_vstorage.h
+++ b/sys/dev/hyperv/storvsc/hv_vstorage.h
@@ -53,7 +53,7 @@
* V1 RC > 2008/1/31 2.0
*/
-#define VMSTOR_PROTOCOL_VERSION_CURRENT VMSTOR_PROTOCOL_VERSION(2, 0)
+#define VMSTOR_PROTOCOL_VERSION_CURRENT VMSTOR_PROTOCOL_VERSION(5, 1)
/**
* Packet structure ops describing virtual storage requests.
@@ -69,7 +69,10 @@ enum vstor_packet_ops {
VSTOR_OPERATION_ENDINITIALIZATION = 8,
VSTOR_OPERATION_QUERYPROTOCOLVERSION = 9,
VSTOR_OPERATION_QUERYPROPERTIES = 10,
- VSTOR_OPERATION_MAXIMUM = 10
+ VSTOR_OPERATION_ENUMERATE_BUS = 11,
+ VSTOR_OPERATION_FCHBA_DATA = 12,
+ VSTOR_OPERATION_CREATE_MULTI_CHANNELS = 13,
+ VSTOR_OPERATION_MAXIMUM = 13
};
@@ -123,10 +126,12 @@ struct vmstor_chan_props {
uint8_t path_id;
uint8_t target_id;
+ uint16_t max_channel_cnt;
+
/**
* Note: port number is only really known on the client side
*/
- uint32_t port;
+ uint16_t port;
uint32_t flags;
uint32_t max_transfer_bytes;
@@ -193,6 +198,11 @@ struct vstor_packet {
* Used during version negotiations.
*/
struct vmstor_proto_ver version;
+
+ /**
+ * Number of multichannels to create
+ */
+ uint16_t multi_channels_cnt;
} u;
} __packed;
diff --git a/sys/dev/hyperv/utilities/hv_kvp.c b/sys/dev/hyperv/utilities/hv_kvp.c
index 848d364a4b33..4598510bb8d5 100644
--- a/sys/dev/hyperv/utilities/hv_kvp.c
+++ b/sys/dev/hyperv/utilities/hv_kvp.c
@@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$");
#include <sys/_null.h>
#include <sys/signal.h>
#include <sys/syslog.h>
+#include <sys/systm.h>
#include <sys/mutex.h>
#include <net/if_arp.h>
@@ -232,7 +233,7 @@ hv_kvp_negotiate_version(struct hv_vmbus_icmsg_hdr *icmsghdrp,
*/
if ((icframe_vercnt >= 2) && (negop->icversion_data[1].major == 3)) {
icframe_vercnt = 3;
- if (icmsg_vercnt >= 2)
+ if (icmsg_vercnt > 2)
icmsg_vercnt = 4;
else
icmsg_vercnt = 3;
@@ -734,8 +735,8 @@ hv_kvp_process_request(void *context)
recvlen = 0;
ret = hv_vmbus_channel_recv_packet(channel, kvp_buf, 2 * PAGE_SIZE,
&recvlen, &requestid);
- hv_kvp_log_info("%s: read: context %p, pending_cnt %ju ret =%d, recvlen=%d\n",
- __func__, context, pending_cnt, ret, recvlen);
+ hv_kvp_log_info("%s: read: context %p, pending_cnt %llu ret =%d, recvlen=%d\n",
+ __func__, context, (unsigned long long)pending_cnt, ret, recvlen);
}
}
@@ -813,9 +814,9 @@ static void
hv_kvp_dev_destroy(void)
{
- if (daemon_task != NULL) {
+ if (daemon_task != NULL) {
PROC_LOCK(daemon_task);
- kern_psignal(daemon_task, SIGKILL);
+ kern_psignal(daemon_task, SIGKILL);
PROC_UNLOCK(daemon_task);
}
diff --git a/sys/dev/hyperv/utilities/hv_util.c b/sys/dev/hyperv/utilities/hv_util.c
index 3e545cff50c3..dc4b1e2537ba 100644
--- a/sys/dev/hyperv/utilities/hv_util.c
+++ b/sys/dev/hyperv/utilities/hv_util.c
@@ -408,6 +408,15 @@ hv_util_attach(device_t dev)
}
}
+ /*
+ * These services are not performance critical and do not need
+ * batched reading. Furthermore, some services such as KVP can
+ * only handle one message from the host at a time.
+ * Turn off batched reading for all util drivers before we open the
+ * channel.
+ */
+ hv_set_channel_read_state(hv_dev->channel, FALSE);
+
ret = hv_vmbus_channel_open(hv_dev->channel, 4 * PAGE_SIZE,
4 * PAGE_SIZE, NULL, 0,
service->callback, hv_dev->channel);
diff --git a/sys/dev/hyperv/vmbus/hv_channel.c b/sys/dev/hyperv/vmbus/hv_channel.c
index 103260a6adf7..94137fbeb225 100644
--- a/sys/dev/hyperv/vmbus/hv_channel.c
+++ b/sys/dev/hyperv/vmbus/hv_channel.c
@@ -75,7 +75,7 @@ vmbus_channel_set_event(hv_vmbus_channel *channel)
(uint32_t *)&monitor_page->
trigger_group[channel->monitor_group].u.pending);
} else {
- hv_vmbus_set_event(channel->offer_msg.child_rel_id);
+ hv_vmbus_set_event(channel);
}
}
@@ -99,6 +99,18 @@ hv_vmbus_channel_open(
hv_vmbus_channel_open_channel* open_msg;
hv_vmbus_channel_msg_info* open_info;
+ mtx_lock(&new_channel->sc_lock);
+ if (new_channel->state == HV_CHANNEL_OPEN_STATE) {
+ new_channel->state = HV_CHANNEL_OPENING_STATE;
+ } else {
+ mtx_unlock(&new_channel->sc_lock);
+ if(bootverbose)
+ printf("VMBUS: Trying to open channel <%p> which in "
+ "%d state.\n", new_channel, new_channel->state);
+ return (EINVAL);
+ }
+ mtx_unlock(&new_channel->sc_lock);
+
new_channel->on_channel_callback = pfn_on_channel_callback;
new_channel->channel_callback_context = context;
@@ -162,7 +174,7 @@ hv_vmbus_channel_open(
new_channel->ring_buffer_gpadl_handle;
open_msg->downstream_ring_buffer_page_offset = send_ring_buffer_size
>> PAGE_SHIFT;
- open_msg->server_context_area_gpadl_handle = 0;
+ open_msg->target_vcpu = new_channel->target_vcpu;
if (user_data_len)
memcpy(open_msg->user_data, user_data, user_data_len);
@@ -182,10 +194,14 @@ hv_vmbus_channel_open(
ret = sema_timedwait(&open_info->wait_sema, 500); /* KYS 5 seconds */
- if (ret)
+ if (ret) {
+ if(bootverbose)
+ printf("VMBUS: channel <%p> open timeout.\n", new_channel);
goto cleanup;
+ }
if (open_info->response.open_result.status == 0) {
+ new_channel->state = HV_CHANNEL_OPENED_STATE;
if(bootverbose)
printf("VMBUS: channel <%p> open success.\n", new_channel);
} else {
@@ -497,16 +513,20 @@ cleanup:
return (ret);
}
-/**
- * @brief Close the specified channel
- */
-void
-hv_vmbus_channel_close(hv_vmbus_channel *channel)
+static void
+hv_vmbus_channel_close_internal(hv_vmbus_channel *channel)
{
int ret = 0;
hv_vmbus_channel_close_channel* msg;
hv_vmbus_channel_msg_info* info;
+ channel->state = HV_CHANNEL_OPEN_STATE;
+ channel->sc_creation_callback = NULL;
+
+ /*
+ * Grab the lock to prevent race condition when a packet received
+ * and unloading driver is in the process.
+ */
mtx_lock(&channel->inbound_lock);
channel->on_channel_callback = NULL;
mtx_unlock(&channel->inbound_lock);
@@ -545,23 +565,37 @@ hv_vmbus_channel_close(hv_vmbus_channel *channel)
M_DEVBUF);
free(info, M_DEVBUF);
+}
+
+/**
+ * @brief Close the specified channel
+ */
+void
+hv_vmbus_channel_close(hv_vmbus_channel *channel)
+{
+ hv_vmbus_channel* sub_channel;
+
+ if (channel->primary_channel != NULL) {
+ /*
+ * We only close multi-channels when the primary is
+ * closed.
+ */
+ return;
+ }
/*
- * If we are closing the channel during an error path in
- * opening the channel, don't free the channel
- * since the caller will free the channel
+ * Close all multi-channels first.
*/
- if (channel->state == HV_CHANNEL_OPEN_STATE) {
- mtx_lock_spin(&hv_vmbus_g_connection.channel_lock);
- TAILQ_REMOVE(
- &hv_vmbus_g_connection.channel_anchor,
- channel,
- list_entry);
- mtx_unlock_spin(&hv_vmbus_g_connection.channel_lock);
-
- hv_vmbus_free_vmbus_channel(channel);
+ TAILQ_FOREACH(sub_channel, &channel->sc_list_anchor,
+ sc_list_entry) {
+ if (sub_channel->state != HV_CHANNEL_OPENED_STATE)
+ continue;
+ hv_vmbus_channel_close_internal(sub_channel);
}
-
+ /*
+ * Then close the primary channel.
+ */
+ hv_vmbus_channel_close_internal(channel);
}
/**
@@ -581,6 +615,7 @@ hv_vmbus_channel_send_packet(
uint32_t packet_len;
uint64_t aligned_data;
uint32_t packet_len_aligned;
+ boolean_t need_sig;
hv_vmbus_sg_buffer_list buffer_list[3];
packet_len = sizeof(hv_vm_packet_descriptor) + buffer_len;
@@ -604,12 +639,11 @@ hv_vmbus_channel_send_packet(
buffer_list[2].data = &aligned_data;
buffer_list[2].length = packet_len_aligned - packet_len;
- ret = hv_ring_buffer_write(&channel->outbound, buffer_list, 3);
+ ret = hv_ring_buffer_write(&channel->outbound, buffer_list, 3,
+ &need_sig);
/* TODO: We should determine if this is optional */
- if (ret == 0
- && !hv_vmbus_get_ring_buffer_interrupt_mask(
- &channel->outbound)) {
+ if (ret == 0 && need_sig) {
vmbus_channel_set_event(channel);
}
@@ -632,6 +666,7 @@ hv_vmbus_channel_send_packet_pagebuffer(
int ret = 0;
int i = 0;
+ boolean_t need_sig;
uint32_t packet_len;
uint32_t packetLen_aligned;
hv_vmbus_sg_buffer_list buffer_list[3];
@@ -675,11 +710,11 @@ hv_vmbus_channel_send_packet_pagebuffer(
buffer_list[2].data = &alignedData;
buffer_list[2].length = packetLen_aligned - packet_len;
- ret = hv_ring_buffer_write(&channel->outbound, buffer_list, 3);
+ ret = hv_ring_buffer_write(&channel->outbound, buffer_list, 3,
+ &need_sig);
/* TODO: We should determine if this is optional */
- if (ret == 0 &&
- !hv_vmbus_get_ring_buffer_interrupt_mask(&channel->outbound)) {
+ if (ret == 0 && need_sig) {
vmbus_channel_set_event(channel);
}
@@ -700,6 +735,7 @@ hv_vmbus_channel_send_packet_multipagebuffer(
int ret = 0;
uint32_t desc_size;
+ boolean_t need_sig;
uint32_t packet_len;
uint32_t packet_len_aligned;
uint32_t pfn_count;
@@ -750,11 +786,11 @@ hv_vmbus_channel_send_packet_multipagebuffer(
buffer_list[2].data = &aligned_data;
buffer_list[2].length = packet_len_aligned - packet_len;
- ret = hv_ring_buffer_write(&channel->outbound, buffer_list, 3);
+ ret = hv_ring_buffer_write(&channel->outbound, buffer_list, 3,
+ &need_sig);
/* TODO: We should determine if this is optional */
- if (ret == 0 &&
- !hv_vmbus_get_ring_buffer_interrupt_mask(&channel->outbound)) {
+ if (ret == 0 && need_sig) {
vmbus_channel_set_event(channel);
}
diff --git a/sys/dev/hyperv/vmbus/hv_channel_mgmt.c b/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
index 011e305709e6..783f6bcf2f62 100644
--- a/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
+++ b/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
@@ -50,6 +50,8 @@ static void vmbus_channel_on_gpadl_torndown(hv_vmbus_channel_msg_header* hdr);
static void vmbus_channel_on_offers_delivered(hv_vmbus_channel_msg_header* hdr);
static void vmbus_channel_on_version_response(hv_vmbus_channel_msg_header* hdr);
static void vmbus_channel_process_offer(void *context);
+struct hv_vmbus_channel*
+ vmbus_select_outgoing_channel(struct hv_vmbus_channel *promary);
/**
* Channel message dispatch table
@@ -233,6 +235,9 @@ hv_vmbus_allocate_channel(void)
return (NULL);
mtx_init(&channel->inbound_lock, "channel inbound", NULL, MTX_DEF);
+ mtx_init(&channel->sc_lock, "vmbus multi channel", NULL, MTX_DEF);
+
+ TAILQ_INIT(&channel->sc_list_anchor);
channel->control_work_queue = hv_work_queue_create("control");
@@ -262,6 +267,7 @@ ReleaseVmbusChannel(void *context)
void
hv_vmbus_free_vmbus_channel(hv_vmbus_channel* channel)
{
+ mtx_destroy(&channel->sc_lock);
mtx_destroy(&channel->inbound_lock);
/*
* We have to release the channel's workqueue/thread in
@@ -279,10 +285,10 @@ hv_vmbus_free_vmbus_channel(hv_vmbus_channel* channel)
static void
vmbus_channel_process_offer(void *context)
{
- int ret;
hv_vmbus_channel* new_channel;
boolean_t f_new;
hv_vmbus_channel* channel;
+ int ret;
new_channel = (hv_vmbus_channel*) context;
f_new = TRUE;
@@ -291,38 +297,76 @@ vmbus_channel_process_offer(void *context)
/*
* Make sure this is a new offer
*/
- mtx_lock_spin(&hv_vmbus_g_connection.channel_lock);
+ mtx_lock(&hv_vmbus_g_connection.channel_lock);
TAILQ_FOREACH(channel, &hv_vmbus_g_connection.channel_anchor,
list_entry)
{
- if (!memcmp(
- &channel->offer_msg.offer.interface_type,
- &new_channel->offer_msg.offer.interface_type,
- sizeof(hv_guid))
- && !memcmp(
- &channel->offer_msg.offer.interface_instance,
+ if (memcmp(&channel->offer_msg.offer.interface_type,
+ &new_channel->offer_msg.offer.interface_type,
+ sizeof(hv_guid)) == 0 &&
+ memcmp(&channel->offer_msg.offer.interface_instance,
&new_channel->offer_msg.offer.interface_instance,
- sizeof(hv_guid))) {
- f_new = FALSE;
- break;
- }
+ sizeof(hv_guid)) == 0) {
+ f_new = FALSE;
+ break;
+ }
}
if (f_new) {
- /* Insert at tail */
- TAILQ_INSERT_TAIL(
- &hv_vmbus_g_connection.channel_anchor,
- new_channel,
- list_entry);
+ /* Insert at tail */
+ TAILQ_INSERT_TAIL(
+ &hv_vmbus_g_connection.channel_anchor,
+ new_channel,
+ list_entry);
}
- mtx_unlock_spin(&hv_vmbus_g_connection.channel_lock);
+ mtx_unlock(&hv_vmbus_g_connection.channel_lock);
+
+ /*XXX add new channel to percpu_list */
if (!f_new) {
+ /*
+ * Check if this is a sub channel.
+ */
+ if (new_channel->offer_msg.offer.sub_channel_index != 0) {
+ /*
+ * It is a sub channel offer, process it.
+ */
+ new_channel->primary_channel = channel;
+ mtx_lock(&channel->sc_lock);
+ TAILQ_INSERT_TAIL(
+ &channel->sc_list_anchor,
+ new_channel,
+ sc_list_entry);
+ mtx_unlock(&channel->sc_lock);
+
+ /* Insert new channel into channel_anchor. */
+ printf("Storvsc get multi-channel offer, rel=%u.\n",
+ new_channel->offer_msg.child_rel_id);
+ mtx_lock(&hv_vmbus_g_connection.channel_lock);
+ TAILQ_INSERT_TAIL(&hv_vmbus_g_connection.channel_anchor,
+ new_channel, list_entry);
+ mtx_unlock(&hv_vmbus_g_connection.channel_lock);
+
+ if(bootverbose)
+ printf("VMBUS: new multi-channel offer <%p>.\n",
+ new_channel);
+
+ /*XXX add it to percpu_list */
+
+ new_channel->state = HV_CHANNEL_OPEN_STATE;
+ if (channel->sc_creation_callback != NULL) {
+ channel->sc_creation_callback(new_channel);
+ }
+ return;
+ }
+
hv_vmbus_free_vmbus_channel(new_channel);
return;
}
+ new_channel->state = HV_CHANNEL_OPEN_STATE;
+
/*
* Start the process of binding this offer to the driver
* (We need to set the device field before calling
@@ -333,35 +377,86 @@ vmbus_channel_process_offer(void *context)
new_channel->offer_msg.offer.interface_instance, new_channel);
/*
- * TODO - the HV_CHANNEL_OPEN_STATE flag should not be set below
- * but in the "open" channel request. The ret != 0 logic below
- * doesn't take into account that a channel
- * may have been opened successfully
- */
-
- /*
* Add the new device to the bus. This will kick off device-driver
* binding which eventually invokes the device driver's AddDevice()
* method.
*/
ret = hv_vmbus_child_device_register(new_channel->device);
if (ret != 0) {
- mtx_lock_spin(&hv_vmbus_g_connection.channel_lock);
- TAILQ_REMOVE(
- &hv_vmbus_g_connection.channel_anchor,
- new_channel,
- list_entry);
- mtx_unlock_spin(&hv_vmbus_g_connection.channel_lock);
- hv_vmbus_free_vmbus_channel(new_channel);
- } else {
- /*
- * This state is used to indicate a successful open
- * so that when we do close the channel normally,
- * we can clean up properly
- */
- new_channel->state = HV_CHANNEL_OPEN_STATE;
+ mtx_lock(&hv_vmbus_g_connection.channel_lock);
+ TAILQ_REMOVE(
+ &hv_vmbus_g_connection.channel_anchor,
+ new_channel,
+ list_entry);
+ mtx_unlock(&hv_vmbus_g_connection.channel_lock);
+ hv_vmbus_free_vmbus_channel(new_channel);
+ }
+}
+
+/**
+ * Array of device guids that are performance critical. We try to distribute
+ * the interrupt load for these devices across all online cpus.
+ */
+static const hv_guid high_perf_devices[] = {
+ {HV_NIC_GUID, },
+ {HV_IDE_GUID, },
+ {HV_SCSI_GUID, },
+};
+
+enum {
+ PERF_CHN_NIC = 0,
+ PERF_CHN_IDE,
+ PERF_CHN_SCSI,
+ MAX_PERF_CHN,
+};
+/*
+ * We use this static number to distribute the channel interrupt load.
+ */
+static uint32_t next_vcpu;
+
+/**
+ * Starting with Win8, we can statically distribute the incoming
+ * channel interrupt load by binding a channel to VCPU. We
+ * implement here a simple round robin scheme for distributing
+ * the interrupt load.
+ * We will bind channels that are not performance critical to cpu 0 and
+ * performance critical channels (IDE, SCSI and Network) will be uniformly
+ * distributed across all available CPUs.
+ */
+static void
+vmbus_channel_select_cpu(hv_vmbus_channel *channel, hv_guid *guid)
+{
+ uint32_t current_cpu;
+ int i;
+ boolean_t is_perf_channel = FALSE;
+
+ for (i = PERF_CHN_NIC; i < MAX_PERF_CHN; i++) {
+ if (memcmp(guid->data, high_perf_devices[i].data,
+ sizeof(hv_guid)) == 0) {
+ is_perf_channel = TRUE;
+ break;
+ }
+ }
+
+ if ((hv_vmbus_protocal_version == HV_VMBUS_VERSION_WS2008) ||
+ (hv_vmbus_protocal_version == HV_VMBUS_VERSION_WIN7) ||
+ (!is_perf_channel)) {
+ /* Host's view of guest cpu */
+ channel->target_vcpu = 0;
+ /* Guest's own view of cpu */
+ channel->target_cpu = 0;
+ return;
}
+ /* mp_ncpus should have the number cpus currently online */
+ current_cpu = (++next_vcpu % mp_ncpus);
+ channel->target_cpu = current_cpu;
+ channel->target_vcpu =
+ hv_vmbus_g_context.hv_vcpu_index[current_cpu];
+ if (bootverbose)
+ printf("VMBUS: Total online cpus %d, assign perf channel %d "
+ "to vcpu %d, cpu %d\n", mp_ncpus, i, channel->target_vcpu,
+ current_cpu);
}
/**
@@ -391,6 +486,38 @@ vmbus_channel_on_offer(hv_vmbus_channel_msg_header* hdr)
if (new_channel == NULL)
return;
+ /*
+ * By default we setup state to enable batched
+ * reading. A specific service can choose to
+ * disable this prior to opening the channel.
+ */
+ new_channel->batched_reading = TRUE;
+
+ new_channel->signal_event_param =
+ (hv_vmbus_input_signal_event *)
+ (HV_ALIGN_UP((unsigned long)
+ &new_channel->signal_event_buffer,
+ HV_HYPERCALL_PARAM_ALIGN));
+
+ new_channel->signal_event_param->connection_id.as_uint32_t = 0;
+ new_channel->signal_event_param->connection_id.u.id =
+ HV_VMBUS_EVENT_CONNECTION_ID;
+ new_channel->signal_event_param->flag_number = 0;
+ new_channel->signal_event_param->rsvd_z = 0;
+
+ if (hv_vmbus_protocal_version != HV_VMBUS_VERSION_WS2008) {
+ new_channel->is_dedicated_interrupt =
+ (offer->is_dedicated_interrupt != 0);
+ new_channel->signal_event_param->connection_id.u.id =
+ offer->connection_id;
+ }
+
+ /*
+ * Bind the channel to a chosen cpu.
+ */
+ vmbus_channel_select_cpu(new_channel,
+ &offer->offer.interface_type);
+
memcpy(&new_channel->offer_msg, offer,
sizeof(hv_vmbus_channel_offer_channel));
new_channel->monitor_group = (uint8_t) offer->monitor_id / 32;
@@ -666,7 +793,7 @@ hv_vmbus_release_unattached_channels(void)
{
hv_vmbus_channel *channel;
- mtx_lock_spin(&hv_vmbus_g_connection.channel_lock);
+ mtx_lock(&hv_vmbus_g_connection.channel_lock);
while (!TAILQ_EMPTY(&hv_vmbus_g_connection.channel_anchor)) {
channel = TAILQ_FIRST(&hv_vmbus_g_connection.channel_anchor);
@@ -676,5 +803,61 @@ hv_vmbus_release_unattached_channels(void)
hv_vmbus_child_device_unregister(channel->device);
hv_vmbus_free_vmbus_channel(channel);
}
- mtx_unlock_spin(&hv_vmbus_g_connection.channel_lock);
+ mtx_unlock(&hv_vmbus_g_connection.channel_lock);
+}
+
+/**
+ * @brief Select the best outgoing channel
+ *
+ * The channel whose vcpu binding is closest to the currect vcpu will
+ * be selected.
+ * If no multi-channel, always select primary channel
+ *
+ * @param primary - primary channel
+ */
+struct hv_vmbus_channel *
+vmbus_select_outgoing_channel(struct hv_vmbus_channel *primary)
+{
+ hv_vmbus_channel *new_channel = NULL;
+ hv_vmbus_channel *outgoing_channel = primary;
+ int old_cpu_distance = 0;
+ int new_cpu_distance = 0;
+ int cur_vcpu = 0;
+ int smp_pro_id = PCPU_GET(cpuid);
+
+ if (TAILQ_EMPTY(&primary->sc_list_anchor)) {
+ return outgoing_channel;
+ }
+
+ if (smp_pro_id >= MAXCPU) {
+ return outgoing_channel;
+ }
+
+ cur_vcpu = hv_vmbus_g_context.hv_vcpu_index[smp_pro_id];
+
+ TAILQ_FOREACH(new_channel, &primary->sc_list_anchor, sc_list_entry) {
+ if (new_channel->state != HV_CHANNEL_OPENED_STATE){
+ continue;
+ }
+
+ if (new_channel->target_vcpu == cur_vcpu){
+ return new_channel;
+ }
+
+ old_cpu_distance = ((outgoing_channel->target_vcpu > cur_vcpu) ?
+ (outgoing_channel->target_vcpu - cur_vcpu) :
+ (cur_vcpu - outgoing_channel->target_vcpu));
+
+ new_cpu_distance = ((new_channel->target_vcpu > cur_vcpu) ?
+ (new_channel->target_vcpu - cur_vcpu) :
+ (cur_vcpu - new_channel->target_vcpu));
+
+ if (old_cpu_distance < new_cpu_distance) {
+ continue;
+ }
+
+ outgoing_channel = new_channel;
+ }
+
+ return(outgoing_channel);
}
diff --git a/sys/dev/hyperv/vmbus/hv_connection.c b/sys/dev/hyperv/vmbus/hv_connection.c
index c8e0b48ac65c..0300828961ba 100644
--- a/sys/dev/hyperv/vmbus/hv_connection.c
+++ b/sys/dev/hyperv/vmbus/hv_connection.c
@@ -45,14 +45,113 @@ hv_vmbus_connection hv_vmbus_g_connection =
{ .connect_state = HV_DISCONNECTED,
.next_gpadl_handle = 0xE1E10, };
+uint32_t hv_vmbus_protocal_version = HV_VMBUS_VERSION_WS2008;
+
+static uint32_t
+hv_vmbus_get_next_version(uint32_t current_ver)
+{
+ switch (current_ver) {
+ case (HV_VMBUS_VERSION_WIN7):
+ return(HV_VMBUS_VERSION_WS2008);
+
+ case (HV_VMBUS_VERSION_WIN8):
+ return(HV_VMBUS_VERSION_WIN7);
+
+ case (HV_VMBUS_VERSION_WIN8_1):
+ return(HV_VMBUS_VERSION_WIN8);
+
+ case (HV_VMBUS_VERSION_WS2008):
+ default:
+ return(HV_VMBUS_VERSION_INVALID);
+ }
+}
+
+/**
+ * Negotiate the highest supported hypervisor version.
+ */
+static int
+hv_vmbus_negotiate_version(hv_vmbus_channel_msg_info *msg_info,
+ uint32_t version)
+{
+ int ret = 0;
+ hv_vmbus_channel_initiate_contact *msg;
+
+ sema_init(&msg_info->wait_sema, 0, "Msg Info Sema");
+ msg = (hv_vmbus_channel_initiate_contact*) msg_info->msg;
+
+ msg->header.message_type = HV_CHANNEL_MESSAGE_INITIATED_CONTACT;
+ msg->vmbus_version_requested = version;
+
+ msg->interrupt_page = hv_get_phys_addr(
+ hv_vmbus_g_connection.interrupt_page);
+
+ msg->monitor_page_1 = hv_get_phys_addr(
+ hv_vmbus_g_connection.monitor_pages);
+
+ msg->monitor_page_2 =
+ hv_get_phys_addr(
+ ((uint8_t *) hv_vmbus_g_connection.monitor_pages
+ + PAGE_SIZE));
+
+ /**
+ * Add to list before we send the request since we may receive the
+ * response before returning from this routine
+ */
+ mtx_lock_spin(&hv_vmbus_g_connection.channel_msg_lock);
+
+ TAILQ_INSERT_TAIL(
+ &hv_vmbus_g_connection.channel_msg_anchor,
+ msg_info,
+ msg_list_entry);
+
+ mtx_unlock_spin(&hv_vmbus_g_connection.channel_msg_lock);
+
+ ret = hv_vmbus_post_message(
+ msg,
+ sizeof(hv_vmbus_channel_initiate_contact));
+
+ if (ret != 0) {
+ mtx_lock_spin(&hv_vmbus_g_connection.channel_msg_lock);
+ TAILQ_REMOVE(
+ &hv_vmbus_g_connection.channel_msg_anchor,
+ msg_info,
+ msg_list_entry);
+ mtx_unlock_spin(&hv_vmbus_g_connection.channel_msg_lock);
+ return (ret);
+ }
+
+ /**
+ * Wait for the connection response
+ */
+ ret = sema_timedwait(&msg_info->wait_sema, 500); /* KYS 5 seconds */
+
+ mtx_lock_spin(&hv_vmbus_g_connection.channel_msg_lock);
+ TAILQ_REMOVE(
+ &hv_vmbus_g_connection.channel_msg_anchor,
+ msg_info,
+ msg_list_entry);
+ mtx_unlock_spin(&hv_vmbus_g_connection.channel_msg_lock);
+
+ /**
+ * Check if successful
+ */
+ if (msg_info->response.version_response.version_supported) {
+ hv_vmbus_g_connection.connect_state = HV_CONNECTED;
+ } else {
+ ret = ECONNREFUSED;
+ }
+
+ return (ret);
+}
+
/**
* Send a connect request on the partition service connection
*/
int
hv_vmbus_connect(void) {
int ret = 0;
+ uint32_t version;
hv_vmbus_channel_msg_info* msg_info = NULL;
- hv_vmbus_channel_initiate_contact* msg;
/**
* Make sure we are not connecting or connected
@@ -74,7 +173,7 @@ hv_vmbus_connect(void) {
TAILQ_INIT(&hv_vmbus_g_connection.channel_anchor);
mtx_init(&hv_vmbus_g_connection.channel_lock, "vmbus channel",
- NULL, MTX_SPIN);
+ NULL, MTX_DEF);
/**
* Setup the vmbus event connection for channel interrupt abstraction
@@ -130,71 +229,30 @@ hv_vmbus_connect(void) {
goto cleanup;
}
- sema_init(&msg_info->wait_sema, 0, "Msg Info Sema");
- msg = (hv_vmbus_channel_initiate_contact*) msg_info->msg;
-
- msg->header.message_type = HV_CHANNEL_MESSAGE_INITIATED_CONTACT;
- msg->vmbus_version_requested = HV_VMBUS_REVISION_NUMBER;
-
- msg->interrupt_page = hv_get_phys_addr(
- hv_vmbus_g_connection.interrupt_page);
-
- msg->monitor_page_1 = hv_get_phys_addr(
- hv_vmbus_g_connection.monitor_pages);
-
- msg->monitor_page_2 =
- hv_get_phys_addr(
- ((uint8_t *) hv_vmbus_g_connection.monitor_pages
- + PAGE_SIZE));
-
- /**
- * Add to list before we send the request since we may receive the
- * response before returning from this routine
+ /*
+ * Find the highest vmbus version number we can support.
*/
- mtx_lock_spin(&hv_vmbus_g_connection.channel_msg_lock);
-
- TAILQ_INSERT_TAIL(
- &hv_vmbus_g_connection.channel_msg_anchor,
- msg_info,
- msg_list_entry);
-
- mtx_unlock_spin(&hv_vmbus_g_connection.channel_msg_lock);
-
- ret = hv_vmbus_post_message(
- msg,
- sizeof(hv_vmbus_channel_initiate_contact));
-
- if (ret != 0) {
- mtx_lock_spin(&hv_vmbus_g_connection.channel_msg_lock);
- TAILQ_REMOVE(
- &hv_vmbus_g_connection.channel_msg_anchor,
- msg_info,
- msg_list_entry);
- mtx_unlock_spin(&hv_vmbus_g_connection.channel_msg_lock);
- goto cleanup;
- }
+ version = HV_VMBUS_VERSION_CURRENT;
+
+ do {
+ ret = hv_vmbus_negotiate_version(msg_info, version);
+ if (ret == EWOULDBLOCK) {
+ /*
+ * We timed out.
+ */
+ goto cleanup;
+ }
- /**
- * Wait for the connection response
- */
- ret = sema_timedwait(&msg_info->wait_sema, 500); /* KYS 5 seconds */
+ if (hv_vmbus_g_connection.connect_state == HV_CONNECTED)
+ break;
- mtx_lock_spin(&hv_vmbus_g_connection.channel_msg_lock);
- TAILQ_REMOVE(
- &hv_vmbus_g_connection.channel_msg_anchor,
- msg_info,
- msg_list_entry);
- mtx_unlock_spin(&hv_vmbus_g_connection.channel_msg_lock);
+ version = hv_vmbus_get_next_version(version);
+ } while (version != HV_VMBUS_VERSION_INVALID);
- /**
- * Check if successful
- */
- if (msg_info->response.version_response.version_supported) {
- hv_vmbus_g_connection.connect_state = HV_CONNECTED;
- } else {
- ret = ECONNREFUSED;
- goto cleanup;
- }
+ hv_vmbus_protocal_version = version;
+ if (bootverbose)
+ printf("VMBUS: Portocal Version: %d.%d\n",
+ version >> 16, version & 0xFFFF);
sema_destroy(&msg_info->wait_sema);
free(msg_info, M_DEVBUF);
@@ -286,7 +344,7 @@ hv_vmbus_get_channel_from_rel_id(uint32_t rel_id) {
* and channels are accessed without the need to take this lock or search
* the list.
*/
- mtx_lock_spin(&hv_vmbus_g_connection.channel_lock);
+ mtx_lock(&hv_vmbus_g_connection.channel_lock);
TAILQ_FOREACH(channel,
&hv_vmbus_g_connection.channel_anchor, list_entry) {
@@ -295,7 +353,7 @@ hv_vmbus_get_channel_from_rel_id(uint32_t rel_id) {
break;
}
}
- mtx_unlock_spin(&hv_vmbus_g_connection.channel_lock);
+ mtx_unlock(&hv_vmbus_g_connection.channel_lock);
return (foundChannel);
}
@@ -306,7 +364,10 @@ hv_vmbus_get_channel_from_rel_id(uint32_t rel_id) {
static void
VmbusProcessChannelEvent(uint32_t relid)
{
+ void* arg;
+ uint32_t bytes_to_read;
hv_vmbus_channel* channel;
+ boolean_t is_batched_reading;
/**
* Find the channel based on this relid and invokes
@@ -327,31 +388,98 @@ VmbusProcessChannelEvent(uint32_t relid)
* callback to NULL. This closes the window.
*/
- mtx_lock(&channel->inbound_lock);
+ /*
+ * Disable the lock due to newly added WITNESS check in r277723.
+ * Will seek other way to avoid race condition.
+ * -- whu
+ */
+ // mtx_lock(&channel->inbound_lock);
if (channel->on_channel_callback != NULL) {
- channel->on_channel_callback(channel->channel_callback_context);
+ arg = channel->channel_callback_context;
+ is_batched_reading = channel->batched_reading;
+ /*
+ * Optimize host to guest signaling by ensuring:
+ * 1. While reading the channel, we disable interrupts from
+ * host.
+ * 2. Ensure that we process all posted messages from the host
+ * before returning from this callback.
+ * 3. Once we return, enable signaling from the host. Once this
+ * state is set we check to see if additional packets are
+ * available to read. In this case we repeat the process.
+ */
+ do {
+ if (is_batched_reading)
+ hv_ring_buffer_read_begin(&channel->inbound);
+
+ channel->on_channel_callback(arg);
+
+ if (is_batched_reading)
+ bytes_to_read =
+ hv_ring_buffer_read_end(&channel->inbound);
+ else
+ bytes_to_read = 0;
+ } while (is_batched_reading && (bytes_to_read != 0));
}
- mtx_unlock(&channel->inbound_lock);
+ // mtx_unlock(&channel->inbound_lock);
}
+#ifdef HV_DEBUG_INTR
+extern uint32_t hv_intr_count;
+extern uint32_t hv_vmbus_swintr_event_cpu[MAXCPU];
+extern uint32_t hv_vmbus_intr_cpu[MAXCPU];
+#endif
+
/**
* Handler for events
*/
void
hv_vmbus_on_events(void *arg)
{
- int dword;
int bit;
+ int cpu;
+ int dword;
+ void *page_addr;
+ uint32_t* recv_interrupt_page = NULL;
int rel_id;
- int maxdword = HV_MAX_NUM_CHANNELS_SUPPORTED >> 5;
+ int maxdword;
+ hv_vmbus_synic_event_flags *event;
/* int maxdword = PAGE_SIZE >> 3; */
- /*
- * receive size is 1/2 page and divide that by 4 bytes
- */
-
- uint32_t* recv_interrupt_page =
- hv_vmbus_g_connection.recv_interrupt_page;
+ cpu = (int)(long)arg;
+ KASSERT(cpu <= mp_maxid, ("VMBUS: hv_vmbus_on_events: "
+ "cpu out of range!"));
+
+#ifdef HV_DEBUG_INTR
+ int i;
+ hv_vmbus_swintr_event_cpu[cpu]++;
+ if (hv_intr_count % 10000 == 0) {
+ printf("VMBUS: Total interrupt %d\n", hv_intr_count);
+ for (i = 0; i < mp_ncpus; i++)
+ printf("VMBUS: hw cpu[%d]: %d, event sw intr cpu[%d]: %d\n",
+ i, hv_vmbus_intr_cpu[i], i, hv_vmbus_swintr_event_cpu[i]);
+ }
+#endif
+
+ if ((hv_vmbus_protocal_version == HV_VMBUS_VERSION_WS2008) ||
+ (hv_vmbus_protocal_version == HV_VMBUS_VERSION_WIN7)) {
+ maxdword = HV_MAX_NUM_CHANNELS_SUPPORTED >> 5;
+ /*
+ * receive size is 1/2 page and divide that by 4 bytes
+ */
+ recv_interrupt_page =
+ hv_vmbus_g_connection.recv_interrupt_page;
+ } else {
+ /*
+ * On Host with Win8 or above, the event page can be
+ * checked directly to get the id of the channel
+ * that has the pending interrupt.
+ */
+ maxdword = HV_EVENT_FLAGS_DWORD_COUNT;
+ page_addr = hv_vmbus_g_context.syn_ic_event_page[cpu];
+ event = (hv_vmbus_synic_event_flags *)
+ page_addr + HV_VMBUS_MESSAGE_SINT;
+ recv_interrupt_page = event->flags32;
+ }
/*
* Check events
@@ -416,16 +544,16 @@ int hv_vmbus_post_message(void *buffer, size_t bufferLen) {
* Send an event notification to the parent
*/
int
-hv_vmbus_set_event(uint32_t child_rel_id) {
+hv_vmbus_set_event(hv_vmbus_channel *channel) {
int ret = 0;
+ uint32_t child_rel_id = channel->offer_msg.child_rel_id;
/* Each uint32_t represents 32 channels */
synch_set_bit(child_rel_id & 31,
(((uint32_t *)hv_vmbus_g_connection.send_interrupt_page
+ (child_rel_id >> 5))));
- ret = hv_vmbus_signal_event();
+ ret = hv_vmbus_signal_event(channel->signal_event_param);
return (ret);
}
-
diff --git a/sys/dev/hyperv/vmbus/hv_hv.c b/sys/dev/hyperv/vmbus/hv_hv.c
index 80a1f42940c6..84e2a5e46fcf 100644
--- a/sys/dev/hyperv/vmbus/hv_hv.c
+++ b/sys/dev/hyperv/vmbus/hv_hv.c
@@ -67,8 +67,6 @@ static inline void do_cpuid_inline(unsigned int op, unsigned int *eax,
hv_vmbus_context hv_vmbus_g_context = {
.syn_ic_initialized = FALSE,
.hypercall_page = NULL,
- .signal_event_param = NULL,
- .signal_event_buffer = NULL,
};
static struct timecounter hv_timecounter = {
@@ -256,28 +254,6 @@ hv_vmbus_init(void)
hv_vmbus_g_context.hypercall_page = virt_addr;
- /*
- * Setup the global signal event param for the signal event hypercall
- */
- hv_vmbus_g_context.signal_event_buffer =
- malloc(sizeof(hv_vmbus_input_signal_event_buffer), M_DEVBUF,
- M_ZERO | M_NOWAIT);
- KASSERT(hv_vmbus_g_context.signal_event_buffer != NULL,
- ("Error VMBUS: Failed to allocate signal_event_buffer\n"));
- if (hv_vmbus_g_context.signal_event_buffer == NULL)
- goto cleanup;
-
- hv_vmbus_g_context.signal_event_param =
- (hv_vmbus_input_signal_event*)
- (HV_ALIGN_UP((unsigned long)
- hv_vmbus_g_context.signal_event_buffer,
- HV_HYPERCALL_PARAM_ALIGN));
- hv_vmbus_g_context.signal_event_param->connection_id.as_uint32_t = 0;
- hv_vmbus_g_context.signal_event_param->connection_id.u.id =
- HV_VMBUS_EVENT_CONNECTION_ID;
- hv_vmbus_g_context.signal_event_param->flag_number = 0;
- hv_vmbus_g_context.signal_event_param->rsvd_z = 0;
-
tc_init(&hv_timecounter); /* register virtual timecount */
return (0);
@@ -303,12 +279,6 @@ hv_vmbus_cleanup(void)
{
hv_vmbus_x64_msr_hypercall_contents hypercall_msr;
- if (hv_vmbus_g_context.signal_event_buffer != NULL) {
- free(hv_vmbus_g_context.signal_event_buffer, M_DEVBUF);
- hv_vmbus_g_context.signal_event_buffer = NULL;
- hv_vmbus_g_context.signal_event_param = NULL;
- }
-
if (hv_vmbus_g_context.guest_id == HV_FREEBSD_GUEST_ID) {
if (hv_vmbus_g_context.hypercall_page != NULL) {
hypercall_msr.as_uint64_t = 0;
@@ -370,13 +340,13 @@ hv_vmbus_post_msg_via_msg_ipc(
* event IPC. (This involves a hypercall.)
*/
hv_vmbus_status
-hv_vmbus_signal_event()
+hv_vmbus_signal_event(void *con_id)
{
hv_vmbus_status status;
status = hv_vmbus_do_hypercall(
HV_CALL_SIGNAL_EVENT,
- hv_vmbus_g_context.signal_event_param,
+ con_id,
0) & 0xFFFF;
return (status);
@@ -390,6 +360,7 @@ hv_vmbus_synic_init(void *arg)
{
int cpu;
+ uint64_t hv_vcpu_index;
hv_vmbus_synic_simp simp;
hv_vmbus_synic_siefp siefp;
hv_vmbus_synic_scontrol sctrl;
@@ -403,23 +374,14 @@ hv_vmbus_synic_init(void *arg)
return;
/*
- * KYS: Looks like we can only initialize on cpu0; don't we support
- * SMP guests?
- *
- * TODO: Need to add SMP support for FreeBSD V9
- */
-
- if (cpu != 0)
- return;
-
- /*
* TODO: Check the version
*/
version = rdmsr(HV_X64_MSR_SVERSION);
-
- hv_vmbus_g_context.syn_ic_msg_page[cpu] = setup_args->page_buffers[0];
- hv_vmbus_g_context.syn_ic_event_page[cpu] = setup_args->page_buffers[1];
+ hv_vmbus_g_context.syn_ic_msg_page[cpu] =
+ setup_args->page_buffers[2 * cpu];
+ hv_vmbus_g_context.syn_ic_event_page[cpu] =
+ setup_args->page_buffers[2 * cpu + 1];
/*
* Setup the Synic's message page
@@ -443,9 +405,10 @@ hv_vmbus_synic_init(void *arg)
wrmsr(HV_X64_MSR_SIEFP, siefp.as_uint64_t);
/*HV_SHARED_SINT_IDT_VECTOR + 0x20; */
+ shared_sint.as_uint64_t = 0;
shared_sint.u.vector = setup_args->vector;
shared_sint.u.masked = FALSE;
- shared_sint.u.auto_eoi = FALSE;
+ shared_sint.u.auto_eoi = TRUE;
wrmsr(HV_X64_MSR_SINT0 + HV_VMBUS_MESSAGE_SINT,
shared_sint.as_uint64_t);
@@ -458,6 +421,13 @@ hv_vmbus_synic_init(void *arg)
hv_vmbus_g_context.syn_ic_initialized = TRUE;
+ /*
+ * Set up the cpuid mapping from Hyper-V to FreeBSD.
+ * The array is indexed using FreeBSD cpuid.
+ */
+ hv_vcpu_index = rdmsr(HV_X64_MSR_VP_INDEX);
+ hv_vmbus_g_context.hv_vcpu_index[cpu] = (uint32_t)hv_vcpu_index;
+
return;
}
@@ -469,14 +439,10 @@ void hv_vmbus_synic_cleanup(void *arg)
hv_vmbus_synic_sint shared_sint;
hv_vmbus_synic_simp simp;
hv_vmbus_synic_siefp siefp;
- int cpu = PCPU_GET(cpuid);
if (!hv_vmbus_g_context.syn_ic_initialized)
return;
- if (cpu != 0)
- return; /* TODO: XXXKYS: SMP? */
-
shared_sint.as_uint64_t = rdmsr(
HV_X64_MSR_SINT0 + HV_VMBUS_MESSAGE_SINT);
diff --git a/sys/dev/hyperv/vmbus/hv_ring_buffer.c b/sys/dev/hyperv/vmbus/hv_ring_buffer.c
index f7c1965c8334..5e4f52a54ecb 100644
--- a/sys/dev/hyperv/vmbus/hv_ring_buffer.c
+++ b/sys/dev/hyperv/vmbus/hv_ring_buffer.c
@@ -144,6 +144,69 @@ get_ring_buffer_indices(hv_vmbus_ring_buffer_info* ring_info)
return (uint64_t) ring_info->ring_buffer->write_index << 32;
}
+void
+hv_ring_buffer_read_begin(
+ hv_vmbus_ring_buffer_info* ring_info)
+{
+ ring_info->ring_buffer->interrupt_mask = 1;
+ mb();
+}
+
+uint32_t
+hv_ring_buffer_read_end(
+ hv_vmbus_ring_buffer_info* ring_info)
+{
+ uint32_t read, write;
+
+ ring_info->ring_buffer->interrupt_mask = 0;
+ mb();
+
+ /*
+ * Now check to see if the ring buffer is still empty.
+ * If it is not, we raced and we need to process new
+ * incoming messages.
+ */
+ get_ring_buffer_avail_bytes(ring_info, &read, &write);
+
+ return (read);
+}
+
+/*
+ * When we write to the ring buffer, check if the host needs to
+ * be signaled. Here is the details of this protocol:
+ *
+ * 1. The host guarantees that while it is draining the
+ * ring buffer, it will set the interrupt_mask to
+ * indicate it does not need to be interrupted when
+ * new data is placed.
+ *
+ * 2. The host guarantees that it will completely drain
+ * the ring buffer before exiting the read loop. Further,
+ * once the ring buffer is empty, it will clear the
+ * interrupt_mask and re-check to see if new data has
+ * arrived.
+ */
+static boolean_t
+hv_ring_buffer_needsig_on_write(
+ uint32_t old_write_location,
+ hv_vmbus_ring_buffer_info* rbi)
+{
+ mb();
+ if (rbi->ring_buffer->interrupt_mask)
+ return (FALSE);
+
+ /* Read memory barrier */
+ rmb();
+ /*
+ * This is the only case we need to signal when the
+ * ring transitions from being empty to non-empty.
+ */
+ if (old_write_location == rbi->ring_buffer->read_index)
+ return (TRUE);
+
+ return (FALSE);
+}
+
static uint32_t copy_to_ring_buffer(
hv_vmbus_ring_buffer_info* ring_info,
uint32_t start_write_offset,
@@ -204,11 +267,13 @@ int
hv_ring_buffer_write(
hv_vmbus_ring_buffer_info* out_ring_info,
hv_vmbus_sg_buffer_list sg_buffers[],
- uint32_t sg_buffer_count)
+ uint32_t sg_buffer_count,
+ boolean_t *need_sig)
{
int i = 0;
uint32_t byte_avail_to_write;
uint32_t byte_avail_to_read;
+ uint32_t old_write_location;
uint32_t total_bytes_to_write = 0;
volatile uint32_t next_write_location;
@@ -242,6 +307,8 @@ hv_ring_buffer_write(
*/
next_write_location = get_next_write_location(out_ring_info);
+ old_write_location = next_write_location;
+
for (i = 0; i < sg_buffer_count; i++) {
next_write_location = copy_to_ring_buffer(out_ring_info,
next_write_location, (char *) sg_buffers[i].data,
@@ -258,9 +325,9 @@ hv_ring_buffer_write(
(char *) &prev_indices, sizeof(uint64_t));
/*
- * Make sure we flush all writes before updating the writeIndex
+ * Full memory barrier before upding the write index.
*/
- wmb();
+ mb();
/*
* Now, update the write location
@@ -269,6 +336,9 @@ hv_ring_buffer_write(
mtx_unlock_spin(&out_ring_info->ring_lock);
+ *need_sig = hv_ring_buffer_needsig_on_write(old_write_location,
+ out_ring_info);
+
return (0);
}
diff --git a/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c b/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
index ca28fd5892cd..f9432c8ee521 100644
--- a/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
+++ b/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
@@ -53,22 +53,17 @@ __FBSDID("$FreeBSD$");
#include <machine/stdarg.h>
#include <machine/intr_machdep.h>
+#include <machine/md_var.h>
+#include <machine/segments.h>
#include <sys/pcpu.h>
+#include <x86/apicvar.h>
#include "hv_vmbus_priv.h"
#define VMBUS_IRQ 0x5
-static struct intr_event *hv_msg_intr_event;
-static struct intr_event *hv_event_intr_event;
-static void *msg_swintr;
-static void *event_swintr;
static device_t vmbus_devp;
-static void *vmbus_cookiep;
-static int vmbus_rid;
-struct resource *intr_res;
-static int vmbus_irq = VMBUS_IRQ;
static int vmbus_inited;
static hv_setup_args setup_args; /* only CPU 0 supported at this time */
@@ -77,14 +72,17 @@ static hv_setup_args setup_args; /* only CPU 0 supported at this time */
* the hypervisor.
*/
static void
-vmbus_msg_swintr(void *dummy)
+vmbus_msg_swintr(void *arg)
{
int cpu;
void* page_addr;
hv_vmbus_message* msg;
hv_vmbus_message* copied;
- cpu = PCPU_GET(cpuid);
+ cpu = (int)(long)arg;
+ KASSERT(cpu <= mp_maxid, ("VMBUS: vmbus_msg_swintr: "
+ "cpu out of range!"));
+
page_addr = hv_vmbus_g_context.syn_ic_msg_page[cpu];
msg = (hv_vmbus_message*) page_addr + HV_VMBUS_MESSAGE_SINT;
@@ -130,17 +128,8 @@ vmbus_msg_swintr(void *dummy)
*
* The purpose of this routine is to determine the type of VMBUS protocol
* message to process - an event or a channel message.
- * As this is an interrupt filter routine, the function runs in a very
- * restricted envinronment. From the manpage for bus_setup_intr(9)
- *
- * In this restricted environment, care must be taken to account for all
- * races. A careful analysis of races should be done as well. It is gener-
- * ally cheaper to take an extra interrupt, for example, than to protect
- * variables with spinlocks. Read, modify, write cycles of hardware regis-
- * ters need to be carefully analyzed if other threads are accessing the
- * same registers.
*/
-static int
+static inline int
hv_vmbus_isr(void *unused)
{
int cpu;
@@ -149,8 +138,6 @@ hv_vmbus_isr(void *unused)
void* page_addr;
cpu = PCPU_GET(cpuid);
- /* (Temporary limit) */
- KASSERT(cpu == 0, ("hv_vmbus_isr: Interrupt on CPU other than zero"));
/*
* The Windows team has advised that we check for events
@@ -162,9 +149,21 @@ hv_vmbus_isr(void *unused)
event = (hv_vmbus_synic_event_flags*)
page_addr + HV_VMBUS_MESSAGE_SINT;
- /* Since we are a child, we only need to check bit 0 */
- if (synch_test_and_clear_bit(0, &event->flags32[0])) {
- swi_sched(event_swintr, 0);
+ if ((hv_vmbus_protocal_version == HV_VMBUS_VERSION_WS2008) ||
+ (hv_vmbus_protocal_version == HV_VMBUS_VERSION_WIN7)) {
+ /* Since we are a child, we only need to check bit 0 */
+ if (synch_test_and_clear_bit(0, &event->flags32[0])) {
+ swi_sched(hv_vmbus_g_context.event_swintr[cpu], 0);
+ }
+ } else {
+ /*
+ * On host with Win8 or above, we can directly look at
+ * the event page. If bit n is set, we have an interrupt
+ * on the channel with id n.
+ * Directly schedule the event software interrupt on
+ * current cpu.
+ */
+ swi_sched(hv_vmbus_g_context.event_swintr[cpu], 0);
}
/* Check if there are actual msgs to be process */
@@ -172,12 +171,47 @@ hv_vmbus_isr(void *unused)
msg = (hv_vmbus_message*) page_addr + HV_VMBUS_MESSAGE_SINT;
if (msg->header.message_type != HV_MESSAGE_TYPE_NONE) {
- swi_sched(msg_swintr, 0);
+ swi_sched(hv_vmbus_g_context.msg_swintr[cpu], 0);
}
return FILTER_HANDLED;
}
+#ifdef HV_DEBUG_INTR
+uint32_t hv_intr_count = 0;
+#endif
+uint32_t hv_vmbus_swintr_event_cpu[MAXCPU];
+uint32_t hv_vmbus_intr_cpu[MAXCPU];
+
+void
+hv_vector_handler(struct trapframe *trap_frame)
+{
+#ifdef HV_DEBUG_INTR
+ int cpu;
+#endif
+
+ /*
+ * Disable preemption.
+ */
+ critical_enter();
+
+#ifdef HV_DEBUG_INTR
+ /*
+ * Do a little interrupt counting.
+ */
+ cpu = PCPU_GET(cpuid);
+ hv_vmbus_intr_cpu[cpu]++;
+ hv_intr_count++;
+#endif
+
+ hv_vmbus_isr(NULL);
+
+ /*
+ * Enable preemption.
+ */
+ critical_exit();
+}
+
static int
vmbus_read_ivar(
device_t dev,
@@ -316,6 +350,81 @@ vmbus_probe(device_t dev) {
return (BUS_PROBE_NOWILDCARD);
}
+#ifdef HYPERV
+extern inthand_t IDTVEC(rsvd), IDTVEC(hv_vmbus_callback);
+
+/**
+ * @brief Find a free IDT slot and setup the interrupt handler.
+ */
+static int
+vmbus_vector_alloc(void)
+{
+ int vector;
+ uintptr_t func;
+ struct gate_descriptor *ip;
+
+ /*
+ * Search backwards form the highest IDT vector available for use
+ * as vmbus channel callback vector. We install 'hv_vmbus_callback'
+ * handler at that vector and use it to interrupt vcpus.
+ */
+ vector = APIC_SPURIOUS_INT;
+ while (--vector >= APIC_IPI_INTS) {
+ ip = &idt[vector];
+ func = ((long)ip->gd_hioffset << 16 | ip->gd_looffset);
+ if (func == (uintptr_t)&IDTVEC(rsvd)) {
+#ifdef __i386__
+ setidt(vector , IDTVEC(hv_vmbus_callback), SDT_SYS386IGT,
+ SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
+#else
+ setidt(vector , IDTVEC(hv_vmbus_callback), SDT_SYSIGT,
+ SEL_KPL, 0);
+#endif
+
+ return (vector);
+ }
+ }
+ return (0);
+}
+
+/**
+ * @brief Restore the IDT slot to rsvd.
+ */
+static void
+vmbus_vector_free(int vector)
+{
+ uintptr_t func;
+ struct gate_descriptor *ip;
+
+ if (vector == 0)
+ return;
+
+ KASSERT(vector >= APIC_IPI_INTS && vector < APIC_SPURIOUS_INT,
+ ("invalid vector %d", vector));
+
+ ip = &idt[vector];
+ func = ((long)ip->gd_hioffset << 16 | ip->gd_looffset);
+ KASSERT(func == (uintptr_t)&IDTVEC(hv_vmbus_callback),
+ ("invalid vector %d", vector));
+
+ setidt(vector, IDTVEC(rsvd), SDT_SYSIGT, SEL_KPL, 0);
+}
+
+#else /* HYPERV */
+
+static int
+vmbus_vector_alloc(void)
+{
+ return(0);
+}
+
+static void
+vmbus_vector_free(int vector)
+{
+}
+
+#endif /* HYPERV */
+
/**
* @brief Main vmbus driver initialization routine.
*
@@ -331,22 +440,7 @@ vmbus_probe(device_t dev) {
static int
vmbus_bus_init(void)
{
- struct ioapic_intsrc {
- struct intsrc io_intsrc;
- u_int io_irq;
- u_int io_intpin:8;
- u_int io_vector:8;
- u_int io_cpu:8;
- u_int io_activehi:1;
- u_int io_edgetrigger:1;
- u_int io_masked:1;
- int io_bus:4;
- uint32_t io_lowreg;
- };
- int i, ret;
- unsigned int vector = 0;
- struct intsrc *isrc;
- struct ioapic_intsrc *intpin;
+ int i, j, n, ret;
if (vmbus_inited)
return (0);
@@ -361,80 +455,100 @@ vmbus_bus_init(void)
return (ret);
}
- ret = swi_add(&hv_msg_intr_event, "hv_msg", vmbus_msg_swintr,
- NULL, SWI_CLOCK, 0, &msg_swintr);
-
- if (ret)
- goto cleanup;
-
/*
- * Message SW interrupt handler checks a per-CPU page and
- * thus the thread needs to be bound to CPU-0 - which is where
- * all interrupts are processed.
+ * Find a free IDT slot for vmbus callback.
*/
- ret = intr_event_bind(hv_msg_intr_event, 0);
-
- if (ret)
- goto cleanup1;
+ hv_vmbus_g_context.hv_cb_vector = vmbus_vector_alloc();
- ret = swi_add(&hv_event_intr_event, "hv_event", hv_vmbus_on_events,
- NULL, SWI_CLOCK, 0, &event_swintr);
-
- if (ret)
- goto cleanup1;
+ if (hv_vmbus_g_context.hv_cb_vector == 0) {
+ if(bootverbose)
+ printf("Error VMBUS: Cannot find free IDT slot for "
+ "vmbus callback!\n");
+ goto cleanup;
+ }
- intr_res = bus_alloc_resource(vmbus_devp,
- SYS_RES_IRQ, &vmbus_rid, vmbus_irq, vmbus_irq, 1, RF_ACTIVE);
+ if(bootverbose)
+ printf("VMBUS: vmbus callback vector %d\n",
+ hv_vmbus_g_context.hv_cb_vector);
- if (intr_res == NULL) {
- ret = ENOMEM; /* XXXKYS: Need a better errno */
- goto cleanup2;
+ /*
+ * Notify the hypervisor of our vector.
+ */
+ setup_args.vector = hv_vmbus_g_context.hv_cb_vector;
+
+ CPU_FOREACH(j) {
+ hv_vmbus_intr_cpu[j] = 0;
+ hv_vmbus_swintr_event_cpu[j] = 0;
+ hv_vmbus_g_context.hv_event_intr_event[j] = NULL;
+ hv_vmbus_g_context.hv_msg_intr_event[j] = NULL;
+ hv_vmbus_g_context.event_swintr[j] = NULL;
+ hv_vmbus_g_context.msg_swintr[j] = NULL;
+
+ for (i = 0; i < 2; i++)
+ setup_args.page_buffers[2 * j + i] = NULL;
}
/*
- * Setup interrupt filter handler
+ * Per cpu setup.
*/
- ret = bus_setup_intr(vmbus_devp, intr_res,
- INTR_TYPE_NET | INTR_MPSAFE, hv_vmbus_isr, NULL,
- NULL, &vmbus_cookiep);
-
- if (ret != 0)
- goto cleanup3;
-
- ret = bus_bind_intr(vmbus_devp, intr_res, 0);
- if (ret != 0)
- goto cleanup4;
-
- isrc = intr_lookup_source(vmbus_irq);
- if ((isrc == NULL) || (isrc->is_event == NULL)) {
- ret = EINVAL;
- goto cleanup4;
- }
+ CPU_FOREACH(j) {
+ /*
+ * Setup software interrupt thread and handler for msg handling.
+ */
+ ret = swi_add(&hv_vmbus_g_context.hv_msg_intr_event[j],
+ "hv_msg", vmbus_msg_swintr, (void *)(long)j, SWI_CLOCK, 0,
+ &hv_vmbus_g_context.msg_swintr[j]);
+ if (ret) {
+ if(bootverbose)
+ printf("VMBUS: failed to setup msg swi for "
+ "cpu %d\n", j);
+ goto cleanup1;
+ }
- /* vector = isrc->is_event->ie_vector; */
- intpin = (struct ioapic_intsrc *)isrc;
- vector = intpin->io_vector;
+ /*
+ * Bind the swi thread to the cpu.
+ */
+ ret = intr_event_bind(hv_vmbus_g_context.hv_msg_intr_event[j],
+ j);
+ if (ret) {
+ if(bootverbose)
+ printf("VMBUS: failed to bind msg swi thread "
+ "to cpu %d\n", j);
+ goto cleanup1;
+ }
- if(bootverbose)
- printf("VMBUS: irq 0x%x vector 0x%x\n", vmbus_irq, vector);
+ /*
+ * Setup software interrupt thread and handler for
+ * event handling.
+ */
+ ret = swi_add(&hv_vmbus_g_context.hv_event_intr_event[j],
+ "hv_event", hv_vmbus_on_events, (void *)(long)j,
+ SWI_CLOCK, 0, &hv_vmbus_g_context.event_swintr[j]);
+ if (ret) {
+ if(bootverbose)
+ printf("VMBUS: failed to setup event swi for "
+ "cpu %d\n", j);
+ goto cleanup1;
+ }
- /**
- * Notify the hypervisor of our irq.
- */
- setup_args.vector = vector;
- for(i = 0; i < 2; i++) {
- setup_args.page_buffers[i] =
+ /*
+ * Prepare the per cpu msg and event pages to be called on each cpu.
+ */
+ for(i = 0; i < 2; i++) {
+ setup_args.page_buffers[2 * j + i] =
malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT | M_ZERO);
- if (setup_args.page_buffers[i] == NULL) {
- KASSERT(setup_args.page_buffers[i] != NULL,
+ if (setup_args.page_buffers[2 * j + i] == NULL) {
+ KASSERT(setup_args.page_buffers[2 * j + i] != NULL,
("Error VMBUS: malloc failed!"));
- if (i > 0)
- free(setup_args.page_buffers[0], M_DEVBUF);
- goto cleanup4;
+ goto cleanup1;
+ }
}
}
- /* only CPU #0 supported at this time */
+ if (bootverbose)
+ printf("VMBUS: Calling smp_rendezvous, smp_started = %d\n",
+ smp_started);
+
smp_rendezvous(NULL, hv_vmbus_synic_init, NULL, &setup_args);
/*
@@ -443,26 +557,32 @@ vmbus_bus_init(void)
ret = hv_vmbus_connect();
if (ret != 0)
- goto cleanup4;
+ goto cleanup1;
hv_vmbus_request_channel_offers();
return (ret);
- cleanup4:
-
+ cleanup1:
/*
- * remove swi, bus and intr resource
+ * Free pages alloc'ed
*/
- bus_teardown_intr(vmbus_devp, intr_res, vmbus_cookiep);
+ for (n = 0; n < 2 * MAXCPU; n++)
+ if (setup_args.page_buffers[n] != NULL)
+ free(setup_args.page_buffers[n], M_DEVBUF);
- cleanup3:
- bus_release_resource(vmbus_devp, SYS_RES_IRQ, vmbus_rid, intr_res);
-
- cleanup2:
- swi_remove(event_swintr);
+ /*
+ * remove swi and vmbus callback vector;
+ */
+ CPU_FOREACH(j) {
+ if (hv_vmbus_g_context.msg_swintr[j] != NULL)
+ swi_remove(hv_vmbus_g_context.msg_swintr[j]);
+ if (hv_vmbus_g_context.event_swintr[j] != NULL)
+ swi_remove(hv_vmbus_g_context.event_swintr[j]);
+ hv_vmbus_g_context.hv_msg_intr_event[j] = NULL;
+ hv_vmbus_g_context.hv_event_intr_event[j] = NULL;
+ }
- cleanup1:
- swi_remove(msg_swintr);
+ vmbus_vector_free(hv_vmbus_g_context.hv_cb_vector);
cleanup:
hv_vmbus_cleanup();
@@ -515,20 +635,24 @@ vmbus_bus_exit(void)
smp_rendezvous(NULL, hv_vmbus_synic_cleanup, NULL, NULL);
- for(i = 0; i < 2; i++) {
+ for(i = 0; i < 2 * MAXCPU; i++) {
if (setup_args.page_buffers[i] != 0)
free(setup_args.page_buffers[i], M_DEVBUF);
}
hv_vmbus_cleanup();
- /* remove swi, bus and intr resource */
- bus_teardown_intr(vmbus_devp, intr_res, vmbus_cookiep);
-
- bus_release_resource(vmbus_devp, SYS_RES_IRQ, vmbus_rid, intr_res);
+ /* remove swi */
+ CPU_FOREACH(i) {
+ if (hv_vmbus_g_context.msg_swintr[i] != NULL)
+ swi_remove(hv_vmbus_g_context.msg_swintr[i]);
+ if (hv_vmbus_g_context.event_swintr[i] != NULL)
+ swi_remove(hv_vmbus_g_context.event_swintr[i]);
+ hv_vmbus_g_context.hv_msg_intr_event[i] = NULL;
+ hv_vmbus_g_context.hv_event_intr_event[i] = NULL;
+ }
- swi_remove(msg_swintr);
- swi_remove(event_swintr);
+ vmbus_vector_free(hv_vmbus_g_context.hv_cb_vector);
return;
}
@@ -603,6 +727,6 @@ devclass_t vmbus_devclass;
DRIVER_MODULE(vmbus, nexus, vmbus_driver, vmbus_devclass, vmbus_modevent, 0);
MODULE_VERSION(vmbus,1);
-/* TODO: We want to be earlier than SI_SUB_VFS */
-SYSINIT(vmb_init, SI_SUB_VFS, SI_ORDER_MIDDLE, vmbus_init, NULL);
+/* We want to be started after SMP is initialized */
+SYSINIT(vmb_init, SI_SUB_SMP + 1, SI_ORDER_FIRST, vmbus_init, NULL);
diff --git a/sys/dev/hyperv/vmbus/hv_vmbus_priv.h b/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
index 6bc875df1e1c..faa6decd9ac2 100644
--- a/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
+++ b/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
@@ -181,49 +181,30 @@ enum {
#define HV_HYPERCALL_PARAM_ALIGN sizeof(uint64_t)
-/*
- * Connection identifier type
- */
-typedef union {
- uint32_t as_uint32_t;
- struct {
- uint32_t id:24;
- uint32_t reserved:8;
- } u;
-
-} __packed hv_vmbus_connection_id;
-
-/*
- * Definition of the hv_vmbus_signal_event hypercall input structure
- */
-typedef struct {
- hv_vmbus_connection_id connection_id;
- uint16_t flag_number;
- uint16_t rsvd_z;
-} __packed hv_vmbus_input_signal_event;
-
-typedef struct {
- uint64_t align8;
- hv_vmbus_input_signal_event event;
-} __packed hv_vmbus_input_signal_event_buffer;
-
typedef struct {
uint64_t guest_id;
void* hypercall_page;
hv_bool_uint8_t syn_ic_initialized;
+
+ hv_vmbus_handle syn_ic_msg_page[MAXCPU];
+ hv_vmbus_handle syn_ic_event_page[MAXCPU];
/*
- * This is used as an input param to HV_CALL_SIGNAL_EVENT hypercall.
- * The input param is immutable in our usage and
- * must be dynamic mem (vs stack or global).
+ * For FreeBSD cpuid to Hyper-V vcpuid mapping.
*/
- hv_vmbus_input_signal_event_buffer *signal_event_buffer;
+ uint32_t hv_vcpu_index[MAXCPU];
/*
- * 8-bytes aligned of the buffer above
+ * Each cpu has its own software interrupt handler for channel
+ * event and msg handling.
*/
- hv_vmbus_input_signal_event *signal_event_param;
-
- hv_vmbus_handle syn_ic_msg_page[MAXCPU];
- hv_vmbus_handle syn_ic_event_page[MAXCPU];
+ struct intr_event *hv_event_intr_event[MAXCPU];
+ struct intr_event *hv_msg_intr_event[MAXCPU];
+ void *event_swintr[MAXCPU];
+ void *msg_swintr[MAXCPU];
+ /*
+ * Host use this vector to intrrupt guest for vmbus channel
+ * event and msg.
+ */
+ unsigned int hv_cb_vector;
} hv_vmbus_context;
/*
@@ -368,7 +349,8 @@ typedef struct {
TAILQ_HEAD(, hv_vmbus_channel_msg_info) channel_msg_anchor;
struct mtx channel_msg_lock;
/**
- * List of channels
+ * List of primary channels. Sub channels will be linked
+ * under their primary channel.
*/
TAILQ_HEAD(, hv_vmbus_channel) channel_anchor;
struct mtx channel_lock;
@@ -560,6 +542,8 @@ typedef union {
uint32_t flags32[HV_EVENT_FLAGS_DWORD_COUNT];
} hv_vmbus_synic_event_flags;
+/* MSR used to provide vcpu index */
+#define HV_X64_MSR_VP_INDEX (0x40000002)
/*
* Define synthetic interrupt controller model specific registers
@@ -618,7 +602,8 @@ void hv_ring_buffer_cleanup(
int hv_ring_buffer_write(
hv_vmbus_ring_buffer_info *ring_info,
hv_vmbus_sg_buffer_list sg_buffers[],
- uint32_t sg_buff_count);
+ uint32_t sg_buff_count,
+ boolean_t *need_sig);
int hv_ring_buffer_peek(
hv_vmbus_ring_buffer_info *ring_info,
@@ -638,6 +623,12 @@ void hv_vmbus_dump_ring_info(
hv_vmbus_ring_buffer_info *ring_info,
char *prefix);
+void hv_ring_buffer_read_begin(
+ hv_vmbus_ring_buffer_info *ring_info);
+
+uint32_t hv_ring_buffer_read_end(
+ hv_vmbus_ring_buffer_info *ring_info);
+
hv_vmbus_channel* hv_vmbus_allocate_channel(void);
void hv_vmbus_free_vmbus_channel(hv_vmbus_channel *channel);
void hv_vmbus_on_channel_message(void *context);
@@ -652,7 +643,7 @@ uint16_t hv_vmbus_post_msg_via_msg_ipc(
void *payload,
size_t payload_size);
-uint16_t hv_vmbus_signal_event(void);
+uint16_t hv_vmbus_signal_event(void *con_id);
void hv_vmbus_synic_init(void *irq_arg);
void hv_vmbus_synic_cleanup(void *arg);
int hv_vmbus_query_hypervisor_presence(void);
@@ -674,7 +665,7 @@ hv_vmbus_channel* hv_vmbus_get_channel_from_rel_id(uint32_t rel_id);
int hv_vmbus_connect(void);
int hv_vmbus_disconnect(void);
int hv_vmbus_post_message(void *buffer, size_t buf_size);
-int hv_vmbus_set_event(uint32_t child_rel_id);
+int hv_vmbus_set_event(hv_vmbus_channel *channel);
void hv_vmbus_on_events(void *);
@@ -718,7 +709,7 @@ static inline uint64_t hv_generate_guest_id(
typedef struct {
unsigned int vector;
- void *page_buffers[2];
+ void *page_buffers[2 * MAXCPU];
} hv_setup_args;
#endif /* __HYPERV_PRIV_H__ */
diff --git a/sys/dev/ichsmb/ichsmb_pci.c b/sys/dev/ichsmb/ichsmb_pci.c
index 5c1ef544b010..ae8b17904a81 100644
--- a/sys/dev/ichsmb/ichsmb_pci.c
+++ b/sys/dev/ichsmb/ichsmb_pci.c
@@ -88,6 +88,7 @@ __FBSDID("$FreeBSD$");
#define ID_AVOTON 0x1f3c8086
#define ID_COLETOCRK 0x23B08086
#define ID_LPT 0x8c228086
+#define ID_LPTLP 0x9c228086
#define ID_WCPT 0x8ca28086
#define ID_WCPTLP 0x9ca28086
@@ -199,6 +200,9 @@ ichsmb_pci_probe(device_t dev)
case ID_LPT:
device_set_desc(dev, "Intel Lynx Point SMBus controller");
break;
+ case ID_LPTLP:
+ device_set_desc(dev, "Intel Lynx Point-LP SMBus controller");
+ break;
case ID_WCPT:
device_set_desc(dev, "Intel Wildcat Point SMBus controller");
break;
diff --git a/sys/dev/iicbus/pcf8563.c b/sys/dev/iicbus/pcf8563.c
index 88307a5728a2..556943a34fed 100644
--- a/sys/dev/iicbus/pcf8563.c
+++ b/sys/dev/iicbus/pcf8563.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2012 Marius Strobl <marius@FreeBSD.org>
+ * Copyright (c) 2015 Juraj Lutter
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,6 +32,8 @@ __FBSDID("$FreeBSD$");
* Driver for NXP PCF8563 real-time clock/calendar
*/
+#include "opt_platform.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
@@ -41,6 +44,11 @@ __FBSDID("$FreeBSD$");
#include <dev/iicbus/iicbus.h>
#include <dev/iicbus/iiconf.h>
#include <dev/iicbus/pcf8563reg.h>
+#ifdef FDT
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#endif
#include "clock_if.h"
#include "iicbus_if.h"
@@ -48,6 +56,7 @@ __FBSDID("$FreeBSD$");
#define PCF8563_NCLOCKREGS (PCF8563_R_YEAR - PCF8563_R_CS1 + 1)
struct pcf8563_softc {
+ struct intr_config_hook enum_hook;
uint32_t sc_flags;
#define PCF8563_CPOL (1 << 0) /* PCF8563_R_MONTH_C means 19xx */
uint16_t sc_addr; /* PCF8563 slave address */
@@ -58,30 +67,62 @@ static device_attach_t pcf8563_attach;
static device_probe_t pcf8563_probe;
static clock_gettime_t pcf8563_gettime;
static clock_settime_t pcf8563_settime;
+static void pcf8563_start(void *);
static int
pcf8563_probe(device_t dev)
{
+#ifdef FDT
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
+ if (!ofw_bus_is_compatible(dev, "nxp,pcf8563") &&
+ !ofw_bus_is_compatible(dev, "philips,pcf8563") &&
+ !ofw_bus_is_compatible(dev, "pcf8563"))
+ return (ENXIO);
+#endif
device_set_desc(dev, "NXP PCF8563 RTC");
- return (BUS_PROBE_NOWILDCARD);
+
+ return (BUS_PROBE_DEFAULT);
}
static int
pcf8563_attach(device_t dev)
{
+ struct pcf8563_softc *sc;
+
+ sc = device_get_softc(dev);
+ sc->sc_addr = iicbus_get_addr(dev);
+ if (sc->sc_addr == 0)
+ sc->sc_addr = PCF8563_ADDR;
+ sc->sc_year0 = 1900;
+ sc->enum_hook.ich_func = pcf8563_start;
+ sc->enum_hook.ich_arg = dev;
+
+ /*
+ * We have to wait until interrupts are enabled. Sometimes I2C read
+ * and write only works when the interrupts are available.
+ */
+ if (config_intrhook_establish(&sc->enum_hook) != 0)
+ return (ENOMEM);
+
+ return (0);
+}
+
+static void
+pcf8563_start(void *xdev)
+{
+ device_t dev;
uint8_t reg = PCF8563_R_SECOND, val;
struct iic_msg msgs[] = {
{ 0, IIC_M_WR, sizeof(reg), &reg },
{ 0, IIC_M_RD, sizeof(val), &val }
};
struct pcf8563_softc *sc;
- int error;
+ dev = (device_t)xdev;
sc = device_get_softc(dev);
- sc->sc_addr = iicbus_get_addr(dev);
- if (sc->sc_addr == 0)
- sc->sc_addr = PCF8563_ADDR;
+ config_intrhook_disestablish(&sc->enum_hook);
/*
* NB: PCF8563_R_SECOND_VL doesn't automatically clear when VDD
@@ -94,18 +135,14 @@ pcf8563_attach(device_t dev)
* as a side-effect.
*/
msgs[0].slave = msgs[1].slave = sc->sc_addr;
- error = iicbus_transfer(device_get_parent(dev), msgs, sizeof(msgs) /
- sizeof(*msgs));
- if (error != 0) {
+ if (iicbus_transfer(dev, msgs, nitems(msgs)) != 0) {
device_printf(dev, "%s: cannot read RTC\n", __func__);
- return (error);
+ return;
}
if ((val & PCF8563_R_SECOND_VL) != 0)
device_printf(dev, "%s: battery low\n", __func__);
- sc->sc_year0 = 1900;
clock_register(dev, 1000000); /* 1 second resolution */
- return (0);
}
static int
@@ -122,8 +159,7 @@ pcf8563_gettime(device_t dev, struct timespec *ts)
sc = device_get_softc(dev);
msgs[0].slave = msgs[1].slave = sc->sc_addr;
- error = iicbus_transfer(device_get_parent(dev), msgs, sizeof(msgs) /
- sizeof(*msgs));
+ error = iicbus_transfer(dev, msgs, nitems(msgs));
if (error != 0) {
device_printf(dev, "%s: cannot read RTC\n", __func__);
return (error);
@@ -145,6 +181,7 @@ pcf8563_gettime(device_t dev, struct timespec *ts)
sc->sc_flags |= PCF8563_CPOL;
} else if (ct.year < 100 + sc->sc_year0)
sc->sc_flags |= PCF8563_CPOL;
+
return (clock_ct_to_ts(&ct, ts));
}
@@ -180,10 +217,10 @@ pcf8563_settime(device_t dev, struct timespec *ts)
val[PCF8563_R_MONTH] |= PCF8563_R_MONTH_C;
msgs[0].slave = sc->sc_addr;
- error = iicbus_transfer(device_get_parent(dev), msgs, sizeof(msgs) /
- sizeof(*msgs));
+ error = iicbus_transfer(dev, msgs, nitems(msgs));
if (error != 0)
device_printf(dev, "%s: cannot write RTC\n", __func__);
+
return (error);
}
diff --git a/sys/dev/ipmi/ipmi.c b/sys/dev/ipmi/ipmi.c
index a1edbf64524b..810171751f5c 100644
--- a/sys/dev/ipmi/ipmi.c
+++ b/sys/dev/ipmi/ipmi.c
@@ -756,17 +756,22 @@ ipmi_startup(void *arg)
}
device_printf(dev, "Number of channels %d\n", i);
- /* probe for watchdog */
- IPMI_INIT_DRIVER_REQUEST(req, IPMI_ADDR(IPMI_APP_REQUEST, 0),
- IPMI_GET_WDOG, 0, 0);
+ /*
+ * Probe for watchdog, but only for backends which support
+ * polled driver requests.
+ */
+ if (sc->ipmi_driver_requests_polled) {
+ IPMI_INIT_DRIVER_REQUEST(req, IPMI_ADDR(IPMI_APP_REQUEST, 0),
+ IPMI_GET_WDOG, 0, 0);
- ipmi_submit_driver_request(sc, req, 0);
+ ipmi_submit_driver_request(sc, req, 0);
- if (req->ir_compcode == 0x00) {
- device_printf(dev, "Attached watchdog\n");
- /* register the watchdog event handler */
- sc->ipmi_watchdog_tag = EVENTHANDLER_REGISTER(watchdog_list,
- ipmi_wd_event, sc, 0);
+ if (req->ir_compcode == 0x00) {
+ device_printf(dev, "Attached watchdog\n");
+ /* register the watchdog event handler */
+ sc->ipmi_watchdog_tag = EVENTHANDLER_REGISTER(
+ watchdog_list, ipmi_wd_event, sc, 0);
+ }
}
sc->ipmi_cdev = make_dev(&ipmi_cdevsw, device_get_unit(dev),
diff --git a/sys/dev/ipmi/ipmi_kcs.c b/sys/dev/ipmi/ipmi_kcs.c
index 1c586467667b..864e9a0a0bcb 100644
--- a/sys/dev/ipmi/ipmi_kcs.c
+++ b/sys/dev/ipmi/ipmi_kcs.c
@@ -520,6 +520,7 @@ ipmi_kcs_attach(struct ipmi_softc *sc)
sc->ipmi_startup = kcs_startup;
sc->ipmi_enqueue_request = ipmi_polled_enqueue_request;
sc->ipmi_driver_request = kcs_driver_request;
+ sc->ipmi_driver_requests_polled = 1;
/* See if we can talk to the controller. */
status = INB(sc, KCS_CTL_STS);
diff --git a/sys/dev/ipmi/ipmi_smic.c b/sys/dev/ipmi/ipmi_smic.c
index 4e26553e98e7..92cf14e9e615 100644
--- a/sys/dev/ipmi/ipmi_smic.c
+++ b/sys/dev/ipmi/ipmi_smic.c
@@ -415,6 +415,7 @@ ipmi_smic_attach(struct ipmi_softc *sc)
sc->ipmi_startup = smic_startup;
sc->ipmi_enqueue_request = ipmi_polled_enqueue_request;
sc->ipmi_driver_request = smic_driver_request;
+ sc->ipmi_driver_requests_polled = 1;
/* See if we can talk to the controller. */
flags = INB(sc, SMIC_FLAGS);
diff --git a/sys/dev/ipmi/ipmivars.h b/sys/dev/ipmi/ipmivars.h
index 9d7dc3220893..9a0b43514ea6 100644
--- a/sys/dev/ipmi/ipmivars.h
+++ b/sys/dev/ipmi/ipmivars.h
@@ -105,6 +105,7 @@ struct ipmi_softc {
int ipmi_opened;
struct cdev *ipmi_cdev;
TAILQ_HEAD(,ipmi_request) ipmi_pending_requests;
+ int ipmi_driver_requests_polled;
eventhandler_tag ipmi_watchdog_tag;
int ipmi_watchdog_active;
struct intr_config_hook ipmi_ich;
diff --git a/sys/dev/ixgbe/if_ix.c b/sys/dev/ixgbe/if_ix.c
index 48ff9d1c4f81..b9bba31a5908 100644
--- a/sys/dev/ixgbe/if_ix.c
+++ b/sys/dev/ixgbe/if_ix.c
@@ -54,7 +54,7 @@ int ixgbe_display_debug_stats = 0;
/*********************************************************************
* Driver version
*********************************************************************/
-char ixgbe_driver_version[] = "2.7.4";
+char ixgbe_driver_version[] = "2.8.3";
/*********************************************************************
* PCI Device ID Table
@@ -117,6 +117,8 @@ static int ixgbe_probe(device_t);
static int ixgbe_attach(device_t);
static int ixgbe_detach(device_t);
static int ixgbe_shutdown(device_t);
+static int ixgbe_suspend(device_t);
+static int ixgbe_resume(device_t);
static int ixgbe_ioctl(struct ifnet *, u_long, caddr_t);
static void ixgbe_init(void *);
static void ixgbe_init_locked(struct adapter *);
@@ -136,7 +138,12 @@ static int ixgbe_setup_msix(struct adapter *);
static void ixgbe_free_pci_resources(struct adapter *);
static void ixgbe_local_timer(void *);
static int ixgbe_setup_interface(device_t, struct adapter *);
+static void ixgbe_config_dmac(struct adapter *);
+static void ixgbe_config_delay_values(struct adapter *);
static void ixgbe_config_link(struct adapter *);
+static void ixgbe_check_eee_support(struct adapter *);
+static void ixgbe_check_wol_support(struct adapter *);
+static int ixgbe_setup_low_power_mode(struct adapter *);
static void ixgbe_rearm_queues(struct adapter *, u64);
static void ixgbe_initialize_transmit_units(struct adapter *);
@@ -150,9 +157,6 @@ static void ixgbe_update_stats_counters(struct adapter *);
static void ixgbe_set_promisc(struct adapter *);
static void ixgbe_set_multi(struct adapter *);
static void ixgbe_update_link_status(struct adapter *);
-static int ixgbe_set_flowcntl(SYSCTL_HANDLER_ARGS);
-static int ixgbe_set_advertise(SYSCTL_HANDLER_ARGS);
-static int ixgbe_set_thermal_test(SYSCTL_HANDLER_ARGS);
static void ixgbe_set_ivar(struct adapter *, u8, u8, s8);
static void ixgbe_configure_ivars(struct adapter *);
static u8 * ixgbe_mc_array_itr(struct ixgbe_hw *, u8 **, u32 *);
@@ -161,7 +165,22 @@ static void ixgbe_setup_vlan_hw_support(struct adapter *);
static void ixgbe_register_vlan(void *, struct ifnet *, u16);
static void ixgbe_unregister_vlan(void *, struct ifnet *, u16);
-static void ixgbe_add_hw_stats(struct adapter *adapter);
+static void ixgbe_add_device_sysctls(struct adapter *);
+static void ixgbe_add_hw_stats(struct adapter *);
+
+/* Sysctl handlers */
+static int ixgbe_set_flowcntl(SYSCTL_HANDLER_ARGS);
+static int ixgbe_set_advertise(SYSCTL_HANDLER_ARGS);
+static int ixgbe_sysctl_thermal_test(SYSCTL_HANDLER_ARGS);
+static int ixgbe_sysctl_dmac(SYSCTL_HANDLER_ARGS);
+static int ixgbe_sysctl_phy_temp(SYSCTL_HANDLER_ARGS);
+static int ixgbe_sysctl_phy_overtemp_occurred(SYSCTL_HANDLER_ARGS);
+static int ixgbe_sysctl_wol_enable(SYSCTL_HANDLER_ARGS);
+static int ixgbe_sysctl_wufc(SYSCTL_HANDLER_ARGS);
+static int ixgbe_sysctl_eee_enable(SYSCTL_HANDLER_ARGS);
+static int ixgbe_sysctl_eee_negotiated(SYSCTL_HANDLER_ARGS);
+static int ixgbe_sysctl_eee_rx_lpi_status(SYSCTL_HANDLER_ARGS);
+static int ixgbe_sysctl_eee_tx_lpi_status(SYSCTL_HANDLER_ARGS);
/* Support for pluggable optic modules */
static bool ixgbe_sfp_probe(struct adapter *);
@@ -179,15 +198,12 @@ static void ixgbe_handle_que(void *, int);
static void ixgbe_handle_link(void *, int);
static void ixgbe_handle_msf(void *, int);
static void ixgbe_handle_mod(void *, int);
+static void ixgbe_handle_phy(void *, int);
#ifdef IXGBE_FDIR
static void ixgbe_reinit_fdir(void *, int);
#endif
-
-/* Missing shared code prototype */
-extern void ixgbe_stop_mac_link_on_d3_82599(struct ixgbe_hw *hw);
-
/*********************************************************************
* FreeBSD Device Interface Entry Points
*********************************************************************/
@@ -198,6 +214,8 @@ static device_method_t ix_methods[] = {
DEVMETHOD(device_attach, ixgbe_attach),
DEVMETHOD(device_detach, ixgbe_detach),
DEVMETHOD(device_shutdown, ixgbe_shutdown),
+ DEVMETHOD(device_suspend, ixgbe_suspend),
+ DEVMETHOD(device_resume, ixgbe_resume),
DEVMETHOD_END
};
@@ -404,32 +422,6 @@ ixgbe_attach(device_t dev)
/* Core Lock Init*/
IXGBE_CORE_LOCK_INIT(adapter, device_get_nameunit(dev));
- /* SYSCTL APIs */
- SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
- SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
- OID_AUTO, "fc", CTLTYPE_INT | CTLFLAG_RW,
- adapter, 0, ixgbe_set_flowcntl, "I", IXGBE_SYSCTL_DESC_SET_FC);
-
- SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
- SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
- OID_AUTO, "enable_aim", CTLFLAG_RW,
- &ixgbe_enable_aim, 1, "Interrupt Moderation");
-
- /*
- ** Allow a kind of speed control by forcing the autoneg
- ** advertised speed list to only a certain value, this
- ** supports 1G on 82599 devices, and 100Mb on x540.
- */
- SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
- SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
- OID_AUTO, "advertise_speed", CTLTYPE_INT | CTLFLAG_RW,
- adapter, 0, ixgbe_set_advertise, "I", IXGBE_SYSCTL_DESC_ADV_SPEED);
-
- SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
- SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
- OID_AUTO, "ts", CTLTYPE_INT | CTLFLAG_RW, adapter,
- 0, ixgbe_set_thermal_test, "I", "Thermal Test");
-
/* Set up the timer callout */
callout_init_mtx(&adapter->timer, &adapter->core_mtx, 0);
@@ -559,22 +551,26 @@ ixgbe_attach(device_t dev)
adapter->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig,
ixgbe_unregister_vlan, adapter, EVENTHANDLER_PRI_FIRST);
- /*
- ** Check PCIE slot type/speed/width
- */
+ /* Check PCIE slot type/speed/width */
ixgbe_get_slot_info(hw);
/* Set an initial default flow control value */
adapter->fc = ixgbe_fc_full;
+ /* Check for certain supported features */
+ ixgbe_check_wol_support(adapter);
+ ixgbe_check_eee_support(adapter);
+
+ /* Add sysctls */
+ ixgbe_add_device_sysctls(adapter);
+ ixgbe_add_hw_stats(adapter);
+
/* let hardware know driver is loaded */
ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
ctrl_ext |= IXGBE_CTRL_EXT_DRV_LOAD;
IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext);
- ixgbe_add_hw_stats(adapter);
-
#ifdef DEV_NETMAP
ixgbe_netmap_attach(adapter);
#endif /* DEV_NETMAP */
@@ -618,8 +614,9 @@ ixgbe_detach(device_t dev)
return (EBUSY);
}
+ /* Stop the adapter */
IXGBE_CORE_LOCK(adapter);
- ixgbe_stop(adapter);
+ ixgbe_setup_low_power_mode(adapter);
IXGBE_CORE_UNLOCK(adapter);
for (int i = 0; i < adapter->num_queues; i++, que++, txr++) {
@@ -637,6 +634,7 @@ ixgbe_detach(device_t dev)
taskqueue_drain(adapter->tq, &adapter->link_task);
taskqueue_drain(adapter->tq, &adapter->mod_task);
taskqueue_drain(adapter->tq, &adapter->msf_task);
+ taskqueue_drain(adapter->tq, &adapter->phy_task);
#ifdef IXGBE_FDIR
taskqueue_drain(adapter->tq, &adapter->fdir_task);
#endif
@@ -681,9 +679,77 @@ static int
ixgbe_shutdown(device_t dev)
{
struct adapter *adapter = device_get_softc(dev);
+ int error = 0;
+
+ INIT_DEBUGOUT("ixgbe_shutdown: begin");
+
IXGBE_CORE_LOCK(adapter);
- ixgbe_stop(adapter);
+ error = ixgbe_setup_low_power_mode(adapter);
+ IXGBE_CORE_UNLOCK(adapter);
+
+ return (error);
+}
+
+/**
+ * Methods for going from:
+ * D0 -> D3: ixgbe_suspend
+ * D3 -> D0: ixgbe_resume
+ */
+static int
+ixgbe_suspend(device_t dev)
+{
+ struct adapter *adapter = device_get_softc(dev);
+ int error = 0;
+
+ INIT_DEBUGOUT("ixgbe_suspend: begin");
+
+ IXGBE_CORE_LOCK(adapter);
+
+ error = ixgbe_setup_low_power_mode(adapter);
+
+ /* Save state and power down */
+ pci_save_state(dev);
+ pci_set_powerstate(dev, PCI_POWERSTATE_D3);
+
+ IXGBE_CORE_UNLOCK(adapter);
+
+ return (error);
+}
+
+static int
+ixgbe_resume(device_t dev)
+{
+ struct adapter *adapter = device_get_softc(dev);
+ struct ifnet *ifp = adapter->ifp;
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 wus;
+
+ INIT_DEBUGOUT("ixgbe_resume: begin");
+
+ IXGBE_CORE_LOCK(adapter);
+
+ pci_set_powerstate(dev, PCI_POWERSTATE_D0);
+ pci_restore_state(dev);
+
+ /* Read & clear WUS register */
+ wus = IXGBE_READ_REG(hw, IXGBE_WUS);
+ if (wus)
+ device_printf(dev, "Woken up by (WUS): %#010x\n",
+ IXGBE_READ_REG(hw, IXGBE_WUS));
+ IXGBE_WRITE_REG(hw, IXGBE_WUS, 0xffffffff);
+ /* And clear WUFC until next low-power transition */
+ IXGBE_WRITE_REG(hw, IXGBE_WUFC, 0);
+
+ /*
+ * Required after D3->D0 transition;
+ * will re-advertise all previous advertised speeds
+ */
+ if (ifp->if_flags & IFF_UP)
+ ixgbe_init_locked(adapter);
+
IXGBE_CORE_UNLOCK(adapter);
+
+ INIT_DEBUGOUT("ixgbe_resume: end");
return (0);
}
@@ -736,13 +802,13 @@ ixgbe_ioctl(struct ifnet * ifp, u_long command, caddr_t data)
break;
case SIOCSIFMTU:
IOCTL_DEBUGOUT("ioctl: SIOCSIFMTU (Set Interface MTU)");
- if (ifr->ifr_mtu > IXGBE_MAX_FRAME_SIZE - ETHER_HDR_LEN) {
+ if (ifr->ifr_mtu > IXGBE_MAX_MTU) {
error = EINVAL;
} else {
IXGBE_CORE_LOCK(adapter);
ifp->if_mtu = ifr->ifr_mtu;
adapter->max_frame_size =
- ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN;
+ ifp->if_mtu + IXGBE_MTU_HDR;
ixgbe_init_locked(adapter);
IXGBE_CORE_UNLOCK(adapter);
}
@@ -891,7 +957,7 @@ ixgbe_init_locked(struct adapter *adapter)
/* Prepare transmit descriptors and buffers */
if (ixgbe_setup_transmit_structures(adapter)) {
- device_printf(dev,"Could not setup transmit structures\n");
+ device_printf(dev, "Could not setup transmit structures\n");
ixgbe_stop(adapter);
return;
}
@@ -917,7 +983,7 @@ ixgbe_init_locked(struct adapter *adapter)
/* Prepare receive descriptors and buffers */
if (ixgbe_setup_receive_structures(adapter)) {
- device_printf(dev,"Could not setup receive structures\n");
+ device_printf(dev, "Could not setup receive structures\n");
ixgbe_stop(adapter);
return;
}
@@ -932,11 +998,16 @@ ixgbe_init_locked(struct adapter *adapter)
/* Add for Module detection */
if (hw->mac.type == ixgbe_mac_82599EB)
- gpie |= IXGBE_SDP2_GPIEN_BY_MAC(hw);
+ gpie |= IXGBE_SDP2_GPIEN;
- /* Thermal Failure Detection */
- if (hw->mac.type == ixgbe_mac_X540)
- gpie |= IXGBE_SDP0_GPIEN_BY_MAC(hw);
+ /*
+ * Thermal Failure Detection (X540)
+ * Link Detection (X552)
+ */
+ if (hw->mac.type == ixgbe_mac_X540 ||
+ hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP ||
+ hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T)
+ gpie |= IXGBE_SDP0_GPIEN_X540;
if (adapter->msix > 1) {
/* Enable Enhanced MSIX mode */
@@ -948,6 +1019,7 @@ ixgbe_init_locked(struct adapter *adapter)
/* Set MTU size */
if (ifp->if_mtu > ETHERMTU) {
+ /* aka IXGBE_MAXFRS on 82599 and newer */
mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD);
mhadd &= ~IXGBE_MHADD_MFS_MASK;
mhadd |= adapter->max_frame_size << IXGBE_MHADD_MFS_SHIFT;
@@ -955,7 +1027,6 @@ ixgbe_init_locked(struct adapter *adapter)
}
/* Now enable all the queues */
-
for (int i = 0; i < adapter->num_queues; i++) {
txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(i));
txdctl |= IXGBE_TXDCTL_ENABLE;
@@ -1072,55 +1143,25 @@ ixgbe_init_locked(struct adapter *adapter)
/* Set moderation on the Link interrupt */
IXGBE_WRITE_REG(hw, IXGBE_EITR(adapter->vector), IXGBE_LINK_ITR);
+ /* Configure Energy Efficient Ethernet for supported devices */
+ if (adapter->eee_support)
+ ixgbe_setup_eee(hw, adapter->eee_enabled);
+
/* Config/Enable Link */
ixgbe_config_link(adapter);
/* Hardware Packet Buffer & Flow Control setup */
- {
- u32 rxpb, frame, size, tmp;
-
- frame = adapter->max_frame_size;
+ ixgbe_config_delay_values(adapter);
- /* Calculate High Water */
- switch (hw->mac.type) {
- case ixgbe_mac_X540:
- case ixgbe_mac_X550:
- case ixgbe_mac_X550EM_a:
- case ixgbe_mac_X550EM_x:
- tmp = IXGBE_DV_X540(frame, frame);
- break;
- default:
- tmp = IXGBE_DV(frame, frame);
- break;
- }
- size = IXGBE_BT2KB(tmp);
- rxpb = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(0)) >> 10;
- hw->fc.high_water[0] = rxpb - size;
-
- /* Now calculate Low Water */
- switch (hw->mac.type) {
- case ixgbe_mac_X540:
- case ixgbe_mac_X550:
- case ixgbe_mac_X550EM_a:
- case ixgbe_mac_X550EM_x:
- tmp = IXGBE_LOW_DV_X540(frame);
- break;
- default:
- tmp = IXGBE_LOW_DV(frame);
- break;
- }
- hw->fc.low_water[0] = IXGBE_BT2KB(tmp);
-
- hw->fc.requested_mode = adapter->fc;
- hw->fc.pause_time = IXGBE_FC_PAUSE;
- hw->fc.send_xon = TRUE;
- }
/* Initialize the FC settings */
ixgbe_start_hw(hw);
/* Set up VLAN support and filter */
ixgbe_setup_vlan_hw_support(adapter);
+ /* Setup DMA Coalescing */
+ ixgbe_config_dmac(adapter);
+
/* And now turn on interrupts */
ixgbe_enable_intr(adapter);
@@ -1141,6 +1182,46 @@ ixgbe_init(void *arg)
return;
}
+static void
+ixgbe_config_delay_values(struct adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 rxpb, frame, size, tmp;
+
+ frame = adapter->max_frame_size;
+
+ /* Calculate High Water */
+ switch (hw->mac.type) {
+ case ixgbe_mac_X540:
+ case ixgbe_mac_X550:
+ case ixgbe_mac_X550EM_x:
+ tmp = IXGBE_DV_X540(frame, frame);
+ break;
+ default:
+ tmp = IXGBE_DV(frame, frame);
+ break;
+ }
+ size = IXGBE_BT2KB(tmp);
+ rxpb = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(0)) >> 10;
+ hw->fc.high_water[0] = rxpb - size;
+
+ /* Now calculate Low Water */
+ switch (hw->mac.type) {
+ case ixgbe_mac_X540:
+ case ixgbe_mac_X550:
+ case ixgbe_mac_X550EM_x:
+ tmp = IXGBE_LOW_DV_X540(frame);
+ break;
+ default:
+ tmp = IXGBE_LOW_DV(frame);
+ break;
+ }
+ hw->fc.low_water[0] = IXGBE_BT2KB(tmp);
+
+ hw->fc.requested_mode = adapter->fc;
+ hw->fc.pause_time = IXGBE_FC_PAUSE;
+ hw->fc.send_xon = TRUE;
+}
/*
**
@@ -1195,9 +1276,10 @@ ixgbe_handle_que(void *context, int pending)
struct adapter *adapter = que->adapter;
struct tx_ring *txr = que->txr;
struct ifnet *ifp = adapter->ifp;
+ bool more;
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- ixgbe_rxeof(que);
+ more = ixgbe_rxeof(que);
IXGBE_TX_LOCK(txr);
ixgbe_txeof(txr);
#ifndef IXGBE_LEGACY_TX
@@ -1270,6 +1352,11 @@ ixgbe_legacy_irq(void *arg)
if (reg_eicr & IXGBE_EICR_LSC)
taskqueue_enqueue(adapter->tq, &adapter->link_task);
+ /* External PHY interrupt */
+ if (hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T &&
+ (reg_eicr & IXGBE_EICR_GPI_SDP0_X540))
+ taskqueue_enqueue(adapter->tq, &adapter->phy_task);
+
if (more)
taskqueue_enqueue(que->tq, &que->que_task);
else
@@ -1378,9 +1465,9 @@ ixgbe_msix_link(void *arg)
{
struct adapter *adapter = arg;
struct ixgbe_hw *hw = &adapter->hw;
- u32 reg_eicr;
+ u32 reg_eicr, mod_mask;
- ++adapter->vector_irq;
+ ++adapter->link_irq;
/* First get the cause */
reg_eicr = IXGBE_READ_REG(hw, IXGBE_EICS);
@@ -1408,42 +1495,46 @@ ixgbe_msix_link(void *arg)
device_printf(adapter->dev, "\nCRITICAL: ECC ERROR!! "
"Please Reboot!!\n");
IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_ECC);
- } else
+ }
- if (ixgbe_is_sfp(hw)) {
- if (reg_eicr & IXGBE_EICR_GPI_SDP1) {
- IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1_BY_MAC(hw));
- taskqueue_enqueue(adapter->tq, &adapter->msf_task);
- } else if (reg_eicr & IXGBE_EICR_GPI_SDP2) {
- IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP2_BY_MAC(hw));
- taskqueue_enqueue(adapter->tq, &adapter->mod_task);
- }
+ /* Check for over temp condition */
+ if (reg_eicr & IXGBE_EICR_TS) {
+ device_printf(adapter->dev, "\nCRITICAL: OVER TEMP!! "
+ "PHY IS SHUT DOWN!!\n");
+ device_printf(adapter->dev, "System shutdown required!\n");
+ IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_TS);
}
- }
+ }
+
+ /* Pluggable optics-related interrupt */
+ if (hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP)
+ mod_mask = IXGBE_EICR_GPI_SDP0_X540;
+ else
+ mod_mask = IXGBE_EICR_GPI_SDP2_BY_MAC(hw);
+
+ if (ixgbe_is_sfp(hw)) {
+ if (reg_eicr & IXGBE_EICR_GPI_SDP1_BY_MAC(hw)) {
+ IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1_BY_MAC(hw));
+ taskqueue_enqueue(adapter->tq, &adapter->msf_task);
+ } else if (reg_eicr & mod_mask) {
+ IXGBE_WRITE_REG(hw, IXGBE_EICR, mod_mask);
+ taskqueue_enqueue(adapter->tq, &adapter->mod_task);
+ }
+ }
/* Check for fan failure */
if ((hw->device_id == IXGBE_DEV_ID_82598AT) &&
- (reg_eicr & IXGBE_EICR_GPI_SDP1_BY_MAC(hw))) {
+ (reg_eicr & IXGBE_EICR_GPI_SDP1)) {
+ IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1);
device_printf(adapter->dev, "\nCRITICAL: FAN FAILURE!! "
"REPLACE IMMEDIATELY!!\n");
- IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1_BY_MAC(hw));
}
- /* Check for over temp condition */
- switch (hw->mac.type) {
- case ixgbe_mac_X540:
- case ixgbe_mac_X550:
- case ixgbe_mac_X550EM_a:
- if (reg_eicr & IXGBE_EICR_TS) {
- device_printf(adapter->dev, "\nCRITICAL: OVER TEMP!! "
- "PHY IS SHUT DOWN!!\n");
- device_printf(adapter->dev, "System shutdown required\n");
- IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_TS);
- }
- break;
- default:
- /* Other MACs have no thermal sensor interrupt */
- break;
+ /* External PHY interrupt */
+ if (hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T &&
+ (reg_eicr & IXGBE_EICR_GPI_SDP0_X540)) {
+ IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP0_X540);
+ taskqueue_enqueue(adapter->tq, &adapter->phy_task);
}
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, IXGBE_EIMS_OTHER);
@@ -1542,20 +1633,26 @@ ixgbe_media_status(struct ifnet * ifp, struct ifmediareq * ifmr)
if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KR)
switch (adapter->link_speed) {
case IXGBE_LINK_SPEED_10GB_FULL:
- ifmr->ifm_active |= IFM_10_T | IFM_FDX;
+ ifmr->ifm_active |= IFM_10G_SR | IFM_FDX;
+ break;
+ case IXGBE_LINK_SPEED_2_5GB_FULL:
+ ifmr->ifm_active |= IFM_2500_SX | IFM_FDX;
break;
case IXGBE_LINK_SPEED_1GB_FULL:
- ifmr->ifm_active |= IFM_10_5 | IFM_FDX;
+ ifmr->ifm_active |= IFM_1000_CX | IFM_FDX;
break;
}
- if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KX4
+ else if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KX4
|| layer & IXGBE_PHYSICAL_LAYER_1000BASE_KX)
switch (adapter->link_speed) {
case IXGBE_LINK_SPEED_10GB_FULL:
- ifmr->ifm_active |= IFM_10_2 | IFM_FDX;
+ ifmr->ifm_active |= IFM_10G_CX4 | IFM_FDX;
+ break;
+ case IXGBE_LINK_SPEED_2_5GB_FULL:
+ ifmr->ifm_active |= IFM_2500_SX | IFM_FDX;
break;
case IXGBE_LINK_SPEED_1GB_FULL:
- ifmr->ifm_active |= IFM_10_5 | IFM_FDX;
+ ifmr->ifm_active |= IFM_1000_CX | IFM_FDX;
break;
}
@@ -1564,10 +1661,12 @@ ixgbe_media_status(struct ifnet * ifp, struct ifmediareq * ifmr)
ifmr->ifm_active |= IFM_UNKNOWN;
#if __FreeBSD_version >= 900025
- /* Flow control setting */
- if (adapter->fc == ixgbe_fc_rx_pause || adapter->fc == ixgbe_fc_full)
+ /* Display current flow control setting used on link */
+ if (hw->fc.current_mode == ixgbe_fc_rx_pause ||
+ hw->fc.current_mode == ixgbe_fc_full)
ifmr->ifm_active |= IFM_ETH_RXPAUSE;
- if (adapter->fc == ixgbe_fc_tx_pause || adapter->fc == ixgbe_fc_full)
+ if (hw->fc.current_mode == ixgbe_fc_tx_pause ||
+ hw->fc.current_mode == ixgbe_fc_full)
ifmr->ifm_active |= IFM_ETH_TXPAUSE;
#endif
@@ -1597,21 +1696,22 @@ ixgbe_media_change(struct ifnet * ifp)
if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
return (EINVAL);
+ if (hw->phy.media_type == ixgbe_media_type_backplane)
+ return (EPERM);
+
/*
** We don't actually need to check against the supported
** media types of the adapter; ifmedia will take care of
** that for us.
- ** NOTE: this relies on falling thru the switch
- ** to get all the values set, it can be confusing.
*/
switch (IFM_SUBTYPE(ifm->ifm_media)) {
case IFM_AUTO:
case IFM_10G_T:
speed |= IXGBE_LINK_SPEED_100_FULL;
case IFM_10G_LRM:
- case IFM_10G_SR: /* KR, too */
+ case IFM_10G_SR: /* KR, too */
case IFM_10G_LR:
- case IFM_10G_CX4: /* KX4 for now */
+ case IFM_10G_CX4: /* KX4 */
speed |= IXGBE_LINK_SPEED_1GB_FULL;
case IFM_10G_TWINAX:
speed |= IXGBE_LINK_SPEED_10GB_FULL;
@@ -1620,7 +1720,7 @@ ixgbe_media_change(struct ifnet * ifp)
speed |= IXGBE_LINK_SPEED_100_FULL;
case IFM_1000_LX:
case IFM_1000_SX:
- case IFM_1000_CX: /* KX until there's real support */
+ case IFM_1000_CX: /* KX */
speed |= IXGBE_LINK_SPEED_1GB_FULL;
break;
case IFM_100_TX:
@@ -1640,7 +1740,7 @@ ixgbe_media_change(struct ifnet * ifp)
return (0);
invalid:
- device_printf(adapter->dev, "Invalid media type\n");
+ device_printf(adapter->dev, "Invalid media type!\n");
return (EINVAL);
}
@@ -1865,7 +1965,6 @@ ixgbe_update_link_status(struct adapter *adapter)
struct ifnet *ifp = adapter->ifp;
device_t dev = adapter->dev;
-
if (adapter->link_up){
if (adapter->link_active == FALSE) {
if (bootverbose)
@@ -1875,6 +1974,8 @@ ixgbe_update_link_status(struct adapter *adapter)
adapter->link_active = TRUE;
/* Update any Flow Control changes */
ixgbe_fc_enable(&adapter->hw);
+ /* Update DMA coalescing config */
+ ixgbe_config_dmac(adapter);
if_link_state_change(ifp, LINK_STATE_UP);
}
} else { /* Link down */
@@ -1961,7 +2062,7 @@ ixgbe_identify_hardware(struct adapter *adapter)
/* We need this here to set the num_segs below */
ixgbe_set_mac_type(hw);
- /* Pick up the 82599 and VF settings */
+ /* Pick up the 82599 settings */
if (hw->mac.type != ixgbe_mac_82598EB) {
hw->phy.smart_speed = ixgbe_smart_speed;
adapter->num_segs = IXGBE_82599_SCATTER;
@@ -2071,6 +2172,7 @@ ixgbe_allocate_legacy(struct adapter *adapter)
TASK_INIT(&adapter->link_task, 0, ixgbe_handle_link, adapter);
TASK_INIT(&adapter->mod_task, 0, ixgbe_handle_mod, adapter);
TASK_INIT(&adapter->msf_task, 0, ixgbe_handle_msf, adapter);
+ TASK_INIT(&adapter->phy_task, 0, ixgbe_handle_phy, adapter);
#ifdef IXGBE_FDIR
TASK_INIT(&adapter->fdir_task, 0, ixgbe_reinit_fdir, adapter);
#endif
@@ -2136,8 +2238,6 @@ ixgbe_allocate_msix(struct adapter *adapter)
}
#endif
-
-
for (int i = 0; i < adapter->num_queues; i++, vector++, que++, txr++) {
rid = vector + 1;
que->res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
@@ -2187,14 +2287,11 @@ ixgbe_allocate_msix(struct adapter *adapter)
"Bound RSS bucket %d to CPU %d\n",
i, cpu_id);
#else
-#if 0 // This is too noisy
- device_printf(dev,
- "Bound queue %d to cpu %d\n",
- i, cpu_id);
-#endif
+ if (bootverbose)
+ device_printf(dev,
+ "Bound queue %d to cpu %d\n",
+ i, cpu_id);
#endif
-
-
#ifndef IXGBE_LEGACY_TX
TASK_INIT(&txr->txq_task, 0, ixgbe_deferred_mq_start, txr);
#endif
@@ -2240,6 +2337,7 @@ ixgbe_allocate_msix(struct adapter *adapter)
TASK_INIT(&adapter->link_task, 0, ixgbe_handle_link, adapter);
TASK_INIT(&adapter->mod_task, 0, ixgbe_handle_mod, adapter);
TASK_INIT(&adapter->msf_task, 0, ixgbe_handle_msf, adapter);
+ TASK_INIT(&adapter->phy_task, 0, ixgbe_handle_phy, adapter);
#ifdef IXGBE_FDIR
TASK_INIT(&adapter->fdir_task, 0, ixgbe_reinit_fdir, adapter);
#endif
@@ -2465,6 +2563,12 @@ ixgbe_setup_interface(device_t dev, struct adapter *adapter)
#if __FreeBSD_version >= 1100036
if_setgetcounterfn(ifp, ixgbe_get_counter);
#endif
+#if __FreeBSD_version >= 1100045
+ /* TSO parameters */
+ ifp->if_hw_tsomax = 65518;
+ ifp->if_hw_tsomaxsegcount = IXGBE_82599_SCATTER;
+ ifp->if_hw_tsomaxsegsize = 2048;
+#endif
#ifndef IXGBE_LEGACY_TX
ifp->if_transmit = ixgbe_mq_start;
ifp->if_qflush = ixgbe_qflush;
@@ -2548,10 +2652,6 @@ ixgbe_add_media_types(struct adapter *adapter)
ifmedia_add(&adapter->media, IFM_ETHER | IFM_10G_CX4, 0, NULL);
if (layer & IXGBE_PHYSICAL_LAYER_1000BASE_SX)
ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_SX, 0, NULL);
-#if 0
- if (layer & IXGBE_PHYSICAL_LAYER_1000BASE_LX)
- ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_LX, 0, NULL);
-#endif
/*
** Other (no matching FreeBSD media type):
@@ -2560,25 +2660,24 @@ ixgbe_add_media_types(struct adapter *adapter)
*/
if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KR) {
device_printf(dev, "Media supported: 10GbaseKR\n");
- device_printf(dev, "10GbaseKR mapped to 10baseT\n");
- ifmedia_add(&adapter->media, IFM_ETHER | IFM_10_T, 0, NULL);
+ device_printf(dev, "10GbaseKR mapped to 10GbaseSR\n");
+ ifmedia_add(&adapter->media, IFM_ETHER | IFM_10G_SR, 0, NULL);
}
if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KX4) {
device_printf(dev, "Media supported: 10GbaseKX4\n");
- device_printf(dev, "10GbaseKX4 mapped to 10base2\n");
- ifmedia_add(&adapter->media, IFM_ETHER | IFM_10_2, 0, NULL);
+ device_printf(dev, "10GbaseKX4 mapped to 10GbaseCX4\n");
+ ifmedia_add(&adapter->media, IFM_ETHER | IFM_10G_CX4, 0, NULL);
}
if (layer & IXGBE_PHYSICAL_LAYER_1000BASE_KX) {
device_printf(dev, "Media supported: 1000baseKX\n");
- device_printf(dev, "1000baseKX mapped to 10base5\n");
- ifmedia_add(&adapter->media, IFM_ETHER | IFM_10_5, 0, NULL);
+ device_printf(dev, "1000baseKX mapped to 1000baseCX\n");
+ ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_CX, 0, NULL);
}
if (layer & IXGBE_PHYSICAL_LAYER_1000BASE_BX) {
/* Someday, someone will care about you... */
device_printf(dev, "Media supported: 1000baseBX\n");
}
- /* Very old */
if (hw->device_id == IXGBE_DEV_ID_82598AT) {
ifmedia_add(&adapter->media,
IFM_ETHER | IFM_1000_T | IFM_FDX, 0, NULL);
@@ -2706,7 +2805,8 @@ ixgbe_initialise_rss_mapping(struct adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
uint32_t reta;
- int i, j, queue_id;
+ int i, j, queue_id, table_size;
+ int index_mult;
uint32_t rss_key[10];
uint32_t mrqc;
#ifdef RSS
@@ -2724,8 +2824,23 @@ ixgbe_initialise_rss_mapping(struct adapter *adapter)
arc4rand(&rss_key, sizeof(rss_key), 0);
#endif
+ /* Set multiplier for RETA setup and table size based on MAC */
+ index_mult = 0x1;
+ table_size = 128;
+ switch (adapter->hw.mac.type) {
+ case ixgbe_mac_82598EB:
+ index_mult = 0x11;
+ break;
+ case ixgbe_mac_X550:
+ case ixgbe_mac_X550EM_x:
+ table_size = 512;
+ break;
+ default:
+ break;
+ }
+
/* Set up the redirection table */
- for (i = 0, j = 0; i < 128; i++, j++) {
+ for (i = 0, j = 0; i < table_size; i++, j++) {
if (j == adapter->num_queues) j = 0;
#ifdef RSS
/*
@@ -2736,7 +2851,7 @@ ixgbe_initialise_rss_mapping(struct adapter *adapter)
queue_id = rss_get_indirection_to_bucket(i);
queue_id = queue_id % adapter->num_queues;
#else
- queue_id = (j * 0x11);
+ queue_id = (j * index_mult);
#endif
/*
* The low 8 bits are for hash value (n+0);
@@ -2745,7 +2860,10 @@ ixgbe_initialise_rss_mapping(struct adapter *adapter)
reta = reta >> 8;
reta = reta | ( ((uint32_t) queue_id) << 24);
if ((i & 3) == 3) {
- IXGBE_WRITE_REG(hw, IXGBE_RETA(i >> 2), reta);
+ if (i < 128)
+ IXGBE_WRITE_REG(hw, IXGBE_RETA(i >> 2), reta);
+ else
+ IXGBE_WRITE_REG(hw, IXGBE_ERETA((i >> 2) - 32), reta);
reta = 0;
}
}
@@ -2834,8 +2952,10 @@ ixgbe_initialize_receive_units(struct adapter *adapter)
/* Enable broadcasts */
fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
fctrl |= IXGBE_FCTRL_BAM;
- fctrl |= IXGBE_FCTRL_DPF;
- fctrl |= IXGBE_FCTRL_PMCF;
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+ fctrl |= IXGBE_FCTRL_DPF;
+ fctrl |= IXGBE_FCTRL_PMCF;
+ }
IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
/* Set for Jumbo Frames? */
@@ -3045,30 +3165,37 @@ ixgbe_enable_intr(struct adapter *adapter)
mask = (IXGBE_EIMS_ENABLE_MASK & ~IXGBE_EIMS_RTX_QUEUE);
/* Enable Fan Failure detection */
if (hw->device_id == IXGBE_DEV_ID_82598AT)
- mask |= IXGBE_EIMS_GPI_SDP1_BY_MAC(hw);
+ mask |= IXGBE_EIMS_GPI_SDP1;
switch (adapter->hw.mac.type) {
case ixgbe_mac_82599EB:
mask |= IXGBE_EIMS_ECC;
/* Temperature sensor on some adapters */
- mask |= IXGBE_EIMS_GPI_SDP0_BY_MAC(hw);
+ mask |= IXGBE_EIMS_GPI_SDP0;
/* SFP+ (RX_LOS_N & MOD_ABS_N) */
- mask |= IXGBE_EIMS_GPI_SDP1_BY_MAC(hw);
- mask |= IXGBE_EIMS_GPI_SDP2_BY_MAC(hw);
+ mask |= IXGBE_EIMS_GPI_SDP1;
+ mask |= IXGBE_EIMS_GPI_SDP2;
#ifdef IXGBE_FDIR
mask |= IXGBE_EIMS_FLOW_DIR;
#endif
break;
case ixgbe_mac_X540:
- case ixgbe_mac_X550:
- case ixgbe_mac_X550EM_a:
- case ixgbe_mac_X550EM_x:
/* Detect if Thermal Sensor is enabled */
fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM);
if (fwsm & IXGBE_FWSM_TS_ENABLED)
mask |= IXGBE_EIMS_TS;
- /* XXX: Which SFP mode line does this look at? */
- if (hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP)
+ mask |= IXGBE_EIMS_ECC;
+#ifdef IXGBE_FDIR
+ mask |= IXGBE_EIMS_FLOW_DIR;
+#endif
+ break;
+ case ixgbe_mac_X550:
+ case ixgbe_mac_X550EM_x:
+ /* MAC thermal sensor is automatically enabled */
+ mask |= IXGBE_EIMS_TS;
+ /* Some devices use SDP0 for important information */
+ if (hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP ||
+ hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T)
mask |= IXGBE_EIMS_GPI_SDP0_BY_MAC(hw);
mask |= IXGBE_EIMS_ECC;
#ifdef IXGBE_FDIR
@@ -3081,7 +3208,7 @@ ixgbe_enable_intr(struct adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_EIMS, mask);
- /* With RSS we use auto clear */
+ /* With MSI-X we use auto clear */
if (adapter->msix_mem) {
mask = IXGBE_EIMS_ENABLE_MASK;
/* Don't autoclear Link */
@@ -3135,10 +3262,12 @@ ixgbe_get_slot_info(struct ixgbe_hw *hw)
if (hw->device_id != IXGBE_DEV_ID_82599_SFP_SF_QP) {
ixgbe_get_bus_info(hw);
/* These devices don't use PCI-E */
- if (hw->mac.type == ixgbe_mac_X550EM_x
- || hw->mac.type == ixgbe_mac_X550EM_a)
+ switch (hw->mac.type) {
+ case ixgbe_mac_X550EM_x:
return;
- goto display;
+ default:
+ goto display;
+ }
}
/*
@@ -3260,7 +3389,6 @@ ixgbe_set_ivar(struct adapter *adapter, u8 entry, u8 vector, s8 type)
case ixgbe_mac_82599EB:
case ixgbe_mac_X540:
case ixgbe_mac_X550:
- case ixgbe_mac_X550EM_a:
case ixgbe_mac_X550EM_x:
if (type == -1) { /* MISC IVAR */
index = (entry & 1) * 8;
@@ -3289,8 +3417,14 @@ ixgbe_configure_ivars(struct adapter *adapter)
if (ixgbe_max_interrupt_rate > 0)
newitr = (4000000 / ixgbe_max_interrupt_rate) & 0x0FF8;
- else
+ else {
+ /*
+ ** Disable DMA coalescing if interrupt moderation is
+ ** disabled.
+ */
+ adapter->dmac = 0;
newitr = 0;
+ }
for (int i = 0; i < adapter->num_queues; i++, que++) {
/* First the RX queue entry */
@@ -3350,7 +3484,7 @@ ixgbe_handle_link(void *context, int pending)
ixgbe_check_link(&adapter->hw,
&adapter->link_speed, &adapter->link_up, 0);
- ixgbe_update_link_status(adapter);
+ ixgbe_update_link_status(adapter);
}
/*
@@ -3410,6 +3544,28 @@ ixgbe_handle_msf(void *context, int pending)
return;
}
+/*
+** Tasklet for handling interrupts from an external PHY
+*/
+static void
+ixgbe_handle_phy(void *context, int pending)
+{
+ struct adapter *adapter = context;
+ struct ixgbe_hw *hw = &adapter->hw;
+ int error;
+
+ error = hw->phy.ops.handle_lasi(hw);
+ if (error == IXGBE_ERR_OVERTEMP)
+ device_printf(adapter->dev,
+ "CRITICAL: EXTERNAL PHY OVER TEMP!! "
+ " PHY will downshift to lower power state!\n");
+ else if (error)
+ device_printf(adapter->dev,
+ "Error handling LASI interrupt: %d\n",
+ error);
+ return;
+}
+
#ifdef IXGBE_FDIR
/*
** Tasklet for reinitializing the Flow Director filter table
@@ -3432,6 +3588,127 @@ ixgbe_reinit_fdir(void *context, int pending)
}
#endif
+/*********************************************************************
+ *
+ * Configure DMA Coalescing
+ *
+ **********************************************************************/
+static void
+ixgbe_config_dmac(struct adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ struct ixgbe_dmac_config *dcfg = &hw->mac.dmac_config;
+
+ if (hw->mac.type < ixgbe_mac_X550 ||
+ !hw->mac.ops.dmac_config)
+ return;
+
+ if (dcfg->watchdog_timer ^ adapter->dmac ||
+ dcfg->link_speed ^ adapter->link_speed) {
+ dcfg->watchdog_timer = adapter->dmac;
+ dcfg->fcoe_en = false;
+ dcfg->link_speed = adapter->link_speed;
+ dcfg->num_tcs = 1;
+
+ INIT_DEBUGOUT2("dmac settings: watchdog %d, link speed %d\n",
+ dcfg->watchdog_timer, dcfg->link_speed);
+
+ hw->mac.ops.dmac_config(hw);
+ }
+}
+
+/*
+ * Checks whether the adapter supports Energy Efficient Ethernet
+ * or not, based on device ID.
+ */
+static void
+ixgbe_check_eee_support(struct adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+
+ adapter->eee_support = adapter->eee_enabled =
+ (hw->device_id == IXGBE_DEV_ID_X550T ||
+ hw->device_id == IXGBE_DEV_ID_X550EM_X_KR);
+}
+
+/*
+ * Checks whether the adapter's ports are capable of
+ * Wake On LAN by reading the adapter's NVM.
+ *
+ * Sets each port's hw->wol_enabled value depending
+ * on the value read here.
+ */
+static void
+ixgbe_check_wol_support(struct adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ u16 dev_caps = 0;
+
+ /* Find out WoL support for port */
+ adapter->wol_support = hw->wol_enabled = 0;
+ ixgbe_get_device_caps(hw, &dev_caps);
+ if ((dev_caps & IXGBE_DEVICE_CAPS_WOL_PORT0_1) ||
+ ((dev_caps & IXGBE_DEVICE_CAPS_WOL_PORT0) &&
+ hw->bus.func == 0))
+ adapter->wol_support = hw->wol_enabled = 1;
+
+ /* Save initial wake up filter configuration */
+ adapter->wufc = IXGBE_READ_REG(hw, IXGBE_WUFC);
+
+ return;
+}
+
+/*
+ * Prepare the adapter/port for LPLU and/or WoL
+ */
+static int
+ixgbe_setup_low_power_mode(struct adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ device_t dev = adapter->dev;
+ s32 error = 0;
+
+ mtx_assert(&adapter->core_mtx, MA_OWNED);
+
+ /* Limit power management flow to X550EM baseT */
+ if (hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T
+ && hw->phy.ops.enter_lplu) {
+ /* Turn off support for APM wakeup. (Using ACPI instead) */
+ IXGBE_WRITE_REG(hw, IXGBE_GRC,
+ IXGBE_READ_REG(hw, IXGBE_GRC) & ~(u32)2);
+
+ /*
+ * Clear Wake Up Status register to prevent any previous wakeup
+ * events from waking us up immediately after we suspend.
+ */
+ IXGBE_WRITE_REG(hw, IXGBE_WUS, 0xffffffff);
+
+ /*
+ * Program the Wakeup Filter Control register with user filter
+ * settings
+ */
+ IXGBE_WRITE_REG(hw, IXGBE_WUFC, adapter->wufc);
+
+ /* Enable wakeups and power management in Wakeup Control */
+ IXGBE_WRITE_REG(hw, IXGBE_WUC,
+ IXGBE_WUC_WKEN | IXGBE_WUC_PME_EN);
+
+ /* X550EM baseT adapters need a special LPLU flow */
+ hw->phy.reset_disable = true;
+ ixgbe_stop(adapter);
+ error = hw->phy.ops.enter_lplu(hw);
+ if (error)
+ device_printf(dev,
+ "Error entering LPLU: %d\n", error);
+ hw->phy.reset_disable = false;
+ } else {
+ /* Just stop for other adapters */
+ ixgbe_stop(adapter);
+ }
+
+ return error;
+}
+
/**********************************************************************
*
* Update the board statistics counters.
@@ -3449,42 +3726,6 @@ ixgbe_update_stats_counters(struct adapter *adapter)
adapter->stats.pf.errbc += IXGBE_READ_REG(hw, IXGBE_ERRBC);
adapter->stats.pf.mspdc += IXGBE_READ_REG(hw, IXGBE_MSPDC);
- /*
- ** Note: these are for the 8 possible traffic classes,
- ** which in current implementation is unused,
- ** therefore only 0 should read real data.
- */
- for (int i = 0; i < 8; i++) {
- u32 mp;
- mp = IXGBE_READ_REG(hw, IXGBE_MPC(i));
- /* missed_rx tallies misses for the gprc workaround */
- missed_rx += mp;
- /* global total per queue */
- adapter->stats.pf.mpc[i] += mp;
- /* total for stats display */
- total_missed_rx += adapter->stats.pf.mpc[i];
- if (hw->mac.type == ixgbe_mac_82598EB) {
- adapter->stats.pf.rnbc[i] +=
- IXGBE_READ_REG(hw, IXGBE_RNBC(i));
- adapter->stats.pf.qbtc[i] +=
- IXGBE_READ_REG(hw, IXGBE_QBTC(i));
- adapter->stats.pf.qbrc[i] +=
- IXGBE_READ_REG(hw, IXGBE_QBRC(i));
- adapter->stats.pf.pxonrxc[i] +=
- IXGBE_READ_REG(hw, IXGBE_PXONRXC(i));
- } else
- adapter->stats.pf.pxonrxc[i] +=
- IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i));
- adapter->stats.pf.pxontxc[i] +=
- IXGBE_READ_REG(hw, IXGBE_PXONTXC(i));
- adapter->stats.pf.pxofftxc[i] +=
- IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i));
- if (hw->mac.type != ixgbe_mac_X550EM_x)
- adapter->stats.pf.pxoffrxc[i] +=
- IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i));
- adapter->stats.pf.pxon2offc[i] +=
- IXGBE_READ_REG(hw, IXGBE_PXON2OFFCNT(i));
- }
for (int i = 0; i < 16; i++) {
adapter->stats.pf.qprc[i] += IXGBE_READ_REG(hw, IXGBE_QPRC(i));
adapter->stats.pf.qptc[i] += IXGBE_READ_REG(hw, IXGBE_QPTC(i));
@@ -3592,6 +3833,8 @@ static uint64_t
ixgbe_get_counter(struct ifnet *ifp, ift_counter cnt)
{
struct adapter *adapter;
+ struct tx_ring *txr;
+ uint64_t rv;
adapter = if_getsoftc(ifp);
@@ -3612,6 +3855,12 @@ ixgbe_get_counter(struct ifnet *ifp, ift_counter cnt)
return (0);
case IFCOUNTER_IQDROPS:
return (adapter->iqdrops);
+ case IFCOUNTER_OQDROPS:
+ rv = 0;
+ txr = adapter->tx_rings;
+ for (int i = 0; i < adapter->num_queues; i++, txr++)
+ rv += txr->br->br_drops;
+ return (rv);
case IFCOUNTER_IERRORS:
return (adapter->ierrors);
default:
@@ -3720,6 +3969,108 @@ ixgbe_sysctl_interrupt_rate_handler(SYSCTL_HANDLER_ARGS)
return 0;
}
+static void
+ixgbe_add_device_sysctls(struct adapter *adapter)
+{
+ device_t dev = adapter->dev;
+ struct ixgbe_hw *hw = &adapter->hw;
+ struct sysctl_oid_list *child;
+ struct sysctl_ctx_list *ctx;
+
+ ctx = device_get_sysctl_ctx(dev);
+ child = SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
+
+ /* Sysctls for all devices */
+ SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "fc",
+ CTLTYPE_INT | CTLFLAG_RW, adapter, 0,
+ ixgbe_set_flowcntl, "I", IXGBE_SYSCTL_DESC_SET_FC);
+
+ SYSCTL_ADD_INT(ctx, child, OID_AUTO, "enable_aim",
+ CTLFLAG_RW,
+ &ixgbe_enable_aim, 1, "Interrupt Moderation");
+
+ SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "advertise_speed",
+ CTLTYPE_INT | CTLFLAG_RW, adapter, 0,
+ ixgbe_set_advertise, "I", IXGBE_SYSCTL_DESC_ADV_SPEED);
+
+ SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "thermal_test",
+ CTLTYPE_INT | CTLFLAG_RW, adapter, 0,
+ ixgbe_sysctl_thermal_test, "I", "Thermal Test");
+
+ /* for X550 devices */
+ if (hw->mac.type >= ixgbe_mac_X550)
+ SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "dmac",
+ CTLTYPE_INT | CTLFLAG_RW, adapter, 0,
+ ixgbe_sysctl_dmac, "I", "DMA Coalesce");
+
+ /* for X550T and X550EM backplane devices */
+ if (hw->device_id == IXGBE_DEV_ID_X550T ||
+ hw->device_id == IXGBE_DEV_ID_X550EM_X_KR) {
+ struct sysctl_oid *eee_node;
+ struct sysctl_oid_list *eee_list;
+
+ eee_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "eee",
+ CTLFLAG_RD, NULL,
+ "Energy Efficient Ethernet sysctls");
+ eee_list = SYSCTL_CHILDREN(eee_node);
+
+ SYSCTL_ADD_PROC(ctx, eee_list, OID_AUTO, "enable",
+ CTLTYPE_INT | CTLFLAG_RW, adapter, 0,
+ ixgbe_sysctl_eee_enable, "I",
+ "Enable or Disable EEE");
+
+ SYSCTL_ADD_PROC(ctx, eee_list, OID_AUTO, "negotiated",
+ CTLTYPE_INT | CTLFLAG_RD, adapter, 0,
+ ixgbe_sysctl_eee_negotiated, "I",
+ "EEE negotiated on link");
+
+ SYSCTL_ADD_PROC(ctx, eee_list, OID_AUTO, "tx_lpi_status",
+ CTLTYPE_INT | CTLFLAG_RD, adapter, 0,
+ ixgbe_sysctl_eee_tx_lpi_status, "I",
+ "Whether or not TX link is in LPI state");
+
+ SYSCTL_ADD_PROC(ctx, eee_list, OID_AUTO, "rx_lpi_status",
+ CTLTYPE_INT | CTLFLAG_RD, adapter, 0,
+ ixgbe_sysctl_eee_rx_lpi_status, "I",
+ "Whether or not RX link is in LPI state");
+ }
+
+ /* for certain 10GBaseT devices */
+ if (hw->device_id == IXGBE_DEV_ID_X550T ||
+ hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T) {
+ SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "wol_enable",
+ CTLTYPE_INT | CTLFLAG_RW, adapter, 0,
+ ixgbe_sysctl_wol_enable, "I",
+ "Enable/Disable Wake on LAN");
+
+ SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "wufc",
+ CTLTYPE_INT | CTLFLAG_RW, adapter, 0,
+ ixgbe_sysctl_wufc, "I",
+ "Enable/Disable Wake Up Filters");
+ }
+
+ /* for X550EM 10GBaseT devices */
+ if (hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T) {
+ struct sysctl_oid *phy_node;
+ struct sysctl_oid_list *phy_list;
+
+ phy_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "phy",
+ CTLFLAG_RD, NULL,
+ "External PHY sysctls");
+ phy_list = SYSCTL_CHILDREN(phy_node);
+
+ SYSCTL_ADD_PROC(ctx, phy_list, OID_AUTO, "temp",
+ CTLTYPE_INT | CTLFLAG_RD, adapter, 0,
+ ixgbe_sysctl_phy_temp, "I",
+ "Current External PHY Temperature (Celsius)");
+
+ SYSCTL_ADD_PROC(ctx, phy_list, OID_AUTO, "overtemp_occurred",
+ CTLTYPE_INT | CTLFLAG_RD, adapter, 0,
+ ixgbe_sysctl_phy_overtemp_occurred, "I",
+ "External PHY High Temperature Event Occurred");
+ }
+}
+
/*
* Add sysctl variables, one per statistic, to the system.
*/
@@ -3753,7 +4104,7 @@ ixgbe_add_hw_stats(struct adapter *adapter)
CTLFLAG_RD, &adapter->watchdog_events,
"Watchdog timeouts");
SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "link_irq",
- CTLFLAG_RD, &adapter->vector_irq,
+ CTLFLAG_RD, &adapter->link_irq,
"Link MSIX IRQ Handled");
for (int i = 0; i < adapter->num_queues; i++, txr++) {
@@ -3790,6 +4141,9 @@ ixgbe_add_hw_stats(struct adapter *adapter)
SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_packets",
CTLFLAG_RD, &txr->total_packets,
"Queue Packets Transmitted");
+ SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "br_drops",
+ CTLFLAG_RD, &txr->br->br_drops,
+ "Packets dropped in buf_ring");
}
for (int i = 0; i < adapter->num_queues; i++, rxr++) {
@@ -4082,20 +4436,77 @@ ixgbe_set_advertise(SYSCTL_HANDLER_ARGS)
}
/*
-** Thermal Shutdown Trigger
-** - cause a Thermal Overtemp IRQ
-** - this now requires firmware enabling
-*/
+ * The following two sysctls are for X550 BaseT devices;
+ * they deal with the external PHY used in them.
+ */
static int
-ixgbe_set_thermal_test(SYSCTL_HANDLER_ARGS)
+ixgbe_sysctl_phy_temp(SYSCTL_HANDLER_ARGS)
{
- int error, fire = 0;
struct adapter *adapter = (struct adapter *) arg1;
struct ixgbe_hw *hw = &adapter->hw;
+ u16 reg;
+ if (hw->device_id != IXGBE_DEV_ID_X550EM_X_10G_T) {
+ device_printf(adapter->dev,
+ "Device has no supported external thermal sensor.\n");
+ return (ENODEV);
+ }
- if (hw->mac.type < ixgbe_mac_X540)
- return (0);
+ if (hw->phy.ops.read_reg(hw, IXGBE_PHY_CURRENT_TEMP,
+ IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
+ &reg)) {
+ device_printf(adapter->dev,
+ "Error reading from PHY's current temperature register\n");
+ return (EAGAIN);
+ }
+
+ /* Shift temp for output */
+ reg = reg >> 8;
+
+ return (sysctl_handle_int(oidp, NULL, reg, req));
+}
+
+/*
+ * Reports whether the current PHY temperature is over
+ * the overtemp threshold.
+ * - This is reported directly from the PHY
+ */
+static int
+ixgbe_sysctl_phy_overtemp_occurred(SYSCTL_HANDLER_ARGS)
+{
+ struct adapter *adapter = (struct adapter *) arg1;
+ struct ixgbe_hw *hw = &adapter->hw;
+ u16 reg;
+
+ if (hw->device_id != IXGBE_DEV_ID_X550EM_X_10G_T) {
+ device_printf(adapter->dev,
+ "Device has no supported external thermal sensor.\n");
+ return (ENODEV);
+ }
+
+ if (hw->phy.ops.read_reg(hw, IXGBE_PHY_OVERTEMP_STATUS,
+ IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
+ &reg)) {
+ device_printf(adapter->dev,
+ "Error reading from PHY's temperature status register\n");
+ return (EAGAIN);
+ }
+
+ /* Get occurrence bit */
+ reg = !!(reg & 0x4000);
+ return (sysctl_handle_int(oidp, 0, reg, req));
+}
+
+/*
+** Thermal Shutdown Trigger (internal MAC)
+** - Set this to 1 to cause an overtemp event to occur
+*/
+static int
+ixgbe_sysctl_thermal_test(SYSCTL_HANDLER_ARGS)
+{
+ struct adapter *adapter = (struct adapter *) arg1;
+ struct ixgbe_hw *hw = &adapter->hw;
+ int error, fire = 0;
error = sysctl_handle_int(oidp, &fire, 0, req);
if ((error) || (req->newptr == NULL))
@@ -4111,6 +4522,223 @@ ixgbe_set_thermal_test(SYSCTL_HANDLER_ARGS)
}
/*
+** Manage DMA Coalescing.
+** Control values:
+** 0/1 - off / on (use default value of 1000)
+**
+** Legal timer values are:
+** 50,100,250,500,1000,2000,5000,10000
+**
+** Turning off interrupt moderation will also turn this off.
+*/
+static int
+ixgbe_sysctl_dmac(SYSCTL_HANDLER_ARGS)
+{
+ struct adapter *adapter = (struct adapter *) arg1;
+ struct ixgbe_hw *hw = &adapter->hw;
+ struct ifnet *ifp = adapter->ifp;
+ int error;
+ u16 oldval;
+
+ oldval = adapter->dmac;
+ error = sysctl_handle_int(oidp, &adapter->dmac, 0, req);
+ if ((error) || (req->newptr == NULL))
+ return (error);
+
+ switch (hw->mac.type) {
+ case ixgbe_mac_X550:
+ case ixgbe_mac_X550EM_x:
+ break;
+ default:
+ device_printf(adapter->dev,
+ "DMA Coalescing is only supported on X550 devices\n");
+ return (ENODEV);
+ }
+
+ switch (adapter->dmac) {
+ case 0:
+ /* Disabled */
+ break;
+ case 1: /* Enable and use default */
+ adapter->dmac = 1000;
+ break;
+ case 50:
+ case 100:
+ case 250:
+ case 500:
+ case 1000:
+ case 2000:
+ case 5000:
+ case 10000:
+ /* Legal values - allow */
+ break;
+ default:
+ /* Do nothing, illegal value */
+ adapter->dmac = oldval;
+ return (EINVAL);
+ }
+
+ /* Re-initialize hardware if it's already running */
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ ixgbe_init(adapter);
+
+ return (0);
+}
+
+/*
+ * Sysctl to enable/disable the WoL capability, if supported by the adapter.
+ * Values:
+ * 0 - disabled
+ * 1 - enabled
+ */
+static int
+ixgbe_sysctl_wol_enable(SYSCTL_HANDLER_ARGS)
+{
+ struct adapter *adapter = (struct adapter *) arg1;
+ struct ixgbe_hw *hw = &adapter->hw;
+ int new_wol_enabled;
+ int error = 0;
+
+ new_wol_enabled = hw->wol_enabled;
+ error = sysctl_handle_int(oidp, &new_wol_enabled, 0, req);
+ if ((error) || (req->newptr == NULL))
+ return (error);
+ if (new_wol_enabled == hw->wol_enabled)
+ return (0);
+
+ if (new_wol_enabled > 0 && !adapter->wol_support)
+ return (ENODEV);
+ else
+ hw->wol_enabled = !!(new_wol_enabled);
+
+ return (0);
+}
+
+/*
+ * Sysctl to enable/disable the Energy Efficient Ethernet capability,
+ * if supported by the adapter.
+ * Values:
+ * 0 - disabled
+ * 1 - enabled
+ */
+static int
+ixgbe_sysctl_eee_enable(SYSCTL_HANDLER_ARGS)
+{
+ struct adapter *adapter = (struct adapter *) arg1;
+ struct ifnet *ifp = adapter->ifp;
+ int new_eee_enabled, error = 0;
+
+ new_eee_enabled = adapter->eee_enabled;
+ error = sysctl_handle_int(oidp, &new_eee_enabled, 0, req);
+ if ((error) || (req->newptr == NULL))
+ return (error);
+ if (new_eee_enabled == adapter->eee_enabled)
+ return (0);
+
+ if (new_eee_enabled > 0 && !adapter->eee_support)
+ return (ENODEV);
+ else
+ adapter->eee_enabled = !!(new_eee_enabled);
+
+ /* Re-initialize hardware if it's already running */
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ ixgbe_init(adapter);
+
+ return (0);
+}
+
+/*
+ * Read-only sysctl indicating whether EEE support was negotiated
+ * on the link.
+ */
+static int
+ixgbe_sysctl_eee_negotiated(SYSCTL_HANDLER_ARGS)
+{
+ struct adapter *adapter = (struct adapter *) arg1;
+ struct ixgbe_hw *hw = &adapter->hw;
+ bool status;
+
+ status = !!(IXGBE_READ_REG(hw, IXGBE_EEE_STAT) & IXGBE_EEE_STAT_NEG);
+
+ return (sysctl_handle_int(oidp, 0, status, req));
+}
+
+/*
+ * Read-only sysctl indicating whether RX Link is in LPI state.
+ */
+static int
+ixgbe_sysctl_eee_rx_lpi_status(SYSCTL_HANDLER_ARGS)
+{
+ struct adapter *adapter = (struct adapter *) arg1;
+ struct ixgbe_hw *hw = &adapter->hw;
+ bool status;
+
+ status = !!(IXGBE_READ_REG(hw, IXGBE_EEE_STAT) &
+ IXGBE_EEE_RX_LPI_STATUS);
+
+ return (sysctl_handle_int(oidp, 0, status, req));
+}
+
+/*
+ * Read-only sysctl indicating whether TX Link is in LPI state.
+ */
+static int
+ixgbe_sysctl_eee_tx_lpi_status(SYSCTL_HANDLER_ARGS)
+{
+ struct adapter *adapter = (struct adapter *) arg1;
+ struct ixgbe_hw *hw = &adapter->hw;
+ bool status;
+
+ status = !!(IXGBE_READ_REG(hw, IXGBE_EEE_STAT) &
+ IXGBE_EEE_TX_LPI_STATUS);
+
+ return (sysctl_handle_int(oidp, 0, status, req));
+}
+
+/*
+ * Sysctl to enable/disable the types of packets that the
+ * adapter will wake up on upon receipt.
+ * WUFC - Wake Up Filter Control
+ * Flags:
+ * 0x1 - Link Status Change
+ * 0x2 - Magic Packet
+ * 0x4 - Direct Exact
+ * 0x8 - Directed Multicast
+ * 0x10 - Broadcast
+ * 0x20 - ARP/IPv4 Request Packet
+ * 0x40 - Direct IPv4 Packet
+ * 0x80 - Direct IPv6 Packet
+ *
+ * Setting another flag will cause the sysctl to return an
+ * error.
+ */
+static int
+ixgbe_sysctl_wufc(SYSCTL_HANDLER_ARGS)
+{
+ struct adapter *adapter = (struct adapter *) arg1;
+ int error = 0;
+ u32 new_wufc;
+
+ new_wufc = adapter->wufc;
+
+ error = sysctl_handle_int(oidp, &new_wufc, 0, req);
+ if ((error) || (req->newptr == NULL))
+ return (error);
+ if (new_wufc == adapter->wufc)
+ return (0);
+
+ if (new_wufc & 0xffffff00)
+ return (EINVAL);
+ else {
+ new_wufc &= 0xff;
+ new_wufc |= (0xffffff & adapter->wufc);
+ adapter->wufc = new_wufc;
+ }
+
+ return (0);
+}
+
+/*
** Enable the hardware to drop packets when the buffer is
** full. This is useful when multiqueue,so that no single
** queue being full stalls the entire RX engine. We only
@@ -4154,6 +4782,7 @@ ixgbe_rearm_queues(struct adapter *adapter, u64 queues)
case ixgbe_mac_82599EB:
case ixgbe_mac_X540:
case ixgbe_mac_X550:
+ case ixgbe_mac_X550EM_x:
mask = (queues & 0xFFFFFFFF);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS_EX(0), mask);
mask = (queues >> 32);
diff --git a/sys/dev/ixgbe/if_ixv.c b/sys/dev/ixgbe/if_ixv.c
index 672077b78b6d..a550a856e6f8 100644
--- a/sys/dev/ixgbe/if_ixv.c
+++ b/sys/dev/ixgbe/if_ixv.c
@@ -60,7 +60,6 @@ static ixgbe_vendor_info_t ixv_vendor_info_array[] =
{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_VF, 0, 0, 0},
{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X540_VF, 0, 0, 0},
{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550_VF, 0, 0, 0},
- {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_VF, 0, 0, 0},
{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_VF, 0, 0, 0},
/* required last entry */
{0, 0, 0, 0, 0}
@@ -882,7 +881,7 @@ ixv_msix_mbx(void *arg)
struct ixgbe_hw *hw = &adapter->hw;
u32 reg;
- ++adapter->vector_irq;
+ ++adapter->link_irq;
/* First get the cause */
reg = IXGBE_READ_REG(hw, IXGBE_VTEICS);
@@ -2034,8 +2033,8 @@ ixv_add_stats_sysctls(struct adapter *adapter)
SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_packets",
CTLFLAG_RD, &(txr->total_packets),
"TX Packets");
- SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_bytes",
- CTLFLAG_RD, &(txr->tx_bytes),
+ SYSCTL_ADD_UINT(ctx, queue_list, OID_AUTO, "tx_bytes",
+ CTLFLAG_RD, &(txr->bytes), 0,
"TX Bytes");
SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_no_desc",
CTLFLAG_RD, &(txr->no_desc_avail),
@@ -2083,7 +2082,7 @@ ixv_print_debug_info(struct adapter *adapter)
}
device_printf(dev,"MBX IRQ Handled: %lu\n",
- (long)adapter->vector_irq);
+ (long)adapter->link_irq);
return;
}
diff --git a/sys/dev/ixgbe/ix_txrx.c b/sys/dev/ixgbe/ix_txrx.c
index 6c9c84a0d03d..bfe16070e374 100644
--- a/sys/dev/ixgbe/ix_txrx.c
+++ b/sys/dev/ixgbe/ix_txrx.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2014, Intel Corporation
+ Copyright (c) 2001-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -210,7 +210,11 @@ ixgbe_mq_start(struct ifnet *ifp, struct mbuf *m)
* If everything is setup correctly, it should be the
* same bucket that the current CPU we're on is.
*/
+#if __FreeBSD_version < 1100054
+ if (m->m_flags & M_FLOWID) {
+#else
if (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE) {
+#endif
#ifdef RSS
if (rss_hash2bucket(m->m_pkthdr.flowid,
M_HASHTYPE_GET(m), &bucket_id) == 0)
@@ -276,7 +280,12 @@ ixgbe_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr)
enqueued++;
#if 0 // this is VF-only
#if __FreeBSD_version >= 1100036
- if (next->m_flags & M_MCAST)
+ /*
+ * Since we're looking at the tx ring, we can check
+ * to see if we're a VF by examing our tail register
+ * address.
+ */
+ if (txr->tail < IXGBE_TDT(0) && next->m_flags & M_MCAST)
if_inc_counter(ifp, IFCOUNTER_OMCASTS, 1);
#endif
#endif
@@ -312,8 +321,8 @@ ixgbe_deferred_mq_start(void *arg, int pending)
}
/*
-** Flush all ring buffers
-*/
+ * Flush all ring buffers
+ */
void
ixgbe_qflush(struct ifnet *ifp)
{
@@ -387,6 +396,10 @@ retry:
/* Try it again? - one try */
if (remap == TRUE) {
remap = FALSE;
+ /*
+ * XXX: m_defrag will choke on
+ * non-MCLBYTES-sized clusters
+ */
m = m_defrag(*m_headp, M_NOWAIT);
if (m == NULL) {
adapter->mbuf_defrag_failed++;
@@ -418,9 +431,9 @@ retry:
m_head = *m_headp;
/*
- ** Set up the appropriate offload context
- ** this will consume the first descriptor
- */
+ * Set up the appropriate offload context
+ * this will consume the first descriptor
+ */
error = ixgbe_tx_ctx_setup(txr, m_head, &cmd_type_len, &olinfo_status);
if (__predict_false(error)) {
if (error == ENOBUFS)
@@ -439,7 +452,6 @@ retry:
}
#endif
- olinfo_status |= IXGBE_ADVTXD_CC;
i = txr->next_avail_desc;
for (j = 0; j < nsegs; j++) {
bus_size_t seglen;
@@ -466,11 +478,11 @@ retry:
txbuf->m_head = m_head;
/*
- ** Here we swap the map so the last descriptor,
- ** which gets the completion interrupt has the
- ** real map, and the first descriptor gets the
- ** unused map from this descriptor.
- */
+ * Here we swap the map so the last descriptor,
+ * which gets the completion interrupt has the
+ * real map, and the first descriptor gets the
+ * unused map from this descriptor.
+ */
txr->tx_buffers[first].map = txbuf->map;
txbuf->map = map;
bus_dmamap_sync(txr->txtag, map, BUS_DMASYNC_PREWRITE);
@@ -493,7 +505,6 @@ retry:
txr->busy = 1;
return (0);
-
}
@@ -732,6 +743,7 @@ static int
ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp,
u32 *cmd_type_len, u32 *olinfo_status)
{
+ struct adapter *adapter = txr->adapter;
struct ixgbe_adv_tx_context_desc *TXD;
struct ether_vlan_header *eh;
struct ip *ip;
@@ -766,6 +778,8 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp,
vtag = htole16(mp->m_pkthdr.ether_vtag);
vlan_macip_lens |= (vtag << IXGBE_ADVTXD_VLAN_SHIFT);
}
+ else if (!IXGBE_IS_X550VF(adapter) && (offload == FALSE))
+ return (0);
/*
* Determine where frame payload starts.
@@ -1727,9 +1741,6 @@ ixgbe_rx_discard(struct rx_ring *rxr, int i)
* the mbufs in the descriptor and sends data which has been
* dma'ed into host memory to upper layer.
*
- * We loop at most count times if count is > 0, or until done if
- * count < 0.
- *
* Return TRUE for more work, FALSE for all clean.
*********************************************************************/
bool
@@ -1792,10 +1803,9 @@ ixgbe_rxeof(struct ix_queue *que)
/* Make sure bad packets are discarded */
if (eop && (staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK) != 0) {
-#if 0 // VF-only
#if __FreeBSD_version >= 1100036
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
-#endif
+ if (IXGBE_IS_VF(adapter))
+ if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
#endif
rxr->rx_discarded++;
ixgbe_rx_discard(rxr, i);
@@ -1906,6 +1916,9 @@ ixgbe_rxeof(struct ix_queue *que)
#ifdef RSS
sendmp->m_pkthdr.flowid =
le32toh(cur->wb.lower.hi_dword.rss);
+#if __FreeBSD_version < 1100054
+ sendmp->m_flags |= M_FLOWID;
+#endif
switch (pkt_info & IXGBE_RXDADV_RSSTYPE_MASK) {
case IXGBE_RXDADV_RSSTYPE_IPV4_TCP:
M_HASHTYPE_SET(sendmp, M_HASHTYPE_RSS_TCP_IPV4);
@@ -1939,7 +1952,11 @@ ixgbe_rxeof(struct ix_queue *que)
}
#else /* RSS */
sendmp->m_pkthdr.flowid = que->msix;
+#if __FreeBSD_version >= 1100054
M_HASHTYPE_SET(sendmp, M_HASHTYPE_OPAQUE);
+#else
+ sendmp->m_flags |= M_FLOWID;
+#endif
#endif /* RSS */
#endif /* FreeBSD_version */
}
diff --git a/sys/dev/ixgbe/ixgbe.h b/sys/dev/ixgbe/ixgbe.h
index 813ee4f54130..44e7c3c26802 100644
--- a/sys/dev/ixgbe/ixgbe.h
+++ b/sys/dev/ixgbe/ixgbe.h
@@ -90,8 +90,11 @@
#include <sys/pcpu.h>
#include <sys/smp.h>
#include <machine/smp.h>
+#include <sys/sbuf.h>
#include "ixgbe_api.h"
+#include "ixgbe_common.h"
+#include "ixgbe_phy.h"
#include "ixgbe_vf.h"
/* Tunables */
@@ -146,7 +149,11 @@
#define IXGBE_TX_CLEANUP_THRESHOLD (adapter->num_tx_desc / 8)
#define IXGBE_TX_OP_THRESHOLD (adapter->num_tx_desc / 32)
-#define IXGBE_MAX_FRAME_SIZE 0x3F00
+/* These defines are used in MTU calculations */
+#define IXGBE_MAX_FRAME_SIZE 9728
+#define IXGBE_MTU_HDR (ETHER_HDR_LEN + ETHER_CRC_LEN + \
+ ETHER_VLAN_ENCAP_LEN)
+#define IXGBE_MAX_MTU (IXGBE_MAX_FRAME_SIZE - IXGBE_MTU_HDR)
/* Flow control constants */
#define IXGBE_FC_PAUSE 0xFFFF
@@ -227,6 +234,17 @@
#define IXGBE_BULK_LATENCY 1200
#define IXGBE_LINK_ITR 2000
+/* MAC type macros */
+#define IXGBE_IS_X550VF(_adapter) \
+ ((_adapter->hw.mac.type == ixgbe_mac_X550_vf) || \
+ (_adapter->hw.mac.type == ixgbe_mac_X550EM_x_vf))
+
+#define IXGBE_IS_VF(_adapter) \
+ (IXGBE_IS_X550VF(_adapter) || \
+ (_adapter->hw.mac.type == ixgbe_mac_X540_vf) || \
+ (_adapter->hw.mac.type == ixgbe_mac_82599_vf))
+
+
/*
*****************************************************************************
* vendor_info_array
@@ -323,8 +341,8 @@ struct tx_ring {
u32 bytes; /* used for AIM */
u32 packets;
/* Soft Stats */
- u64 tx_bytes;
unsigned long tso_tx;
+ unsigned long no_tx_map_avail;
unsigned long no_tx_dma_setup;
u64 no_desc_avail;
u64 total_packets;
@@ -419,6 +437,13 @@ struct adapter {
u32 link_speed;
bool link_up;
u32 vector;
+ u16 dmac;
+ bool eee_support;
+ bool eee_enabled;
+
+ /* Power management-related */
+ bool wol_support;
+ u32 wufc;
/* Mbuf cluster size */
u32 rx_mbuf_sz;
@@ -432,6 +457,7 @@ struct adapter {
int fdir_reinit;
struct task fdir_task;
#endif
+ struct task phy_task; /* PHY intr tasklet */
struct taskqueue *tq;
/*
@@ -467,7 +493,7 @@ struct adapter {
unsigned long mbuf_header_failed;
unsigned long mbuf_packet_failed;
unsigned long watchdog_events;
- unsigned long vector_irq;
+ unsigned long link_irq;
union {
struct ixgbe_hw_stats pf;
struct ixgbevf_hw_stats vf;
@@ -540,12 +566,17 @@ struct adapter {
#define IXGBE_SET_IQDROPS(sc, count) (sc)->ifp->if_iqdrops = (count)
#endif
+/* External PHY register addresses */
+#define IXGBE_PHY_CURRENT_TEMP 0xC820
+#define IXGBE_PHY_OVERTEMP_STATUS 0xC830
+
/* Sysctl help messages; displayed with sysctl -d */
#define IXGBE_SYSCTL_DESC_ADV_SPEED \
"\nControl advertised link speed using these flags:\n" \
"\t0x1 - advertise 100M\n" \
"\t0x2 - advertise 1G\n" \
- "\t0x4 - advertise 10G"
+ "\t0x4 - advertise 10G\n\n" \
+ "\t100M is only supported on certain 10GBaseT adapters.\n"
#define IXGBE_SYSCTL_DESC_SET_FC \
"\nSet flow control mode using these values:\n" \
diff --git a/sys/dev/ixgbe/ixgbe_82598.c b/sys/dev/ixgbe/ixgbe_82598.c
index d9b8985aae95..46e64c537ecf 100644
--- a/sys/dev/ixgbe/ixgbe_82598.c
+++ b/sys/dev/ixgbe/ixgbe_82598.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2014, Intel Corporation
+ Copyright (c) 2001-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -260,6 +260,8 @@ s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw)
DEBUGFUNC("ixgbe_start_hw_82598");
ret_val = ixgbe_start_hw_generic(hw);
+ if (ret_val)
+ return ret_val;
/* Disable relaxed ordering */
for (i = 0; ((i < hw->mac.max_tx_queues) &&
@@ -278,8 +280,7 @@ s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw)
}
/* set the completion timeout for interface */
- if (ret_val == IXGBE_SUCCESS)
- ixgbe_set_pcie_completion_timeout(hw);
+ ixgbe_set_pcie_completion_timeout(hw);
return ret_val;
}
diff --git a/sys/dev/ixgbe/ixgbe_82598.h b/sys/dev/ixgbe/ixgbe_82598.h
index 621be4179294..d2241c70cd14 100644
--- a/sys/dev/ixgbe/ixgbe_82598.h
+++ b/sys/dev/ixgbe/ixgbe_82598.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2014, Intel Corporation
+ Copyright (c) 2001-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/sys/dev/ixgbe/ixgbe_82599.c b/sys/dev/ixgbe/ixgbe_82599.c
index d49d8513870a..b38620f01982 100644
--- a/sys/dev/ixgbe/ixgbe_82599.c
+++ b/sys/dev/ixgbe/ixgbe_82599.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2014, Intel Corporation
+ Copyright (c) 2001-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -421,6 +421,8 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
/* Check if 1G SFP module. */
if (hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 ||
hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 ||
+ hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 ||
+ hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 ||
hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1) {
*speed = IXGBE_LINK_SPEED_1GB_FULL;
@@ -1803,7 +1805,6 @@ s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw,
switch (hw->mac.type) {
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
- case ixgbe_mac_X550EM_a:
IXGBE_WRITE_REG(hw, IXGBE_FDIRSCTPM, ~fdirtcpm);
break;
default:
@@ -2465,7 +2466,6 @@ reset_pipeline_out:
return ret_val;
}
-
/**
* ixgbe_read_i2c_byte_82599 - Reads 8 bit word over I2C
* @hw: pointer to hardware structure
diff --git a/sys/dev/ixgbe/ixgbe_82599.h b/sys/dev/ixgbe/ixgbe_82599.h
index 8c973ac58074..bcfb0431bc5b 100644
--- a/sys/dev/ixgbe/ixgbe_82599.h
+++ b/sys/dev/ixgbe/ixgbe_82599.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2014, Intel Corporation
+ Copyright (c) 2001-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/sys/dev/ixgbe/ixgbe_api.c b/sys/dev/ixgbe/ixgbe_api.c
index 253566420534..9784e3cdabb8 100644
--- a/sys/dev/ixgbe/ixgbe_api.c
+++ b/sys/dev/ixgbe/ixgbe_api.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2014, Intel Corporation
+ Copyright (c) 2001-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -35,6 +35,22 @@
#include "ixgbe_api.h"
#include "ixgbe_common.h"
+static const u32 ixgbe_mvals_base[IXGBE_MVALS_IDX_LIMIT] = {
+ IXGBE_MVALS_INIT()
+};
+
+static const u32 ixgbe_mvals_X540[IXGBE_MVALS_IDX_LIMIT] = {
+ IXGBE_MVALS_INIT(_X540)
+};
+
+static const u32 ixgbe_mvals_X550[IXGBE_MVALS_IDX_LIMIT] = {
+ IXGBE_MVALS_INIT(_X550)
+};
+
+static const u32 ixgbe_mvals_X550EM_x[IXGBE_MVALS_IDX_LIMIT] = {
+ IXGBE_MVALS_INIT(_X550EM_x)
+};
+
/**
* ixgbe_dcb_get_rtrup2tc - read rtrup2tc reg
* @hw: pointer to hardware structure
@@ -81,20 +97,16 @@ s32 ixgbe_init_shared_code(struct ixgbe_hw *hw)
case ixgbe_mac_X540:
status = ixgbe_init_ops_X540(hw);
break;
-#if 0 //JFV temporary disable
case ixgbe_mac_X550:
status = ixgbe_init_ops_X550(hw);
break;
case ixgbe_mac_X550EM_x:
- case ixgbe_mac_X550EM_a:
status = ixgbe_init_ops_X550EM(hw);
break;
-#endif
case ixgbe_mac_82599_vf:
case ixgbe_mac_X540_vf:
case ixgbe_mac_X550_vf:
case ixgbe_mac_X550EM_x_vf:
- case ixgbe_mac_X550EM_a_vf:
status = ixgbe_init_ops_vf(hw);
break;
default:
@@ -124,6 +136,8 @@ s32 ixgbe_set_mac_type(struct ixgbe_hw *hw)
return IXGBE_ERR_DEVICE_NOT_SUPPORTED;
}
+ hw->mvals = ixgbe_mvals_base;
+
switch (hw->device_id) {
case IXGBE_DEV_ID_82598:
case IXGBE_DEV_ID_82598_BX:
@@ -164,14 +178,17 @@ s32 ixgbe_set_mac_type(struct ixgbe_hw *hw)
case IXGBE_DEV_ID_X540_VF:
case IXGBE_DEV_ID_X540_VF_HV:
hw->mac.type = ixgbe_mac_X540_vf;
+ hw->mvals = ixgbe_mvals_X540;
break;
case IXGBE_DEV_ID_X540T:
case IXGBE_DEV_ID_X540T1:
case IXGBE_DEV_ID_X540_BYPASS:
hw->mac.type = ixgbe_mac_X540;
+ hw->mvals = ixgbe_mvals_X540;
break;
case IXGBE_DEV_ID_X550T:
hw->mac.type = ixgbe_mac_X550;
+ hw->mvals = ixgbe_mvals_X550;
break;
case IXGBE_DEV_ID_X550EM_X_KX4:
case IXGBE_DEV_ID_X550EM_X_KR:
@@ -179,21 +196,17 @@ s32 ixgbe_set_mac_type(struct ixgbe_hw *hw)
case IXGBE_DEV_ID_X550EM_X_1G_T:
case IXGBE_DEV_ID_X550EM_X_SFP:
hw->mac.type = ixgbe_mac_X550EM_x;
- break;
- case IXGBE_DEV_ID_X550EM_A_KR:
- hw->mac.type = ixgbe_mac_X550EM_a;
+ hw->mvals = ixgbe_mvals_X550EM_x;
break;
case IXGBE_DEV_ID_X550_VF:
case IXGBE_DEV_ID_X550_VF_HV:
hw->mac.type = ixgbe_mac_X550_vf;
+ hw->mvals = ixgbe_mvals_X550;
break;
case IXGBE_DEV_ID_X550EM_X_VF:
case IXGBE_DEV_ID_X550EM_X_VF_HV:
hw->mac.type = ixgbe_mac_X550EM_x_vf;
- break;
- case IXGBE_DEV_ID_X550EM_A_VF:
- case IXGBE_DEV_ID_X550EM_A_VF_HV:
- hw->mac.type = ixgbe_mac_X550EM_a_vf;
+ hw->mvals = ixgbe_mvals_X550EM_x;
break;
default:
ret_val = IXGBE_ERR_DEVICE_NOT_SUPPORTED;
@@ -1283,6 +1296,23 @@ s32 ixgbe_enter_lplu(struct ixgbe_hw *hw)
}
/**
+ * ixgbe_handle_lasi - Handle external Base T PHY interrupt
+ * @hw: pointer to hardware structure
+ *
+ * Handle external Base T PHY interrupt. If high temperature
+ * failure alarm then return error, else if link status change
+ * then setup internal/external PHY link
+ *
+ * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature
+ * failure alarm, else return PHY access status.
+ */
+s32 ixgbe_handle_lasi(struct ixgbe_hw *hw)
+{
+ return ixgbe_call_func(hw, hw->phy.ops.handle_lasi, (hw),
+ IXGBE_NOT_IMPLEMENTED);
+}
+
+/**
* ixgbe_read_analog_reg8 - Reads 8 bit analog register
* @hw: pointer to hardware structure
* @reg: analog register to read
@@ -1340,6 +1370,23 @@ s32 ixgbe_read_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr,
}
/**
+ * ixgbe_read_i2c_byte_unlocked - Reads 8 bit word via I2C from device address
+ * @hw: pointer to hardware structure
+ * @byte_offset: byte offset to read
+ * @dev_addr: I2C bus address to read from
+ * @data: value read
+ *
+ * Performs byte read operation to SFP module's EEPROM over I2C interface.
+ **/
+s32 ixgbe_read_i2c_byte_unlocked(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 dev_addr, u8 *data)
+{
+ return ixgbe_call_func(hw, hw->phy.ops.read_i2c_byte_unlocked,
+ (hw, byte_offset, dev_addr, data),
+ IXGBE_NOT_IMPLEMENTED);
+}
+
+/**
* ixgbe_read_i2c_combined - Perform I2C read combined operation
* @hw: pointer to the hardware structure
* @addr: I2C bus address to read from
@@ -1355,6 +1402,23 @@ s32 ixgbe_read_i2c_combined(struct ixgbe_hw *hw, u8 addr, u16 reg, u16 *val)
}
/**
+ * ixgbe_read_i2c_combined_unlocked - Perform I2C read combined operation
+ * @hw: pointer to the hardware structure
+ * @addr: I2C bus address to read from
+ * @reg: I2C device register to read from
+ * @val: pointer to location to receive read value
+ *
+ * Returns an error code on error.
+ **/
+s32 ixgbe_read_i2c_combined_unlocked(struct ixgbe_hw *hw, u8 addr, u16 reg,
+ u16 *val)
+{
+ return ixgbe_call_func(hw, hw->phy.ops.read_i2c_combined_unlocked,
+ (hw, addr, reg, val),
+ IXGBE_NOT_IMPLEMENTED);
+}
+
+/**
* ixgbe_write_i2c_byte - Writes 8 bit word over I2C
* @hw: pointer to hardware structure
* @byte_offset: byte offset to write
@@ -1372,6 +1436,24 @@ s32 ixgbe_write_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr,
}
/**
+ * ixgbe_write_i2c_byte_unlocked - Writes 8 bit word over I2C
+ * @hw: pointer to hardware structure
+ * @byte_offset: byte offset to write
+ * @dev_addr: I2C bus address to write to
+ * @data: value to write
+ *
+ * Performs byte write operation to SFP module's EEPROM over I2C interface
+ * at a specified device address.
+ **/
+s32 ixgbe_write_i2c_byte_unlocked(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 dev_addr, u8 data)
+{
+ return ixgbe_call_func(hw, hw->phy.ops.write_i2c_byte_unlocked,
+ (hw, byte_offset, dev_addr, data),
+ IXGBE_NOT_IMPLEMENTED);
+}
+
+/**
* ixgbe_write_i2c_combined - Perform I2C write combined operation
* @hw: pointer to the hardware structure
* @addr: I2C bus address to write to
@@ -1387,6 +1469,22 @@ s32 ixgbe_write_i2c_combined(struct ixgbe_hw *hw, u8 addr, u16 reg, u16 val)
}
/**
+ * ixgbe_write_i2c_combined_unlocked - Perform I2C write combined operation
+ * @hw: pointer to the hardware structure
+ * @addr: I2C bus address to write to
+ * @reg: I2C device register to write to
+ * @val: value to write
+ *
+ * Returns an error code on error.
+ **/
+s32 ixgbe_write_i2c_combined_unlocked(struct ixgbe_hw *hw, u8 addr, u16 reg,
+ u16 val)
+{
+ return ixgbe_call_func(hw, hw->phy.ops.write_i2c_combined_unlocked,
+ (hw, addr, reg, val), IXGBE_NOT_IMPLEMENTED);
+}
+
+/**
* ixgbe_write_i2c_eeprom - Writes 8 bit EEPROM word over I2C interface
* @hw: pointer to hardware structure
* @byte_offset: EEPROM byte offset to write
diff --git a/sys/dev/ixgbe/ixgbe_api.h b/sys/dev/ixgbe/ixgbe_api.h
index 650ae67947d9..8c2c4a8155cb 100644
--- a/sys/dev/ixgbe/ixgbe_api.h
+++ b/sys/dev/ixgbe/ixgbe_api.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2014, Intel Corporation
+ Copyright (c) 2001-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -173,10 +173,18 @@ u32 ixgbe_atr_compute_sig_hash_82599(union ixgbe_atr_hash_dword input,
bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw);
s32 ixgbe_read_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr,
u8 *data);
+s32 ixgbe_read_i2c_byte_unlocked(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 dev_addr, u8 *data);
s32 ixgbe_read_i2c_combined(struct ixgbe_hw *hw, u8 addr, u16 reg, u16 *val);
+s32 ixgbe_read_i2c_combined_unlocked(struct ixgbe_hw *hw, u8 addr, u16 reg,
+ u16 *val);
s32 ixgbe_write_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr,
u8 data);
+s32 ixgbe_write_i2c_byte_unlocked(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 dev_addr, u8 data);
s32 ixgbe_write_i2c_combined(struct ixgbe_hw *hw, u8 addr, u16 reg, u16 val);
+s32 ixgbe_write_i2c_combined_unlocked(struct ixgbe_hw *hw, u8 addr, u16 reg,
+ u16 val);
s32 ixgbe_write_i2c_eeprom(struct ixgbe_hw *hw, u8 byte_offset, u8 eeprom_data);
s32 ixgbe_get_san_mac_addr(struct ixgbe_hw *hw, u8 *san_mac_addr);
s32 ixgbe_set_san_mac_addr(struct ixgbe_hw *hw, u8 *san_mac_addr);
@@ -203,6 +211,7 @@ void ixgbe_enable_mdd(struct ixgbe_hw *hw);
void ixgbe_mdd_event(struct ixgbe_hw *hw, u32 *vf_bitmap);
void ixgbe_restore_mdd_vf(struct ixgbe_hw *hw, u32 vf);
s32 ixgbe_enter_lplu(struct ixgbe_hw *hw);
+s32 ixgbe_handle_lasi(struct ixgbe_hw *hw);
void ixgbe_set_rate_select_speed(struct ixgbe_hw *hw, ixgbe_link_speed speed);
void ixgbe_disable_rx(struct ixgbe_hw *hw);
void ixgbe_enable_rx(struct ixgbe_hw *hw);
diff --git a/sys/dev/ixgbe/ixgbe_common.c b/sys/dev/ixgbe/ixgbe_common.c
index 57fe1b589757..f0a07760bad1 100644
--- a/sys/dev/ixgbe/ixgbe_common.c
+++ b/sys/dev/ixgbe/ixgbe_common.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2014, Intel Corporation
+ Copyright (c) 2001-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -188,6 +188,7 @@ bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)
case IXGBE_DEV_ID_X540T1:
case IXGBE_DEV_ID_X540_BYPASS:
case IXGBE_DEV_ID_X550T:
+ case IXGBE_DEV_ID_X550EM_X_10G_T:
supported = TRUE;
break;
default:
@@ -1090,7 +1091,7 @@ s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw)
msec_delay(2);
/*
- * Prevent the PCI-E bus from from hanging by disabling PCI-E master
+ * Prevent the PCI-E bus from hanging by disabling PCI-E master
* access and verify no pending requests
*/
return ixgbe_disable_pcie_master(hw);
@@ -3573,7 +3574,6 @@ u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw)
case ixgbe_mac_X540:
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
- case ixgbe_mac_X550EM_a:
pcie_offset = IXGBE_PCIE_MSIX_82599_CAPS;
max_msix_count = IXGBE_MAX_MSIX_VECTORS_82599;
break;
diff --git a/sys/dev/ixgbe/ixgbe_common.h b/sys/dev/ixgbe/ixgbe_common.h
index 94c7f975372d..e685f5b32a39 100644
--- a/sys/dev/ixgbe/ixgbe_common.h
+++ b/sys/dev/ixgbe/ixgbe_common.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2014, Intel Corporation
+ Copyright (c) 2001-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/sys/dev/ixgbe/ixgbe_dcb.c b/sys/dev/ixgbe/ixgbe_dcb.c
index 6f848e7546a0..3659d179712b 100644
--- a/sys/dev/ixgbe/ixgbe_dcb.c
+++ b/sys/dev/ixgbe/ixgbe_dcb.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2014, Intel Corporation
+ Copyright (c) 2001-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -396,7 +396,6 @@ s32 ixgbe_dcb_get_tc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats,
case ixgbe_mac_X540:
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
- case ixgbe_mac_X550EM_a:
#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
ret = ixgbe_dcb_get_tc_stats_82599(hw, stats, tc_count);
break;
@@ -427,7 +426,6 @@ s32 ixgbe_dcb_get_pfc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats,
case ixgbe_mac_X540:
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
- case ixgbe_mac_X550EM_a:
#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
ret = ixgbe_dcb_get_pfc_stats_82599(hw, stats, tc_count);
break;
@@ -469,7 +467,6 @@ s32 ixgbe_dcb_config_rx_arbiter_cee(struct ixgbe_hw *hw,
case ixgbe_mac_X540:
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
- case ixgbe_mac_X550EM_a:
#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
ret = ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwgid,
tsa, map);
@@ -511,7 +508,6 @@ s32 ixgbe_dcb_config_tx_desc_arbiter_cee(struct ixgbe_hw *hw,
case ixgbe_mac_X540:
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
- case ixgbe_mac_X550EM_a:
#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
ret = ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max,
bwgid, tsa);
@@ -555,7 +551,6 @@ s32 ixgbe_dcb_config_tx_data_arbiter_cee(struct ixgbe_hw *hw,
case ixgbe_mac_X540:
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
- case ixgbe_mac_X550EM_a:
#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
ret = ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max,
bwgid, tsa,
@@ -593,7 +588,6 @@ s32 ixgbe_dcb_config_pfc_cee(struct ixgbe_hw *hw,
case ixgbe_mac_X540:
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
- case ixgbe_mac_X550EM_a:
#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en, map);
break;
@@ -622,7 +616,6 @@ s32 ixgbe_dcb_config_tc_stats(struct ixgbe_hw *hw)
case ixgbe_mac_X540:
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
- case ixgbe_mac_X550EM_a:
#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
ret = ixgbe_dcb_config_tc_stats_82599(hw, NULL);
break;
@@ -670,7 +663,6 @@ s32 ixgbe_dcb_hw_config_cee(struct ixgbe_hw *hw,
case ixgbe_mac_X540:
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
- case ixgbe_mac_X550EM_a:
#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
ixgbe_dcb_config_82599(hw, dcb_config);
ret = ixgbe_dcb_hw_config_82599(hw, dcb_config->link_speed,
@@ -705,7 +697,6 @@ s32 ixgbe_dcb_config_pfc(struct ixgbe_hw *hw, u8 pfc_en, u8 *map)
case ixgbe_mac_X540:
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
- case ixgbe_mac_X550EM_a:
#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en, map);
break;
@@ -731,7 +722,6 @@ s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw, u16 *refill, u16 *max,
case ixgbe_mac_X540:
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
- case ixgbe_mac_X550EM_a:
#if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT)
ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwg_id,
tsa, map);
diff --git a/sys/dev/ixgbe/ixgbe_dcb.h b/sys/dev/ixgbe/ixgbe_dcb.h
index 878bbf82f93c..871b7842e30c 100644
--- a/sys/dev/ixgbe/ixgbe_dcb.h
+++ b/sys/dev/ixgbe/ixgbe_dcb.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2014, Intel Corporation
+ Copyright (c) 2001-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/sys/dev/ixgbe/ixgbe_dcb_82598.c b/sys/dev/ixgbe/ixgbe_dcb_82598.c
index a5a090d5e8a6..fb946c94097c 100644
--- a/sys/dev/ixgbe/ixgbe_dcb_82598.c
+++ b/sys/dev/ixgbe/ixgbe_dcb_82598.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2014, Intel Corporation
+ Copyright (c) 2001-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/sys/dev/ixgbe/ixgbe_dcb_82598.h b/sys/dev/ixgbe/ixgbe_dcb_82598.h
index 47f19f656553..35974f709e02 100644
--- a/sys/dev/ixgbe/ixgbe_dcb_82598.h
+++ b/sys/dev/ixgbe/ixgbe_dcb_82598.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2014, Intel Corporation
+ Copyright (c) 2001-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/sys/dev/ixgbe/ixgbe_dcb_82599.c b/sys/dev/ixgbe/ixgbe_dcb_82599.c
index 0232d3c578d9..4443411f4be3 100644
--- a/sys/dev/ixgbe/ixgbe_dcb_82599.c
+++ b/sys/dev/ixgbe/ixgbe_dcb_82599.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2014, Intel Corporation
+ Copyright (c) 2001-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/sys/dev/ixgbe/ixgbe_dcb_82599.h b/sys/dev/ixgbe/ixgbe_dcb_82599.h
index 7702dc9f662e..bab7628ecf43 100644
--- a/sys/dev/ixgbe/ixgbe_dcb_82599.h
+++ b/sys/dev/ixgbe/ixgbe_dcb_82599.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2014, Intel Corporation
+ Copyright (c) 2001-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/sys/dev/ixgbe/ixgbe_mbx.c b/sys/dev/ixgbe/ixgbe_mbx.c
index 067bba0a018d..d8ba55a0638f 100644
--- a/sys/dev/ixgbe/ixgbe_mbx.c
+++ b/sys/dev/ixgbe/ixgbe_mbx.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2014, Intel Corporation
+ Copyright (c) 2001-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -607,7 +607,6 @@ static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number)
break;
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
- case ixgbe_mac_X550EM_a:
case ixgbe_mac_X540:
vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset));
break;
@@ -745,7 +744,6 @@ void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
if (hw->mac.type != ixgbe_mac_82599EB &&
hw->mac.type != ixgbe_mac_X550 &&
hw->mac.type != ixgbe_mac_X550EM_x &&
- hw->mac.type != ixgbe_mac_X550EM_a &&
hw->mac.type != ixgbe_mac_X540)
return;
diff --git a/sys/dev/ixgbe/ixgbe_mbx.h b/sys/dev/ixgbe/ixgbe_mbx.h
index 2cffb8af6912..ea75cbeeb5a6 100644
--- a/sys/dev/ixgbe/ixgbe_mbx.h
+++ b/sys/dev/ixgbe/ixgbe_mbx.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2014, Intel Corporation
+ Copyright (c) 2001-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/sys/dev/ixgbe/ixgbe_osdep.h b/sys/dev/ixgbe/ixgbe_osdep.h
index ebb55f45b9e8..95f6ed5c45ac 100644
--- a/sys/dev/ixgbe/ixgbe_osdep.h
+++ b/sys/dev/ixgbe/ixgbe_osdep.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2013, Intel Corporation
+ Copyright (c) 2001-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -108,13 +108,14 @@
#define UNREFERENCED_3PARAMETER(_p, _q, _r)
#define UNREFERENCED_4PARAMETER(_p, _q, _r, _s)
-
#define IXGBE_NTOHL(_i) ntohl(_i)
#define IXGBE_NTOHS(_i) ntohs(_i)
/* XXX these need to be revisited */
-#define IXGBE_CPU_TO_LE32 le32toh
-#define IXGBE_LE32_TO_CPUS le32dec
+#define IXGBE_CPU_TO_LE32 htole32
+#define IXGBE_LE32_TO_CPUS(x)
+#define IXGBE_CPU_TO_BE16 htobe16
+#define IXGBE_CPU_TO_BE32 htobe32
typedef uint8_t u8;
typedef int8_t s8;
diff --git a/sys/dev/ixgbe/ixgbe_phy.c b/sys/dev/ixgbe/ixgbe_phy.c
index 5ac719ce9a6f..88206c7f9cb1 100644
--- a/sys/dev/ixgbe/ixgbe_phy.c
+++ b/sys/dev/ixgbe/ixgbe_phy.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2014, Intel Corporation
+ Copyright (c) 2001-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -101,16 +101,17 @@ static u8 ixgbe_ones_comp_byte_add(u8 add1, u8 add2)
}
/**
- * ixgbe_read_i2c_combined_generic - Perform I2C read combined operation
+ * ixgbe_read_i2c_combined_generic_int - Perform I2C read combined operation
* @hw: pointer to the hardware structure
* @addr: I2C bus address to read from
* @reg: I2C device register to read from
* @val: pointer to location to receive read value
+ * @lock: TRUE if to take and release semaphore
*
* Returns an error code on error.
*/
-static s32 ixgbe_read_i2c_combined_generic(struct ixgbe_hw *hw, u8 addr,
- u16 reg, u16 *val)
+static s32 ixgbe_read_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr,
+ u16 reg, u16 *val, bool lock)
{
u32 swfw_mask = hw->phy.phy_semaphore_mask;
int max_retry = 10;
@@ -121,11 +122,13 @@ static s32 ixgbe_read_i2c_combined_generic(struct ixgbe_hw *hw, u8 addr,
u8 reg_high;
u8 csum;
+ if (hw->mac.type >= ixgbe_mac_X550)
+ max_retry = 3;
reg_high = ((reg >> 7) & 0xFE) | 1; /* Indicate read combined */
csum = ixgbe_ones_comp_byte_add(reg_high, reg & 0xFF);
csum = ~csum;
do {
- if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
+ if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
return IXGBE_ERR_SWFW_SYNC;
ixgbe_i2c_start(hw);
/* Device Address and write indication */
@@ -158,13 +161,15 @@ static s32 ixgbe_read_i2c_combined_generic(struct ixgbe_hw *hw, u8 addr,
if (ixgbe_clock_out_i2c_bit(hw, FALSE))
goto fail;
ixgbe_i2c_stop(hw);
- hw->mac.ops.release_swfw_sync(hw, swfw_mask);
+ if (lock)
+ hw->mac.ops.release_swfw_sync(hw, swfw_mask);
*val = (high_bits << 8) | low_bits;
return 0;
fail:
ixgbe_i2c_bus_clear(hw);
- hw->mac.ops.release_swfw_sync(hw, swfw_mask);
+ if (lock)
+ hw->mac.ops.release_swfw_sync(hw, swfw_mask);
retry++;
if (retry < max_retry)
DEBUGOUT("I2C byte read combined error - Retrying.\n");
@@ -176,17 +181,50 @@ fail:
}
/**
- * ixgbe_write_i2c_combined_generic - Perform I2C write combined operation
+ * ixgbe_read_i2c_combined_generic - Perform I2C read combined operation
+ * @hw: pointer to the hardware structure
+ * @addr: I2C bus address to read from
+ * @reg: I2C device register to read from
+ * @val: pointer to location to receive read value
+ *
+ * Returns an error code on error.
+ **/
+static s32 ixgbe_read_i2c_combined_generic(struct ixgbe_hw *hw, u8 addr,
+ u16 reg, u16 *val)
+{
+ return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, TRUE);
+}
+
+/**
+ * ixgbe_read_i2c_combined_generic_unlocked - Do I2C read combined operation
+ * @hw: pointer to the hardware structure
+ * @addr: I2C bus address to read from
+ * @reg: I2C device register to read from
+ * @val: pointer to location to receive read value
+ *
+ * Returns an error code on error.
+ **/
+static s32
+ixgbe_read_i2c_combined_generic_unlocked(struct ixgbe_hw *hw, u8 addr,
+ u16 reg, u16 *val)
+{
+ return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, FALSE);
+}
+
+/**
+ * ixgbe_write_i2c_combined_generic_int - Perform I2C write combined operation
* @hw: pointer to the hardware structure
* @addr: I2C bus address to write to
* @reg: I2C device register to write to
* @val: value to write
+ * @lock: TRUE if to take and release semaphore
*
* Returns an error code on error.
*/
-static s32 ixgbe_write_i2c_combined_generic(struct ixgbe_hw *hw,
- u8 addr, u16 reg, u16 val)
+static s32 ixgbe_write_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr,
+ u16 reg, u16 val, bool lock)
{
+ u32 swfw_mask = hw->phy.phy_semaphore_mask;
int max_retry = 1;
int retry = 0;
u8 reg_high;
@@ -198,6 +236,8 @@ static s32 ixgbe_write_i2c_combined_generic(struct ixgbe_hw *hw,
csum = ixgbe_ones_comp_byte_add(csum, val & 0xFF);
csum = ~csum;
do {
+ if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
+ return IXGBE_ERR_SWFW_SYNC;
ixgbe_i2c_start(hw);
/* Device Address and write indication */
if (ixgbe_out_i2c_byte_ack(hw, addr))
@@ -218,10 +258,14 @@ static s32 ixgbe_write_i2c_combined_generic(struct ixgbe_hw *hw,
if (ixgbe_out_i2c_byte_ack(hw, csum))
goto fail;
ixgbe_i2c_stop(hw);
+ if (lock)
+ hw->mac.ops.release_swfw_sync(hw, swfw_mask);
return 0;
fail:
ixgbe_i2c_bus_clear(hw);
+ if (lock)
+ hw->mac.ops.release_swfw_sync(hw, swfw_mask);
retry++;
if (retry < max_retry)
DEBUGOUT("I2C byte write combined error - Retrying.\n");
@@ -233,6 +277,37 @@ fail:
}
/**
+ * ixgbe_write_i2c_combined_generic - Perform I2C write combined operation
+ * @hw: pointer to the hardware structure
+ * @addr: I2C bus address to write to
+ * @reg: I2C device register to write to
+ * @val: value to write
+ *
+ * Returns an error code on error.
+ **/
+static s32 ixgbe_write_i2c_combined_generic(struct ixgbe_hw *hw,
+ u8 addr, u16 reg, u16 val)
+{
+ return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, TRUE);
+}
+
+/**
+ * ixgbe_write_i2c_combined_generic_unlocked - Do I2C write combined operation
+ * @hw: pointer to the hardware structure
+ * @addr: I2C bus address to write to
+ * @reg: I2C device register to write to
+ * @val: value to write
+ *
+ * Returns an error code on error.
+ **/
+static s32
+ixgbe_write_i2c_combined_generic_unlocked(struct ixgbe_hw *hw,
+ u8 addr, u16 reg, u16 val)
+{
+ return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, FALSE);
+}
+
+/**
* ixgbe_init_phy_ops_generic - Inits PHY function ptrs
* @hw: pointer to the hardware structure
*
@@ -265,6 +340,13 @@ s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw)
phy->sfp_type = ixgbe_sfp_type_unknown;
phy->ops.read_i2c_combined = ixgbe_read_i2c_combined_generic;
phy->ops.write_i2c_combined = ixgbe_write_i2c_combined_generic;
+ phy->ops.read_i2c_combined_unlocked =
+ ixgbe_read_i2c_combined_generic_unlocked;
+ phy->ops.write_i2c_combined_unlocked =
+ ixgbe_write_i2c_combined_generic_unlocked;
+ phy->ops.read_i2c_byte_unlocked = ixgbe_read_i2c_byte_generic_unlocked;
+ phy->ops.write_i2c_byte_unlocked =
+ ixgbe_write_i2c_byte_generic_unlocked;
phy->ops.check_overtemp = ixgbe_tn_check_overtemp;
return IXGBE_SUCCESS;
}
@@ -1363,6 +1445,13 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
else
hw->phy.sfp_type =
ixgbe_sfp_type_1g_sx_core1;
+ } else if (comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) {
+ if (hw->bus.lan_id == 0)
+ hw->phy.sfp_type =
+ ixgbe_sfp_type_1g_lx_core0;
+ else
+ hw->phy.sfp_type =
+ ixgbe_sfp_type_1g_lx_core1;
} else {
hw->phy.sfp_type = ixgbe_sfp_type_unknown;
}
@@ -1450,6 +1539,8 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
if (comp_codes_10g == 0 &&
!(hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 ||
hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 ||
+ hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 ||
+ hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 ||
hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) {
hw->phy.type = ixgbe_phy_sfp_unsupported;
@@ -1467,6 +1558,8 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP) &&
!(hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0 ||
hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core1 ||
+ hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 ||
+ hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 ||
hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) {
/* Make sure we're a supported PHY type */
@@ -1600,6 +1693,9 @@ s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw)
goto out;
}
+ /* LAN ID is needed for I2C access */
+ hw->mac.ops.set_lan_id(hw);
+
status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_IDENTIFIER,
&identifier);
@@ -1614,9 +1710,6 @@ s32 ixgbe_identify_qsfp_module_generic(struct ixgbe_hw *hw)
hw->phy.id = identifier;
- /* LAN ID is needed for sfp_type determination */
- hw->mac.ops.set_lan_id(hw);
-
status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_QSFP_10GBE_COMP,
&comp_codes_10g);
@@ -1804,10 +1897,12 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
* SR modules
*/
if (sfp_type == ixgbe_sfp_type_da_act_lmt_core0 ||
+ sfp_type == ixgbe_sfp_type_1g_lx_core0 ||
sfp_type == ixgbe_sfp_type_1g_cu_core0 ||
sfp_type == ixgbe_sfp_type_1g_sx_core0)
sfp_type = ixgbe_sfp_type_srlr_core0;
else if (sfp_type == ixgbe_sfp_type_da_act_lmt_core1 ||
+ sfp_type == ixgbe_sfp_type_1g_lx_core1 ||
sfp_type == ixgbe_sfp_type_1g_cu_core1 ||
sfp_type == ixgbe_sfp_type_1g_sx_core1)
sfp_type = ixgbe_sfp_type_srlr_core1;
@@ -1932,16 +2027,17 @@ static bool ixgbe_is_sfp_probe(struct ixgbe_hw *hw, u8 offset, u8 addr)
}
/**
- * ixgbe_read_i2c_byte_generic - Reads 8 bit word over I2C
+ * ixgbe_read_i2c_byte_generic_int - Reads 8 bit word over I2C
* @hw: pointer to hardware structure
* @byte_offset: byte offset to read
* @data: value read
+ * @lock: TRUE if to take and release semaphore
*
* Performs byte read operation to SFP module's EEPROM over I2C interface at
* a specified device address.
**/
-s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
- u8 dev_addr, u8 *data)
+static s32 ixgbe_read_i2c_byte_generic_int(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 dev_addr, u8 *data, bool lock)
{
s32 status;
u32 max_retry = 10;
@@ -1952,11 +2048,13 @@ s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
DEBUGFUNC("ixgbe_read_i2c_byte_generic");
+ if (hw->mac.type >= ixgbe_mac_X550)
+ max_retry = 3;
if (ixgbe_is_sfp_probe(hw, byte_offset, dev_addr))
max_retry = IXGBE_SFP_DETECT_RETRIES;
do {
- if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
+ if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
return IXGBE_ERR_SWFW_SYNC;
ixgbe_i2c_start(hw);
@@ -1998,13 +2096,16 @@ s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
goto fail;
ixgbe_i2c_stop(hw);
- hw->mac.ops.release_swfw_sync(hw, swfw_mask);
+ if (lock)
+ hw->mac.ops.release_swfw_sync(hw, swfw_mask);
return IXGBE_SUCCESS;
fail:
ixgbe_i2c_bus_clear(hw);
- hw->mac.ops.release_swfw_sync(hw, swfw_mask);
- msec_delay(100);
+ if (lock) {
+ hw->mac.ops.release_swfw_sync(hw, swfw_mask);
+ msec_delay(100);
+ }
retry++;
if (retry < max_retry)
DEBUGOUT("I2C byte read error - Retrying.\n");
@@ -2017,28 +2118,60 @@ fail:
}
/**
- * ixgbe_write_i2c_byte_generic - Writes 8 bit word over I2C
+ * ixgbe_read_i2c_byte_generic - Reads 8 bit word over I2C
+ * @hw: pointer to hardware structure
+ * @byte_offset: byte offset to read
+ * @data: value read
+ *
+ * Performs byte read operation to SFP module's EEPROM over I2C interface at
+ * a specified device address.
+ **/
+s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 dev_addr, u8 *data)
+{
+ return ixgbe_read_i2c_byte_generic_int(hw, byte_offset, dev_addr,
+ data, TRUE);
+}
+
+/**
+ * ixgbe_read_i2c_byte_generic_unlocked - Reads 8 bit word over I2C
+ * @hw: pointer to hardware structure
+ * @byte_offset: byte offset to read
+ * @data: value read
+ *
+ * Performs byte read operation to SFP module's EEPROM over I2C interface at
+ * a specified device address.
+ **/
+s32 ixgbe_read_i2c_byte_generic_unlocked(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 dev_addr, u8 *data)
+{
+ return ixgbe_read_i2c_byte_generic_int(hw, byte_offset, dev_addr,
+ data, FALSE);
+}
+
+/**
+ * ixgbe_write_i2c_byte_generic_int - Writes 8 bit word over I2C
* @hw: pointer to hardware structure
* @byte_offset: byte offset to write
* @data: value to write
+ * @lock: TRUE if to take and release semaphore
*
* Performs byte write operation to SFP module's EEPROM over I2C interface at
* a specified device address.
**/
-s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
- u8 dev_addr, u8 data)
+static s32 ixgbe_write_i2c_byte_generic_int(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 dev_addr, u8 data, bool lock)
{
- s32 status = IXGBE_SUCCESS;
+ s32 status;
u32 max_retry = 1;
u32 retry = 0;
u32 swfw_mask = hw->phy.phy_semaphore_mask;
DEBUGFUNC("ixgbe_write_i2c_byte_generic");
- if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) != IXGBE_SUCCESS) {
- status = IXGBE_ERR_SWFW_SYNC;
- goto write_byte_out;
- }
+ if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) !=
+ IXGBE_SUCCESS)
+ return IXGBE_ERR_SWFW_SYNC;
do {
ixgbe_i2c_start(hw);
@@ -2068,7 +2201,8 @@ s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
goto fail;
ixgbe_i2c_stop(hw);
- hw->mac.ops.release_swfw_sync(hw, swfw_mask);
+ if (lock)
+ hw->mac.ops.release_swfw_sync(hw, swfw_mask);
return IXGBE_SUCCESS;
fail:
@@ -2080,13 +2214,45 @@ fail:
DEBUGOUT("I2C byte write error.\n");
} while (retry < max_retry);
- hw->mac.ops.release_swfw_sync(hw, swfw_mask);
+ if (lock)
+ hw->mac.ops.release_swfw_sync(hw, swfw_mask);
-write_byte_out:
return status;
}
/**
+ * ixgbe_write_i2c_byte_generic - Writes 8 bit word over I2C
+ * @hw: pointer to hardware structure
+ * @byte_offset: byte offset to write
+ * @data: value to write
+ *
+ * Performs byte write operation to SFP module's EEPROM over I2C interface at
+ * a specified device address.
+ **/
+s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 dev_addr, u8 data)
+{
+ return ixgbe_write_i2c_byte_generic_int(hw, byte_offset, dev_addr,
+ data, TRUE);
+}
+
+/**
+ * ixgbe_write_i2c_byte_generic_unlocked - Writes 8 bit word over I2C
+ * @hw: pointer to hardware structure
+ * @byte_offset: byte offset to write
+ * @data: value to write
+ *
+ * Performs byte write operation to SFP module's EEPROM over I2C interface at
+ * a specified device address.
+ **/
+s32 ixgbe_write_i2c_byte_generic_unlocked(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 dev_addr, u8 data)
+{
+ return ixgbe_write_i2c_byte_generic_int(hw, byte_offset, dev_addr,
+ data, FALSE);
+}
+
+/**
* ixgbe_i2c_start - Sets I2C start condition
* @hw: pointer to hardware structure
*
diff --git a/sys/dev/ixgbe/ixgbe_phy.h b/sys/dev/ixgbe/ixgbe_phy.h
index 021d5f0944a1..fad31bd89fcb 100644
--- a/sys/dev/ixgbe/ixgbe_phy.h
+++ b/sys/dev/ixgbe/ixgbe_phy.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2014, Intel Corporation
+ Copyright (c) 2001-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -89,9 +89,24 @@
#define IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS 0x3
#define IXGBE_CS4227 0xBE /* CS4227 address */
-#define IXGBE_CS4227_SPARE24_LSB 0x12B0 /* Reg to program EDC */
+#define IXGBE_CS4227_GLOBAL_ID_LSB 0
+#define IXGBE_CS4227_SCRATCH 2
+#define IXGBE_CS4227_GLOBAL_ID_VALUE 0x03E5
+#define IXGBE_CS4227_SCRATCH_VALUE 0x5aa5
+#define IXGBE_CS4227_RETRIES 5
+#define IXGBE_CS4227_LINE_SPARE22_MSB 0x12AD /* Reg to program speed */
+#define IXGBE_CS4227_LINE_SPARE24_LSB 0x12B0 /* Reg to program EDC */
+#define IXGBE_CS4227_HOST_SPARE22_MSB 0x1AAD /* Reg to program speed */
+#define IXGBE_CS4227_HOST_SPARE24_LSB 0x1AB0 /* Reg to program EDC */
#define IXGBE_CS4227_EDC_MODE_CX1 0x0002
#define IXGBE_CS4227_EDC_MODE_SR 0x0004
+#define IXGBE_CS4227_RESET_HOLD 500 /* microseconds */
+#define IXGBE_CS4227_RESET_DELAY 500 /* milliseconds */
+#define IXGBE_CS4227_CHECK_DELAY 30 /* milliseconds */
+#define IXGBE_PE 0xE0 /* Port expander address */
+#define IXGBE_PE_OUTPUT 1 /* Output register offset */
+#define IXGBE_PE_CONFIG 3 /* Config register offset */
+#define IXGBE_PE_BIT1 (1 << 1)
/* Flow control defines */
#define IXGBE_TAF_SYM_PAUSE 0x400
@@ -175,8 +190,12 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
s32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw);
s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
u8 dev_addr, u8 *data);
+s32 ixgbe_read_i2c_byte_generic_unlocked(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 dev_addr, u8 *data);
s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
u8 dev_addr, u8 data);
+s32 ixgbe_write_i2c_byte_generic_unlocked(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 dev_addr, u8 data);
s32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
u8 *eeprom_data);
s32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
diff --git a/sys/dev/ixgbe/ixgbe_type.h b/sys/dev/ixgbe/ixgbe_type.h
index 24ba046b5c0b..2a539527564e 100644
--- a/sys/dev/ixgbe/ixgbe_type.h
+++ b/sys/dev/ixgbe/ixgbe_type.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2014, Intel Corporation
+ Copyright (c) 2001-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -111,6 +111,7 @@
#define IXGBE_SUBDEV_ID_82599_LOM_SNAP6 0x2159
#define IXGBE_SUBDEV_ID_82599_SFP_1OCP 0x000D
#define IXGBE_SUBDEV_ID_82599_SFP_2OCP 0x0008
+#define IXGBE_SUBDEV_ID_82599_SFP_LOM 0x06EE
#define IXGBE_DEV_ID_82599_BACKPLANE_FCOE 0x152A
#define IXGBE_DEV_ID_82599_SFP_FCOE 0x1529
#define IXGBE_DEV_ID_82599_SFP_EM 0x1507
@@ -130,8 +131,6 @@
#define IXGBE_DEV_ID_X540_BYPASS 0x155C
#define IXGBE_DEV_ID_X540T1 0x1560
#define IXGBE_DEV_ID_X550T 0x1563
-/* Placeholder value, pending official value. */
-#define IXGBE_DEV_ID_X550EM_A_KR 0xABCD
#define IXGBE_DEV_ID_X550EM_X_KX4 0x15AA
#define IXGBE_DEV_ID_X550EM_X_KR 0x15AB
#define IXGBE_DEV_ID_X550EM_X_SFP 0x15AC
@@ -139,11 +138,13 @@
#define IXGBE_DEV_ID_X550EM_X_1G_T 0x15AE
#define IXGBE_DEV_ID_X550_VF_HV 0x1564
#define IXGBE_DEV_ID_X550_VF 0x1565
-#define IXGBE_DEV_ID_X550EM_A_VF 0x15B3
-#define IXGBE_DEV_ID_X550EM_A_VF_HV 0x15B4
#define IXGBE_DEV_ID_X550EM_X_VF 0x15A8
#define IXGBE_DEV_ID_X550EM_X_VF_HV 0x15A9
+#define IXGBE_CAT(r,m) IXGBE_##r##m
+
+#define IXGBE_BY_MAC(_hw, r) ((_hw)->mvals[IXGBE_CAT(r, _IDX)])
+
/* General Registers */
#define IXGBE_CTRL 0x00000
#define IXGBE_STATUS 0x00008
@@ -151,9 +152,11 @@
#define IXGBE_ESDP 0x00020
#define IXGBE_EODSDP 0x00028
#define IXGBE_I2CCTL_82599 0x00028
+#define IXGBE_I2CCTL IXGBE_I2CCTL_82599
+#define IXGBE_I2CCTL_X540 IXGBE_I2CCTL_82599
#define IXGBE_I2CCTL_X550 0x15F5C
-#define IXGBE_I2CCTL_BY_MAC(_hw) ((((_hw)->mac.type >= ixgbe_mac_X550) ? \
- IXGBE_I2CCTL_X550 : IXGBE_I2CCTL_82599))
+#define IXGBE_I2CCTL_X550EM_x IXGBE_I2CCTL_X550
+#define IXGBE_I2CCTL_BY_MAC(_hw) IXGBE_BY_MAC((_hw), I2CCTL)
#define IXGBE_PHY_GPIO 0x00028
#define IXGBE_MAC_GPIO 0x00030
#define IXGBE_PHYINT_STATUS0 0x00100
@@ -166,18 +169,40 @@
#define IXGBE_EXVET 0x05078
/* NVM Registers */
-#define IXGBE_EEC 0x10010
-#define IXGBE_EERD 0x10014
-#define IXGBE_EEWR 0x10018
-#define IXGBE_FLA 0x1001C
+#define IXGBE_EEC 0x10010
+#define IXGBE_EEC_X540 IXGBE_EEC
+#define IXGBE_EEC_X550 IXGBE_EEC
+#define IXGBE_EEC_X550EM_x IXGBE_EEC
+#define IXGBE_EEC_BY_MAC(_hw) IXGBE_EEC
+
+#define IXGBE_EERD 0x10014
+#define IXGBE_EEWR 0x10018
+
+#define IXGBE_FLA 0x1001C
+#define IXGBE_FLA_X540 IXGBE_FLA
+#define IXGBE_FLA_X550 IXGBE_FLA
+#define IXGBE_FLA_X550EM_x IXGBE_FLA
+#define IXGBE_FLA_BY_MAC(_hw) IXGBE_FLA
+
#define IXGBE_EEMNGCTL 0x10110
#define IXGBE_EEMNGDATA 0x10114
#define IXGBE_FLMNGCTL 0x10118
#define IXGBE_FLMNGDATA 0x1011C
#define IXGBE_FLMNGCNT 0x10120
#define IXGBE_FLOP 0x1013C
-#define IXGBE_GRC 0x10200
-#define IXGBE_SRAMREL 0x10210
+
+#define IXGBE_GRC 0x10200
+#define IXGBE_GRC_X540 IXGBE_GRC
+#define IXGBE_GRC_X550 IXGBE_GRC
+#define IXGBE_GRC_X550EM_x IXGBE_GRC
+#define IXGBE_GRC_BY_MAC(_hw) IXGBE_GRC
+
+#define IXGBE_SRAMREL 0x10210
+#define IXGBE_SRAMREL_X540 IXGBE_SRAMREL
+#define IXGBE_SRAMREL_X550 IXGBE_SRAMREL
+#define IXGBE_SRAMREL_X550EM_x IXGBE_SRAMREL
+#define IXGBE_SRAMREL_BY_MAC(_hw) IXGBE_SRAMREL
+
#define IXGBE_PHYDBG 0x10218
/* General Receive Control */
@@ -188,20 +213,48 @@
#define IXGBE_VPDDIAG1 0x10208
/* I2CCTL Bit Masks */
-#define IXGBE_I2C_CLK_IN_BY_MAC(_hw)(((_hw)->mac.type) >= ixgbe_mac_X550 ? \
- 0x00004000 : 0x00000001)
-#define IXGBE_I2C_CLK_OUT_BY_MAC(_hw)(((_hw)->mac.type) >= ixgbe_mac_X550 ? \
- 0x00000200 : 0x00000002)
-#define IXGBE_I2C_DATA_IN_BY_MAC(_hw)(((_hw)->mac.type) >= ixgbe_mac_X550 ? \
- 0x00001000 : 0x00000004)
-#define IXGBE_I2C_DATA_OUT_BY_MAC(_hw)(((_hw)->mac.type) >= ixgbe_mac_X550 ? \
- 0x00000400 : 0x00000008)
-#define IXGBE_I2C_BB_EN_BY_MAC(hw) ((hw)->mac.type >= ixgbe_mac_X550 ? \
- 0x00000100 : 0)
-#define IXGBE_I2C_DATA_OE_N_EN_BY_MAC(hw) ((hw)->mac.type >= ixgbe_mac_X550 ? \
- 0x00000800 : 0)
-#define IXGBE_I2C_CLK_OE_N_EN_BY_MAC(hw) ((hw)->mac.type >= ixgbe_mac_X550 ? \
- 0x00002000 : 0)
+#define IXGBE_I2C_CLK_IN 0x00000001
+#define IXGBE_I2C_CLK_IN_X540 IXGBE_I2C_CLK_IN
+#define IXGBE_I2C_CLK_IN_X550 0x00004000
+#define IXGBE_I2C_CLK_IN_X550EM_x IXGBE_I2C_CLK_IN_X550
+#define IXGBE_I2C_CLK_IN_BY_MAC(_hw) IXGBE_BY_MAC((_hw), I2C_CLK_IN)
+
+#define IXGBE_I2C_CLK_OUT 0x00000002
+#define IXGBE_I2C_CLK_OUT_X540 IXGBE_I2C_CLK_OUT
+#define IXGBE_I2C_CLK_OUT_X550 0x00000200
+#define IXGBE_I2C_CLK_OUT_X550EM_x IXGBE_I2C_CLK_OUT_X550
+#define IXGBE_I2C_CLK_OUT_BY_MAC(_hw) IXGBE_BY_MAC((_hw), I2C_CLK_OUT)
+
+#define IXGBE_I2C_DATA_IN 0x00000004
+#define IXGBE_I2C_DATA_IN_X540 IXGBE_I2C_DATA_IN
+#define IXGBE_I2C_DATA_IN_X550 0x00001000
+#define IXGBE_I2C_DATA_IN_X550EM_x IXGBE_I2C_DATA_IN_X550
+#define IXGBE_I2C_DATA_IN_BY_MAC(_hw) IXGBE_BY_MAC((_hw), I2C_DATA_IN)
+
+#define IXGBE_I2C_DATA_OUT 0x00000008
+#define IXGBE_I2C_DATA_OUT_X540 IXGBE_I2C_DATA_OUT
+#define IXGBE_I2C_DATA_OUT_X550 0x00000400
+#define IXGBE_I2C_DATA_OUT_X550EM_x IXGBE_I2C_DATA_OUT_X550
+#define IXGBE_I2C_DATA_OUT_BY_MAC(_hw) IXGBE_BY_MAC((_hw), I2C_DATA_OUT)
+
+#define IXGBE_I2C_DATA_OE_N_EN 0
+#define IXGBE_I2C_DATA_OE_N_EN_X540 IXGBE_I2C_DATA_OE_N_EN
+#define IXGBE_I2C_DATA_OE_N_EN_X550 0x00000800
+#define IXGBE_I2C_DATA_OE_N_EN_X550EM_x IXGBE_I2C_DATA_OE_N_EN_X550
+#define IXGBE_I2C_DATA_OE_N_EN_BY_MAC(_hw) IXGBE_BY_MAC((_hw), I2C_DATA_OE_N_EN)
+
+#define IXGBE_I2C_BB_EN 0
+#define IXGBE_I2C_BB_EN_X540 IXGBE_I2C_BB_EN
+#define IXGBE_I2C_BB_EN_X550 0x00000100
+#define IXGBE_I2C_BB_EN_X550EM_x IXGBE_I2C_BB_EN_X550
+
+#define IXGBE_I2C_BB_EN_BY_MAC(_hw) IXGBE_BY_MAC((_hw), I2C_BB_EN)
+
+#define IXGBE_I2C_CLK_OE_N_EN 0
+#define IXGBE_I2C_CLK_OE_N_EN_X540 IXGBE_I2C_CLK_OE_N_EN
+#define IXGBE_I2C_CLK_OE_N_EN_X550 0x00002000
+#define IXGBE_I2C_CLK_OE_N_EN_X550EM_x IXGBE_I2C_CLK_OE_N_EN_X550
+#define IXGBE_I2C_CLK_OE_N_EN_BY_MAC(_hw) IXGBE_BY_MAC((_hw), I2C_CLK_OE_N_EN)
#define IXGBE_I2C_CLOCK_STRETCHING_TIMEOUT 500
@@ -612,6 +665,7 @@ struct ixgbe_dmac_config {
#define IXGBE_EEER 0x043A0 /* EEE register */
#define IXGBE_EEE_STAT 0x04398 /* EEE Status */
#define IXGBE_EEE_SU 0x04380 /* EEE Set up */
+#define IXGBE_EEE_SU_TEEE_DLY_SHIFT 26
#define IXGBE_TLPIC 0x041F4 /* EEE Tx LPI count */
#define IXGBE_RLPIC 0x041F8 /* EEE Rx LPI count */
@@ -989,14 +1043,34 @@ struct ixgbe_dmac_config {
#define IXGBE_GSCN_2 0x11028
#define IXGBE_GSCN_3 0x1102C
#define IXGBE_FACTPS 0x10150
+#define IXGBE_FACTPS_X540 IXGBE_FACTPS
+#define IXGBE_FACTPS_X550 IXGBE_FACTPS
+#define IXGBE_FACTPS_X550EM_x IXGBE_FACTPS
+#define IXGBE_FACTPS_BY_MAC(_hw) IXGBE_FACTPS
+
#define IXGBE_PCIEANACTL 0x11040
#define IXGBE_SWSM 0x10140
+#define IXGBE_SWSM_X540 IXGBE_SWSM
+#define IXGBE_SWSM_X550 IXGBE_SWSM
+#define IXGBE_SWSM_X550EM_x IXGBE_SWSM
+#define IXGBE_SWSM_BY_MAC(_hw) IXGBE_SWSM
+
#define IXGBE_FWSM 0x10148
+#define IXGBE_FWSM_X540 IXGBE_FWSM
+#define IXGBE_FWSM_X550 IXGBE_FWSM
+#define IXGBE_FWSM_X550EM_x IXGBE_FWSM
+#define IXGBE_FWSM_BY_MAC(_hw) IXGBE_FWSM
+
+#define IXGBE_SWFW_SYNC IXGBE_GSSR
+#define IXGBE_SWFW_SYNC_X540 IXGBE_SWFW_SYNC
+#define IXGBE_SWFW_SYNC_X550 IXGBE_SWFW_SYNC
+#define IXGBE_SWFW_SYNC_X550EM_x IXGBE_SWFW_SYNC
+#define IXGBE_SWFW_SYNC_BY_MAC(_hw) IXGBE_SWFW_SYNC
+
#define IXGBE_GSSR 0x10160
#define IXGBE_MREVID 0x11064
#define IXGBE_DCA_ID 0x11070
#define IXGBE_DCA_CTRL 0x11074
-#define IXGBE_SWFW_SYNC IXGBE_GSSR
/* PCI-E registers 82599-Specific */
#define IXGBE_GCR_EXT 0x11050
@@ -1008,14 +1082,18 @@ struct ixgbe_dmac_config {
#define IXGBE_PHYDAT_82599 0x11044
#define IXGBE_PHYCTL_82599 0x11048
#define IXGBE_PBACLR_82599 0x11068
-#define IXGBE_CIAA_82599 0x11088
-#define IXGBE_CIAD_82599 0x1108C
+#define IXGBE_CIAA 0x11088
+#define IXGBE_CIAD 0x1108C
+#define IXGBE_CIAA_82599 IXGBE_CIAA
+#define IXGBE_CIAD_82599 IXGBE_CIAD
+#define IXGBE_CIAA_X540 IXGBE_CIAA
+#define IXGBE_CIAD_X540 IXGBE_CIAD
#define IXGBE_CIAA_X550 0x11508
#define IXGBE_CIAD_X550 0x11510
-#define IXGBE_CIAA_BY_MAC(_hw) ((((_hw)->mac.type >= ixgbe_mac_X550) ? \
- IXGBE_CIAA_X550 : IXGBE_CIAA_82599))
-#define IXGBE_CIAD_BY_MAC(_hw) ((((_hw)->mac.type >= ixgbe_mac_X550) ? \
- IXGBE_CIAD_X550 : IXGBE_CIAD_82599))
+#define IXGBE_CIAA_X550EM_x IXGBE_CIAA_X550
+#define IXGBE_CIAD_X550EM_x IXGBE_CIAD_X550
+#define IXGBE_CIAA_BY_MAC(_hw) IXGBE_BY_MAC((_hw), CIAA)
+#define IXGBE_CIAD_BY_MAC(_hw) IXGBE_BY_MAC((_hw), CIAD)
#define IXGBE_PICAUSE 0x110B0
#define IXGBE_PIENA 0x110B8
#define IXGBE_CDQ_MBR_82599 0x110B4
@@ -1365,6 +1443,8 @@ struct ixgbe_dmac_config {
#define IXGBE_MDIO_AUTO_NEG_STATUS 0x1 /* AUTO_NEG Status Reg */
#define IXGBE_MDIO_AUTO_NEG_VENDOR_STAT 0xC800 /* AUTO_NEG Vendor Status Reg */
#define IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM 0xCC00 /* AUTO_NEG Vendor TX Reg */
+#define IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM2 0xCC01 /* AUTO_NEG Vendor Tx Reg */
+#define IXGBE_MDIO_AUTO_NEG_VEN_LSC 0x1 /* AUTO_NEG Vendor Tx LSC */
#define IXGBE_MDIO_AUTO_NEG_ADVT 0x10 /* AUTO_NEG Advt Reg */
#define IXGBE_MDIO_AUTO_NEG_LP 0x13 /* AUTO_NEG LP Status Reg */
#define IXGBE_MDIO_AUTO_NEG_EEE_ADVT 0x3C /* AUTO_NEG EEE Advt Reg */
@@ -1393,11 +1473,24 @@ struct ixgbe_dmac_config {
#define IXGBE_MDIO_TX_VENDOR_ALARMS_3_RST_MASK 0x3 /* PHY Reset Complete Mask */
#define IXGBE_MDIO_GLOBAL_RES_PR_10 0xC479 /* Global Resv Provisioning 10 Reg */
#define IXGBE_MDIO_POWER_UP_STALL 0x8000 /* Power Up Stall */
-
+#define IXGBE_MDIO_GLOBAL_INT_CHIP_STD_MASK 0xFF00 /* int std mask */
+#define IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG 0xFC00 /* chip std int flag */
+#define IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK 0xFF01 /* int chip-wide mask */
+#define IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_FLAG 0xFC01 /* int chip-wide mask */
+#define IXGBE_MDIO_GLOBAL_ALARM_1 0xCC00 /* Global alarm 1 */
+#define IXGBE_MDIO_GLOBAL_ALM_1_HI_TMP_FAIL 0x4000 /* high temp failure */
+#define IXGBE_MDIO_GLOBAL_INT_MASK 0xD400 /* Global int mask */
+#define IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN 0x1000 /* autoneg vendor alarm int enable */
+#define IXGBE_MDIO_GLOBAL_ALARM_1_INT 0x4 /* int in Global alarm 1 */
+#define IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN 0x1 /* vendor alarm int enable */
+#define IXGBE_MDIO_GLOBAL_STD_ALM2_INT 0x200 /* vendor alarm2 int mask */
+#define IXGBE_MDIO_GLOBAL_INT_HI_TEMP_EN 0x4000 /* int high temp enable */
#define IXGBE_MDIO_PMA_PMD_CONTROL_ADDR 0x0000 /* PMA/PMD Control Reg */
#define IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR 0xC30A /* PHY_XS SDA/SCL Addr Reg */
#define IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA 0xC30B /* PHY_XS SDA/SCL Data Reg */
#define IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT 0xC30C /* PHY_XS SDA/SCL Status Reg */
+#define IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK 0xD401 /* PHY TX Vendor LASI */
+#define IXGBE_MDIO_PMA_TX_VEN_LASI_INT_EN 0x1 /* PHY TX Vendor LASI enable */
#define IXGBE_MDIO_PMD_STD_TX_DISABLE_CNTR 0x9 /* Standard Transmit Dis Reg */
#define IXGBE_MDIO_PMD_GLOBAL_TX_DISABLE 0x0001 /* PMD Global Transmit Dis */
@@ -1479,12 +1572,16 @@ struct ixgbe_dmac_config {
#define IXGBE_SDP0_GPIEN_X540 0x00000002 /* SDP0 on X540 and X550 */
#define IXGBE_SDP1_GPIEN_X540 0x00000004 /* SDP1 on X540 and X550 */
#define IXGBE_SDP2_GPIEN_X540 0x00000008 /* SDP2 on X540 and X550 */
-#define IXGBE_SDP0_GPIEN_BY_MAC(_hw) ((_hw)->mac.type >= ixgbe_mac_X540 ? \
- IXGBE_SDP0_GPIEN_X540 : IXGBE_SDP0_GPIEN)
-#define IXGBE_SDP1_GPIEN_BY_MAC(_hw) ((_hw)->mac.type >= ixgbe_mac_X540 ? \
- IXGBE_SDP1_GPIEN_X540 : IXGBE_SDP1_GPIEN)
-#define IXGBE_SDP2_GPIEN_BY_MAC(_hw) ((_hw)->mac.type >= ixgbe_mac_X540 ? \
- IXGBE_SDP2_GPIEN_X540 : IXGBE_SDP2_GPIEN)
+#define IXGBE_SDP0_GPIEN_X550 IXGBE_SDP0_GPIEN_X540
+#define IXGBE_SDP1_GPIEN_X550 IXGBE_SDP1_GPIEN_X540
+#define IXGBE_SDP2_GPIEN_X550 IXGBE_SDP2_GPIEN_X540
+#define IXGBE_SDP0_GPIEN_X550EM_x IXGBE_SDP0_GPIEN_X540
+#define IXGBE_SDP1_GPIEN_X550EM_x IXGBE_SDP1_GPIEN_X540
+#define IXGBE_SDP2_GPIEN_X550EM_x IXGBE_SDP2_GPIEN_X540
+#define IXGBE_SDP0_GPIEN_BY_MAC(_hw) IXGBE_BY_MAC((_hw), SDP0_GPIEN)
+#define IXGBE_SDP1_GPIEN_BY_MAC(_hw) IXGBE_BY_MAC((_hw), SDP1_GPIEN)
+#define IXGBE_SDP2_GPIEN_BY_MAC(_hw) IXGBE_BY_MAC((_hw), SDP2_GPIEN)
+
#define IXGBE_GPIE_MSIX_MODE 0x00000010 /* MSI-X mode */
#define IXGBE_GPIE_OCD 0x00000020 /* Other Clear Disable */
#define IXGBE_GPIE_EIMEN 0x00000040 /* Immediate Interrupt Enable */
@@ -1665,15 +1762,16 @@ enum {
#define IXGBE_EICR_GPI_SDP0_X540 0x02000000 /* Gen Purpose Interrupt on SDP0 */
#define IXGBE_EICR_GPI_SDP1_X540 0x04000000 /* Gen Purpose Interrupt on SDP1 */
#define IXGBE_EICR_GPI_SDP2_X540 0x08000000 /* Gen Purpose Interrupt on SDP2 */
-#define IXGBE_EICR_GPI_SDP0_BY_MAC(_hw) ((_hw)->mac.type >= ixgbe_mac_X540 ? \
- IXGBE_EICR_GPI_SDP0_X540 : \
- IXGBE_EICR_GPI_SDP0)
-#define IXGBE_EICR_GPI_SDP1_BY_MAC(_hw) ((_hw)->mac.type >= ixgbe_mac_X540 ? \
- IXGBE_EICR_GPI_SDP1_X540 : \
- IXGBE_EICR_GPI_SDP1)
-#define IXGBE_EICR_GPI_SDP2_BY_MAC(_hw) ((_hw)->mac.type >= ixgbe_mac_X540 ? \
- IXGBE_EICR_GPI_SDP2_X540 : \
- IXGBE_EICR_GPI_SDP2)
+#define IXGBE_EICR_GPI_SDP0_X550 IXGBE_EICR_GPI_SDP0_X540
+#define IXGBE_EICR_GPI_SDP1_X550 IXGBE_EICR_GPI_SDP1_X540
+#define IXGBE_EICR_GPI_SDP2_X550 IXGBE_EICR_GPI_SDP2_X540
+#define IXGBE_EICR_GPI_SDP0_X550EM_x IXGBE_EICR_GPI_SDP0_X540
+#define IXGBE_EICR_GPI_SDP1_X550EM_x IXGBE_EICR_GPI_SDP1_X540
+#define IXGBE_EICR_GPI_SDP2_X550EM_x IXGBE_EICR_GPI_SDP2_X540
+#define IXGBE_EICR_GPI_SDP0_BY_MAC(_hw) IXGBE_BY_MAC((_hw), EICR_GPI_SDP0)
+#define IXGBE_EICR_GPI_SDP1_BY_MAC(_hw) IXGBE_BY_MAC((_hw), EICR_GPI_SDP1)
+#define IXGBE_EICR_GPI_SDP2_BY_MAC(_hw) IXGBE_BY_MAC((_hw), EICR_GPI_SDP2)
+
#define IXGBE_EICR_PBUR 0x10000000 /* Packet Buffer Handler Error */
#define IXGBE_EICR_DHER 0x20000000 /* Descriptor Handler Error */
#define IXGBE_EICR_TCP_TIMER 0x40000000 /* TCP Timer */
@@ -1901,6 +1999,9 @@ enum {
#define IXGBE_LED_IVRT(_i) IXGBE_LED_OFFSET(IXGBE_LED_IVRT_BASE, _i)
#define IXGBE_LED_BLINK(_i) IXGBE_LED_OFFSET(IXGBE_LED_BLINK_BASE, _i)
#define IXGBE_LED_MODE_MASK(_i) IXGBE_LED_OFFSET(IXGBE_LED_MODE_MASK_BASE, _i)
+#define IXGBE_X557_LED_MANUAL_SET_MASK (1 << 8)
+#define IXGBE_X557_MAX_LED_INDEX 3
+#define IXGBE_X557_LED_PROVISIONING 0xC430
/* LED modes */
#define IXGBE_LED_LINK_UP 0x0
@@ -2784,6 +2885,7 @@ enum ixgbe_fdir_pballoc_type {
#define IXGBE_HI_FLASH_ERASE_TIMEOUT 1000 /* Process Erase command limit */
#define IXGBE_HI_FLASH_UPDATE_TIMEOUT 5000 /* Process Update command limit */
#define IXGBE_HI_FLASH_APPLY_TIMEOUT 0 /* Process Apply command limit */
+#define IXGBE_HI_PHY_MGMT_REQ_TIMEOUT 2000 /* Wait up to 2 seconds */
/* CEM Support */
#define FW_CEM_HDR_LEN 0x4
@@ -2804,6 +2906,7 @@ enum ixgbe_fdir_pballoc_type {
#define FW_MAX_READ_BUFFER_SIZE 1024
#define FW_DISABLE_RXEN_CMD 0xDE
#define FW_DISABLE_RXEN_LEN 0x1
+#define FW_PHY_MGMT_REQ_CMD 0x20
/* Host Interface Command Structures */
struct ixgbe_hic_hdr {
@@ -3200,6 +3303,36 @@ union ixgbe_atr_hash_dword {
};
+#define IXGBE_MVALS_INIT(m) \
+ IXGBE_CAT(EEC, m), \
+ IXGBE_CAT(FLA, m), \
+ IXGBE_CAT(GRC, m), \
+ IXGBE_CAT(SRAMREL, m), \
+ IXGBE_CAT(FACTPS, m), \
+ IXGBE_CAT(SWSM, m), \
+ IXGBE_CAT(FWSM, m), \
+ IXGBE_CAT(SDP0_GPIEN, m), \
+ IXGBE_CAT(SDP1_GPIEN, m), \
+ IXGBE_CAT(SDP2_GPIEN, m), \
+ IXGBE_CAT(EICR_GPI_SDP0, m), \
+ IXGBE_CAT(EICR_GPI_SDP1, m), \
+ IXGBE_CAT(EICR_GPI_SDP2, m), \
+ IXGBE_CAT(CIAA, m), \
+ IXGBE_CAT(CIAD, m), \
+ IXGBE_CAT(I2C_CLK_IN, m), \
+ IXGBE_CAT(I2C_CLK_OUT, m), \
+ IXGBE_CAT(I2C_DATA_IN, m), \
+ IXGBE_CAT(I2C_DATA_OUT, m), \
+ IXGBE_CAT(I2C_DATA_OE_N_EN, m), \
+ IXGBE_CAT(I2C_BB_EN, m), \
+ IXGBE_CAT(I2C_CLK_OE_N_EN, m), \
+ IXGBE_CAT(I2CCTL, m)
+
+enum ixgbe_mvals {
+ IXGBE_MVALS_INIT(_IDX),
+ IXGBE_MVALS_IDX_LIMIT
+};
+
/*
* Unavailable: The FCoE Boot Option ROM is not present in the flash.
* Disabled: Present; boot order is not set for any targets on the port.
@@ -3225,17 +3358,10 @@ enum ixgbe_mac_type {
ixgbe_mac_82599_vf,
ixgbe_mac_X540,
ixgbe_mac_X540_vf,
- /*
- * X550EM MAC type decoder:
- * ixgbe_mac_X550EM_x: "x" = Xeon
- * ixgbe_mac_X550EM_a: "a" = Atom
- */
ixgbe_mac_X550,
ixgbe_mac_X550EM_x,
- ixgbe_mac_X550EM_a,
ixgbe_mac_X550_vf,
ixgbe_mac_X550EM_x_vf,
- ixgbe_mac_X550EM_a_vf,
ixgbe_num_macs
};
@@ -3294,6 +3420,8 @@ enum ixgbe_sfp_type {
ixgbe_sfp_type_1g_cu_core1 = 10,
ixgbe_sfp_type_1g_sx_core0 = 11,
ixgbe_sfp_type_1g_sx_core1 = 12,
+ ixgbe_sfp_type_1g_lx_core0 = 13,
+ ixgbe_sfp_type_1g_lx_core1 = 14,
ixgbe_sfp_type_not_present = 0xFFFE,
ixgbe_sfp_type_unknown = 0xFFFF
};
@@ -3611,6 +3739,15 @@ struct ixgbe_phy_operations {
s32 (*check_overtemp)(struct ixgbe_hw *);
s32 (*set_phy_power)(struct ixgbe_hw *, bool on);
s32 (*enter_lplu)(struct ixgbe_hw *);
+ s32 (*handle_lasi)(struct ixgbe_hw *hw);
+ s32 (*read_i2c_combined_unlocked)(struct ixgbe_hw *, u8 addr, u16 reg,
+ u16 *value);
+ s32 (*write_i2c_combined_unlocked)(struct ixgbe_hw *, u8 addr, u16 reg,
+ u16 value);
+ s32 (*read_i2c_byte_unlocked)(struct ixgbe_hw *, u8 offset, u8 addr,
+ u8 *value);
+ s32 (*write_i2c_byte_unlocked)(struct ixgbe_hw *, u8 offset, u8 addr,
+ u8 value);
};
struct ixgbe_eeprom_info {
@@ -3674,6 +3811,7 @@ struct ixgbe_phy_info {
bool multispeed_fiber;
bool reset_if_overtemp;
bool qsfp_shared_i2c_bus;
+ u32 nw_mng_if_sel;
};
#include "ixgbe_mbx.h"
@@ -3717,6 +3855,7 @@ struct ixgbe_hw {
struct ixgbe_eeprom_info eeprom;
struct ixgbe_bus_info bus;
struct ixgbe_mbx_info mbx;
+ const u32 *mvals;
u16 device_id;
u16 vendor_id;
u16 subsystem_device_id;
@@ -3775,6 +3914,10 @@ struct ixgbe_hw {
#define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF
+#define IXGBE_FUSES0_GROUP(_i) (0x11158 + ((_i) * 4))
+#define IXGBE_FUSES0_300MHZ (1 << 5)
+#define IXGBE_FUSES0_REV1 (1 << 6)
+
#define IXGBE_KRM_PORT_CAR_GEN_CTRL(P) ((P == 0) ? (0x4010) : (0x8010))
#define IXGBE_KRM_LINK_CTRL_1(P) ((P == 0) ? (0x420C) : (0x820C))
#define IXGBE_KRM_AN_CNTL_1(P) ((P == 0) ? (0x422C) : (0x822C))
@@ -3842,8 +3985,10 @@ struct ixgbe_hw {
#define IXGBE_SB_IOSF_CTRL_BUSY_SHIFT 31
#define IXGBE_SB_IOSF_CTRL_BUSY (1 << IXGBE_SB_IOSF_CTRL_BUSY_SHIFT)
#define IXGBE_SB_IOSF_TARGET_KR_PHY 0
-#define IXGBE_SB_IOSF_TARGET_KX4_UNIPHY 1
-#define IXGBE_SB_IOSF_TARGET_KX4_PCS0 2
-#define IXGBE_SB_IOSF_TARGET_KX4_PCS1 3
+#define IXGBE_SB_IOSF_TARGET_KX4_PHY 1
+#define IXGBE_SB_IOSF_TARGET_KX4_PCS 2
+
+#define IXGBE_NW_MNG_IF_SEL 0x00011178
+#define IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE (1 << 24)
#endif /* _IXGBE_TYPE_H_ */
diff --git a/sys/dev/ixgbe/ixgbe_vf.c b/sys/dev/ixgbe/ixgbe_vf.c
index 964514cddae3..c010cf4357dd 100644
--- a/sys/dev/ixgbe/ixgbe_vf.c
+++ b/sys/dev/ixgbe/ixgbe_vf.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2014, Intel Corporation
+ Copyright (c) 2001-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -669,4 +669,3 @@ int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs,
UNREFERENCED_3PARAMETER(hw, num_tcs, default_tc);
return IXGBE_SUCCESS;
}
-
diff --git a/sys/dev/ixgbe/ixgbe_vf.h b/sys/dev/ixgbe/ixgbe_vf.h
index 8f4d46eeeb5d..edc801367d2f 100644
--- a/sys/dev/ixgbe/ixgbe_vf.h
+++ b/sys/dev/ixgbe/ixgbe_vf.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2014, Intel Corporation
+ Copyright (c) 2001-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/sys/dev/ixgbe/ixgbe_x540.c b/sys/dev/ixgbe/ixgbe_x540.c
index 93c6ca4de6d8..ddf06743ed9e 100644
--- a/sys/dev/ixgbe/ixgbe_x540.c
+++ b/sys/dev/ixgbe/ixgbe_x540.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2014, Intel Corporation
+ Copyright (c) 2001-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -932,14 +932,14 @@ static void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw)
/* Release both semaphores by writing 0 to the bits REGSMP and SMBI */
- swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
- swsm &= ~IXGBE_SWSM_SMBI;
- IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm);
-
swsm = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC);
swsm &= ~IXGBE_SWFW_REGSMP;
IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swsm);
+ swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
+ swsm &= ~IXGBE_SWSM_SMBI;
+ IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm);
+
IXGBE_WRITE_FLUSH(hw);
}
@@ -1011,5 +1011,3 @@ s32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index)
return IXGBE_SUCCESS;
}
-
-
diff --git a/sys/dev/ixgbe/ixgbe_x540.h b/sys/dev/ixgbe/ixgbe_x540.h
index 12da8273c2a9..efd0d41f417f 100644
--- a/sys/dev/ixgbe/ixgbe_x540.h
+++ b/sys/dev/ixgbe/ixgbe_x540.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2014, Intel Corporation
+ Copyright (c) 2001-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/sys/dev/ixgbe/ixgbe_x550.c b/sys/dev/ixgbe/ixgbe_x550.c
new file mode 100644
index 000000000000..65daa17c6034
--- /dev/null
+++ b/sys/dev/ixgbe/ixgbe_x550.c
@@ -0,0 +1,3191 @@
+/******************************************************************************
+
+ Copyright (c) 2001-2015, Intel Corporation
+ 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. Neither the name of the Intel Corporation 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 OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+******************************************************************************/
+/*$FreeBSD$*/
+
+#include "ixgbe_x550.h"
+#include "ixgbe_x540.h"
+#include "ixgbe_type.h"
+#include "ixgbe_api.h"
+#include "ixgbe_common.h"
+#include "ixgbe_phy.h"
+
+static s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed);
+
+/**
+ * ixgbe_init_ops_X550 - Inits func ptrs and MAC type
+ * @hw: pointer to hardware structure
+ *
+ * Initialize the function pointers and assign the MAC type for X550.
+ * Does not touch the hardware.
+ **/
+s32 ixgbe_init_ops_X550(struct ixgbe_hw *hw)
+{
+ struct ixgbe_mac_info *mac = &hw->mac;
+ struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
+ s32 ret_val;
+
+ DEBUGFUNC("ixgbe_init_ops_X550");
+
+ ret_val = ixgbe_init_ops_X540(hw);
+ mac->ops.dmac_config = ixgbe_dmac_config_X550;
+ mac->ops.dmac_config_tcs = ixgbe_dmac_config_tcs_X550;
+ mac->ops.dmac_update_tcs = ixgbe_dmac_update_tcs_X550;
+ mac->ops.setup_eee = ixgbe_setup_eee_X550;
+ mac->ops.set_source_address_pruning =
+ ixgbe_set_source_address_pruning_X550;
+ mac->ops.set_ethertype_anti_spoofing =
+ ixgbe_set_ethertype_anti_spoofing_X550;
+
+ mac->ops.get_rtrup2tc = ixgbe_dcb_get_rtrup2tc_generic;
+ eeprom->ops.init_params = ixgbe_init_eeprom_params_X550;
+ eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_X550;
+ eeprom->ops.read = ixgbe_read_ee_hostif_X550;
+ eeprom->ops.read_buffer = ixgbe_read_ee_hostif_buffer_X550;
+ eeprom->ops.write = ixgbe_write_ee_hostif_X550;
+ eeprom->ops.write_buffer = ixgbe_write_ee_hostif_buffer_X550;
+ eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_X550;
+ eeprom->ops.validate_checksum = ixgbe_validate_eeprom_checksum_X550;
+
+ mac->ops.disable_mdd = ixgbe_disable_mdd_X550;
+ mac->ops.enable_mdd = ixgbe_enable_mdd_X550;
+ mac->ops.mdd_event = ixgbe_mdd_event_X550;
+ mac->ops.restore_mdd_vf = ixgbe_restore_mdd_vf_X550;
+ mac->ops.disable_rx = ixgbe_disable_rx_x550;
+ if (hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T) {
+ hw->mac.ops.led_on = ixgbe_led_on_t_X550em;
+ hw->mac.ops.led_off = ixgbe_led_off_t_X550em;
+ }
+ return ret_val;
+}
+
+/**
+ * ixgbe_read_cs4227 - Read CS4227 register
+ * @hw: pointer to hardware structure
+ * @reg: register number to write
+ * @value: pointer to receive value read
+ *
+ * Returns status code
+ **/
+static s32 ixgbe_read_cs4227(struct ixgbe_hw *hw, u16 reg, u16 *value)
+{
+ return ixgbe_read_i2c_combined_unlocked(hw, IXGBE_CS4227, reg, value);
+}
+
+/**
+ * ixgbe_write_cs4227 - Write CS4227 register
+ * @hw: pointer to hardware structure
+ * @reg: register number to write
+ * @value: value to write to register
+ *
+ * Returns status code
+ **/
+static s32 ixgbe_write_cs4227(struct ixgbe_hw *hw, u16 reg, u16 value)
+{
+ return ixgbe_write_i2c_combined_unlocked(hw, IXGBE_CS4227, reg, value);
+}
+
+/**
+ * ixgbe_get_cs4227_status - Return CS4227 status
+ * @hw: pointer to hardware structure
+ *
+ * Returns error if CS4227 not successfully initialized
+ **/
+static s32 ixgbe_get_cs4227_status(struct ixgbe_hw *hw)
+{
+ s32 status;
+ u16 value = 0;
+ u16 reg_slice, reg_val;
+ u8 retry;
+
+ for (retry = 0; retry < IXGBE_CS4227_RETRIES; ++retry) {
+ status = ixgbe_read_cs4227(hw, IXGBE_CS4227_GLOBAL_ID_LSB,
+ &value);
+ if (status != IXGBE_SUCCESS)
+ return status;
+ if (value == IXGBE_CS4227_GLOBAL_ID_VALUE)
+ break;
+ msec_delay(IXGBE_CS4227_CHECK_DELAY);
+ }
+ if (value != IXGBE_CS4227_GLOBAL_ID_VALUE)
+ return IXGBE_ERR_PHY;
+
+ status = ixgbe_read_cs4227(hw, IXGBE_CS4227_SCRATCH, &value);
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ /* If this is the first time after power-on, check the ucode.
+ * Otherwise, this will disrupt link on all ports. Because we
+ * can only do this the first time, we must check all ports,
+ * not just our own.
+ */
+ if (value != IXGBE_CS4227_SCRATCH_VALUE) {
+ reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB;
+ reg_val = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1;
+ status = ixgbe_write_cs4227(hw, reg_slice,
+ reg_val);
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ reg_slice = IXGBE_CS4227_HOST_SPARE24_LSB;
+ reg_val = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1;
+ status = ixgbe_write_cs4227(hw, reg_slice,
+ reg_val);
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB + (1 << 12);
+ reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
+ status = ixgbe_write_cs4227(hw, reg_slice,
+ reg_val);
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ reg_slice = IXGBE_CS4227_HOST_SPARE24_LSB + (1 << 12);
+ reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
+ status = ixgbe_write_cs4227(hw, reg_slice,
+ reg_val);
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ msec_delay(10);
+ }
+
+ /* Verify that the ucode is operational on all ports. */
+ reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB;
+ reg_val = 0xFFFF;
+ status = ixgbe_read_cs4227(hw, reg_slice, &reg_val);
+ if (status != IXGBE_SUCCESS)
+ return status;
+ if (reg_val != 0)
+ return IXGBE_ERR_PHY;
+
+ reg_slice = IXGBE_CS4227_HOST_SPARE24_LSB;
+ reg_val = 0xFFFF;
+ status = ixgbe_read_cs4227(hw, reg_slice, &reg_val);
+ if (status != IXGBE_SUCCESS)
+ return status;
+ if (reg_val != 0)
+ return IXGBE_ERR_PHY;
+
+ reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB + (1 << 12);
+ reg_val = 0xFFFF;
+ status = ixgbe_read_cs4227(hw, reg_slice, &reg_val);
+ if (status != IXGBE_SUCCESS)
+ return status;
+ if (reg_val != 0)
+ return IXGBE_ERR_PHY;
+
+ reg_slice = IXGBE_CS4227_HOST_SPARE24_LSB + (1 << 12);
+ reg_val = 0xFFFF;
+ status = ixgbe_read_cs4227(hw, reg_slice, &reg_val);
+ if (status != IXGBE_SUCCESS)
+ return status;
+ if (reg_val != 0)
+ return IXGBE_ERR_PHY;
+
+ /* Set scratch for next time. */
+ status = ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH,
+ IXGBE_CS4227_SCRATCH_VALUE);
+ if (status != IXGBE_SUCCESS)
+ return status;
+ status = ixgbe_read_cs4227(hw, IXGBE_CS4227_SCRATCH, &value);
+ if (status != IXGBE_SUCCESS)
+ return status;
+ if (value != IXGBE_CS4227_SCRATCH_VALUE)
+ return IXGBE_ERR_PHY;
+
+ return IXGBE_SUCCESS;
+}
+
+/**
+ * ixgbe_read_pe - Read register from port expander
+ * @hw: pointer to hardware structure
+ * @reg: register number to read
+ * @value: pointer to receive read value
+ *
+ * Returns status code
+ **/
+static s32 ixgbe_read_pe(struct ixgbe_hw *hw, u8 reg, u8 *value)
+{
+ s32 status;
+
+ status = ixgbe_read_i2c_byte_unlocked(hw, reg, IXGBE_PE, value);
+ if (status != IXGBE_SUCCESS)
+ ERROR_REPORT2(IXGBE_ERROR_CAUTION,
+ "port expander access failed with %d\n", status);
+ return status;
+}
+
+/**
+ * ixgbe_write_pe - Write register to port expander
+ * @hw: pointer to hardware structure
+ * @reg: register number to write
+ * @value: value to write
+ *
+ * Returns status code
+ **/
+static s32 ixgbe_write_pe(struct ixgbe_hw *hw, u8 reg, u8 value)
+{
+ s32 status;
+
+ status = ixgbe_write_i2c_byte_unlocked(hw, reg, IXGBE_PE, value);
+ if (status != IXGBE_SUCCESS)
+ ERROR_REPORT2(IXGBE_ERROR_CAUTION,
+ "port expander access failed with %d\n", status);
+ return status;
+}
+
+/**
+ * ixgbe_reset_cs4227 - Reset CS4227 using port expander
+ * @hw: pointer to hardware structure
+ *
+ * Returns error code
+ **/
+static s32 ixgbe_reset_cs4227(struct ixgbe_hw *hw)
+{
+ s32 status;
+ u8 reg;
+
+ status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
+ if (status != IXGBE_SUCCESS)
+ return status;
+ reg |= IXGBE_PE_BIT1;
+ status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ status = ixgbe_read_pe(hw, IXGBE_PE_CONFIG, &reg);
+ if (status != IXGBE_SUCCESS)
+ return status;
+ reg &= ~IXGBE_PE_BIT1;
+ status = ixgbe_write_pe(hw, IXGBE_PE_CONFIG, reg);
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
+ if (status != IXGBE_SUCCESS)
+ return status;
+ reg &= ~IXGBE_PE_BIT1;
+ status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ usec_delay(IXGBE_CS4227_RESET_HOLD);
+
+ status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
+ if (status != IXGBE_SUCCESS)
+ return status;
+ reg |= IXGBE_PE_BIT1;
+ status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ msec_delay(IXGBE_CS4227_RESET_DELAY);
+
+ return IXGBE_SUCCESS;
+}
+
+/**
+ * ixgbe_check_cs4227 - Check CS4227 and reset as needed
+ * @hw: pointer to hardware structure
+ **/
+static void ixgbe_check_cs4227(struct ixgbe_hw *hw)
+{
+ u32 swfw_mask = hw->phy.phy_semaphore_mask;
+ s32 status;
+ u8 retry;
+
+ for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) {
+ status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
+ if (status != IXGBE_SUCCESS) {
+ ERROR_REPORT2(IXGBE_ERROR_CAUTION,
+ "semaphore failed with %d\n", status);
+ return;
+ }
+ status = ixgbe_get_cs4227_status(hw);
+ if (status == IXGBE_SUCCESS) {
+ hw->mac.ops.release_swfw_sync(hw, swfw_mask);
+ msec_delay(hw->eeprom.semaphore_delay);
+ return;
+ }
+ ixgbe_reset_cs4227(hw);
+ hw->mac.ops.release_swfw_sync(hw, swfw_mask);
+ msec_delay(hw->eeprom.semaphore_delay);
+ }
+ ERROR_REPORT2(IXGBE_ERROR_CAUTION,
+ "Unable to initialize CS4227, err=%d\n", status);
+}
+
+/**
+ * ixgbe_setup_mux_ctl - Setup ESDP register for I2C mux control
+ * @hw: pointer to hardware structure
+ **/
+static void ixgbe_setup_mux_ctl(struct ixgbe_hw *hw)
+{
+ u32 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
+
+ if (hw->bus.lan_id) {
+ esdp &= ~(IXGBE_ESDP_SDP1_NATIVE | IXGBE_ESDP_SDP1);
+ esdp |= IXGBE_ESDP_SDP1_DIR;
+ }
+ esdp &= ~(IXGBE_ESDP_SDP0_NATIVE | IXGBE_ESDP_SDP0_DIR);
+ IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
+ IXGBE_WRITE_FLUSH(hw);
+}
+
+/**
+ * ixgbe_identify_phy_x550em - Get PHY type based on device id
+ * @hw: pointer to hardware structure
+ *
+ * Returns error code
+ */
+static s32 ixgbe_identify_phy_x550em(struct ixgbe_hw *hw)
+{
+ switch (hw->device_id) {
+ case IXGBE_DEV_ID_X550EM_X_SFP:
+ /* set up for CS4227 usage */
+ hw->phy.phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
+ ixgbe_setup_mux_ctl(hw);
+ ixgbe_check_cs4227(hw);
+
+ return ixgbe_identify_module_generic(hw);
+ break;
+ case IXGBE_DEV_ID_X550EM_X_KX4:
+ hw->phy.type = ixgbe_phy_x550em_kx4;
+ break;
+ case IXGBE_DEV_ID_X550EM_X_KR:
+ hw->phy.type = ixgbe_phy_x550em_kr;
+ break;
+ case IXGBE_DEV_ID_X550EM_X_1G_T:
+ case IXGBE_DEV_ID_X550EM_X_10G_T:
+ return ixgbe_identify_phy_generic(hw);
+ default:
+ break;
+ }
+ return IXGBE_SUCCESS;
+}
+
+static s32 ixgbe_read_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr,
+ u32 device_type, u16 *phy_data)
+{
+ UNREFERENCED_4PARAMETER(*hw, reg_addr, device_type, *phy_data);
+ return IXGBE_NOT_IMPLEMENTED;
+}
+
+static s32 ixgbe_write_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr,
+ u32 device_type, u16 phy_data)
+{
+ UNREFERENCED_4PARAMETER(*hw, reg_addr, device_type, phy_data);
+ return IXGBE_NOT_IMPLEMENTED;
+}
+
+/**
+* ixgbe_init_ops_X550EM - Inits func ptrs and MAC type
+* @hw: pointer to hardware structure
+*
+* Initialize the function pointers and for MAC type X550EM.
+* Does not touch the hardware.
+**/
+s32 ixgbe_init_ops_X550EM(struct ixgbe_hw *hw)
+{
+ struct ixgbe_mac_info *mac = &hw->mac;
+ struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
+ struct ixgbe_phy_info *phy = &hw->phy;
+ s32 ret_val;
+
+ DEBUGFUNC("ixgbe_init_ops_X550EM");
+
+ /* Similar to X550 so start there. */
+ ret_val = ixgbe_init_ops_X550(hw);
+
+ /* Since this function eventually calls
+ * ixgbe_init_ops_540 by design, we are setting
+ * the pointers to NULL explicitly here to overwrite
+ * the values being set in the x540 function.
+ */
+
+ /* FCOE not supported in x550EM */
+ mac->ops.get_san_mac_addr = NULL;
+ mac->ops.set_san_mac_addr = NULL;
+ mac->ops.get_wwn_prefix = NULL;
+ mac->ops.get_fcoe_boot_status = NULL;
+
+ /* IPsec not supported in x550EM */
+ mac->ops.disable_sec_rx_path = NULL;
+ mac->ops.enable_sec_rx_path = NULL;
+
+ /* AUTOC register is not present in x550EM. */
+ mac->ops.prot_autoc_read = NULL;
+ mac->ops.prot_autoc_write = NULL;
+
+ /* X550EM bus type is internal*/
+ hw->bus.type = ixgbe_bus_type_internal;
+ mac->ops.get_bus_info = ixgbe_get_bus_info_X550em;
+
+ mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550;
+ mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550;
+ mac->ops.get_media_type = ixgbe_get_media_type_X550em;
+ mac->ops.setup_sfp = ixgbe_setup_sfp_modules_X550em;
+ mac->ops.get_link_capabilities = ixgbe_get_link_capabilities_X550em;
+ mac->ops.reset_hw = ixgbe_reset_hw_X550em;
+ mac->ops.get_supported_physical_layer =
+ ixgbe_get_supported_physical_layer_X550em;
+
+ if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper)
+ mac->ops.setup_fc = ixgbe_setup_fc_generic;
+ else
+ mac->ops.setup_fc = ixgbe_setup_fc_X550em;
+
+ mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X550em;
+ mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X550em;
+
+ if (hw->device_id != IXGBE_DEV_ID_X550EM_X_KR)
+ mac->ops.setup_eee = NULL;
+
+ /* PHY */
+ phy->ops.init = ixgbe_init_phy_ops_X550em;
+ phy->ops.identify = ixgbe_identify_phy_x550em;
+ if (mac->ops.get_media_type(hw) != ixgbe_media_type_copper)
+ phy->ops.set_phy_power = NULL;
+
+
+ /* EEPROM */
+ eeprom->ops.init_params = ixgbe_init_eeprom_params_X540;
+ eeprom->ops.read = ixgbe_read_ee_hostif_X550;
+ eeprom->ops.read_buffer = ixgbe_read_ee_hostif_buffer_X550;
+ eeprom->ops.write = ixgbe_write_ee_hostif_X550;
+ eeprom->ops.write_buffer = ixgbe_write_ee_hostif_buffer_X550;
+ eeprom->ops.update_checksum = ixgbe_update_eeprom_checksum_X550;
+ eeprom->ops.validate_checksum = ixgbe_validate_eeprom_checksum_X550;
+ eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_X550;
+
+ return ret_val;
+}
+
+/**
+ * ixgbe_dmac_config_X550
+ * @hw: pointer to hardware structure
+ *
+ * Configure DMA coalescing. If enabling dmac, dmac is activated.
+ * When disabling dmac, dmac enable dmac bit is cleared.
+ **/
+s32 ixgbe_dmac_config_X550(struct ixgbe_hw *hw)
+{
+ u32 reg, high_pri_tc;
+
+ DEBUGFUNC("ixgbe_dmac_config_X550");
+
+ /* Disable DMA coalescing before configuring */
+ reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
+ reg &= ~IXGBE_DMACR_DMAC_EN;
+ IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
+
+ /* Disable DMA Coalescing if the watchdog timer is 0 */
+ if (!hw->mac.dmac_config.watchdog_timer)
+ goto out;
+
+ ixgbe_dmac_config_tcs_X550(hw);
+
+ /* Configure DMA Coalescing Control Register */
+ reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
+
+ /* Set the watchdog timer in units of 40.96 usec */
+ reg &= ~IXGBE_DMACR_DMACWT_MASK;
+ reg |= (hw->mac.dmac_config.watchdog_timer * 100) / 4096;
+
+ reg &= ~IXGBE_DMACR_HIGH_PRI_TC_MASK;
+ /* If fcoe is enabled, set high priority traffic class */
+ if (hw->mac.dmac_config.fcoe_en) {
+ high_pri_tc = 1 << hw->mac.dmac_config.fcoe_tc;
+ reg |= ((high_pri_tc << IXGBE_DMACR_HIGH_PRI_TC_SHIFT) &
+ IXGBE_DMACR_HIGH_PRI_TC_MASK);
+ }
+ reg |= IXGBE_DMACR_EN_MNG_IND;
+
+ /* Enable DMA coalescing after configuration */
+ reg |= IXGBE_DMACR_DMAC_EN;
+ IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
+
+out:
+ return IXGBE_SUCCESS;
+}
+
+/**
+ * ixgbe_dmac_config_tcs_X550
+ * @hw: pointer to hardware structure
+ *
+ * Configure DMA coalescing threshold per TC. The dmac enable bit must
+ * be cleared before configuring.
+ **/
+s32 ixgbe_dmac_config_tcs_X550(struct ixgbe_hw *hw)
+{
+ u32 tc, reg, pb_headroom, rx_pb_size, maxframe_size_kb;
+
+ DEBUGFUNC("ixgbe_dmac_config_tcs_X550");
+
+ /* Configure DMA coalescing enabled */
+ switch (hw->mac.dmac_config.link_speed) {
+ case IXGBE_LINK_SPEED_100_FULL:
+ pb_headroom = IXGBE_DMACRXT_100M;
+ break;
+ case IXGBE_LINK_SPEED_1GB_FULL:
+ pb_headroom = IXGBE_DMACRXT_1G;
+ break;
+ default:
+ pb_headroom = IXGBE_DMACRXT_10G;
+ break;
+ }
+
+ maxframe_size_kb = ((IXGBE_READ_REG(hw, IXGBE_MAXFRS) >>
+ IXGBE_MHADD_MFS_SHIFT) / 1024);
+
+ /* Set the per Rx packet buffer receive threshold */
+ for (tc = 0; tc < IXGBE_DCB_MAX_TRAFFIC_CLASS; tc++) {
+ reg = IXGBE_READ_REG(hw, IXGBE_DMCTH(tc));
+ reg &= ~IXGBE_DMCTH_DMACRXT_MASK;
+
+ if (tc < hw->mac.dmac_config.num_tcs) {
+ /* Get Rx PB size */
+ rx_pb_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(tc));
+ rx_pb_size = (rx_pb_size & IXGBE_RXPBSIZE_MASK) >>
+ IXGBE_RXPBSIZE_SHIFT;
+
+ /* Calculate receive buffer threshold in kilobytes */
+ if (rx_pb_size > pb_headroom)
+ rx_pb_size = rx_pb_size - pb_headroom;
+ else
+ rx_pb_size = 0;
+
+ /* Minimum of MFS shall be set for DMCTH */
+ reg |= (rx_pb_size > maxframe_size_kb) ?
+ rx_pb_size : maxframe_size_kb;
+ }
+ IXGBE_WRITE_REG(hw, IXGBE_DMCTH(tc), reg);
+ }
+ return IXGBE_SUCCESS;
+}
+
+/**
+ * ixgbe_dmac_update_tcs_X550
+ * @hw: pointer to hardware structure
+ *
+ * Disables dmac, updates per TC settings, and then enables dmac.
+ **/
+s32 ixgbe_dmac_update_tcs_X550(struct ixgbe_hw *hw)
+{
+ u32 reg;
+
+ DEBUGFUNC("ixgbe_dmac_update_tcs_X550");
+
+ /* Disable DMA coalescing before configuring */
+ reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
+ reg &= ~IXGBE_DMACR_DMAC_EN;
+ IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
+
+ ixgbe_dmac_config_tcs_X550(hw);
+
+ /* Enable DMA coalescing after configuration */
+ reg = IXGBE_READ_REG(hw, IXGBE_DMACR);
+ reg |= IXGBE_DMACR_DMAC_EN;
+ IXGBE_WRITE_REG(hw, IXGBE_DMACR, reg);
+
+ return IXGBE_SUCCESS;
+}
+
+/**
+ * ixgbe_init_eeprom_params_X550 - Initialize EEPROM params
+ * @hw: pointer to hardware structure
+ *
+ * Initializes the EEPROM parameters ixgbe_eeprom_info within the
+ * ixgbe_hw struct in order to set up EEPROM access.
+ **/
+s32 ixgbe_init_eeprom_params_X550(struct ixgbe_hw *hw)
+{
+ struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
+ u32 eec;
+ u16 eeprom_size;
+
+ DEBUGFUNC("ixgbe_init_eeprom_params_X550");
+
+ if (eeprom->type == ixgbe_eeprom_uninitialized) {
+ eeprom->semaphore_delay = 10;
+ eeprom->type = ixgbe_flash;
+
+ eec = IXGBE_READ_REG(hw, IXGBE_EEC);
+ eeprom_size = (u16)((eec & IXGBE_EEC_SIZE) >>
+ IXGBE_EEC_SIZE_SHIFT);
+ eeprom->word_size = 1 << (eeprom_size +
+ IXGBE_EEPROM_WORD_SIZE_SHIFT);
+
+ DEBUGOUT2("Eeprom params: type = %d, size = %d\n",
+ eeprom->type, eeprom->word_size);
+ }
+
+ return IXGBE_SUCCESS;
+}
+
+/**
+ * ixgbe_setup_eee_X550 - Enable/disable EEE support
+ * @hw: pointer to the HW structure
+ * @enable_eee: boolean flag to enable EEE
+ *
+ * Enable/disable EEE based on enable_eee flag.
+ * Auto-negotiation must be started after BASE-T EEE bits in PHY register 7.3C
+ * are modified.
+ *
+ **/
+s32 ixgbe_setup_eee_X550(struct ixgbe_hw *hw, bool enable_eee)
+{
+ u32 eeer;
+ u16 autoneg_eee_reg;
+ u32 link_reg;
+ s32 status;
+ u32 fuse;
+
+ DEBUGFUNC("ixgbe_setup_eee_X550");
+
+ eeer = IXGBE_READ_REG(hw, IXGBE_EEER);
+ /* Enable or disable EEE per flag */
+ if (enable_eee) {
+ eeer |= (IXGBE_EEER_TX_LPI_EN | IXGBE_EEER_RX_LPI_EN);
+
+ if (hw->device_id == IXGBE_DEV_ID_X550T) {
+ /* Advertise EEE capability */
+ hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_EEE_ADVT,
+ IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_eee_reg);
+
+ autoneg_eee_reg |= (IXGBE_AUTO_NEG_10GBASE_EEE_ADVT |
+ IXGBE_AUTO_NEG_1000BASE_EEE_ADVT |
+ IXGBE_AUTO_NEG_100BASE_EEE_ADVT);
+
+ hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_EEE_ADVT,
+ IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_eee_reg);
+ } else if (hw->device_id == IXGBE_DEV_ID_X550EM_X_KR) {
+ /* Not supported on first revision. */
+ fuse = IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0));
+ if (!(fuse & IXGBE_FUSES0_REV1))
+ return IXGBE_SUCCESS;
+
+ status = ixgbe_read_iosf_sb_reg_x550(hw,
+ IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
+ IXGBE_SB_IOSF_TARGET_KR_PHY, &link_reg);
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ link_reg |= IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KR |
+ IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KX;
+
+ /* Don't advertise FEC capability when EEE enabled. */
+ link_reg &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_FEC;
+
+ status = ixgbe_write_iosf_sb_reg_x550(hw,
+ IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
+ IXGBE_SB_IOSF_TARGET_KR_PHY, link_reg);
+ if (status != IXGBE_SUCCESS)
+ return status;
+ }
+ } else {
+ eeer &= ~(IXGBE_EEER_TX_LPI_EN | IXGBE_EEER_RX_LPI_EN);
+
+ if (hw->device_id == IXGBE_DEV_ID_X550T) {
+ /* Disable advertised EEE capability */
+ hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_EEE_ADVT,
+ IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_eee_reg);
+
+ autoneg_eee_reg &= ~(IXGBE_AUTO_NEG_10GBASE_EEE_ADVT |
+ IXGBE_AUTO_NEG_1000BASE_EEE_ADVT |
+ IXGBE_AUTO_NEG_100BASE_EEE_ADVT);
+
+ hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_EEE_ADVT,
+ IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_eee_reg);
+ } else if (hw->device_id == IXGBE_DEV_ID_X550EM_X_KR) {
+ status = ixgbe_read_iosf_sb_reg_x550(hw,
+ IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
+ IXGBE_SB_IOSF_TARGET_KR_PHY, &link_reg);
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ link_reg &= ~(IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KR |
+ IXGBE_KRM_LINK_CTRL_1_TETH_EEE_CAP_KX);
+
+ /* Advertise FEC capability when EEE is disabled. */
+ link_reg |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_FEC;
+
+ status = ixgbe_write_iosf_sb_reg_x550(hw,
+ IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
+ IXGBE_SB_IOSF_TARGET_KR_PHY, link_reg);
+ if (status != IXGBE_SUCCESS)
+ return status;
+ }
+ }
+ IXGBE_WRITE_REG(hw, IXGBE_EEER, eeer);
+
+ return IXGBE_SUCCESS;
+}
+
+/**
+ * ixgbe_set_source_address_pruning_X550 - Enable/Disbale source address pruning
+ * @hw: pointer to hardware structure
+ * @enable: enable or disable source address pruning
+ * @pool: Rx pool to set source address pruning for
+ **/
+void ixgbe_set_source_address_pruning_X550(struct ixgbe_hw *hw, bool enable,
+ unsigned int pool)
+{
+ u64 pfflp;
+
+ /* max rx pool is 63 */
+ if (pool > 63)
+ return;
+
+ pfflp = (u64)IXGBE_READ_REG(hw, IXGBE_PFFLPL);
+ pfflp |= (u64)IXGBE_READ_REG(hw, IXGBE_PFFLPH) << 32;
+
+ if (enable)
+ pfflp |= (1ULL << pool);
+ else
+ pfflp &= ~(1ULL << pool);
+
+ IXGBE_WRITE_REG(hw, IXGBE_PFFLPL, (u32)pfflp);
+ IXGBE_WRITE_REG(hw, IXGBE_PFFLPH, (u32)(pfflp >> 32));
+}
+
+/**
+ * ixgbe_set_ethertype_anti_spoofing_X550 - Enable/Disable Ethertype anti-spoofing
+ * @hw: pointer to hardware structure
+ * @enable: enable or disable switch for Ethertype anti-spoofing
+ * @vf: Virtual Function pool - VF Pool to set for Ethertype anti-spoofing
+ *
+ **/
+void ixgbe_set_ethertype_anti_spoofing_X550(struct ixgbe_hw *hw,
+ bool enable, int vf)
+{
+ int vf_target_reg = vf >> 3;
+ int vf_target_shift = vf % 8 + IXGBE_SPOOF_ETHERTYPEAS_SHIFT;
+ u32 pfvfspoof;
+
+ DEBUGFUNC("ixgbe_set_ethertype_anti_spoofing_X550");
+
+ pfvfspoof = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg));
+ if (enable)
+ pfvfspoof |= (1 << vf_target_shift);
+ else
+ pfvfspoof &= ~(1 << vf_target_shift);
+
+ IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof);
+}
+
+/**
+ * ixgbe_iosf_wait - Wait for IOSF command completion
+ * @hw: pointer to hardware structure
+ * @ctrl: pointer to location to receive final IOSF control value
+ *
+ * Returns failing status on timeout
+ *
+ * Note: ctrl can be NULL if the IOSF control register value is not needed
+ **/
+static s32 ixgbe_iosf_wait(struct ixgbe_hw *hw, u32 *ctrl)
+{
+ u32 i, command;
+
+ /* Check every 10 usec to see if the address cycle completed.
+ * The SB IOSF BUSY bit will clear when the operation is
+ * complete
+ */
+ for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
+ command = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL);
+ if ((command & IXGBE_SB_IOSF_CTRL_BUSY) == 0)
+ break;
+ usec_delay(10);
+ }
+ if (ctrl)
+ *ctrl = command;
+ if (i == IXGBE_MDIO_COMMAND_TIMEOUT) {
+ ERROR_REPORT1(IXGBE_ERROR_POLLING, "Wait timed out\n");
+ return IXGBE_ERR_PHY;
+ }
+
+ return IXGBE_SUCCESS;
+}
+
+/**
+ * ixgbe_write_iosf_sb_reg_x550 - Writes a value to specified register of the IOSF
+ * device
+ * @hw: pointer to hardware structure
+ * @reg_addr: 32 bit PHY register to write
+ * @device_type: 3 bit device type
+ * @data: Data to write to the register
+ **/
+s32 ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
+ u32 device_type, u32 data)
+{
+ u32 gssr = IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_PHY0_SM;
+ u32 command, error;
+ s32 ret;
+
+ ret = ixgbe_acquire_swfw_semaphore(hw, gssr);
+ if (ret != IXGBE_SUCCESS)
+ return ret;
+
+ ret = ixgbe_iosf_wait(hw, NULL);
+ if (ret != IXGBE_SUCCESS)
+ goto out;
+
+ command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) |
+ (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT));
+
+ /* Write IOSF control register */
+ IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command);
+
+ /* Write IOSF data register */
+ IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA, data);
+
+ ret = ixgbe_iosf_wait(hw, &command);
+
+ if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) {
+ error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >>
+ IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT;
+ ERROR_REPORT2(IXGBE_ERROR_POLLING,
+ "Failed to write, error %x\n", error);
+ ret = IXGBE_ERR_PHY;
+ }
+
+out:
+ ixgbe_release_swfw_semaphore(hw, gssr);
+ return ret;
+}
+
+/**
+ * ixgbe_read_iosf_sb_reg_x550 - Writes a value to specified register of the IOSF
+ * device
+ * @hw: pointer to hardware structure
+ * @reg_addr: 32 bit PHY register to write
+ * @device_type: 3 bit device type
+ * @phy_data: Pointer to read data from the register
+ **/
+s32 ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
+ u32 device_type, u32 *data)
+{
+ u32 gssr = IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_PHY0_SM;
+ u32 command, error;
+ s32 ret;
+
+ ret = ixgbe_acquire_swfw_semaphore(hw, gssr);
+ if (ret != IXGBE_SUCCESS)
+ return ret;
+
+ ret = ixgbe_iosf_wait(hw, NULL);
+ if (ret != IXGBE_SUCCESS)
+ goto out;
+
+ command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) |
+ (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT));
+
+ /* Write IOSF control register */
+ IXGBE_WRITE_REG(hw, IXGBE_SB_IOSF_INDIRECT_CTRL, command);
+
+ ret = ixgbe_iosf_wait(hw, &command);
+
+ if ((command & IXGBE_SB_IOSF_CTRL_RESP_STAT_MASK) != 0) {
+ error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >>
+ IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT;
+ ERROR_REPORT2(IXGBE_ERROR_POLLING,
+ "Failed to read, error %x\n", error);
+ ret = IXGBE_ERR_PHY;
+ }
+
+ if (ret == IXGBE_SUCCESS)
+ *data = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA);
+
+out:
+ ixgbe_release_swfw_semaphore(hw, gssr);
+ return ret;
+}
+
+/**
+ * ixgbe_disable_mdd_X550
+ * @hw: pointer to hardware structure
+ *
+ * Disable malicious driver detection
+ **/
+void ixgbe_disable_mdd_X550(struct ixgbe_hw *hw)
+{
+ u32 reg;
+
+ DEBUGFUNC("ixgbe_disable_mdd_X550");
+
+ /* Disable MDD for TX DMA and interrupt */
+ reg = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
+ reg &= ~(IXGBE_DMATXCTL_MDP_EN | IXGBE_DMATXCTL_MBINTEN);
+ IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg);
+
+ /* Disable MDD for RX and interrupt */
+ reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
+ reg &= ~(IXGBE_RDRXCTL_MDP_EN | IXGBE_RDRXCTL_MBINTEN);
+ IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg);
+}
+
+/**
+ * ixgbe_enable_mdd_X550
+ * @hw: pointer to hardware structure
+ *
+ * Enable malicious driver detection
+ **/
+void ixgbe_enable_mdd_X550(struct ixgbe_hw *hw)
+{
+ u32 reg;
+
+ DEBUGFUNC("ixgbe_enable_mdd_X550");
+
+ /* Enable MDD for TX DMA and interrupt */
+ reg = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
+ reg |= (IXGBE_DMATXCTL_MDP_EN | IXGBE_DMATXCTL_MBINTEN);
+ IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg);
+
+ /* Enable MDD for RX and interrupt */
+ reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
+ reg |= (IXGBE_RDRXCTL_MDP_EN | IXGBE_RDRXCTL_MBINTEN);
+ IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg);
+}
+
+/**
+ * ixgbe_restore_mdd_vf_X550
+ * @hw: pointer to hardware structure
+ * @vf: vf index
+ *
+ * Restore VF that was disabled during malicious driver detection event
+ **/
+void ixgbe_restore_mdd_vf_X550(struct ixgbe_hw *hw, u32 vf)
+{
+ u32 idx, reg, num_qs, start_q, bitmask;
+
+ DEBUGFUNC("ixgbe_restore_mdd_vf_X550");
+
+ /* Map VF to queues */
+ reg = IXGBE_READ_REG(hw, IXGBE_MRQC);
+ switch (reg & IXGBE_MRQC_MRQE_MASK) {
+ case IXGBE_MRQC_VMDQRT8TCEN:
+ num_qs = 8; /* 16 VFs / pools */
+ bitmask = 0x000000FF;
+ break;
+ case IXGBE_MRQC_VMDQRSS32EN:
+ case IXGBE_MRQC_VMDQRT4TCEN:
+ num_qs = 4; /* 32 VFs / pools */
+ bitmask = 0x0000000F;
+ break;
+ default: /* 64 VFs / pools */
+ num_qs = 2;
+ bitmask = 0x00000003;
+ break;
+ }
+ start_q = vf * num_qs;
+
+ /* Release vf's queues by clearing WQBR_TX and WQBR_RX (RW1C) */
+ idx = start_q / 32;
+ reg = 0;
+ reg |= (bitmask << (start_q % 32));
+ IXGBE_WRITE_REG(hw, IXGBE_WQBR_TX(idx), reg);
+ IXGBE_WRITE_REG(hw, IXGBE_WQBR_RX(idx), reg);
+}
+
+/**
+ * ixgbe_mdd_event_X550
+ * @hw: pointer to hardware structure
+ * @vf_bitmap: vf bitmap of malicious vfs
+ *
+ * Handle malicious driver detection event.
+ **/
+void ixgbe_mdd_event_X550(struct ixgbe_hw *hw, u32 *vf_bitmap)
+{
+ u32 wqbr;
+ u32 i, j, reg, q, shift, vf, idx;
+
+ DEBUGFUNC("ixgbe_mdd_event_X550");
+
+ /* figure out pool size for mapping to vf's */
+ reg = IXGBE_READ_REG(hw, IXGBE_MRQC);
+ switch (reg & IXGBE_MRQC_MRQE_MASK) {
+ case IXGBE_MRQC_VMDQRT8TCEN:
+ shift = 3; /* 16 VFs / pools */
+ break;
+ case IXGBE_MRQC_VMDQRSS32EN:
+ case IXGBE_MRQC_VMDQRT4TCEN:
+ shift = 2; /* 32 VFs / pools */
+ break;
+ default:
+ shift = 1; /* 64 VFs / pools */
+ break;
+ }
+
+ /* Read WQBR_TX and WQBR_RX and check for malicious queues */
+ for (i = 0; i < 4; i++) {
+ wqbr = IXGBE_READ_REG(hw, IXGBE_WQBR_TX(i));
+ wqbr |= IXGBE_READ_REG(hw, IXGBE_WQBR_RX(i));
+
+ if (!wqbr)
+ continue;
+
+ /* Get malicious queue */
+ for (j = 0; j < 32 && wqbr; j++) {
+
+ if (!(wqbr & (1 << j)))
+ continue;
+
+ /* Get queue from bitmask */
+ q = j + (i * 32);
+
+ /* Map queue to vf */
+ vf = (q >> shift);
+
+ /* Set vf bit in vf_bitmap */
+ idx = vf / 32;
+ vf_bitmap[idx] |= (1 << (vf % 32));
+ wqbr &= ~(1 << j);
+ }
+ }
+}
+
+/**
+ * ixgbe_get_media_type_X550em - Get media type
+ * @hw: pointer to hardware structure
+ *
+ * Returns the media type (fiber, copper, backplane)
+ */
+enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw)
+{
+ enum ixgbe_media_type media_type;
+
+ DEBUGFUNC("ixgbe_get_media_type_X550em");
+
+ /* Detect if there is a copper PHY attached. */
+ switch (hw->device_id) {
+ case IXGBE_DEV_ID_X550EM_X_KR:
+ case IXGBE_DEV_ID_X550EM_X_KX4:
+ media_type = ixgbe_media_type_backplane;
+ break;
+ case IXGBE_DEV_ID_X550EM_X_SFP:
+ media_type = ixgbe_media_type_fiber;
+ break;
+ case IXGBE_DEV_ID_X550EM_X_1G_T:
+ case IXGBE_DEV_ID_X550EM_X_10G_T:
+ media_type = ixgbe_media_type_copper;
+ break;
+ default:
+ media_type = ixgbe_media_type_unknown;
+ break;
+ }
+ return media_type;
+}
+
+/**
+ * ixgbe_supported_sfp_modules_X550em - Check if SFP module type is supported
+ * @hw: pointer to hardware structure
+ * @linear: TRUE if SFP module is linear
+ */
+static s32 ixgbe_supported_sfp_modules_X550em(struct ixgbe_hw *hw, bool *linear)
+{
+ DEBUGFUNC("ixgbe_supported_sfp_modules_X550em");
+
+ switch (hw->phy.sfp_type) {
+ case ixgbe_sfp_type_not_present:
+ return IXGBE_ERR_SFP_NOT_PRESENT;
+ case ixgbe_sfp_type_da_cu_core0:
+ case ixgbe_sfp_type_da_cu_core1:
+ *linear = TRUE;
+ break;
+ case ixgbe_sfp_type_srlr_core0:
+ case ixgbe_sfp_type_srlr_core1:
+ case ixgbe_sfp_type_da_act_lmt_core0:
+ case ixgbe_sfp_type_da_act_lmt_core1:
+ case ixgbe_sfp_type_1g_sx_core0:
+ case ixgbe_sfp_type_1g_sx_core1:
+ case ixgbe_sfp_type_1g_lx_core0:
+ case ixgbe_sfp_type_1g_lx_core1:
+ *linear = FALSE;
+ break;
+ case ixgbe_sfp_type_unknown:
+ case ixgbe_sfp_type_1g_cu_core0:
+ case ixgbe_sfp_type_1g_cu_core1:
+ default:
+ return IXGBE_ERR_SFP_NOT_SUPPORTED;
+ }
+
+ return IXGBE_SUCCESS;
+}
+
+/**
+ * ixgbe_identify_sfp_module_X550em - Identifies SFP modules
+ * @hw: pointer to hardware structure
+ *
+ * Searches for and identifies the SFP module and assigns appropriate PHY type.
+ **/
+s32 ixgbe_identify_sfp_module_X550em(struct ixgbe_hw *hw)
+{
+ s32 status;
+ bool linear;
+
+ DEBUGFUNC("ixgbe_identify_sfp_module_X550em");
+
+ status = ixgbe_identify_module_generic(hw);
+
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ /* Check if SFP module is supported */
+ status = ixgbe_supported_sfp_modules_X550em(hw, &linear);
+
+ return status;
+}
+
+/**
+ * ixgbe_setup_sfp_modules_X550em - Setup MAC link ops
+ * @hw: pointer to hardware structure
+ */
+s32 ixgbe_setup_sfp_modules_X550em(struct ixgbe_hw *hw)
+{
+ s32 status;
+ bool linear;
+
+ DEBUGFUNC("ixgbe_setup_sfp_modules_X550em");
+
+ /* Check if SFP module is supported */
+ status = ixgbe_supported_sfp_modules_X550em(hw, &linear);
+
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ ixgbe_init_mac_link_ops_X550em(hw);
+ hw->phy.ops.reset = NULL;
+
+ return IXGBE_SUCCESS;
+}
+
+/**
+ * ixgbe_init_mac_link_ops_X550em - init mac link function pointers
+ * @hw: pointer to hardware structure
+ */
+void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw)
+{
+ struct ixgbe_mac_info *mac = &hw->mac;
+
+ DEBUGFUNC("ixgbe_init_mac_link_ops_X550em");
+
+ switch (hw->mac.ops.get_media_type(hw)) {
+ case ixgbe_media_type_fiber:
+ /* CS4227 does not support autoneg, so disable the laser control
+ * functions for SFP+ fiber
+ */
+ mac->ops.disable_tx_laser = NULL;
+ mac->ops.enable_tx_laser = NULL;
+ mac->ops.flap_tx_laser = NULL;
+ mac->ops.setup_link = ixgbe_setup_mac_link_multispeed_fiber;
+ mac->ops.setup_mac_link = ixgbe_setup_mac_link_sfp_x550em;
+ mac->ops.set_rate_select_speed =
+ ixgbe_set_soft_rate_select_speed;
+ break;
+ case ixgbe_media_type_copper:
+ mac->ops.setup_link = ixgbe_setup_mac_link_t_X550em;
+ mac->ops.check_link = ixgbe_check_link_t_X550em;
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * ixgbe_get_link_capabilities_x550em - Determines link capabilities
+ * @hw: pointer to hardware structure
+ * @speed: pointer to link speed
+ * @autoneg: TRUE when autoneg or autotry is enabled
+ */
+s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw,
+ ixgbe_link_speed *speed,
+ bool *autoneg)
+{
+ DEBUGFUNC("ixgbe_get_link_capabilities_X550em");
+
+ /* SFP */
+ if (hw->phy.media_type == ixgbe_media_type_fiber) {
+
+ /* CS4227 SFP must not enable auto-negotiation */
+ *autoneg = FALSE;
+
+ /* Check if 1G SFP module. */
+ if (hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
+ hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1
+ || hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 ||
+ hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1) {
+ *speed = IXGBE_LINK_SPEED_1GB_FULL;
+ return IXGBE_SUCCESS;
+ }
+
+ /* Link capabilities are based on SFP */
+ if (hw->phy.multispeed_fiber)
+ *speed = IXGBE_LINK_SPEED_10GB_FULL |
+ IXGBE_LINK_SPEED_1GB_FULL;
+ else
+ *speed = IXGBE_LINK_SPEED_10GB_FULL;
+ } else {
+ *speed = IXGBE_LINK_SPEED_10GB_FULL |
+ IXGBE_LINK_SPEED_1GB_FULL;
+ *autoneg = TRUE;
+ }
+
+ return IXGBE_SUCCESS;
+}
+
+/**
+ * ixgbe_get_lasi_ext_t_x550em - Determime external Base T PHY interrupt cause
+ * @hw: pointer to hardware structure
+ * @lsc: pointer to boolean flag which indicates whether external Base T
+ * PHY interrupt is lsc
+ *
+ * Determime if external Base T PHY interrupt cause is high temperature
+ * failure alarm or link status change.
+ *
+ * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature
+ * failure alarm, else return PHY access status.
+ */
+static s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc)
+{
+ u32 status;
+ u16 reg;
+
+ *lsc = FALSE;
+
+ /* Vendor alarm triggered */
+ status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG,
+ IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
+ &reg);
+
+ if (status != IXGBE_SUCCESS ||
+ !(reg & IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN))
+ return status;
+
+ /* Vendor Auto-Neg alarm triggered or Global alarm 1 triggered */
+ status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_FLAG,
+ IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
+ &reg);
+
+ if (status != IXGBE_SUCCESS ||
+ !(reg & (IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN |
+ IXGBE_MDIO_GLOBAL_ALARM_1_INT)))
+ return status;
+
+ /* High temperature failure alarm triggered */
+ status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_ALARM_1,
+ IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
+ &reg);
+
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ /* If high temperature failure, then return over temp error and exit */
+ if (reg & IXGBE_MDIO_GLOBAL_ALM_1_HI_TMP_FAIL) {
+ /* power down the PHY in case the PHY FW didn't already */
+ ixgbe_set_copper_phy_power(hw, FALSE);
+ return IXGBE_ERR_OVERTEMP;
+ }
+
+ /* Vendor alarm 2 triggered */
+ status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG,
+ IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &reg);
+
+ if (status != IXGBE_SUCCESS ||
+ !(reg & IXGBE_MDIO_GLOBAL_STD_ALM2_INT))
+ return status;
+
+ /* link connect/disconnect event occurred */
+ status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM2,
+ IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &reg);
+
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ /* Indicate LSC */
+ if (reg & IXGBE_MDIO_AUTO_NEG_VEN_LSC)
+ *lsc = TRUE;
+
+ return IXGBE_SUCCESS;
+}
+
+/**
+ * ixgbe_enable_lasi_ext_t_x550em - Enable external Base T PHY interrupts
+ * @hw: pointer to hardware structure
+ *
+ * Enable link status change and temperature failure alarm for the external
+ * Base T PHY
+ *
+ * Returns PHY access status
+ */
+static s32 ixgbe_enable_lasi_ext_t_x550em(struct ixgbe_hw *hw)
+{
+ u32 status;
+ u16 reg;
+ bool lsc;
+
+ /* Clear interrupt flags */
+ status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc);
+
+ /* Enable link status change alarm */
+ status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK,
+ IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &reg);
+
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ reg |= IXGBE_MDIO_PMA_TX_VEN_LASI_INT_EN;
+
+ status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_PMA_TX_VEN_LASI_INT_MASK,
+ IXGBE_MDIO_AUTO_NEG_DEV_TYPE, reg);
+
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ /* Enables high temperature failure alarm */
+ status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK,
+ IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
+ &reg);
+
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ reg |= IXGBE_MDIO_GLOBAL_INT_HI_TEMP_EN;
+
+ status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK,
+ IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
+ reg);
+
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ /* Enable vendor Auto-Neg alarm and Global Interrupt Mask 1 alarm */
+ status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK,
+ IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
+ &reg);
+
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ reg |= (IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN |
+ IXGBE_MDIO_GLOBAL_ALARM_1_INT);
+
+ status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK,
+ IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
+ reg);
+
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ /* Enable chip-wide vendor alarm */
+ status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_STD_MASK,
+ IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
+ &reg);
+
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ reg |= IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN;
+
+ status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_CHIP_STD_MASK,
+ IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
+ reg);
+
+ return status;
+}
+
+/**
+ * ixgbe_setup_kr_speed_x550em - Configure the KR PHY for link speed.
+ * @hw: pointer to hardware structure
+ * @speed: link speed
+ *
+ * Configures the integrated KR PHY.
+ **/
+static s32 ixgbe_setup_kr_speed_x550em(struct ixgbe_hw *hw,
+ ixgbe_link_speed speed)
+{
+ s32 status;
+ u32 reg_val;
+
+ status = ixgbe_read_iosf_sb_reg_x550(hw,
+ IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
+ IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
+ if (status)
+ return status;
+
+ reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
+ reg_val &= ~(IXGBE_KRM_LINK_CTRL_1_TETH_AN_FEC_REQ |
+ IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_FEC);
+ reg_val &= ~(IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR |
+ IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX);
+
+ /* Advertise 10G support. */
+ if (speed & IXGBE_LINK_SPEED_10GB_FULL)
+ reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KR;
+
+ /* Advertise 1G support. */
+ if (speed & IXGBE_LINK_SPEED_1GB_FULL)
+ reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX;
+
+ /* Restart auto-negotiation. */
+ reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
+ status = ixgbe_write_iosf_sb_reg_x550(hw,
+ IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
+ IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
+
+ return status;
+}
+
+/**
+ * ixgbe_init_phy_ops_X550em - PHY/SFP specific init
+ * @hw: pointer to hardware structure
+ *
+ * Initialize any function pointers that were not able to be
+ * set during init_shared_code because the PHY/SFP type was
+ * not known. Perform the SFP init if necessary.
+ */
+s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw)
+{
+ struct ixgbe_phy_info *phy = &hw->phy;
+ ixgbe_link_speed speed;
+ s32 ret_val;
+
+ DEBUGFUNC("ixgbe_init_phy_ops_X550em");
+
+ hw->mac.ops.set_lan_id(hw);
+
+ if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) {
+ phy->phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
+ ixgbe_setup_mux_ctl(hw);
+
+ /* Save NW management interface connected on board. This is used
+ * to determine internal PHY mode.
+ */
+ phy->nw_mng_if_sel = IXGBE_READ_REG(hw, IXGBE_NW_MNG_IF_SEL);
+
+ /* If internal PHY mode is KR, then initialize KR link */
+ if (phy->nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE) {
+ speed = IXGBE_LINK_SPEED_10GB_FULL |
+ IXGBE_LINK_SPEED_1GB_FULL;
+ ret_val = ixgbe_setup_kr_speed_x550em(hw, speed);
+ }
+
+ phy->ops.identify_sfp = ixgbe_identify_sfp_module_X550em;
+ }
+
+ /* Identify the PHY or SFP module */
+ ret_val = phy->ops.identify(hw);
+ if (ret_val == IXGBE_ERR_SFP_NOT_SUPPORTED)
+ return ret_val;
+
+ /* Setup function pointers based on detected hardware */
+ ixgbe_init_mac_link_ops_X550em(hw);
+ if (phy->sfp_type != ixgbe_sfp_type_unknown)
+ phy->ops.reset = NULL;
+
+ /* Set functions pointers based on phy type */
+ switch (hw->phy.type) {
+ case ixgbe_phy_x550em_kx4:
+ phy->ops.setup_link = ixgbe_setup_kx4_x550em;
+ phy->ops.read_reg = ixgbe_read_phy_reg_x550em;
+ phy->ops.write_reg = ixgbe_write_phy_reg_x550em;
+ break;
+ case ixgbe_phy_x550em_kr:
+ phy->ops.setup_link = ixgbe_setup_kr_x550em;
+ phy->ops.read_reg = ixgbe_read_phy_reg_x550em;
+ phy->ops.write_reg = ixgbe_write_phy_reg_x550em;
+ break;
+ case ixgbe_phy_x550em_ext_t:
+ /* Save NW management interface connected on board. This is used
+ * to determine internal PHY mode
+ */
+ phy->nw_mng_if_sel = IXGBE_READ_REG(hw, IXGBE_NW_MNG_IF_SEL);
+
+ /* If internal link mode is XFI, then setup iXFI internal link,
+ * else setup KR now.
+ */
+ if (!(phy->nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) {
+ phy->ops.setup_internal_link =
+ ixgbe_setup_internal_phy_t_x550em;
+ } else {
+ speed = IXGBE_LINK_SPEED_10GB_FULL |
+ IXGBE_LINK_SPEED_1GB_FULL;
+ ret_val = ixgbe_setup_kr_speed_x550em(hw, speed);
+ }
+
+ phy->ops.enter_lplu = ixgbe_enter_lplu_t_x550em;
+ phy->ops.handle_lasi = ixgbe_handle_lasi_ext_t_x550em;
+ phy->ops.reset = ixgbe_reset_phy_t_X550em;
+ break;
+ default:
+ break;
+ }
+ return ret_val;
+}
+
+/**
+ * ixgbe_reset_hw_X550em - Perform hardware reset
+ * @hw: pointer to hardware structure
+ *
+ * Resets the hardware by resetting the transmit and receive units, masks
+ * and clears all interrupts, perform a PHY reset, and perform a link (MAC)
+ * reset.
+ */
+s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw)
+{
+ ixgbe_link_speed link_speed;
+ s32 status;
+ u32 ctrl = 0;
+ u32 i;
+ u32 hlreg0;
+ bool link_up = FALSE;
+
+ DEBUGFUNC("ixgbe_reset_hw_X550em");
+
+ /* Call adapter stop to disable Tx/Rx and clear interrupts */
+ status = hw->mac.ops.stop_adapter(hw);
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ /* flush pending Tx transactions */
+ ixgbe_clear_tx_pending(hw);
+
+ /* PHY ops must be identified and initialized prior to reset */
+
+ /* Identify PHY and related function pointers */
+ status = hw->phy.ops.init(hw);
+
+ if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
+ return status;
+
+ /* start the external PHY */
+ if (hw->phy.type == ixgbe_phy_x550em_ext_t) {
+ status = ixgbe_init_ext_t_x550em(hw);
+ if (status)
+ return status;
+ }
+
+ /* Setup SFP module if there is one present. */
+ if (hw->phy.sfp_setup_needed) {
+ status = hw->mac.ops.setup_sfp(hw);
+ hw->phy.sfp_setup_needed = FALSE;
+ }
+
+ if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
+ return status;
+
+ /* Reset PHY */
+ if (!hw->phy.reset_disable && hw->phy.ops.reset)
+ hw->phy.ops.reset(hw);
+
+mac_reset_top:
+ /* Issue global reset to the MAC. Needs to be SW reset if link is up.
+ * If link reset is used when link is up, it might reset the PHY when
+ * mng is using it. If link is down or the flag to force full link
+ * reset is set, then perform link reset.
+ */
+ ctrl = IXGBE_CTRL_LNK_RST;
+ if (!hw->force_full_reset) {
+ hw->mac.ops.check_link(hw, &link_speed, &link_up, FALSE);
+ if (link_up)
+ ctrl = IXGBE_CTRL_RST;
+ }
+
+ ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
+ IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
+ IXGBE_WRITE_FLUSH(hw);
+
+ /* Poll for reset bit to self-clear meaning reset is complete */
+ for (i = 0; i < 10; i++) {
+ usec_delay(1);
+ ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
+ if (!(ctrl & IXGBE_CTRL_RST_MASK))
+ break;
+ }
+
+ if (ctrl & IXGBE_CTRL_RST_MASK) {
+ status = IXGBE_ERR_RESET_FAILED;
+ DEBUGOUT("Reset polling failed to complete.\n");
+ }
+
+ msec_delay(50);
+
+ /* Double resets are required for recovery from certain error
+ * conditions. Between resets, it is necessary to stall to
+ * allow time for any pending HW events to complete.
+ */
+ if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
+ hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
+ goto mac_reset_top;
+ }
+
+ /* Store the permanent mac address */
+ hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
+
+ /* Store MAC address from RAR0, clear receive address registers, and
+ * clear the multicast table. Also reset num_rar_entries to 128,
+ * since we modify this value when programming the SAN MAC address.
+ */
+ hw->mac.num_rar_entries = 128;
+ hw->mac.ops.init_rx_addrs(hw);
+
+ if (hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T) {
+ /* Config MDIO clock speed. */
+ hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
+ hlreg0 &= ~IXGBE_HLREG0_MDCSPD;
+ IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
+ }
+
+ if (hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP)
+ ixgbe_setup_mux_ctl(hw);
+
+ return status;
+}
+
+/**
+ * ixgbe_init_ext_t_x550em - Start (unstall) the external Base T PHY.
+ * @hw: pointer to hardware structure
+ */
+s32 ixgbe_init_ext_t_x550em(struct ixgbe_hw *hw)
+{
+ u32 status;
+ u16 reg;
+
+ status = hw->phy.ops.read_reg(hw,
+ IXGBE_MDIO_TX_VENDOR_ALARMS_3,
+ IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+ &reg);
+
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ /* If PHY FW reset completed bit is set then this is the first
+ * SW instance after a power on so the PHY FW must be un-stalled.
+ */
+ if (reg & IXGBE_MDIO_TX_VENDOR_ALARMS_3_RST_MASK) {
+ status = hw->phy.ops.read_reg(hw,
+ IXGBE_MDIO_GLOBAL_RES_PR_10,
+ IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
+ &reg);
+
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ reg &= ~IXGBE_MDIO_POWER_UP_STALL;
+
+ status = hw->phy.ops.write_reg(hw,
+ IXGBE_MDIO_GLOBAL_RES_PR_10,
+ IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
+ reg);
+
+ if (status != IXGBE_SUCCESS)
+ return status;
+ }
+
+ return status;
+}
+
+/**
+ * ixgbe_setup_kr_x550em - Configure the KR PHY.
+ * @hw: pointer to hardware structure
+ *
+ * Configures the integrated KR PHY.
+ **/
+s32 ixgbe_setup_kr_x550em(struct ixgbe_hw *hw)
+{
+ return ixgbe_setup_kr_speed_x550em(hw, hw->phy.autoneg_advertised);
+}
+
+/**
+ * ixgbe_setup_kx4_x550em - Configure the KX4 PHY.
+ * @hw: pointer to hardware structure
+ *
+ * Configures the integrated KX4 PHY.
+ **/
+s32 ixgbe_setup_kx4_x550em(struct ixgbe_hw *hw)
+{
+ s32 status;
+ u32 reg_val;
+
+ status = ixgbe_read_iosf_sb_reg_x550(hw, IXGBE_KX4_LINK_CNTL_1,
+ IXGBE_SB_IOSF_TARGET_KX4_PCS, &reg_val);
+ if (status)
+ return status;
+
+ reg_val &= ~(IXGBE_KX4_LINK_CNTL_1_TETH_AN_CAP_KX4 |
+ IXGBE_KX4_LINK_CNTL_1_TETH_AN_CAP_KX);
+
+ reg_val |= IXGBE_KX4_LINK_CNTL_1_TETH_AN_ENABLE;
+
+ /* Advertise 10G support. */
+ if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
+ reg_val |= IXGBE_KX4_LINK_CNTL_1_TETH_AN_CAP_KX4;
+
+ /* Advertise 1G support. */
+ if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
+ reg_val |= IXGBE_KX4_LINK_CNTL_1_TETH_AN_CAP_KX;
+
+ /* Restart auto-negotiation. */
+ reg_val |= IXGBE_KX4_LINK_CNTL_1_TETH_AN_RESTART;
+ status = ixgbe_write_iosf_sb_reg_x550(hw, IXGBE_KX4_LINK_CNTL_1,
+ IXGBE_SB_IOSF_TARGET_KX4_PCS, reg_val);
+
+ return status;
+}
+
+/**
+ * ixgbe_setup_mac_link_sfp_x550em - Setup internal/external the PHY for SFP
+ * @hw: pointer to hardware structure
+ *
+ * Configure the external PHY and the integrated KR PHY for SFP support.
+ **/
+s32 ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw,
+ ixgbe_link_speed speed,
+ bool autoneg_wait_to_complete)
+{
+ s32 ret_val;
+ u16 reg_slice, reg_val;
+ bool setup_linear = FALSE;
+ UNREFERENCED_1PARAMETER(autoneg_wait_to_complete);
+
+ /* Check if SFP module is supported and linear */
+ ret_val = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear);
+
+ /* If no SFP module present, then return success. Return success since
+ * there is no reason to configure CS4227 and SFP not present error is
+ * not excepted in the setup MAC link flow.
+ */
+ if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT)
+ return IXGBE_SUCCESS;
+
+ if (ret_val != IXGBE_SUCCESS)
+ return ret_val;
+
+ /* Configure CS4227 for LINE connection rate then type. */
+ reg_slice = IXGBE_CS4227_LINE_SPARE22_MSB + (hw->bus.lan_id << 12);
+ reg_val = (speed & IXGBE_LINK_SPEED_10GB_FULL) ? 0 : 0x8000;
+ ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice,
+ reg_val);
+
+ reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB + (hw->bus.lan_id << 12);
+ if (setup_linear)
+ reg_val = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1;
+ else
+ reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
+ ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice,
+ reg_val);
+
+ /* Configure CS4227 for HOST connection rate then type. */
+ reg_slice = IXGBE_CS4227_HOST_SPARE22_MSB + (hw->bus.lan_id << 12);
+ reg_val = (speed & IXGBE_LINK_SPEED_10GB_FULL) ? 0 : 0x8000;
+ ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice,
+ reg_val);
+
+ reg_slice = IXGBE_CS4227_HOST_SPARE24_LSB + (hw->bus.lan_id << 12);
+ if (setup_linear)
+ reg_val = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1;
+ else
+ reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
+ ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice,
+ reg_val);
+
+ /* If internal link mode is XFI, then setup XFI internal link. */
+ if (!(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE))
+ ret_val = ixgbe_setup_ixfi_x550em(hw, &speed);
+
+ return ret_val;
+}
+
+/**
+ * ixgbe_setup_ixfi_x550em - Configure the KR PHY for iXFI mode.
+ * @hw: pointer to hardware structure
+ * @speed: the link speed to force
+ *
+ * Configures the integrated KR PHY to use iXFI mode. Used to connect an
+ * internal and external PHY at a specific speed, without autonegotiation.
+ **/
+static s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed)
+{
+ s32 status;
+ u32 reg_val;
+
+ /* Disable AN and force speed to 10G Serial. */
+ status = ixgbe_read_iosf_sb_reg_x550(hw,
+ IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
+ IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
+ reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
+
+ /* Select forced link speed for internal PHY. */
+ switch (*speed) {
+ case IXGBE_LINK_SPEED_10GB_FULL:
+ reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G;
+ break;
+ case IXGBE_LINK_SPEED_1GB_FULL:
+ reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G;
+ break;
+ default:
+ /* Other link speeds are not supported by internal KR PHY. */
+ return IXGBE_ERR_LINK_SETUP;
+ }
+
+ status = ixgbe_write_iosf_sb_reg_x550(hw,
+ IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
+ IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ /* Disable training protocol FSM. */
+ status = ixgbe_read_iosf_sb_reg_x550(hw,
+ IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
+ IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
+ if (status != IXGBE_SUCCESS)
+ return status;
+ reg_val |= IXGBE_KRM_RX_TRN_LINKUP_CTRL_CONV_WO_PROTOCOL;
+ status = ixgbe_write_iosf_sb_reg_x550(hw,
+ IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
+ IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ /* Disable Flex from training TXFFE. */
+ status = ixgbe_read_iosf_sb_reg_x550(hw,
+ IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id),
+ IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
+ if (status != IXGBE_SUCCESS)
+ return status;
+ reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN;
+ reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN;
+ reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN;
+ status = ixgbe_write_iosf_sb_reg_x550(hw,
+ IXGBE_KRM_DSP_TXFFE_STATE_4(hw->bus.lan_id),
+ IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
+ if (status != IXGBE_SUCCESS)
+ return status;
+ status = ixgbe_read_iosf_sb_reg_x550(hw,
+ IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id),
+ IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
+ if (status != IXGBE_SUCCESS)
+ return status;
+ reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_C0_EN;
+ reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN;
+ reg_val &= ~IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN;
+ status = ixgbe_write_iosf_sb_reg_x550(hw,
+ IXGBE_KRM_DSP_TXFFE_STATE_5(hw->bus.lan_id),
+ IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ /* Enable override for coefficients. */
+ status = ixgbe_read_iosf_sb_reg_x550(hw,
+ IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id),
+ IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
+ if (status != IXGBE_SUCCESS)
+ return status;
+ reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_OVRRD_EN;
+ reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CZERO_EN;
+ reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CPLUS1_OVRRD_EN;
+ reg_val |= IXGBE_KRM_TX_COEFF_CTRL_1_CMINUS1_OVRRD_EN;
+ status = ixgbe_write_iosf_sb_reg_x550(hw,
+ IXGBE_KRM_TX_COEFF_CTRL_1(hw->bus.lan_id),
+ IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ /* Toggle port SW reset by AN reset. */
+ status = ixgbe_read_iosf_sb_reg_x550(hw,
+ IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
+ IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
+ if (status != IXGBE_SUCCESS)
+ return status;
+ reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
+ status = ixgbe_write_iosf_sb_reg_x550(hw,
+ IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
+ IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
+
+ return status;
+}
+
+/**
+ * ixgbe_ext_phy_t_x550em_get_link - Get ext phy link status
+ * @hw: address of hardware structure
+ * @link_up: address of boolean to indicate link status
+ *
+ * Returns error code if unable to get link status.
+ */
+static s32 ixgbe_ext_phy_t_x550em_get_link(struct ixgbe_hw *hw, bool *link_up)
+{
+ u32 ret;
+ u16 autoneg_status;
+
+ *link_up = FALSE;
+
+ /* read this twice back to back to indicate current status */
+ ret = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
+ IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
+ &autoneg_status);
+ if (ret != IXGBE_SUCCESS)
+ return ret;
+
+ ret = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
+ IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
+ &autoneg_status);
+ if (ret != IXGBE_SUCCESS)
+ return ret;
+
+ *link_up = !!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS);
+
+ return IXGBE_SUCCESS;
+}
+
+/**
+ * ixgbe_setup_internal_phy_t_x550em - Configure KR PHY to X557 link
+ * @hw: point to hardware structure
+ *
+ * Configures the link between the integrated KR PHY and the external X557 PHY
+ * The driver will call this function when it gets a link status change
+ * interrupt from the X557 PHY. This function configures the link speed
+ * between the PHYs to match the link speed of the BASE-T link.
+ *
+ * A return of a non-zero value indicates an error, and the base driver should
+ * not report link up.
+ */
+s32 ixgbe_setup_internal_phy_t_x550em(struct ixgbe_hw *hw)
+{
+ ixgbe_link_speed force_speed;
+ bool link_up;
+ u32 status;
+ u16 speed;
+
+ if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper)
+ return IXGBE_ERR_CONFIG;
+
+ /* If link is not up, then there is no setup necessary so return */
+ status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ if (!link_up)
+ return IXGBE_SUCCESS;
+
+ status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_STAT,
+ IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
+ &speed);
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ /* If link is not still up, then no setup is necessary so return */
+ status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
+ if (status != IXGBE_SUCCESS)
+ return status;
+ if (!link_up)
+ return IXGBE_SUCCESS;
+
+ /* clear everything but the speed and duplex bits */
+ speed &= IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_MASK;
+
+ switch (speed) {
+ case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB_FULL:
+ force_speed = IXGBE_LINK_SPEED_10GB_FULL;
+ break;
+ case IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB_FULL:
+ force_speed = IXGBE_LINK_SPEED_1GB_FULL;
+ break;
+ default:
+ /* Internal PHY does not support anything else */
+ return IXGBE_ERR_INVALID_LINK_SETTINGS;
+ }
+
+ return ixgbe_setup_ixfi_x550em(hw, &force_speed);
+}
+
+/**
+ * ixgbe_setup_phy_loopback_x550em - Configure the KR PHY for loopback.
+ * @hw: pointer to hardware structure
+ *
+ * Configures the integrated KR PHY to use internal loopback mode.
+ **/
+s32 ixgbe_setup_phy_loopback_x550em(struct ixgbe_hw *hw)
+{
+ s32 status;
+ u32 reg_val;
+
+ /* Disable AN and force speed to 10G Serial. */
+ status = ixgbe_read_iosf_sb_reg_x550(hw,
+ IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
+ IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
+ if (status != IXGBE_SUCCESS)
+ return status;
+ reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
+ reg_val &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
+ reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G;
+ status = ixgbe_write_iosf_sb_reg_x550(hw,
+ IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
+ IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ /* Set near-end loopback clocks. */
+ status = ixgbe_read_iosf_sb_reg_x550(hw,
+ IXGBE_KRM_PORT_CAR_GEN_CTRL(hw->bus.lan_id),
+ IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
+ if (status != IXGBE_SUCCESS)
+ return status;
+ reg_val |= IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_32B;
+ reg_val |= IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_KRPCS;
+ status = ixgbe_write_iosf_sb_reg_x550(hw,
+ IXGBE_KRM_PORT_CAR_GEN_CTRL(hw->bus.lan_id),
+ IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ /* Set loopback enable. */
+ status = ixgbe_read_iosf_sb_reg_x550(hw,
+ IXGBE_KRM_PMD_DFX_BURNIN(hw->bus.lan_id),
+ IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
+ if (status != IXGBE_SUCCESS)
+ return status;
+ reg_val |= IXGBE_KRM_PMD_DFX_BURNIN_TX_RX_KR_LB_MASK;
+ status = ixgbe_write_iosf_sb_reg_x550(hw,
+ IXGBE_KRM_PMD_DFX_BURNIN(hw->bus.lan_id),
+ IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ /* Training bypass. */
+ status = ixgbe_read_iosf_sb_reg_x550(hw,
+ IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
+ IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
+ if (status != IXGBE_SUCCESS)
+ return status;
+ reg_val |= IXGBE_KRM_RX_TRN_LINKUP_CTRL_PROTOCOL_BYPASS;
+ status = ixgbe_write_iosf_sb_reg_x550(hw,
+ IXGBE_KRM_RX_TRN_LINKUP_CTRL(hw->bus.lan_id),
+ IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
+
+ return status;
+}
+
+/**
+ * ixgbe_read_ee_hostif_X550 - Read EEPROM word using a host interface command
+ * assuming that the semaphore is already obtained.
+ * @hw: pointer to hardware structure
+ * @offset: offset of word in the EEPROM to read
+ * @data: word read from the EEPROM
+ *
+ * Reads a 16 bit word from the EEPROM using the hostif.
+ **/
+s32 ixgbe_read_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset,
+ u16 *data)
+{
+ s32 status;
+ struct ixgbe_hic_read_shadow_ram buffer;
+
+ DEBUGFUNC("ixgbe_read_ee_hostif_data_X550");
+ buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD;
+ buffer.hdr.req.buf_lenh = 0;
+ buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN;
+ buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
+
+ /* convert offset from words to bytes */
+ buffer.address = IXGBE_CPU_TO_BE32(offset * 2);
+ /* one word */
+ buffer.length = IXGBE_CPU_TO_BE16(sizeof(u16));
+
+ status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
+ sizeof(buffer),
+ IXGBE_HI_COMMAND_TIMEOUT, FALSE);
+
+ if (status)
+ return status;
+
+ *data = (u16)IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG,
+ FW_NVM_DATA_OFFSET);
+
+ return 0;
+}
+
+/**
+ * ixgbe_read_ee_hostif_X550 - Read EEPROM word using a host interface command
+ * @hw: pointer to hardware structure
+ * @offset: offset of word in the EEPROM to read
+ * @data: word read from the EEPROM
+ *
+ * Reads a 16 bit word from the EEPROM using the hostif.
+ **/
+s32 ixgbe_read_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset,
+ u16 *data)
+{
+ s32 status = IXGBE_SUCCESS;
+
+ DEBUGFUNC("ixgbe_read_ee_hostif_X550");
+
+ if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
+ IXGBE_SUCCESS) {
+ status = ixgbe_read_ee_hostif_data_X550(hw, offset, data);
+ hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
+ } else {
+ status = IXGBE_ERR_SWFW_SYNC;
+ }
+
+ return status;
+}
+
+/**
+ * ixgbe_read_ee_hostif_buffer_X550- Read EEPROM word(s) using hostif
+ * @hw: pointer to hardware structure
+ * @offset: offset of word in the EEPROM to read
+ * @words: number of words
+ * @data: word(s) read from the EEPROM
+ *
+ * Reads a 16 bit word(s) from the EEPROM using the hostif.
+ **/
+s32 ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
+ u16 offset, u16 words, u16 *data)
+{
+ struct ixgbe_hic_read_shadow_ram buffer;
+ u32 current_word = 0;
+ u16 words_to_read;
+ s32 status;
+ u32 i;
+
+ DEBUGFUNC("ixgbe_read_ee_hostif_buffer_X550");
+
+ /* Take semaphore for the entire operation. */
+ status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
+ if (status) {
+ DEBUGOUT("EEPROM read buffer - semaphore failed\n");
+ return status;
+ }
+ while (words) {
+ if (words > FW_MAX_READ_BUFFER_SIZE / 2)
+ words_to_read = FW_MAX_READ_BUFFER_SIZE / 2;
+ else
+ words_to_read = words;
+
+ buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD;
+ buffer.hdr.req.buf_lenh = 0;
+ buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN;
+ buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
+
+ /* convert offset from words to bytes */
+ buffer.address = IXGBE_CPU_TO_BE32((offset + current_word) * 2);
+ buffer.length = IXGBE_CPU_TO_BE16(words_to_read * 2);
+
+ status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
+ sizeof(buffer),
+ IXGBE_HI_COMMAND_TIMEOUT,
+ FALSE);
+
+ if (status) {
+ DEBUGOUT("Host interface command failed\n");
+ goto out;
+ }
+
+ for (i = 0; i < words_to_read; i++) {
+ u32 reg = IXGBE_FLEX_MNG + (FW_NVM_DATA_OFFSET << 2) +
+ 2 * i;
+ u32 value = IXGBE_READ_REG(hw, reg);
+
+ data[current_word] = (u16)(value & 0xffff);
+ current_word++;
+ i++;
+ if (i < words_to_read) {
+ value >>= 16;
+ data[current_word] = (u16)(value & 0xffff);
+ current_word++;
+ }
+ }
+ words -= words_to_read;
+ }
+
+out:
+ hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
+ return status;
+}
+
+/**
+ * ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif
+ * @hw: pointer to hardware structure
+ * @offset: offset of word in the EEPROM to write
+ * @data: word write to the EEPROM
+ *
+ * Write a 16 bit word to the EEPROM using the hostif.
+ **/
+s32 ixgbe_write_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset,
+ u16 data)
+{
+ s32 status;
+ struct ixgbe_hic_write_shadow_ram buffer;
+
+ DEBUGFUNC("ixgbe_write_ee_hostif_data_X550");
+
+ buffer.hdr.req.cmd = FW_WRITE_SHADOW_RAM_CMD;
+ buffer.hdr.req.buf_lenh = 0;
+ buffer.hdr.req.buf_lenl = FW_WRITE_SHADOW_RAM_LEN;
+ buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;
+
+ /* one word */
+ buffer.length = IXGBE_CPU_TO_BE16(sizeof(u16));
+ buffer.data = data;
+ buffer.address = IXGBE_CPU_TO_BE32(offset * 2);
+
+ status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
+ sizeof(buffer),
+ IXGBE_HI_COMMAND_TIMEOUT, FALSE);
+
+ return status;
+}
+
+/**
+ * ixgbe_write_ee_hostif_X550 - Write EEPROM word using hostif
+ * @hw: pointer to hardware structure
+ * @offset: offset of word in the EEPROM to write
+ * @data: word write to the EEPROM
+ *
+ * Write a 16 bit word to the EEPROM using the hostif.
+ **/
+s32 ixgbe_write_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset,
+ u16 data)
+{
+ s32 status = IXGBE_SUCCESS;
+
+ DEBUGFUNC("ixgbe_write_ee_hostif_X550");
+
+ if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
+ IXGBE_SUCCESS) {
+ status = ixgbe_write_ee_hostif_data_X550(hw, offset, data);
+ hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
+ } else {
+ DEBUGOUT("write ee hostif failed to get semaphore");
+ status = IXGBE_ERR_SWFW_SYNC;
+ }
+
+ return status;
+}
+
+/**
+ * ixgbe_write_ee_hostif_buffer_X550 - Write EEPROM word(s) using hostif
+ * @hw: pointer to hardware structure
+ * @offset: offset of word in the EEPROM to write
+ * @words: number of words
+ * @data: word(s) write to the EEPROM
+ *
+ * Write a 16 bit word(s) to the EEPROM using the hostif.
+ **/
+s32 ixgbe_write_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
+ u16 offset, u16 words, u16 *data)
+{
+ s32 status = IXGBE_SUCCESS;
+ u32 i = 0;
+
+ DEBUGFUNC("ixgbe_write_ee_hostif_buffer_X550");
+
+ /* Take semaphore for the entire operation. */
+ status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
+ if (status != IXGBE_SUCCESS) {
+ DEBUGOUT("EEPROM write buffer - semaphore failed\n");
+ goto out;
+ }
+
+ for (i = 0; i < words; i++) {
+ status = ixgbe_write_ee_hostif_data_X550(hw, offset + i,
+ data[i]);
+
+ if (status != IXGBE_SUCCESS) {
+ DEBUGOUT("Eeprom buffered write failed\n");
+ break;
+ }
+ }
+
+ hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
+out:
+
+ return status;
+}
+
+/**
+ * ixgbe_checksum_ptr_x550 - Checksum one pointer region
+ * @hw: pointer to hardware structure
+ * @ptr: pointer offset in eeprom
+ * @size: size of section pointed by ptr, if 0 first word will be used as size
+ * @csum: address of checksum to update
+ *
+ * Returns error status for any failure
+ */
+static s32 ixgbe_checksum_ptr_x550(struct ixgbe_hw *hw, u16 ptr,
+ u16 size, u16 *csum, u16 *buffer,
+ u32 buffer_size)
+{
+ u16 buf[256];
+ s32 status;
+ u16 length, bufsz, i, start;
+ u16 *local_buffer;
+
+ bufsz = sizeof(buf) / sizeof(buf[0]);
+
+ /* Read a chunk at the pointer location */
+ if (!buffer) {
+ status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr, bufsz, buf);
+ if (status) {
+ DEBUGOUT("Failed to read EEPROM image\n");
+ return status;
+ }
+ local_buffer = buf;
+ } else {
+ if (buffer_size < ptr)
+ return IXGBE_ERR_PARAM;
+ local_buffer = &buffer[ptr];
+ }
+
+ if (size) {
+ start = 0;
+ length = size;
+ } else {
+ start = 1;
+ length = local_buffer[0];
+
+ /* Skip pointer section if length is invalid. */
+ if (length == 0xFFFF || length == 0 ||
+ (ptr + length) >= hw->eeprom.word_size)
+ return IXGBE_SUCCESS;
+ }
+
+ if (buffer && ((u32)start + (u32)length > buffer_size))
+ return IXGBE_ERR_PARAM;
+
+ for (i = start; length; i++, length--) {
+ if (i == bufsz && !buffer) {
+ ptr += bufsz;
+ i = 0;
+ if (length < bufsz)
+ bufsz = length;
+
+ /* Read a chunk at the pointer location */
+ status = ixgbe_read_ee_hostif_buffer_X550(hw, ptr,
+ bufsz, buf);
+ if (status) {
+ DEBUGOUT("Failed to read EEPROM image\n");
+ return status;
+ }
+ }
+ *csum += local_buffer[i];
+ }
+ return IXGBE_SUCCESS;
+}
+
+/**
+ * ixgbe_calc_checksum_X550 - Calculates and returns the checksum
+ * @hw: pointer to hardware structure
+ * @buffer: pointer to buffer containing calculated checksum
+ * @buffer_size: size of buffer
+ *
+ * Returns a negative error code on error, or the 16-bit checksum
+ **/
+s32 ixgbe_calc_checksum_X550(struct ixgbe_hw *hw, u16 *buffer, u32 buffer_size)
+{
+ u16 eeprom_ptrs[IXGBE_EEPROM_LAST_WORD + 1];
+ u16 *local_buffer;
+ s32 status;
+ u16 checksum = 0;
+ u16 pointer, i, size;
+
+ DEBUGFUNC("ixgbe_calc_eeprom_checksum_X550");
+
+ hw->eeprom.ops.init_params(hw);
+
+ if (!buffer) {
+ /* Read pointer area */
+ status = ixgbe_read_ee_hostif_buffer_X550(hw, 0,
+ IXGBE_EEPROM_LAST_WORD + 1,
+ eeprom_ptrs);
+ if (status) {
+ DEBUGOUT("Failed to read EEPROM image\n");
+ return status;
+ }
+ local_buffer = eeprom_ptrs;
+ } else {
+ if (buffer_size < IXGBE_EEPROM_LAST_WORD)
+ return IXGBE_ERR_PARAM;
+ local_buffer = buffer;
+ }
+
+ /*
+ * For X550 hardware include 0x0-0x41 in the checksum, skip the
+ * checksum word itself
+ */
+ for (i = 0; i <= IXGBE_EEPROM_LAST_WORD; i++)
+ if (i != IXGBE_EEPROM_CHECKSUM)
+ checksum += local_buffer[i];
+
+ /*
+ * Include all data from pointers 0x3, 0x6-0xE. This excludes the
+ * FW, PHY module, and PCIe Expansion/Option ROM pointers.
+ */
+ for (i = IXGBE_PCIE_ANALOG_PTR_X550; i < IXGBE_FW_PTR; i++) {
+ if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR)
+ continue;
+
+ pointer = local_buffer[i];
+
+ /* Skip pointer section if the pointer is invalid. */
+ if (pointer == 0xFFFF || pointer == 0 ||
+ pointer >= hw->eeprom.word_size)
+ continue;
+
+ switch (i) {
+ case IXGBE_PCIE_GENERAL_PTR:
+ size = IXGBE_IXGBE_PCIE_GENERAL_SIZE;
+ break;
+ case IXGBE_PCIE_CONFIG0_PTR:
+ case IXGBE_PCIE_CONFIG1_PTR:
+ size = IXGBE_PCIE_CONFIG_SIZE;
+ break;
+ default:
+ size = 0;
+ break;
+ }
+
+ status = ixgbe_checksum_ptr_x550(hw, pointer, size, &checksum,
+ buffer, buffer_size);
+ if (status)
+ return status;
+ }
+
+ checksum = (u16)IXGBE_EEPROM_SUM - checksum;
+
+ return (s32)checksum;
+}
+
+/**
+ * ixgbe_calc_eeprom_checksum_X550 - Calculates and returns the checksum
+ * @hw: pointer to hardware structure
+ *
+ * Returns a negative error code on error, or the 16-bit checksum
+ **/
+s32 ixgbe_calc_eeprom_checksum_X550(struct ixgbe_hw *hw)
+{
+ return ixgbe_calc_checksum_X550(hw, NULL, 0);
+}
+
+/**
+ * ixgbe_validate_eeprom_checksum_X550 - Validate EEPROM checksum
+ * @hw: pointer to hardware structure
+ * @checksum_val: calculated checksum
+ *
+ * Performs checksum calculation and validates the EEPROM checksum. If the
+ * caller does not need checksum_val, the value can be NULL.
+ **/
+s32 ixgbe_validate_eeprom_checksum_X550(struct ixgbe_hw *hw, u16 *checksum_val)
+{
+ s32 status;
+ u16 checksum;
+ u16 read_checksum = 0;
+
+ DEBUGFUNC("ixgbe_validate_eeprom_checksum_X550");
+
+ /* Read the first word from the EEPROM. If this times out or fails, do
+ * not continue or we could be in for a very long wait while every
+ * EEPROM read fails
+ */
+ status = hw->eeprom.ops.read(hw, 0, &checksum);
+ if (status) {
+ DEBUGOUT("EEPROM read failed\n");
+ return status;
+ }
+
+ status = hw->eeprom.ops.calc_checksum(hw);
+ if (status < 0)
+ return status;
+
+ checksum = (u16)(status & 0xffff);
+
+ status = ixgbe_read_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM,
+ &read_checksum);
+ if (status)
+ return status;
+
+ /* Verify read checksum from EEPROM is the same as
+ * calculated checksum
+ */
+ if (read_checksum != checksum) {
+ status = IXGBE_ERR_EEPROM_CHECKSUM;
+ ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
+ "Invalid EEPROM checksum");
+ }
+
+ /* If the user cares, return the calculated checksum */
+ if (checksum_val)
+ *checksum_val = checksum;
+
+ return status;
+}
+
+/**
+ * ixgbe_update_eeprom_checksum_X550 - Updates the EEPROM checksum and flash
+ * @hw: pointer to hardware structure
+ *
+ * After writing EEPROM to shadow RAM using EEWR register, software calculates
+ * checksum and updates the EEPROM and instructs the hardware to update
+ * the flash.
+ **/
+s32 ixgbe_update_eeprom_checksum_X550(struct ixgbe_hw *hw)
+{
+ s32 status;
+ u16 checksum = 0;
+
+ DEBUGFUNC("ixgbe_update_eeprom_checksum_X550");
+
+ /* Read the first word from the EEPROM. If this times out or fails, do
+ * not continue or we could be in for a very long wait while every
+ * EEPROM read fails
+ */
+ status = ixgbe_read_ee_hostif_X550(hw, 0, &checksum);
+ if (status) {
+ DEBUGOUT("EEPROM read failed\n");
+ return status;
+ }
+
+ status = ixgbe_calc_eeprom_checksum_X550(hw);
+ if (status < 0)
+ return status;
+
+ checksum = (u16)(status & 0xffff);
+
+ status = ixgbe_write_ee_hostif_X550(hw, IXGBE_EEPROM_CHECKSUM,
+ checksum);
+ if (status)
+ return status;
+
+ status = ixgbe_update_flash_X550(hw);
+
+ return status;
+}
+
+/**
+ * ixgbe_update_flash_X550 - Instruct HW to copy EEPROM to Flash device
+ * @hw: pointer to hardware structure
+ *
+ * Issue a shadow RAM dump to FW to copy EEPROM from shadow RAM to the flash.
+ **/
+s32 ixgbe_update_flash_X550(struct ixgbe_hw *hw)
+{
+ s32 status = IXGBE_SUCCESS;
+ union ixgbe_hic_hdr2 buffer;
+
+ DEBUGFUNC("ixgbe_update_flash_X550");
+
+ buffer.req.cmd = FW_SHADOW_RAM_DUMP_CMD;
+ buffer.req.buf_lenh = 0;
+ buffer.req.buf_lenl = FW_SHADOW_RAM_DUMP_LEN;
+ buffer.req.checksum = FW_DEFAULT_CHECKSUM;
+
+ status = ixgbe_host_interface_command(hw, (u32 *)&buffer,
+ sizeof(buffer),
+ IXGBE_HI_COMMAND_TIMEOUT, FALSE);
+
+ return status;
+}
+
+/**
+ * ixgbe_get_supported_physical_layer_X550em - Returns physical layer type
+ * @hw: pointer to hardware structure
+ *
+ * Determines physical layer capabilities of the current configuration.
+ **/
+u32 ixgbe_get_supported_physical_layer_X550em(struct ixgbe_hw *hw)
+{
+ u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+ u16 ext_ability = 0;
+
+ DEBUGFUNC("ixgbe_get_supported_physical_layer_X550em");
+
+ hw->phy.ops.identify(hw);
+
+ switch (hw->phy.type) {
+ case ixgbe_phy_x550em_kr:
+ physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KR |
+ IXGBE_PHYSICAL_LAYER_1000BASE_KX;
+ break;
+ case ixgbe_phy_x550em_kx4:
+ physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4 |
+ IXGBE_PHYSICAL_LAYER_1000BASE_KX;
+ break;
+ case ixgbe_phy_x550em_ext_t:
+ hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY,
+ IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+ &ext_ability);
+ if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY)
+ physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
+ if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY)
+ physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
+ break;
+ default:
+ break;
+ }
+
+ if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber)
+ physical_layer = ixgbe_get_supported_phy_sfp_layer_generic(hw);
+
+ return physical_layer;
+}
+
+/**
+ * ixgbe_get_bus_info_x550em - Set PCI bus info
+ * @hw: pointer to hardware structure
+ *
+ * Sets bus link width and speed to unknown because X550em is
+ * not a PCI device.
+ **/
+s32 ixgbe_get_bus_info_X550em(struct ixgbe_hw *hw)
+{
+
+ DEBUGFUNC("ixgbe_get_bus_info_x550em");
+
+ hw->bus.width = ixgbe_bus_width_unknown;
+ hw->bus.speed = ixgbe_bus_speed_unknown;
+
+ hw->mac.ops.set_lan_id(hw);
+
+ return IXGBE_SUCCESS;
+}
+
+/**
+ * ixgbe_disable_rx_x550 - Disable RX unit
+ *
+ * Enables the Rx DMA unit for x550
+ **/
+void ixgbe_disable_rx_x550(struct ixgbe_hw *hw)
+{
+ u32 rxctrl, pfdtxgswc;
+ s32 status;
+ struct ixgbe_hic_disable_rxen fw_cmd;
+
+ DEBUGFUNC("ixgbe_enable_rx_dma_x550");
+
+ rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
+ if (rxctrl & IXGBE_RXCTRL_RXEN) {
+ pfdtxgswc = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
+ if (pfdtxgswc & IXGBE_PFDTXGSWC_VT_LBEN) {
+ pfdtxgswc &= ~IXGBE_PFDTXGSWC_VT_LBEN;
+ IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, pfdtxgswc);
+ hw->mac.set_lben = TRUE;
+ } else {
+ hw->mac.set_lben = FALSE;
+ }
+
+ fw_cmd.hdr.cmd = FW_DISABLE_RXEN_CMD;
+ fw_cmd.hdr.buf_len = FW_DISABLE_RXEN_LEN;
+ fw_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
+ fw_cmd.port_number = (u8)hw->bus.lan_id;
+
+ status = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd,
+ sizeof(struct ixgbe_hic_disable_rxen),
+ IXGBE_HI_COMMAND_TIMEOUT, TRUE);
+
+ /* If we fail - disable RX using register write */
+ if (status) {
+ rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
+ if (rxctrl & IXGBE_RXCTRL_RXEN) {
+ rxctrl &= ~IXGBE_RXCTRL_RXEN;
+ IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl);
+ }
+ }
+ }
+}
+
+/**
+ * ixgbe_enter_lplu_x550em - Transition to low power states
+ * @hw: pointer to hardware structure
+ *
+ * Configures Low Power Link Up on transition to low power states
+ * (from D0 to non-D0). Link is required to enter LPLU so avoid resetting the
+ * X557 PHY immediately prior to entering LPLU.
+ **/
+s32 ixgbe_enter_lplu_t_x550em(struct ixgbe_hw *hw)
+{
+ u16 an_10g_cntl_reg, autoneg_reg, speed;
+ s32 status;
+ ixgbe_link_speed lcd_speed;
+ u32 save_autoneg;
+ bool link_up;
+
+ /* If blocked by MNG FW, then don't restart AN */
+ if (ixgbe_check_reset_blocked(hw))
+ return IXGBE_SUCCESS;
+
+ status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ status = ixgbe_read_eeprom(hw, NVM_INIT_CTRL_3, &hw->eeprom.ctrl_word_3);
+
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ /* If link is down, LPLU disabled in NVM, WoL disabled, or manageability
+ * disabled, then force link down by entering low power mode.
+ */
+ if (!link_up || !(hw->eeprom.ctrl_word_3 & NVM_INIT_CTRL_3_LPLU) ||
+ !(hw->wol_enabled || ixgbe_mng_present(hw)))
+ return ixgbe_set_copper_phy_power(hw, FALSE);
+
+ /* Determine LCD */
+ status = ixgbe_get_lcd_t_x550em(hw, &lcd_speed);
+
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ /* If no valid LCD link speed, then force link down and exit. */
+ if (lcd_speed == IXGBE_LINK_SPEED_UNKNOWN)
+ return ixgbe_set_copper_phy_power(hw, FALSE);
+
+ status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_STAT,
+ IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
+ &speed);
+
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ /* If no link now, speed is invalid so take link down */
+ status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
+ if (status != IXGBE_SUCCESS)
+ return ixgbe_set_copper_phy_power(hw, FALSE);
+
+ /* clear everything but the speed bits */
+ speed &= IXGBE_MDIO_AUTO_NEG_VEN_STAT_SPEED_MASK;
+
+ /* If current speed is already LCD, then exit. */
+ if (((speed == IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_1GB) &&
+ (lcd_speed == IXGBE_LINK_SPEED_1GB_FULL)) ||
+ ((speed == IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_10GB) &&
+ (lcd_speed == IXGBE_LINK_SPEED_10GB_FULL)))
+ return status;
+
+ /* Clear AN completed indication */
+ status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM,
+ IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
+ &autoneg_reg);
+
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ status = hw->phy.ops.read_reg(hw, IXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,
+ IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
+ &an_10g_cntl_reg);
+
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ status = hw->phy.ops.read_reg(hw,
+ IXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
+ IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
+ &autoneg_reg);
+
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ save_autoneg = hw->phy.autoneg_advertised;
+
+ /* Setup link at least common link speed */
+ status = hw->mac.ops.setup_link(hw, lcd_speed, FALSE);
+
+ /* restore autoneg from before setting lplu speed */
+ hw->phy.autoneg_advertised = save_autoneg;
+
+ return status;
+}
+
+/**
+ * ixgbe_get_lcd_x550em - Determine lowest common denominator
+ * @hw: pointer to hardware structure
+ * @lcd_speed: pointer to lowest common link speed
+ *
+ * Determine lowest common link speed with link partner.
+ **/
+s32 ixgbe_get_lcd_t_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *lcd_speed)
+{
+ u16 an_lp_status;
+ s32 status;
+ u16 word = hw->eeprom.ctrl_word_3;
+
+ *lcd_speed = IXGBE_LINK_SPEED_UNKNOWN;
+
+ status = hw->phy.ops.read_reg(hw, IXGBE_AUTO_NEG_LP_STATUS,
+ IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
+ &an_lp_status);
+
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ /* If link partner advertised 1G, return 1G */
+ if (an_lp_status & IXGBE_AUTO_NEG_LP_1000BASE_CAP) {
+ *lcd_speed = IXGBE_LINK_SPEED_1GB_FULL;
+ return status;
+ }
+
+ /* If 10G disabled for LPLU via NVM D10GMP, then return no valid LCD */
+ if ((hw->bus.lan_id && (word & NVM_INIT_CTRL_3_D10GMP_PORT1)) ||
+ (word & NVM_INIT_CTRL_3_D10GMP_PORT0))
+ return status;
+
+ /* Link partner not capable of lower speeds, return 10G */
+ *lcd_speed = IXGBE_LINK_SPEED_10GB_FULL;
+ return status;
+}
+
+/**
+ * ixgbe_setup_fc_X550em - Set up flow control
+ * @hw: pointer to hardware structure
+ *
+ * Called at init time to set up flow control.
+ **/
+s32 ixgbe_setup_fc_X550em(struct ixgbe_hw *hw)
+{
+ s32 ret_val = IXGBE_SUCCESS;
+ u32 pause, asm_dir, reg_val;
+
+ DEBUGFUNC("ixgbe_setup_fc_X550em");
+
+ /* Validate the requested mode */
+ if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
+ ERROR_REPORT1(IXGBE_ERROR_UNSUPPORTED,
+ "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
+ ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+ goto out;
+ }
+
+ /* 10gig parts do not have a word in the EEPROM to determine the
+ * default flow control setting, so we explicitly set it to full.
+ */
+ if (hw->fc.requested_mode == ixgbe_fc_default)
+ hw->fc.requested_mode = ixgbe_fc_full;
+
+ /* Determine PAUSE and ASM_DIR bits. */
+ switch (hw->fc.requested_mode) {
+ case ixgbe_fc_none:
+ pause = 0;
+ asm_dir = 0;
+ break;
+ case ixgbe_fc_tx_pause:
+ pause = 0;
+ asm_dir = 1;
+ break;
+ case ixgbe_fc_rx_pause:
+ /* Rx Flow control is enabled and Tx Flow control is
+ * disabled by software override. Since there really
+ * isn't a way to advertise that we are capable of RX
+ * Pause ONLY, we will advertise that we support both
+ * symmetric and asymmetric Rx PAUSE, as such we fall
+ * through to the fc_full statement. Later, we will
+ * disable the adapter's ability to send PAUSE frames.
+ */
+ case ixgbe_fc_full:
+ pause = 1;
+ asm_dir = 1;
+ break;
+ default:
+ ERROR_REPORT1(IXGBE_ERROR_ARGUMENT,
+ "Flow control param set incorrectly\n");
+ ret_val = IXGBE_ERR_CONFIG;
+ goto out;
+ }
+
+ if (hw->phy.media_type == ixgbe_media_type_backplane) {
+ ret_val = ixgbe_read_iosf_sb_reg_x550(hw,
+ IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
+ IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
+ if (ret_val != IXGBE_SUCCESS)
+ goto out;
+ reg_val &= ~(IXGBE_KRM_AN_CNTL_1_SYM_PAUSE |
+ IXGBE_KRM_AN_CNTL_1_ASM_PAUSE);
+ if (pause)
+ reg_val |= IXGBE_KRM_AN_CNTL_1_SYM_PAUSE;
+ if (asm_dir)
+ reg_val |= IXGBE_KRM_AN_CNTL_1_ASM_PAUSE;
+ ret_val = ixgbe_write_iosf_sb_reg_x550(hw,
+ IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
+ IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
+
+ /* Not all devices fully support AN. */
+ if (hw->device_id == IXGBE_DEV_ID_X550EM_X_KR)
+ hw->fc.disable_fc_autoneg = TRUE;
+ }
+
+out:
+ return ret_val;
+}
+
+/**
+ * ixgbe_set_mux - Set mux for port 1 access with CS4227
+ * @hw: pointer to hardware structure
+ * @state: set mux if 1, clear if 0
+ */
+static void ixgbe_set_mux(struct ixgbe_hw *hw, u8 state)
+{
+ u32 esdp;
+
+ if (!hw->bus.lan_id)
+ return;
+ esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
+ if (state)
+ esdp |= IXGBE_ESDP_SDP1;
+ else
+ esdp &= ~IXGBE_ESDP_SDP1;
+ IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
+ IXGBE_WRITE_FLUSH(hw);
+}
+
+/**
+ * ixgbe_acquire_swfw_sync_X550em - Acquire SWFW semaphore
+ * @hw: pointer to hardware structure
+ * @mask: Mask to specify which semaphore to acquire
+ *
+ * Acquires the SWFW semaphore and sets the I2C MUX
+ **/
+s32 ixgbe_acquire_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask)
+{
+ s32 status;
+
+ DEBUGFUNC("ixgbe_acquire_swfw_sync_X550em");
+
+ status = ixgbe_acquire_swfw_sync_X540(hw, mask);
+ if (status)
+ return status;
+
+ if (mask & IXGBE_GSSR_I2C_MASK)
+ ixgbe_set_mux(hw, 1);
+
+ return IXGBE_SUCCESS;
+}
+
+/**
+ * ixgbe_release_swfw_sync_X550em - Release SWFW semaphore
+ * @hw: pointer to hardware structure
+ * @mask: Mask to specify which semaphore to release
+ *
+ * Releases the SWFW semaphore and sets the I2C MUX
+ **/
+void ixgbe_release_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask)
+{
+ DEBUGFUNC("ixgbe_release_swfw_sync_X550em");
+
+ if (mask & IXGBE_GSSR_I2C_MASK)
+ ixgbe_set_mux(hw, 0);
+
+ ixgbe_release_swfw_sync_X540(hw, mask);
+}
+
+/**
+ * ixgbe_handle_lasi_ext_t_x550em - Handle external Base T PHY interrupt
+ * @hw: pointer to hardware structure
+ *
+ * Handle external Base T PHY interrupt. If high temperature
+ * failure alarm then return error, else if link status change
+ * then setup internal/external PHY link
+ *
+ * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature
+ * failure alarm, else return PHY access status.
+ */
+s32 ixgbe_handle_lasi_ext_t_x550em(struct ixgbe_hw *hw)
+{
+ bool lsc;
+ u32 status;
+
+ status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc);
+
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ if (lsc)
+ return ixgbe_setup_internal_phy(hw);
+
+ return IXGBE_SUCCESS;
+}
+
+/**
+ * ixgbe_setup_mac_link_t_X550em - Sets the auto advertised link speed
+ * @hw: pointer to hardware structure
+ * @speed: new link speed
+ * @autoneg_wait_to_complete: TRUE when waiting for completion is needed
+ *
+ * Setup internal/external PHY link speed based on link speed, then set
+ * external PHY auto advertised link speed.
+ *
+ * Returns error status for any failure
+ **/
+s32 ixgbe_setup_mac_link_t_X550em(struct ixgbe_hw *hw,
+ ixgbe_link_speed speed,
+ bool autoneg_wait_to_complete)
+{
+ s32 status;
+ ixgbe_link_speed force_speed;
+
+ DEBUGFUNC("ixgbe_setup_mac_link_t_X550em");
+
+ /* Setup internal/external PHY link speed to iXFI (10G), unless
+ * only 1G is auto advertised then setup KX link.
+ */
+ if (speed & IXGBE_LINK_SPEED_10GB_FULL)
+ force_speed = IXGBE_LINK_SPEED_10GB_FULL;
+ else
+ force_speed = IXGBE_LINK_SPEED_1GB_FULL;
+
+ /* If internal link mode is XFI, then setup XFI internal link. */
+ if (!(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) {
+ status = ixgbe_setup_ixfi_x550em(hw, &force_speed);
+
+ if (status != IXGBE_SUCCESS)
+ return status;
+ }
+
+ return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait_to_complete);
+}
+
+/**
+ * ixgbe_check_link_t_X550em - Determine link and speed status
+ * @hw: pointer to hardware structure
+ * @speed: pointer to link speed
+ * @link_up: TRUE when link is up
+ * @link_up_wait_to_complete: bool used to wait for link up or not
+ *
+ * Check that both the MAC and X557 external PHY have link.
+ **/
+s32 ixgbe_check_link_t_X550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
+ bool *link_up, bool link_up_wait_to_complete)
+{
+ u32 status;
+ u16 autoneg_status;
+
+ if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper)
+ return IXGBE_ERR_CONFIG;
+
+ status = ixgbe_check_mac_link_generic(hw, speed, link_up,
+ link_up_wait_to_complete);
+
+ /* If check link fails or MAC link is not up, then return */
+ if (status != IXGBE_SUCCESS || !(*link_up))
+ return status;
+
+ /* MAC link is up, so check external PHY link.
+ * Read this twice back to back to indicate current status.
+ */
+ status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
+ IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
+ &autoneg_status);
+
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
+ IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
+ &autoneg_status);
+
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ /* If external PHY link is not up, then indicate link not up */
+ if (!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS))
+ *link_up = FALSE;
+
+ return IXGBE_SUCCESS;
+}
+
+/**
+ * ixgbe_reset_phy_t_X550em - Performs X557 PHY reset and enables LASI
+ * @hw: pointer to hardware structure
+ **/
+s32 ixgbe_reset_phy_t_X550em(struct ixgbe_hw *hw)
+{
+ s32 status;
+
+ status = ixgbe_reset_phy_generic(hw);
+
+ if (status != IXGBE_SUCCESS)
+ return status;
+
+ /* Configure Link Status Alarm and Temperature Threshold interrupts */
+ return ixgbe_enable_lasi_ext_t_x550em(hw);
+}
+
+/**
+ * ixgbe_led_on_t_X550em - Turns on the software controllable LEDs.
+ * @hw: pointer to hardware structure
+ * @led_idx: led number to turn on
+ **/
+s32 ixgbe_led_on_t_X550em(struct ixgbe_hw *hw, u32 led_idx)
+{
+ u16 phy_data;
+
+ DEBUGFUNC("ixgbe_led_on_t_X550em");
+
+ if (led_idx >= IXGBE_X557_MAX_LED_INDEX)
+ return IXGBE_ERR_PARAM;
+
+ /* To turn on the LED, set mode to ON. */
+ ixgbe_read_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
+ IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, &phy_data);
+ phy_data |= IXGBE_X557_LED_MANUAL_SET_MASK;
+ ixgbe_write_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
+ IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, phy_data);
+
+ return IXGBE_SUCCESS;
+}
+
+/**
+ * ixgbe_led_off_t_X550em - Turns off the software controllable LEDs.
+ * @hw: pointer to hardware structure
+ * @led_idx: led number to turn off
+ **/
+s32 ixgbe_led_off_t_X550em(struct ixgbe_hw *hw, u32 led_idx)
+{
+ u16 phy_data;
+
+ DEBUGFUNC("ixgbe_led_off_t_X550em");
+
+ if (led_idx >= IXGBE_X557_MAX_LED_INDEX)
+ return IXGBE_ERR_PARAM;
+
+ /* To turn on the LED, set mode to ON. */
+ ixgbe_read_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
+ IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, &phy_data);
+ phy_data &= ~IXGBE_X557_LED_MANUAL_SET_MASK;
+ ixgbe_write_phy_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx,
+ IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, phy_data);
+
+ return IXGBE_SUCCESS;
+}
+
diff --git a/sys/dev/ixgbe/ixgbe_x550.h b/sys/dev/ixgbe/ixgbe_x550.h
new file mode 100644
index 000000000000..8a544ec86a3b
--- /dev/null
+++ b/sys/dev/ixgbe/ixgbe_x550.h
@@ -0,0 +1,109 @@
+/******************************************************************************
+
+ Copyright (c) 2001-2015, Intel Corporation
+ 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. Neither the name of the Intel Corporation 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 OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+******************************************************************************/
+/*$FreeBSD$*/
+
+#ifndef _IXGBE_X550_H_
+#define _IXGBE_X550_H_
+
+#include "ixgbe_type.h"
+
+s32 ixgbe_dmac_config_X550(struct ixgbe_hw *hw);
+s32 ixgbe_dmac_config_tcs_X550(struct ixgbe_hw *hw);
+s32 ixgbe_dmac_update_tcs_X550(struct ixgbe_hw *hw);
+
+s32 ixgbe_get_bus_info_X550em(struct ixgbe_hw *hw);
+s32 ixgbe_init_eeprom_params_X550(struct ixgbe_hw *hw);
+s32 ixgbe_update_eeprom_checksum_X550(struct ixgbe_hw *hw);
+s32 ixgbe_calc_eeprom_checksum_X550(struct ixgbe_hw *hw);
+s32 ixgbe_calc_checksum_X550(struct ixgbe_hw *hw, u16 *buffer, u32 buffer_size);
+s32 ixgbe_validate_eeprom_checksum_X550(struct ixgbe_hw *hw, u16 *checksum_val);
+s32 ixgbe_update_flash_X550(struct ixgbe_hw *hw);
+s32 ixgbe_write_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
+ u16 offset, u16 words, u16 *data);
+s32 ixgbe_write_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset,
+ u16 data);
+s32 ixgbe_read_ee_hostif_buffer_X550(struct ixgbe_hw *hw,
+ u16 offset, u16 words, u16 *data);
+s32 ixgbe_read_ee_hostif_X550(struct ixgbe_hw *hw, u16 offset,
+u16 *data);
+s32 ixgbe_read_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset,
+ u16 *data);
+s32 ixgbe_write_ee_hostif_data_X550(struct ixgbe_hw *hw, u16 offset,
+ u16 data);
+s32 ixgbe_set_eee_X550(struct ixgbe_hw *hw, bool enable_eee);
+s32 ixgbe_setup_eee_X550(struct ixgbe_hw *hw, bool enable_eee);
+void ixgbe_set_source_address_pruning_X550(struct ixgbe_hw *hw, bool enable,
+ unsigned int pool);
+void ixgbe_set_ethertype_anti_spoofing_X550(struct ixgbe_hw *hw,
+ bool enable, int vf);
+s32 ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
+ u32 device_type, u32 data);
+s32 ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
+ u32 device_type, u32 *data);
+void ixgbe_disable_mdd_X550(struct ixgbe_hw *hw);
+void ixgbe_enable_mdd_X550(struct ixgbe_hw *hw);
+void ixgbe_mdd_event_X550(struct ixgbe_hw *hw, u32 *vf_bitmap);
+void ixgbe_restore_mdd_vf_X550(struct ixgbe_hw *hw, u32 vf);
+enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw);
+s32 ixgbe_setup_sfp_modules_X550em(struct ixgbe_hw *hw);
+s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw,
+ ixgbe_link_speed *speed, bool *autoneg);
+void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw);
+s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw);
+s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw);
+s32 ixgbe_setup_kr_x550em(struct ixgbe_hw *hw);
+s32 ixgbe_setup_kx4_x550em(struct ixgbe_hw *hw);
+s32 ixgbe_init_ext_t_x550em(struct ixgbe_hw *hw);
+s32 ixgbe_setup_internal_phy_t_x550em(struct ixgbe_hw *hw);
+s32 ixgbe_setup_phy_loopback_x550em(struct ixgbe_hw *hw);
+u32 ixgbe_get_supported_physical_layer_X550em(struct ixgbe_hw *hw);
+void ixgbe_disable_rx_x550(struct ixgbe_hw *hw);
+s32 ixgbe_get_lcd_t_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *lcd_speed);
+s32 ixgbe_enter_lplu_t_x550em(struct ixgbe_hw *hw);
+s32 ixgbe_acquire_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask);
+void ixgbe_release_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask);
+s32 ixgbe_setup_fc_X550em(struct ixgbe_hw *hw);
+s32 ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw,
+ ixgbe_link_speed speed,
+ bool autoneg_wait_to_complete);
+s32 ixgbe_handle_lasi_ext_t_x550em(struct ixgbe_hw *hw);
+s32 ixgbe_setup_mac_link_t_X550em(struct ixgbe_hw *hw,
+ ixgbe_link_speed speed,
+ bool autoneg_wait_to_complete);
+s32 ixgbe_check_link_t_X550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
+ bool *link_up, bool link_up_wait_to_complete);
+s32 ixgbe_reset_phy_t_X550em(struct ixgbe_hw *hw);
+s32 ixgbe_identify_sfp_module_X550em(struct ixgbe_hw *hw);
+s32 ixgbe_led_on_t_X550em(struct ixgbe_hw *hw, u32 led_idx);
+s32 ixgbe_led_off_t_X550em(struct ixgbe_hw *hw, u32 led_idx);
+#endif /* _IXGBE_X550_H_ */
diff --git a/sys/dev/ixl/ixl.h b/sys/dev/ixl/ixl.h
index df8f04f557bd..1ddfbca3d7d7 100644
--- a/sys/dev/ixl/ixl.h
+++ b/sys/dev/ixl/ixl.h
@@ -324,7 +324,7 @@
#define IXL_SET_IMCASTS(vsi, count) (vsi)->imcasts = (count)
#define IXL_SET_OMCASTS(vsi, count) (vsi)->omcasts = (count)
#define IXL_SET_IQDROPS(vsi, count) (vsi)->iqdrops = (count)
-#define IXL_SET_OQDROPS(vsi, count) (vsi)->iqdrops = (count)
+#define IXL_SET_OQDROPS(vsi, count) (vsi)->oqdrops = (count)
#define IXL_SET_NOPROTO(vsi, count) (vsi)->noproto = (count)
#else
#define IXL_SET_IPACKETS(vsi, count) (vsi)->ifp->if_ipackets = (count)
diff --git a/sys/dev/mii/brgphy.c b/sys/dev/mii/brgphy.c
index 0d22430720fe..32914a386484 100644
--- a/sys/dev/mii/brgphy.c
+++ b/sys/dev/mii/brgphy.c
@@ -160,25 +160,33 @@ static const struct mii_phy_funcs brgphy_funcs = {
brgphy_reset
};
-#define HS21_PRODUCT_ID "IBM eServer BladeCenter HS21"
-#define HS21_BCM_CHIPID 0x57081021
+static const struct hs21_type {
+ const uint32_t id;
+ const char *prod;
+} hs21_type_lists[] = {
+ { 0x57081021, "IBM eServer BladeCenter HS21" },
+ { 0x57081011, "IBM eServer BladeCenter HS21 -[8853PAU]-" },
+};
static int
detect_hs21(struct bce_softc *bce_sc)
{
char *sysenv;
- int found;
+ int found, i;
found = 0;
- if (bce_sc->bce_chipid == HS21_BCM_CHIPID) {
- sysenv = kern_getenv("smbios.system.product");
- if (sysenv != NULL) {
- if (strncmp(sysenv, HS21_PRODUCT_ID,
- strlen(HS21_PRODUCT_ID)) == 0)
- found = 1;
- freeenv(sysenv);
+ sysenv = kern_getenv("smbios.system.product");
+ if (sysenv == NULL)
+ return (found);
+ for (i = 0; i < nitems(hs21_type_lists); i++) {
+ if (bce_sc->bce_chipid == hs21_type_lists[i].id &&
+ strncmp(sysenv, hs21_type_lists[i].prod,
+ strlen(hs21_type_lists[i].prod)) == 0) {
+ found++;
+ break;
}
}
+ freeenv(sysenv);
return (found);
}
diff --git a/sys/dev/mxge/if_mxge.c b/sys/dev/mxge/if_mxge.c
index fe8c08a72495..983caa30bc29 100644
--- a/sys/dev/mxge/if_mxge.c
+++ b/sys/dev/mxge/if_mxge.c
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sysctl.h>
#include <sys/sx.h>
#include <sys/taskqueue.h>
+#include <sys/zlib.h>
#include <net/if.h>
#include <net/if_var.h>
@@ -58,7 +59,6 @@ __FBSDID("$FreeBSD$");
#include <net/if_types.h>
#include <net/if_vlan_var.h>
-#include <net/zlib.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
diff --git a/sys/dev/pccbb/pccbb_pci.c b/sys/dev/pccbb/pccbb_pci.c
index d4f1baace599..7dca418249fb 100644
--- a/sys/dev/pccbb/pccbb_pci.c
+++ b/sys/dev/pccbb/pccbb_pci.c
@@ -259,32 +259,6 @@ cbb_pci_probe(device_t brdev)
}
/*
- * Still need this because the pci code only does power for type 0
- * header devices.
- */
-static void
-cbb_powerstate_d0(device_t dev)
-{
- u_int32_t membase, irq;
-
- if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) {
- /* Save important PCI config data. */
- membase = pci_read_config(dev, CBBR_SOCKBASE, 4);
- irq = pci_read_config(dev, PCIR_INTLINE, 4);
-
- /* Reset the power state. */
- device_printf(dev, "chip is in D%d power mode "
- "-- setting to D0\n", pci_get_powerstate(dev));
-
- pci_set_powerstate(dev, PCI_POWERSTATE_D0);
-
- /* Restore PCI config data. */
- pci_write_config(dev, CBBR_SOCKBASE, membase, 4);
- pci_write_config(dev, PCIR_INTLINE, irq, 4);
- }
-}
-
-/*
* Print out the config space
*/
static void
@@ -321,15 +295,15 @@ cbb_pci_attach(device_t brdev)
sc->cbdev = NULL;
sc->exca[0].pccarddev = NULL;
sc->domain = pci_get_domain(brdev);
- sc->bus.sec = pci_read_config(brdev, PCIR_SECBUS_2, 1);
- sc->bus.sub = pci_read_config(brdev, PCIR_SUBBUS_2, 1);
sc->pribus = pcib_get_bus(parent);
#if defined(NEW_PCIB) && defined(PCI_RES_BUS)
pci_write_config(brdev, PCIR_PRIBUS_2, sc->pribus, 1);
pcib_setup_secbus(brdev, &sc->bus, 1);
+#else
+ sc->bus.sec = pci_read_config(brdev, PCIR_SECBUS_2, 1);
+ sc->bus.sub = pci_read_config(brdev, PCIR_SUBBUS_2, 1);
#endif
SLIST_INIT(&sc->rl);
- cbb_powerstate_d0(brdev);
rid = CBBR_SOCKBASE;
sc->base_res = bus_alloc_resource_any(brdev, SYS_RES_MEMORY, &rid,
@@ -467,18 +441,13 @@ cbb_chipinit(struct cbb_softc *sc)
uint32_t mux, sysctrl, reg;
/* Set CardBus latency timer */
- if (pci_read_config(sc->dev, PCIR_SECLAT_1, 1) < 0x20)
- pci_write_config(sc->dev, PCIR_SECLAT_1, 0x20, 1);
+ if (pci_read_config(sc->dev, PCIR_SECLAT_2, 1) < 0x20)
+ pci_write_config(sc->dev, PCIR_SECLAT_2, 0x20, 1);
/* Set PCI latency timer */
if (pci_read_config(sc->dev, PCIR_LATTIMER, 1) < 0x20)
pci_write_config(sc->dev, PCIR_LATTIMER, 0x20, 1);
- /* Restore bus configuration */
- pci_write_config(sc->dev, PCIR_PRIBUS_2, sc->pribus, 1);
- pci_write_config(sc->dev, PCIR_SECBUS_2, sc->bus.sec, 1);
- pci_write_config(sc->dev, PCIR_SUBBUS_2, sc->bus.sub, 1);
-
/* Enable DMA, memory access for this card and I/O acces for children */
pci_enable_busmaster(sc->dev);
pci_enable_io(sc->dev, SYS_RES_IOPORT);
@@ -906,15 +875,10 @@ cbb_pci_resume(device_t brdev)
* from D0 and back to D0 cause the bridge to lose its config space, so
* all the bus mappings and such are preserved.
*
- * For most drivers, the PCI layer handles this saving. However, since
- * there's much black magic and arcane art hidden in these few lines of
- * code that would be difficult to transition into the PCI
- * layer. chipinit was several years of trial and error to write.
+ * The PCI layer handles standard PCI registers like the
+ * command register and BARs, but cbb-specific registers are
+ * handled here.
*/
- pci_write_config(brdev, CBBR_SOCKBASE, rman_get_start(sc->base_res), 4);
- DEVPRINTF((brdev, "PCI Memory allocated: %08lx\n",
- rman_get_start(sc->base_res)));
-
sc->chipinit(sc);
/* reset interrupt -- Do we really need to do this? */
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index 3fab48643b92..b4c6151210db 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -583,12 +583,24 @@ pci_hdrtypedata(device_t pcib, int b, int s, int f, pcicfgregs *cfg)
case PCIM_HDRTYPE_NORMAL:
cfg->subvendor = REG(PCIR_SUBVEND_0, 2);
cfg->subdevice = REG(PCIR_SUBDEV_0, 2);
+ cfg->mingnt = REG(PCIR_MINGNT, 1);
+ cfg->maxlat = REG(PCIR_MAXLAT, 1);
cfg->nummaps = PCI_MAXMAPS_0;
break;
case PCIM_HDRTYPE_BRIDGE:
+ cfg->bridge.br_seclat = REG(PCIR_SECLAT_1, 1);
+ cfg->bridge.br_subbus = REG(PCIR_SUBBUS_1, 1);
+ cfg->bridge.br_secbus = REG(PCIR_SECBUS_1, 1);
+ cfg->bridge.br_pribus = REG(PCIR_PRIBUS_1, 1);
+ cfg->bridge.br_control = REG(PCIR_BRIDGECTL_1, 2);
cfg->nummaps = PCI_MAXMAPS_1;
break;
case PCIM_HDRTYPE_CARDBUS:
+ cfg->bridge.br_seclat = REG(PCIR_SECLAT_2, 1);
+ cfg->bridge.br_subbus = REG(PCIR_SUBBUS_2, 1);
+ cfg->bridge.br_secbus = REG(PCIR_SECBUS_2, 1);
+ cfg->bridge.br_pribus = REG(PCIR_PRIBUS_2, 1);
+ cfg->bridge.br_control = REG(PCIR_BRIDGECTL_2, 2);
cfg->subvendor = REG(PCIR_SUBVEND_2, 2);
cfg->subdevice = REG(PCIR_SUBDEV_2, 2);
cfg->nummaps = PCI_MAXMAPS_2;
@@ -641,9 +653,6 @@ pci_fill_devinfo(device_t pcib, int d, int b, int s, int f, uint16_t vid,
cfg->intpin = REG(PCIR_INTPIN, 1);
cfg->intline = REG(PCIR_INTLINE, 1);
- cfg->mingnt = REG(PCIR_MINGNT, 1);
- cfg->maxlat = REG(PCIR_MAXLAT, 1);
-
cfg->mfdev = (cfg->hdrtype & PCIM_MFDEV) != 0;
cfg->hdrtype &= ~PCIM_MFDEV;
STAILQ_INIT(&cfg->maps);
@@ -4425,9 +4434,17 @@ pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
*result = cfg->cachelnsz;
break;
case PCI_IVAR_MINGNT:
+ if (cfg->hdrtype != PCIM_HDRTYPE_NORMAL) {
+ *result = -1;
+ return (EINVAL);
+ }
*result = cfg->mingnt;
break;
case PCI_IVAR_MAXLAT:
+ if (cfg->hdrtype != PCIM_HDRTYPE_NORMAL) {
+ *result = -1;
+ return (EINVAL);
+ }
*result = cfg->maxlat;
break;
case PCI_IVAR_LATTIMER:
@@ -5125,16 +5142,6 @@ pci_cfg_restore(device_t dev, struct pci_devinfo *dinfo)
{
/*
- * Only do header type 0 devices. Type 1 devices are bridges,
- * which we know need special treatment. Type 2 devices are
- * cardbus bridges which also require special treatment.
- * Other types are unknown, and we err on the side of safety
- * by ignoring them.
- */
- if ((dinfo->cfg.hdrtype & PCIM_HDRTYPE) != PCIM_HDRTYPE_NORMAL)
- return;
-
- /*
* Restore the device to full power mode. We must do this
* before we restore the registers because moving from D3 to
* D0 will cause the chip's BARs and some other registers to
@@ -5144,16 +5151,44 @@ pci_cfg_restore(device_t dev, struct pci_devinfo *dinfo)
*/
if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0)
pci_set_powerstate(dev, PCI_POWERSTATE_D0);
- pci_restore_bars(dev);
pci_write_config(dev, PCIR_COMMAND, dinfo->cfg.cmdreg, 2);
pci_write_config(dev, PCIR_INTLINE, dinfo->cfg.intline, 1);
pci_write_config(dev, PCIR_INTPIN, dinfo->cfg.intpin, 1);
- pci_write_config(dev, PCIR_MINGNT, dinfo->cfg.mingnt, 1);
- pci_write_config(dev, PCIR_MAXLAT, dinfo->cfg.maxlat, 1);
pci_write_config(dev, PCIR_CACHELNSZ, dinfo->cfg.cachelnsz, 1);
pci_write_config(dev, PCIR_LATTIMER, dinfo->cfg.lattimer, 1);
pci_write_config(dev, PCIR_PROGIF, dinfo->cfg.progif, 1);
pci_write_config(dev, PCIR_REVID, dinfo->cfg.revid, 1);
+ switch (dinfo->cfg.hdrtype & PCIM_HDRTYPE) {
+ case PCIM_HDRTYPE_NORMAL:
+ pci_write_config(dev, PCIR_MINGNT, dinfo->cfg.mingnt, 1);
+ pci_write_config(dev, PCIR_MAXLAT, dinfo->cfg.maxlat, 1);
+ break;
+ case PCIM_HDRTYPE_BRIDGE:
+ pci_write_config(dev, PCIR_SECLAT_1,
+ dinfo->cfg.bridge.br_seclat, 1);
+ pci_write_config(dev, PCIR_SUBBUS_1,
+ dinfo->cfg.bridge.br_subbus, 1);
+ pci_write_config(dev, PCIR_SECBUS_1,
+ dinfo->cfg.bridge.br_secbus, 1);
+ pci_write_config(dev, PCIR_PRIBUS_1,
+ dinfo->cfg.bridge.br_pribus, 1);
+ pci_write_config(dev, PCIR_BRIDGECTL_1,
+ dinfo->cfg.bridge.br_control, 2);
+ break;
+ case PCIM_HDRTYPE_CARDBUS:
+ pci_write_config(dev, PCIR_SECLAT_2,
+ dinfo->cfg.bridge.br_seclat, 1);
+ pci_write_config(dev, PCIR_SUBBUS_2,
+ dinfo->cfg.bridge.br_subbus, 1);
+ pci_write_config(dev, PCIR_SECBUS_2,
+ dinfo->cfg.bridge.br_secbus, 1);
+ pci_write_config(dev, PCIR_PRIBUS_2,
+ dinfo->cfg.bridge.br_pribus, 1);
+ pci_write_config(dev, PCIR_BRIDGECTL_2,
+ dinfo->cfg.bridge.br_control, 2);
+ break;
+ }
+ pci_restore_bars(dev);
/*
* Restore extended capabilities for PCI-Express and PCI-X
@@ -5222,40 +5257,57 @@ pci_cfg_save(device_t dev, struct pci_devinfo *dinfo, int setstate)
int ps;
/*
- * Only do header type 0 devices. Type 1 devices are bridges, which
- * we know need special treatment. Type 2 devices are cardbus bridges
- * which also require special treatment. Other types are unknown, and
- * we err on the side of safety by ignoring them. Powering down
- * bridges should not be undertaken lightly.
- */
- if ((dinfo->cfg.hdrtype & PCIM_HDRTYPE) != PCIM_HDRTYPE_NORMAL)
- return;
-
- /*
* Some drivers apparently write to these registers w/o updating our
* cached copy. No harm happens if we update the copy, so do so here
* so we can restore them. The COMMAND register is modified by the
* bus w/o updating the cache. This should represent the normally
- * writable portion of the 'defined' part of type 0 headers. In
- * theory we also need to save/restore the PCI capability structures
- * we know about, but apart from power we don't know any that are
- * writable.
+ * writable portion of the 'defined' part of type 0/1/2 headers.
*/
- dinfo->cfg.subvendor = pci_read_config(dev, PCIR_SUBVEND_0, 2);
- dinfo->cfg.subdevice = pci_read_config(dev, PCIR_SUBDEV_0, 2);
dinfo->cfg.vendor = pci_read_config(dev, PCIR_VENDOR, 2);
dinfo->cfg.device = pci_read_config(dev, PCIR_DEVICE, 2);
dinfo->cfg.cmdreg = pci_read_config(dev, PCIR_COMMAND, 2);
dinfo->cfg.intline = pci_read_config(dev, PCIR_INTLINE, 1);
dinfo->cfg.intpin = pci_read_config(dev, PCIR_INTPIN, 1);
- dinfo->cfg.mingnt = pci_read_config(dev, PCIR_MINGNT, 1);
- dinfo->cfg.maxlat = pci_read_config(dev, PCIR_MAXLAT, 1);
dinfo->cfg.cachelnsz = pci_read_config(dev, PCIR_CACHELNSZ, 1);
dinfo->cfg.lattimer = pci_read_config(dev, PCIR_LATTIMER, 1);
dinfo->cfg.baseclass = pci_read_config(dev, PCIR_CLASS, 1);
dinfo->cfg.subclass = pci_read_config(dev, PCIR_SUBCLASS, 1);
dinfo->cfg.progif = pci_read_config(dev, PCIR_PROGIF, 1);
dinfo->cfg.revid = pci_read_config(dev, PCIR_REVID, 1);
+ switch (dinfo->cfg.hdrtype & PCIM_HDRTYPE) {
+ case PCIM_HDRTYPE_NORMAL:
+ dinfo->cfg.subvendor = pci_read_config(dev, PCIR_SUBVEND_0, 2);
+ dinfo->cfg.subdevice = pci_read_config(dev, PCIR_SUBDEV_0, 2);
+ dinfo->cfg.mingnt = pci_read_config(dev, PCIR_MINGNT, 1);
+ dinfo->cfg.maxlat = pci_read_config(dev, PCIR_MAXLAT, 1);
+ break;
+ case PCIM_HDRTYPE_BRIDGE:
+ dinfo->cfg.bridge.br_seclat = pci_read_config(dev,
+ PCIR_SECLAT_1, 1);
+ dinfo->cfg.bridge.br_subbus = pci_read_config(dev,
+ PCIR_SUBBUS_1, 1);
+ dinfo->cfg.bridge.br_secbus = pci_read_config(dev,
+ PCIR_SECBUS_1, 1);
+ dinfo->cfg.bridge.br_pribus = pci_read_config(dev,
+ PCIR_PRIBUS_1, 1);
+ dinfo->cfg.bridge.br_control = pci_read_config(dev,
+ PCIR_BRIDGECTL_1, 2);
+ break;
+ case PCIM_HDRTYPE_CARDBUS:
+ dinfo->cfg.bridge.br_seclat = pci_read_config(dev,
+ PCIR_SECLAT_2, 1);
+ dinfo->cfg.bridge.br_subbus = pci_read_config(dev,
+ PCIR_SUBBUS_2, 1);
+ dinfo->cfg.bridge.br_secbus = pci_read_config(dev,
+ PCIR_SECBUS_2, 1);
+ dinfo->cfg.bridge.br_pribus = pci_read_config(dev,
+ PCIR_PRIBUS_2, 1);
+ dinfo->cfg.bridge.br_control = pci_read_config(dev,
+ PCIR_BRIDGECTL_2, 2);
+ dinfo->cfg.subvendor = pci_read_config(dev, PCIR_SUBVEND_2, 2);
+ dinfo->cfg.subdevice = pci_read_config(dev, PCIR_SUBDEV_2, 2);
+ break;
+ }
if (dinfo->cfg.pcie.pcie_location != 0)
pci_cfg_save_pcie(dev, dinfo);
diff --git a/sys/dev/pci/pci_pci.c b/sys/dev/pci/pci_pci.c
index d0d8fb77b9d5..789a9180313c 100644
--- a/sys/dev/pci/pci_pci.c
+++ b/sys/dev/pci/pci_pci.c
@@ -553,18 +553,22 @@ void
pcib_setup_secbus(device_t dev, struct pcib_secbus *bus, int min_count)
{
char buf[64];
- int error, rid;
+ int error, rid, sec_reg;
switch (pci_read_config(dev, PCIR_HDRTYPE, 1) & PCIM_HDRTYPE) {
case PCIM_HDRTYPE_BRIDGE:
+ sec_reg = PCIR_SECBUS_1;
bus->sub_reg = PCIR_SUBBUS_1;
break;
case PCIM_HDRTYPE_CARDBUS:
+ sec_reg = PCIR_SECBUS_2;
bus->sub_reg = PCIR_SUBBUS_2;
break;
default:
panic("not a PCI bridge");
}
+ bus->sec = pci_read_config(dev, sec_reg, 1);
+ bus->sub = pci_read_config(dev, bus->sub_reg, 1);
bus->dev = dev;
bus->rman.rm_start = 0;
bus->rman.rm_end = PCI_BUSMAX;
@@ -849,20 +853,16 @@ pcib_set_mem_decode(struct pcib_softc *sc)
static void
pcib_cfg_save(struct pcib_softc *sc)
{
+#ifndef NEW_PCIB
device_t dev;
+ uint16_t command;
dev = sc->dev;
- sc->command = pci_read_config(dev, PCIR_COMMAND, 2);
- sc->pribus = pci_read_config(dev, PCIR_PRIBUS_1, 1);
- sc->bus.sec = pci_read_config(dev, PCIR_SECBUS_1, 1);
- sc->bus.sub = pci_read_config(dev, PCIR_SUBBUS_1, 1);
- sc->bridgectl = pci_read_config(dev, PCIR_BRIDGECTL_1, 2);
- sc->seclat = pci_read_config(dev, PCIR_SECLAT_1, 1);
-#ifndef NEW_PCIB
- if (sc->command & PCIM_CMD_PORTEN)
+ command = pci_read_config(dev, PCIR_COMMAND, 2);
+ if (command & PCIM_CMD_PORTEN)
pcib_get_io_decode(sc);
- if (sc->command & PCIM_CMD_MEMEN)
+ if (command & PCIM_CMD_MEMEN)
pcib_get_mem_decode(sc);
#endif
}
@@ -874,21 +874,18 @@ static void
pcib_cfg_restore(struct pcib_softc *sc)
{
device_t dev;
-
+#ifndef NEW_PCIB
+ uint16_t command;
+#endif
dev = sc->dev;
- pci_write_config(dev, PCIR_COMMAND, sc->command, 2);
- pci_write_config(dev, PCIR_PRIBUS_1, sc->pribus, 1);
- pci_write_config(dev, PCIR_SECBUS_1, sc->bus.sec, 1);
- pci_write_config(dev, PCIR_SUBBUS_1, sc->bus.sub, 1);
- pci_write_config(dev, PCIR_BRIDGECTL_1, sc->bridgectl, 2);
- pci_write_config(dev, PCIR_SECLAT_1, sc->seclat, 1);
#ifdef NEW_PCIB
pcib_write_windows(sc, WIN_IO | WIN_MEM | WIN_PMEM);
#else
- if (sc->command & PCIM_CMD_PORTEN)
+ command = pci_read_config(dev, PCIR_COMMAND, 2);
+ if (command & PCIM_CMD_PORTEN)
pcib_set_io_decode(sc);
- if (sc->command & PCIM_CMD_MEMEN)
+ if (command & PCIM_CMD_MEMEN)
pcib_set_mem_decode(sc);
#endif
}
@@ -922,7 +919,11 @@ pcib_attach_common(device_t dev)
* Get current bridge configuration.
*/
sc->domain = pci_get_domain(dev);
- sc->secstat = pci_read_config(dev, PCIR_SECSTAT_1, 2);
+#if !(defined(NEW_PCIB) && defined(PCI_RES_BUS))
+ sc->bus.sec = pci_read_config(dev, PCIR_SECBUS_1, 1);
+ sc->bus.sub = pci_read_config(dev, PCIR_SUBBUS_1, 1);
+#endif
+ sc->bridgectl = pci_read_config(dev, PCIR_BRIDGECTL_1, 2);
pcib_cfg_save(sc);
/*
@@ -950,7 +951,7 @@ pcib_attach_common(device_t dev)
* Quirk handling.
*/
switch (pci_get_devid(dev)) {
-#if !defined(NEW_PCIB) && !defined(PCI_RES_BUS)
+#if !(defined(NEW_PCIB) && defined(PCI_RES_BUS))
case 0x12258086: /* Intel 82454KX/GX (Orion) */
{
uint8_t supbus;
@@ -976,7 +977,7 @@ pcib_attach_common(device_t dev)
sc->flags |= PCIB_SUBTRACTIVE;
break;
-#if !defined(NEW_PCIB) && !defined(PCI_RES_BUS)
+#if !(defined(NEW_PCIB) && defined(PCI_RES_BUS))
/* Compaq R3000 BIOS sets wrong subordinate bus number. */
case 0x00dd10de:
{
@@ -1101,32 +1102,15 @@ pcib_attach(device_t dev)
int
pcib_suspend(device_t dev)
{
- device_t pcib;
- int dstate, error;
pcib_cfg_save(device_get_softc(dev));
- error = bus_generic_suspend(dev);
- if (error == 0 && pci_do_power_suspend) {
- dstate = PCI_POWERSTATE_D3;
- pcib = device_get_parent(device_get_parent(dev));
- if (PCIB_POWER_FOR_SLEEP(pcib, dev, &dstate) == 0)
- pci_set_powerstate(dev, dstate);
- }
- return (error);
+ return (bus_generic_suspend(dev));
}
int
pcib_resume(device_t dev)
{
- device_t pcib;
- int dstate;
-
- if (pci_do_power_resume) {
- pcib = device_get_parent(device_get_parent(dev));
- dstate = PCI_POWERSTATE_D0;
- if (PCIB_POWER_FOR_SLEEP(pcib, dev, &dstate) == 0)
- pci_set_powerstate(dev, dstate);
- }
+
pcib_cfg_restore(device_get_softc(dev));
return (bus_generic_resume(dev));
}
diff --git a/sys/dev/pci/pci_subr.c b/sys/dev/pci/pci_subr.c
index 5d0db3665c6b..03bcdc088b9f 100644
--- a/sys/dev/pci/pci_subr.c
+++ b/sys/dev/pci/pci_subr.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2011 Advanced Computing Technologies LLC
+ * Copyright (c) 2011 Hudson River Trading LLC
* Written by: John H. Baldwin <jhb@FreeBSD.org>
* All rights reserved.
*
diff --git a/sys/dev/pci/pcib_private.h b/sys/dev/pci/pcib_private.h
index d8d82b6540f7..20cb014c3b84 100644
--- a/sys/dev/pci/pcib_private.h
+++ b/sys/dev/pci/pcib_private.h
@@ -106,7 +106,6 @@ struct pcib_softc
#define PCIB_DISABLE_MSI 0x2
#define PCIB_DISABLE_MSIX 0x4
#define PCIB_ENABLE_ARI 0x8
- uint16_t command; /* command register */
u_int domain; /* domain number */
u_int pribus; /* primary bus number */
struct pcib_secbus bus; /* secondary bus numbers */
@@ -122,9 +121,7 @@ struct pcib_softc
uint32_t iobase; /* base address of port window */
uint32_t iolimit; /* topmost address of port window */
#endif
- uint16_t secstat; /* secondary bus status register */
uint16_t bridgectl; /* bridge control register */
- uint8_t seclat; /* secondary bus latency timer */
};
#define PCIB_SUPPORTED_ARI_VER 1
diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h
index 478c98eb0a7a..2fd76b6bf8cd 100644
--- a/sys/dev/pci/pcivar.h
+++ b/sys/dev/pci/pcivar.h
@@ -41,6 +41,15 @@ typedef uint64_t pci_addr_t;
struct nvlist;
+/* Config registers for PCI-PCI and PCI-Cardbus bridges. */
+struct pcicfg_bridge {
+ uint8_t br_seclat;
+ uint8_t br_subbus;
+ uint8_t br_secbus;
+ uint8_t br_pribus;
+ uint16_t br_control;
+};
+
/* Interesting values for PCI power management */
struct pcicfg_pp {
uint16_t pp_cap; /* PCI power management capabilities */
@@ -190,6 +199,7 @@ typedef struct pcicfg {
uint32_t flags; /* flags defined above */
size_t devinfo_size; /* Size of devinfo for this bus type. */
+ struct pcicfg_bridge bridge; /* Bridges */
struct pcicfg_pp pp; /* Power management */
struct pcicfg_vpd vpd; /* Vital product data */
struct pcicfg_msi msi; /* PCI MSI */
diff --git a/sys/dev/smbus/smb.c b/sys/dev/smbus/smb.c
index 579204d1a04c..e84244118927 100644
--- a/sys/dev/smbus/smb.c
+++ b/sys/dev/smbus/smb.c
@@ -26,10 +26,6 @@
* $FreeBSD$
*/
-#ifdef HAVE_KERNEL_OPTION_HEADERS
-#include "opt_compat.h"
-#endif
-
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
@@ -104,19 +100,24 @@ smb_identify(driver_t *driver, device_t parent)
static int
smb_probe(device_t dev)
{
- device_set_desc(dev, "SMBus generic I/O");
+ if (smbus_get_addr(dev) != -1)
+ return (ENXIO);
- return (0);
+ device_set_desc(dev, "SMBus generic I/O");
+ return (BUS_PROBE_NOWILDCARD);
}
static int
smb_attach(device_t dev)
{
struct smb_softc *sc = device_get_softc(dev);
-
+ int unit;
+
+ unit = device_get_unit(dev);
sc->sc_dev = dev;
- sc->sc_devnode = make_dev(&smb_cdevsw, device_get_unit(dev),
- UID_ROOT, GID_WHEEL, 0600, "smb%d", device_get_unit(dev));
+
+ sc->sc_devnode = make_dev(&smb_cdevsw, unit, UID_ROOT, GID_WHEEL,
+ 0600, "smb%d", unit);
sc->sc_devnode->si_drv1 = sc;
mtx_init(&sc->sc_lock, device_get_nameunit(dev), NULL, MTX_DEF);
@@ -174,9 +175,16 @@ smbioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, struct thread *t
struct smb_softc *sc = dev->si_drv1;
device_t smbdev = sc->sc_dev;
int error;
- short w;
- u_char count;
- char c;
+ int unit;
+ u_char bcount;
+
+ /*
+ * If a specific slave device is being used, override any passed-in
+ * slave.
+ */
+ unit = dev2unit(dev);
+ if (unit & 0x0400)
+ s->slave = unit & 0x03ff;
parent = device_get_parent(smbdev);
@@ -208,77 +216,101 @@ smbioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, struct thread *t
case SMB_WRITEB:
error = smbus_error(smbus_writeb(parent, s->slave, s->cmd,
- s->data.byte));
+ s->wdata.byte));
break;
case SMB_WRITEW:
error = smbus_error(smbus_writew(parent, s->slave,
- s->cmd, s->data.word));
+ s->cmd, s->wdata.word));
break;
case SMB_READB:
- if (s->data.byte_ptr) {
- error = smbus_error(smbus_readb(parent, s->slave,
- s->cmd, &c));
- if (error)
- break;
- error = copyout(&c, s->data.byte_ptr,
- sizeof(*(s->data.byte_ptr)));
+ error = smbus_error(smbus_readb(parent, s->slave, s->cmd,
+ &s->rdata.byte));
+ if (error)
+ break;
+ if (s->rbuf && s->rcount >= 1) {
+ error = copyout(&s->rdata.byte, s->rbuf, 1);
+ s->rcount = 1;
}
break;
case SMB_READW:
- if (s->data.word_ptr) {
- error = smbus_error(smbus_readw(parent, s->slave,
- s->cmd, &w));
- if (error == 0) {
- error = copyout(&w, s->data.word_ptr,
- sizeof(*(s->data.word_ptr)));
- }
+ error = smbus_error(smbus_readw(parent, s->slave, s->cmd,
+ &s->rdata.word));
+ if (error)
+ break;
+ if (s->rbuf && s->rcount >= 2) {
+ buf[0] = (u_char)s->rdata.word;
+ buf[1] = (u_char)(s->rdata.word >> 8);
+ error = copyout(buf, s->rbuf, 2);
+ s->rcount = 2;
}
break;
case SMB_PCALL:
- if (s->data.process.rdata) {
-
- error = smbus_error(smbus_pcall(parent, s->slave, s->cmd,
- s->data.process.sdata, &w));
- if (error)
- break;
- error = copyout(&w, s->data.process.rdata,
- sizeof(*(s->data.process.rdata)));
+ error = smbus_error(smbus_pcall(parent, s->slave, s->cmd,
+ s->wdata.word, &s->rdata.word));
+ if (error)
+ break;
+ if (s->rbuf && s->rcount >= 2) {
+ buf[0] = (u_char)s->rdata.word;
+ buf[1] = (u_char)(s->rdata.word >> 8);
+ error = copyout(buf, s->rbuf, 2);
+ s->rcount = 2;
}
-
+
break;
case SMB_BWRITE:
- if (s->count && s->data.byte_ptr) {
- if (s->count > SMB_MAXBLOCKSIZE)
- s->count = SMB_MAXBLOCKSIZE;
- error = copyin(s->data.byte_ptr, buf, s->count);
- if (error)
- break;
- error = smbus_error(smbus_bwrite(parent, s->slave,
- s->cmd, s->count, buf));
+ if (s->wcount < 0) {
+ error = EINVAL;
+ break;
}
+ if (s->wcount > SMB_MAXBLOCKSIZE)
+ s->wcount = SMB_MAXBLOCKSIZE;
+ if (s->wcount)
+ error = copyin(s->wbuf, buf, s->wcount);
+ if (error)
+ break;
+ error = smbus_error(smbus_bwrite(parent, s->slave, s->cmd,
+ s->wcount, buf));
break;
-#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || defined(COMPAT_FREEBSD6)
- case SMB_OLD_BREAD:
-#endif
case SMB_BREAD:
- if (s->count && s->data.byte_ptr) {
- count = min(s->count, SMB_MAXBLOCKSIZE);
- error = smbus_error(smbus_bread(parent, s->slave,
- s->cmd, &count, buf));
- if (error)
- break;
- error = copyout(buf, s->data.byte_ptr,
- min(count, s->count));
- s->count = count;
+ if (s->rcount < 0) {
+ error = EINVAL;
+ break;
+ }
+ if (s->rcount > SMB_MAXBLOCKSIZE)
+ s->rcount = SMB_MAXBLOCKSIZE;
+ error = smbus_error(smbus_bread(parent, s->slave, s->cmd,
+ &bcount, buf));
+ if (error)
+ break;
+ if (s->rcount > bcount)
+ s->rcount = bcount;
+ error = copyout(buf, s->rbuf, s->rcount);
+ break;
+
+ case SMB_TRANS:
+ if (s->rcount < 0 || s->wcount < 0) {
+ error = EINVAL;
+ break;
}
+ if (s->rcount > SMB_MAXBLOCKSIZE)
+ s->rcount = SMB_MAXBLOCKSIZE;
+ if (s->wcount > SMB_MAXBLOCKSIZE)
+ s->wcount = SMB_MAXBLOCKSIZE;
+ if (s->wcount)
+ error = copyin(s->wbuf, buf, s->wcount);
+ if (error)
+ break;
+ error = smbus_error(smbus_trans(parent, s->slave, s->cmd,
+ s->op, buf, s->wcount, buf, s->rcount, &s->rcount));
+ if (error == 0)
+ error = copyout(buf, s->rbuf, s->rcount);
break;
-
default:
error = ENOTTY;
}
diff --git a/sys/dev/smbus/smb.h b/sys/dev/smbus/smb.h
index 32347f8f4c2d..80076530bb52 100644
--- a/sys/dev/smbus/smb.h
+++ b/sys/dev/smbus/smb.h
@@ -32,27 +32,33 @@
#include <sys/ioccom.h>
struct smbcmd {
- char cmd;
- int count;
- u_char slave;
+ u_char cmd;
+ u_char reserved;
+ u_short op;
union {
- char byte;
- short word;
-
- char *byte_ptr;
- short *word_ptr;
-
- struct {
- short sdata;
- short *rdata;
- } process;
- } data;
+ char byte;
+ char buf[2];
+ short word;
+ } wdata;
+ union {
+ char byte;
+ char buf[2];
+ short word;
+ } rdata;
+ int slave;
+ char *wbuf; /* use wdata if NULL */
+ int wcount;
+ char *rbuf; /* use rdata if NULL */
+ int rcount;
};
/*
* SMBus spec 2.0 says block transfers may be at most 32 bytes.
+ * We use SMBus for i2c as well, make the size limit something more
+ * reasonable. Keep in mind that a char buf array is declared on the
+ * kernel stack.
*/
-#define SMB_MAXBLOCKSIZE 32
+#define SMB_MAXBLOCKSIZE 1024
#define SMB_QUICK_WRITE _IOW('i', 1, struct smbcmd)
#define SMB_QUICK_READ _IOW('i', 2, struct smbcmd)
@@ -66,5 +72,6 @@ struct smbcmd {
#define SMB_BWRITE _IOW('i', 10, struct smbcmd)
#define SMB_OLD_BREAD _IOW('i', 11, struct smbcmd)
#define SMB_BREAD _IOWR('i', 11, struct smbcmd)
+#define SMB_TRANS _IOWR('i', 12, struct smbcmd)
#endif
diff --git a/sys/dev/smbus/smbconf.h b/sys/dev/smbus/smbconf.h
index a3d403d566ea..f39c44287c35 100644
--- a/sys/dev/smbus/smbconf.h
+++ b/sys/dev/smbus/smbconf.h
@@ -68,9 +68,30 @@
#define SMB_QREAD 0x1
/*
+ * smbus transction op with pass-thru capabilities
+ *
+ * This smbus function is capable of doing a smbus command transaction
+ * (read or write), and can be flagged to not issue the 'cmd' and/or
+ * issue or expect a count field as well as flagged for chaining (no STOP),
+ * which gives it an i2c pass-through capability.
+ *
+ * NOSTOP- Caller chaining transactions, do not issue STOP
+ * NOCMD- Do not transmit the command field
+ * NOCNT- Do not transmit (wr) or expect (rd) the count field
+ */
+#define SMB_TRANS_NOSTOP 0x0001 /* do not send STOP at end */
+#define SMB_TRANS_NOCMD 0x0002 /* ignore cmd field (do not tx) */
+#define SMB_TRANS_NOCNT 0x0004 /* do not tx or rx count field */
+#define SMB_TRANS_7BIT 0x0008 /* change address mode to 7-bit */
+#define SMB_TRANS_10BIT 0x0010 /* change address mode to 10-bit */
+#define SMB_TRANS_NOREPORT 0x0020 /* do not report errors */
+
+/*
* ivars codes
*/
-#define SMBUS_IVAR_ADDR 0x1 /* slave address of the device */
+enum smbus_ivars {
+ SMBUS_IVAR_ADDR, /* slave address of the device */
+};
int smbus_request_bus(device_t, device_t, int);
int smbus_release_bus(device_t, device_t);
@@ -79,7 +100,12 @@ int smbus_error(int error);
void smbus_intr(device_t, u_char, char low, char high, int error);
-u_char smbus_get_addr(device_t);
+#define SMBUS_ACCESSOR(var, ivar, type) \
+ __BUS_ACCESSOR(smbus, var, SMBUS, ivar, type)
+
+SMBUS_ACCESSOR(addr, ADDR, int)
+
+#undef SMBUS_ACCESSOR
extern driver_t smbus_driver;
extern devclass_t smbus_devclass;
@@ -104,6 +130,9 @@ extern devclass_t smbus_devclass;
(SMBUS_BWRITE(device_get_parent(bus), slave, cmd, count, buf))
#define smbus_bread(bus,slave,cmd,count,buf) \
(SMBUS_BREAD(device_get_parent(bus), slave, cmd, count, buf))
+#define smbus_trans(bus,slave,cmd,op,wbuf,wcount,rbuf,rcount,actualp) \
+ (SMBUS_TRANS(device_get_parent(bus), slave, cmd, op, \
+ wbuf, wcount, rbuf, rcount, actualp))
#define SMBUS_MODVER 1
#define SMBUS_MINVER 1
diff --git a/sys/dev/smbus/smbus.c b/sys/dev/smbus/smbus.c
index a111332c6d97..389efac1c6d4 100644
--- a/sys/dev/smbus/smbus.c
+++ b/sys/dev/smbus/smbus.c
@@ -33,11 +33,15 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/module.h>
#include <sys/mutex.h>
-#include <sys/bus.h>
+#include <sys/bus.h>
#include <dev/smbus/smbconf.h>
#include <dev/smbus/smbus.h>
+#include "smbus_if.h"
+#include "bus_if.h"
+
+
/*
* Autoconfiguration and support routines for System Management bus
*/
@@ -49,6 +53,13 @@ static int smbus_probe(device_t);
static int smbus_attach(device_t);
static int smbus_detach(device_t);
+static int smbus_child_location_str(device_t parent, device_t child,
+ char *buf, size_t buflen);
+static int smbus_print_child(device_t parent, device_t child);
+static void smbus_probe_device(device_t dev, u_char* addr);
+static int smbus_read_ivar(device_t parent, device_t child, int which,
+ uintptr_t *result);
+
static device_method_t smbus_methods[] = {
/* device interface */
DEVMETHOD(device_probe, smbus_probe),
@@ -57,6 +68,10 @@ static device_method_t smbus_methods[] = {
/* bus interface */
DEVMETHOD(bus_add_child, bus_generic_add_child),
+ DEVMETHOD(bus_child_location_str, smbus_child_location_str),
+ DEVMETHOD(bus_driver_added, bus_generic_driver_added),
+ DEVMETHOD(bus_print_child, smbus_print_child),
+ DEVMETHOD(bus_read_ivar, smbus_read_ivar),
DEVMETHOD_END
};
@@ -87,9 +102,14 @@ static int
smbus_attach(device_t dev)
{
struct smbus_softc *sc = device_get_softc(dev);
+ unsigned char addr;
mtx_init(&sc->lock, device_get_nameunit(dev), "smbus", MTX_DEF);
bus_generic_probe(dev);
+ for (addr = SMBUS_ADDR_MIN; addr < SMBUS_ADDR_MAX; ++addr) {
+ sc->addrs[addr] = addr;
+ smbus_probe_device(dev, &sc->addrs[addr]);
+ }
bus_generic_attach(dev);
return (0);
@@ -114,4 +134,70 @@ smbus_generic_intr(device_t dev, u_char devaddr, char low, char high, int err)
{
}
+static void
+smbus_probe_device(device_t dev, u_char* addr)
+{
+ device_t child;
+ int error;
+ u_char cmd;
+ u_char buf[2];
+
+ cmd = 0x01;
+ error = smbus_trans(dev, *addr, cmd,
+ SMB_TRANS_NOCNT | SMB_TRANS_NOREPORT,
+ NULL, 0, buf, 1, NULL);
+ if (error == 0) {
+ if (bootverbose)
+ device_printf(dev, "Probed address 0x%02x\n", *addr);
+ child = device_add_child(dev, NULL, -1);
+ device_set_ivars(child, addr);
+ }
+}
+
+static int
+smbus_child_location_str(device_t parent, device_t child, char *buf,
+ size_t buflen)
+{
+ unsigned char *addr;
+
+ addr = device_get_ivars(child);
+ if (addr)
+ snprintf(buf, buflen, "addr=0x%x", *addr);
+ else if (buflen)
+ buf[0] = 0;
+ return (0);
+}
+
+static int
+smbus_print_child(device_t parent, device_t child)
+{
+ unsigned char *addr;
+ int retval;
+
+ addr = device_get_ivars(child);
+ retval = bus_print_child_header(parent, child);
+ if (addr)
+ retval += printf(" at addr 0x%x", *addr);
+ retval += bus_print_child_footer(parent, child);
+
+ return (retval);
+}
+
+static int
+smbus_read_ivar(device_t parent, device_t child, int which,
+ uintptr_t *result)
+{
+ unsigned char *addr;
+
+ addr = device_get_ivars(child);
+ switch (which) {
+ case SMBUS_IVAR_ADDR:
+ *result = (addr == NULL) ? -1 : *addr;
+ break;
+ default:
+ return (ENOENT);
+ }
+ return (0);
+}
+
MODULE_VERSION(smbus, SMBUS_MODVER);
diff --git a/sys/dev/smbus/smbus.h b/sys/dev/smbus/smbus.h
index 56268355f207..2093aa013602 100644
--- a/sys/dev/smbus/smbus.h
+++ b/sys/dev/smbus/smbus.h
@@ -29,9 +29,13 @@
#ifndef __SMBUS_H
#define __SMBUS_H
+#define SMBUS_ADDR_MIN 0x10
+#define SMBUS_ADDR_MAX 0x70
+
struct smbus_softc {
device_t owner; /* smbus owner device structure */
struct mtx lock;
+ unsigned char addrs[SMBUS_ADDR_MAX];
};
void smbus_generic_intr(device_t dev, u_char devaddr, char low, char high, int err);
diff --git a/sys/dev/smbus/smbus_if.m b/sys/dev/smbus/smbus_if.m
index d969e25ed566..6a5acf5dbcb9 100644
--- a/sys/dev/smbus/smbus_if.m
+++ b/sys/dev/smbus/smbus_if.m
@@ -149,3 +149,20 @@ METHOD int bread {
u_char *count;
char *buf;
};
+
+#
+# SMB roll-up transaction with flags that also allow it to be
+# used for (mostly) i2c pass-through and with 10-bit addresses.
+# This function can be used to roll-up all of the above functions.
+#
+METHOD int trans {
+ device_t dev;
+ int slave;
+ char cmd;
+ int op;
+ char *wbuf;
+ int wcount;
+ char *rbuf;
+ int rcount;
+ int *actualp;
+};
diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c
index 68204ff193e3..5b92963375f4 100644
--- a/sys/dev/sound/pcm/dsp.c
+++ b/sys/dev/sound/pcm/dsp.c
@@ -48,6 +48,11 @@ SYSCTL_INT(_hw_snd, OID_AUTO, compat_linux_mmap, CTLFLAG_RWTUN,
&dsp_mmap_allow_prot_exec, 0,
"linux mmap compatibility (-1=force disable 0=auto 1=force enable)");
+static int dsp_basename_clone = 1;
+SYSCTL_INT(_hw_snd, OID_AUTO, basename_clone, CTLFLAG_RWTUN,
+ &dsp_basename_clone, 0,
+ "DSP basename cloning (0: Disable; 1: Enabled)");
+
struct dsp_cdevinfo {
struct pcm_channel *rdch, *wrch;
struct pcm_channel *volch;
@@ -2357,9 +2362,10 @@ dsp_clone(void *arg,
devname = devcmp;
devhw = dsp_cdevs[i].hw;
devcmax = dsp_cdevs[i].max - 1;
- if (strcmp(name, devcmp) == 0)
- unit = snd_unit;
- else if (dsp_stdclone(name, devcmp, devsep,
+ if (strcmp(name, devcmp) == 0) {
+ if (dsp_basename_clone != 0)
+ unit = snd_unit;
+ } else if (dsp_stdclone(name, devcmp, devsep,
dsp_cdevs[i].use_sep, &unit, &cunit) != 0) {
unit = -1;
cunit = -1;
diff --git a/sys/dev/usb/controller/dwc_otg.c b/sys/dev/usb/controller/dwc_otg.c
index 05d2f7125ebf..37b533325fd9 100644
--- a/sys/dev/usb/controller/dwc_otg.c
+++ b/sys/dev/usb/controller/dwc_otg.c
@@ -3876,20 +3876,18 @@ dwc_otg_init(struct dwc_otg_softc *sc)
if (temp & GHWCFG2_MPI) {
uint8_t x;
- DPRINTF("Multi Process Interrupts\n");
+ DPRINTF("Disable Multi Process Interrupts\n");
for (x = 0; x != sc->sc_dev_in_ep_max; x++) {
- DWC_OTG_WRITE_4(sc, DOTG_DIEPEACHINTMSK(x),
- DIEPMSK_XFERCOMPLMSK);
+ DWC_OTG_WRITE_4(sc, DOTG_DIEPEACHINTMSK(x), 0);
DWC_OTG_WRITE_4(sc, DOTG_DOEPEACHINTMSK(x), 0);
}
- DWC_OTG_WRITE_4(sc, DOTG_DEACHINTMSK, 0xFFFF);
- } else {
- DWC_OTG_WRITE_4(sc, DOTG_DIEPMSK,
- DIEPMSK_XFERCOMPLMSK);
- DWC_OTG_WRITE_4(sc, DOTG_DOEPMSK, 0);
- DWC_OTG_WRITE_4(sc, DOTG_DAINTMSK, 0xFFFF);
+ DWC_OTG_WRITE_4(sc, DOTG_DEACHINTMSK, 0);
}
+ DWC_OTG_WRITE_4(sc, DOTG_DIEPMSK,
+ DIEPMSK_XFERCOMPLMSK);
+ DWC_OTG_WRITE_4(sc, DOTG_DOEPMSK, 0);
+ DWC_OTG_WRITE_4(sc, DOTG_DAINTMSK, 0xFFFF);
}
if (sc->sc_mode == DWC_MODE_OTG || sc->sc_mode == DWC_MODE_HOST) {
diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
index 4a10610e16d7..d972bdc7650d 100644
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -3755,6 +3755,7 @@ product REALTEK RTL8188CU_1 0x817a RTL8188CU
product REALTEK RTL8188CU_2 0x817b RTL8188CU
product REALTEK RTL8187 0x8187 RTL8187 Wireless Adapter
product REALTEK RTL8187B_0 0x8189 RTL8187B Wireless Adapter
+product REALTEK RTL8188CU_3 0x8191 RTL8188CU
product REALTEK RTL8196EU 0x8196 RTL8196EU
product REALTEK RTL8187B_1 0x8197 RTL8187B Wireless Adapter
product REALTEK RTL8187B_2 0x8198 RTL8187B Wireless Adapter
diff --git a/sys/dev/usb/wlan/if_urtwn.c b/sys/dev/usb/wlan/if_urtwn.c
index a25114f5903e..72004d9f50de 100644
--- a/sys/dev/usb/wlan/if_urtwn.c
+++ b/sys/dev/usb/wlan/if_urtwn.c
@@ -137,6 +137,7 @@ static const STRUCT_USB_HOST_ID urtwn_devs[] = {
URTWN_DEV(REALTEK, RTL8188CU_0),
URTWN_DEV(REALTEK, RTL8188CU_1),
URTWN_DEV(REALTEK, RTL8188CU_2),
+ URTWN_DEV(REALTEK, RTL8188CU_3),
URTWN_DEV(REALTEK, RTL8188CU_COMBO),
URTWN_DEV(REALTEK, RTL8188CUS),
URTWN_DEV(REALTEK, RTL8188RU_1),
@@ -145,7 +146,6 @@ static const STRUCT_USB_HOST_ID urtwn_devs[] = {
URTWN_DEV(REALTEK, RTL8191CU),
URTWN_DEV(REALTEK, RTL8192CE),
URTWN_DEV(REALTEK, RTL8192CU),
- URTWN_DEV(REALTEK, RTL8188CU_0),
URTWN_DEV(SITECOMEU, RTL8188CU_1),
URTWN_DEV(SITECOMEU, RTL8188CU_2),
URTWN_DEV(SITECOMEU, RTL8192CU),
@@ -1236,9 +1236,11 @@ urtwn_efuse_read(struct urtwn_softc *sc)
static void
urtwn_efuse_switch_power(struct urtwn_softc *sc)
{
- uint8_t vol;
uint32_t reg;
+ if (sc->chip & URTWN_CHIP_88E)
+ urtwn_write_1(sc, R92C_EFUSE_ACCESS, R92C_EFUSE_ACCESS_ON);
+
reg = urtwn_read_2(sc, R92C_SYS_ISO_CTRL);
if (!(reg & R92C_SYS_ISO_CTRL_PWC_EV12V)) {
urtwn_write_2(sc, R92C_SYS_ISO_CTRL,
@@ -1256,11 +1258,15 @@ urtwn_efuse_switch_power(struct urtwn_softc *sc)
reg | R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M);
}
- /* Enable LDO 2.5V. */
- vol = urtwn_read_1(sc, R92C_EFUSE_TEST + 3);
- vol &= 0x0f;
- vol |= 0x30;
- urtwn_write_1(sc, R92C_EFUSE_TEST + 3, (vol | 0x80));
+ if (!(sc->chip & URTWN_CHIP_88E)) {
+ uint8_t vol;
+
+ /* Enable LDO 2.5V. */
+ vol = urtwn_read_1(sc, R92C_EFUSE_TEST + 3);
+ vol &= 0x0f;
+ vol |= 0x30;
+ urtwn_write_1(sc, R92C_EFUSE_TEST + 3, (vol | 0x80));
+ }
}
static int
@@ -1328,7 +1334,7 @@ urtwn_r88e_read_rom(struct urtwn_softc *sc)
/* Read full ROM image. */
memset(&sc->r88e_rom, 0xff, sizeof(sc->r88e_rom));
- while (addr < 1024) {
+ while (addr < 512) {
reg = urtwn_efuse_read_1(sc, addr);
if (reg == 0xff)
break;
@@ -1354,6 +1360,8 @@ urtwn_r88e_read_rom(struct urtwn_softc *sc)
}
}
+ urtwn_write_1(sc, R92C_EFUSE_ACCESS, R92C_EFUSE_ACCESS_OFF);
+
addr = 0x10;
for (i = 0; i < 6; i++)
sc->cck_tx_pwr[i] = sc->r88e_rom[addr++];
@@ -2193,14 +2201,12 @@ urtwn_r92c_power_on(struct urtwn_softc *sc)
static int
urtwn_r88e_power_on(struct urtwn_softc *sc)
{
- uint8_t val;
uint32_t reg;
int ntries;
/* Wait for power ready bit. */
for (ntries = 0; ntries < 5000; ntries++) {
- val = urtwn_read_1(sc, 0x6) & 0x2;
- if (val == 0x2)
+ if (urtwn_read_4(sc, R92C_APS_FSMCO) & R92C_APS_FSMCO_SUS_HOST)
break;
urtwn_ms_delay(sc);
}
@@ -2215,17 +2221,23 @@ urtwn_r88e_power_on(struct urtwn_softc *sc)
urtwn_read_1(sc, R92C_SYS_FUNC_EN) & ~(R92C_SYS_FUNC_EN_BBRSTB |
R92C_SYS_FUNC_EN_BB_GLB_RST));
- urtwn_write_1(sc, 0x26, urtwn_read_1(sc, 0x26) | 0x80);
+ urtwn_write_1(sc, R92C_AFE_XTAL_CTRL + 2,
+ urtwn_read_1(sc, R92C_AFE_XTAL_CTRL + 2) | 0x80);
/* Disable HWPDN. */
- urtwn_write_1(sc, 0x5, urtwn_read_1(sc, 0x5) & ~0x80);
+ urtwn_write_2(sc, R92C_APS_FSMCO,
+ urtwn_read_2(sc, R92C_APS_FSMCO) & ~R92C_APS_FSMCO_APDM_HPDN);
/* Disable WL suspend. */
- urtwn_write_1(sc, 0x5, urtwn_read_1(sc, 0x5) & ~0x18);
+ urtwn_write_2(sc, R92C_APS_FSMCO,
+ urtwn_read_2(sc, R92C_APS_FSMCO) &
+ ~(R92C_APS_FSMCO_AFSM_HSUS | R92C_APS_FSMCO_AFSM_PCIE));
- urtwn_write_1(sc, 0x5, urtwn_read_1(sc, 0x5) | 0x1);
+ urtwn_write_2(sc, R92C_APS_FSMCO,
+ urtwn_read_2(sc, R92C_APS_FSMCO) | R92C_APS_FSMCO_APFM_ONMAC);
for (ntries = 0; ntries < 5000; ntries++) {
- if (!(urtwn_read_1(sc, 0x5) & 0x1))
+ if (!(urtwn_read_2(sc, R92C_APS_FSMCO) &
+ R92C_APS_FSMCO_APFM_ONMAC))
break;
urtwn_ms_delay(sc);
}
@@ -2233,7 +2245,8 @@ urtwn_r88e_power_on(struct urtwn_softc *sc)
return (ETIMEDOUT);
/* Enable LDO normal mode. */
- urtwn_write_1(sc, 0x23, urtwn_read_1(sc, 0x23) & ~0x10);
+ urtwn_write_1(sc, R92C_LPLDO_CTRL,
+ urtwn_read_1(sc, R92C_LPLDO_CTRL) & ~0x10);
/* Enable MAC DMA/WMAC/SCHEDULE/SEC blocks. */
urtwn_write_2(sc, R92C_CR, 0);
@@ -2565,7 +2578,6 @@ urtwn_r88e_dma_init(struct urtwn_softc *sc)
return (EIO);
/* Set number of pages for normal priority queue. */
- urtwn_write_2(sc, R92C_RQPN_NPQ, 0);
urtwn_write_2(sc, R92C_RQPN_NPQ, 0x000d);
urtwn_write_4(sc, R92C_RQPN, 0x808e000d);
@@ -3384,16 +3396,17 @@ urtwn_init_locked(void *arg)
urtwn_write_1(sc, R92C_TRXDMA_CTRL,
urtwn_read_1(sc, R92C_TRXDMA_CTRL) |
R92C_TRXDMA_CTRL_RXDMA_AGG_EN);
- urtwn_write_1(sc, R92C_USB_SPECIAL_OPTION,
- urtwn_read_1(sc, R92C_USB_SPECIAL_OPTION) |
- R92C_USB_SPECIAL_OPTION_AGG_EN);
urtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH, 48);
if (sc->chip & URTWN_CHIP_88E)
urtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH + 1, 4);
- else
+ else {
urtwn_write_1(sc, R92C_USB_DMA_AGG_TO, 4);
- urtwn_write_1(sc, R92C_USB_AGG_TH, 8);
- urtwn_write_1(sc, R92C_USB_AGG_TO, 6);
+ urtwn_write_1(sc, R92C_USB_SPECIAL_OPTION,
+ urtwn_read_1(sc, R92C_USB_SPECIAL_OPTION) |
+ R92C_USB_SPECIAL_OPTION_AGG_EN);
+ urtwn_write_1(sc, R92C_USB_AGG_TH, 8);
+ urtwn_write_1(sc, R92C_USB_AGG_TO, 6);
+ }
/* Initialize beacon parameters. */
urtwn_write_2(sc, R92C_BCN_CTRL, 0x1010);
diff --git a/sys/dev/virtio/network/if_vtnet.c b/sys/dev/virtio/network/if_vtnet.c
index 39fc28d41f45..704a3d95a54d 100644
--- a/sys/dev/virtio/network/if_vtnet.c
+++ b/sys/dev/virtio/network/if_vtnet.c
@@ -2745,6 +2745,11 @@ vtnet_drain_rxtx_queues(struct vtnet_softc *sc)
struct vtnet_txq *txq;
int i;
+#ifdef DEV_NETMAP
+ if (nm_native_on(NA(sc->vtnet_ifp)))
+ return;
+#endif /* DEV_NETMAP */
+
for (i = 0; i < sc->vtnet_act_vq_pairs; i++) {
rxq = &sc->vtnet_rxqs[i];
vtnet_rxq_free_mbufs(rxq);
diff --git a/sys/dev/vt/hw/fb/vt_fb.c b/sys/dev/vt/hw/fb/vt_fb.c
index 40f56fc097e8..b2babd1a7f7b 100644
--- a/sys/dev/vt/hw/fb/vt_fb.c
+++ b/sys/dev/vt/hw/fb/vt_fb.c
@@ -264,46 +264,40 @@ vt_fb_bitblt_bitmap(struct vt_device *vd, const struct vt_window *vw,
{
struct fb_info *info;
uint32_t fgc, bgc, cc, o;
- int c, l, bpp, bpl;
- u_long line;
- uint8_t b, m;
- const uint8_t *ch;
+ int bpp, bpl, xi, yi;
+ int bit, byte;
info = vd->vd_softc;
bpp = FBTYPE_GET_BYTESPP(info);
fgc = info->fb_cmap[fg];
bgc = info->fb_cmap[bg];
- b = m = 0;
- bpl = (width + 7) >> 3; /* Bytes per source line. */
+ bpl = (width + 7) / 8; /* Bytes per source line. */
if (info->fb_flags & FB_FLAG_NOWRITE)
return;
KASSERT((info->fb_vbase != 0), ("Unmapped framebuffer"));
- line = (info->fb_stride * y) + (x * bpp);
- for (l = 0;
- l < height && y + l < vw->vw_draw_area.tr_end.tp_row;
- l++) {
- ch = pattern;
- for (c = 0;
- c < width && x + c < vw->vw_draw_area.tr_end.tp_col;
- c++) {
- if (c % 8 == 0)
- b = *ch++;
- else
- b <<= 1;
- if (mask != NULL) {
- if (c % 8 == 0)
- m = *mask++;
- else
- m <<= 1;
- /* Skip pixel write, if mask has no bit set. */
- if ((m & 0x80) == 0)
- continue;
- }
- o = line + (c * bpp);
- cc = b & 0x80 ? fgc : bgc;
+ /* Bound by right and bottom edges. */
+ if (y + height > vw->vw_draw_area.tr_end.tp_row) {
+ if (y >= vw->vw_draw_area.tr_end.tp_row)
+ return;
+ height = vw->vw_draw_area.tr_end.tp_row - y;
+ }
+ if (x + width > vw->vw_draw_area.tr_end.tp_col) {
+ if (x >= vw->vw_draw_area.tr_end.tp_col)
+ return;
+ width = vw->vw_draw_area.tr_end.tp_col - x;
+ }
+ for (yi = 0; yi < height; yi++) {
+ for (xi = 0; xi < width; xi++) {
+ byte = yi * bpl + xi / 8;
+ bit = 0x80 >> (xi % 8);
+ /* Skip pixel write, if mask bit not set. */
+ if (mask != NULL && (mask[byte] & bit) == 0)
+ continue;
+ o = (y + yi) * info->fb_stride + (x + xi) * bpp;
+ cc = pattern[byte] & bit ? fgc : bgc;
switch(bpp) {
case 1:
@@ -326,8 +320,6 @@ vt_fb_bitblt_bitmap(struct vt_device *vd, const struct vt_window *vw,
break;
}
}
- line += info->fb_stride;
- pattern += bpl;
}
}
diff --git a/sys/dev/vt/hw/vga/vt_vga.c b/sys/dev/vt/hw/vga/vt_vga.c
index e939fdd126f6..689692e27c8c 100644
--- a/sys/dev/vt/hw/vga/vt_vga.c
+++ b/sys/dev/vt/hw/vga/vt_vga.c
@@ -1035,11 +1035,12 @@ vga_initialize_graphics(struct vt_device *vd)
REG_WRITE1(sc, VGA_GC_DATA, 0xff);
}
-static void
+static int
vga_initialize(struct vt_device *vd, int textmode)
{
struct vga_softc *sc = vd->vd_softc;
uint8_t x;
+ int timeout;
/* Make sure the VGA adapter is not in monochrome emulation mode. */
x = REG_READ1(sc, VGA_GEN_MISC_OUTPUT_R);
@@ -1060,10 +1061,16 @@ vga_initialize(struct vt_device *vd, int textmode)
* code therefore also removes that guarantee and appropriate measures
* need to be taken.
*/
+ timeout = 10000;
do {
+ DELAY(10);
x = REG_READ1(sc, VGA_GEN_INPUT_STAT_1);
x &= VGA_GEN_IS1_VR | VGA_GEN_IS1_DE;
- } while (x != (VGA_GEN_IS1_VR | VGA_GEN_IS1_DE));
+ } while (x != (VGA_GEN_IS1_VR | VGA_GEN_IS1_DE) && --timeout != 0);
+ if (timeout == 0) {
+ printf("Timeout initializing vt_vga\n");
+ return (ENXIO);
+ }
/* Now, disable the sync. signals. */
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_MODE_CONTROL);
@@ -1194,6 +1201,8 @@ vga_initialize(struct vt_device *vd, int textmode)
*/
sc->vga_curfg = sc->vga_curbg = 0xff;
}
+
+ return (0);
}
static int
@@ -1235,7 +1244,8 @@ vga_init(struct vt_device *vd)
vd->vd_width = VT_VGA_WIDTH;
vd->vd_height = VT_VGA_HEIGHT;
}
- vga_initialize(vd, textmode);
+ if (vga_initialize(vd, textmode) != 0)
+ return (CN_DEAD);
sc->vga_enabled = true;
return (CN_INTERNAL);
diff --git a/sys/dev/vt/vt_core.c b/sys/dev/vt/vt_core.c
index 1f8731e275a3..a637055e3a61 100644
--- a/sys/dev/vt/vt_core.c
+++ b/sys/dev/vt/vt_core.c
@@ -1029,7 +1029,7 @@ vt_determine_colors(term_char_t c, int cursor,
int
vt_is_cursor_in_area(const struct vt_device *vd, const term_rect_t *area)
{
- unsigned int mx, my, x1, y1, x2, y2;
+ unsigned int mx, my;
/*
* We use the cursor position saved during the current refresh,
@@ -1038,18 +1038,12 @@ vt_is_cursor_in_area(const struct vt_device *vd, const term_rect_t *area)
mx = vd->vd_mx_drawn + vd->vd_curwindow->vw_draw_area.tr_begin.tp_col;
my = vd->vd_my_drawn + vd->vd_curwindow->vw_draw_area.tr_begin.tp_row;
- x1 = area->tr_begin.tp_col;
- y1 = area->tr_begin.tp_row;
- x2 = area->tr_end.tp_col;
- y2 = area->tr_end.tp_row;
-
- if (((mx >= x1 && x2 - 1 >= mx) ||
- (mx < x1 && mx + vd->vd_mcursor->width >= x1)) &&
- ((my >= y1 && y2 - 1 >= my) ||
- (my < y1 && my + vd->vd_mcursor->height >= y1)))
- return (1);
-
- return (0);
+ if (mx >= area->tr_end.tp_col ||
+ mx + vd->vd_mcursor->width <= area->tr_begin.tp_col ||
+ my >= area->tr_end.tp_row ||
+ my + vd->vd_mcursor->height <= area->tr_begin.tp_row)
+ return (0);
+ return (1);
}
static void
diff --git a/sys/dev/xen/balloon/balloon.c b/sys/dev/xen/balloon/balloon.c
index e113e2ce9256..a6036d84961a 100644
--- a/sys/dev/xen/balloon/balloon.c
+++ b/sys/dev/xen/balloon/balloon.c
@@ -118,11 +118,6 @@ current_target(void)
static unsigned long
minimum_target(void)
{
-#ifdef XENHVM
-#define max_pfn realmem
-#else
-#define max_pfn HYPERVISOR_shared_info->arch.max_pfn
-#endif
unsigned long min_pages, curr_pages = current_target();
#define MB2PAGES(mb) ((mb) << (20 - PAGE_SHIFT))
@@ -139,16 +134,15 @@ minimum_target(void)
* 32768 1320
* 131072 4392
*/
- if (max_pfn < MB2PAGES(128))
- min_pages = MB2PAGES(8) + (max_pfn >> 1);
- else if (max_pfn < MB2PAGES(512))
- min_pages = MB2PAGES(40) + (max_pfn >> 2);
- else if (max_pfn < MB2PAGES(2048))
- min_pages = MB2PAGES(104) + (max_pfn >> 3);
+ if (realmem < MB2PAGES(128))
+ min_pages = MB2PAGES(8) + (realmem >> 1);
+ else if (realmem < MB2PAGES(512))
+ min_pages = MB2PAGES(40) + (realmem >> 2);
+ else if (realmem < MB2PAGES(2048))
+ min_pages = MB2PAGES(104) + (realmem >> 3);
else
- min_pages = MB2PAGES(296) + (max_pfn >> 5);
+ min_pages = MB2PAGES(296) + (realmem >> 5);
#undef MB2PAGES
-#undef max_pfn
/* Don't enforce growth */
return (min(min_pages, curr_pages));
@@ -204,12 +198,9 @@ increase_reservation(unsigned long nr_pages)
bs.balloon_low--;
pfn = (VM_PAGE_TO_PHYS(page) >> PAGE_SHIFT);
- KASSERT((xen_feature(XENFEAT_auto_translated_physmap) ||
- !phys_to_machine_mapping_valid(pfn)),
+ KASSERT(xen_feature(XENFEAT_auto_translated_physmap),
("auto translated physmap but mapping is valid"));
- set_phys_to_machine(pfn, frame_list[i]);
-
vm_page_free(page);
}
@@ -258,9 +249,8 @@ decrease_reservation(unsigned long nr_pages)
}
pfn = (VM_PAGE_TO_PHYS(page) >> PAGE_SHIFT);
- frame_list[i] = PFNTOMFN(pfn);
+ frame_list[i] = pfn;
- set_phys_to_machine(pfn, INVALID_P2M_ENTRY);
TAILQ_INSERT_HEAD(&ballooned_pages, page, plinks.q);
bs.balloon_low++;
}
@@ -393,21 +383,11 @@ static int
xenballoon_attach(device_t dev)
{
int err;
-#ifndef XENHVM
- vm_page_t page;
- unsigned long pfn;
-
-#define max_pfn HYPERVISOR_shared_info->arch.max_pfn
-#endif
mtx_init(&balloon_mutex, "balloon_mutex", NULL, MTX_DEF);
-#ifndef XENHVM
- bs.current_pages = min(xen_start_info->nr_pages, max_pfn);
-#else
bs.current_pages = xen_pv_domain() ?
HYPERVISOR_start_info->nr_pages : realmem;
-#endif
bs.target_pages = bs.current_pages;
bs.balloon_low = 0;
bs.balloon_high = 0;
@@ -416,16 +396,6 @@ xenballoon_attach(device_t dev)
kproc_create(balloon_process, NULL, NULL, 0, 0, "balloon");
-#ifndef XENHVM
- /* Initialise the balloon with excess memory space. */
- for (pfn = xen_start_info->nr_pages; pfn < max_pfn; pfn++) {
- page = PHYS_TO_VM_PAGE(pfn << PAGE_SHIFT);
- TAILQ_INSERT_HEAD(&ballooned_pages, page, plinks.q);
- bs.balloon_low++;
- }
-#undef max_pfn
-#endif
-
target_watch.callback = watch_target;
err = xs_register_watch(&target_watch);
diff --git a/sys/dev/xen/blkback/blkback.c b/sys/dev/xen/blkback/blkback.c
index 1273961a3ca8..b647fec8b5c2 100644
--- a/sys/dev/xen/blkback/blkback.c
+++ b/sys/dev/xen/blkback/blkback.c
@@ -742,7 +742,6 @@ struct xbb_softc {
/** Mutex protecting per-instance data. */
struct mtx lock;
-#ifdef XENHVM
/**
* Resource representing allocated physical address space
* associated with our per-instance kva region.
@@ -751,7 +750,6 @@ struct xbb_softc {
/** Resource id for allocated physical address space. */
int pseudo_phys_res_id;
-#endif
/**
* I/O statistics from BlockBack dispatch down. These are
@@ -2818,16 +2816,12 @@ static void
xbb_free_communication_mem(struct xbb_softc *xbb)
{
if (xbb->kva != 0) {
-#ifndef XENHVM
- kva_free(xbb->kva, xbb->kva_size);
-#else
if (xbb->pseudo_phys_res != NULL) {
bus_release_resource(xbb->dev, SYS_RES_MEMORY,
xbb->pseudo_phys_res_id,
xbb->pseudo_phys_res);
xbb->pseudo_phys_res = NULL;
}
-#endif
}
xbb->kva = 0;
xbb->gnt_base_addr = 0;
@@ -3055,12 +3049,6 @@ xbb_alloc_communication_mem(struct xbb_softc *xbb)
DPRINTF("%s: kva_size = %d, reqlist_kva_size = %d\n",
device_get_nameunit(xbb->dev), xbb->kva_size,
xbb->reqlist_kva_size);
-#ifndef XENHVM
- xbb->kva = kva_alloc(xbb->kva_size);
- if (xbb->kva == 0)
- return (ENOMEM);
- xbb->gnt_base_addr = xbb->kva;
-#else /* XENHVM */
/*
* Reserve a range of pseudo physical memory that we can map
* into kva. These pages will only be backed by machine
@@ -3078,7 +3066,6 @@ xbb_alloc_communication_mem(struct xbb_softc *xbb)
}
xbb->kva = (vm_offset_t)rman_get_virtual(xbb->pseudo_phys_res);
xbb->gnt_base_addr = rman_get_start(xbb->pseudo_phys_res);
-#endif /* XENHVM */
DPRINTF("%s: kva: %#jx, gnt_base_addr: %#jx\n",
device_get_nameunit(xbb->dev), (uintmax_t)xbb->kva,
diff --git a/sys/dev/xen/control/control.c b/sys/dev/xen/control/control.c
index 665a5acdbe29..2a0d459ee621 100644
--- a/sys/dev/xen/control/control.c
+++ b/sys/dev/xen/control/control.c
@@ -138,9 +138,7 @@ __FBSDID("$FreeBSD$");
#include <xen/gnttab.h>
#include <xen/xen_intr.h>
-#ifdef XENHVM
#include <xen/hvm.h>
-#endif
#include <xen/interface/event_channel.h>
#include <xen/interface/grant_table.h>
@@ -192,133 +190,6 @@ xctrl_reboot()
shutdown_nice(0);
}
-#ifndef XENHVM
-extern void xencons_suspend(void);
-extern void xencons_resume(void);
-
-/* Full PV mode suspension. */
-static void
-xctrl_suspend()
-{
- int i, j, k, fpp, suspend_cancelled;
- unsigned long max_pfn, start_info_mfn;
-
- EVENTHANDLER_INVOKE(power_suspend);
-
-#ifdef SMP
- struct thread *td;
- cpuset_t map;
- u_int cpuid;
-
- /*
- * Bind us to CPU 0 and stop any other VCPUs.
- */
- td = curthread;
- thread_lock(td);
- sched_bind(td, 0);
- thread_unlock(td);
- cpuid = PCPU_GET(cpuid);
- KASSERT(cpuid == 0, ("xen_suspend: not running on cpu 0"));
-
- map = all_cpus;
- CPU_CLR(cpuid, &map);
- CPU_NAND(&map, &stopped_cpus);
- if (!CPU_EMPTY(&map))
- stop_cpus(map);
-#endif
-
- /*
- * Be sure to hold Giant across DEVICE_SUSPEND/RESUME since non-MPSAFE
- * drivers need this.
- */
- mtx_lock(&Giant);
- if (DEVICE_SUSPEND(root_bus) != 0) {
- mtx_unlock(&Giant);
- printf("%s: device_suspend failed\n", __func__);
-#ifdef SMP
- if (!CPU_EMPTY(&map))
- restart_cpus(map);
-#endif
- return;
- }
- mtx_unlock(&Giant);
-
- local_irq_disable();
-
- xencons_suspend();
- gnttab_suspend();
- intr_suspend();
-
- max_pfn = HYPERVISOR_shared_info->arch.max_pfn;
-
- void *shared_info = HYPERVISOR_shared_info;
- HYPERVISOR_shared_info = NULL;
- pmap_kremove((vm_offset_t) shared_info);
- PT_UPDATES_FLUSH();
-
- xen_start_info->store_mfn = MFNTOPFN(xen_start_info->store_mfn);
- xen_start_info->console.domU.mfn = MFNTOPFN(xen_start_info->console.domU.mfn);
-
- /*
- * We'll stop somewhere inside this hypercall. When it returns,
- * we'll start resuming after the restore.
- */
- start_info_mfn = VTOMFN(xen_start_info);
- pmap_suspend();
- suspend_cancelled = HYPERVISOR_suspend(start_info_mfn);
- pmap_resume();
-
- pmap_kenter_ma((vm_offset_t) shared_info, xen_start_info->shared_info);
- HYPERVISOR_shared_info = shared_info;
-
- HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
- VTOMFN(xen_pfn_to_mfn_frame_list_list);
-
- fpp = PAGE_SIZE/sizeof(unsigned long);
- for (i = 0, j = 0, k = -1; i < max_pfn; i += fpp, j++) {
- if ((j % fpp) == 0) {
- k++;
- xen_pfn_to_mfn_frame_list_list[k] =
- VTOMFN(xen_pfn_to_mfn_frame_list[k]);
- j = 0;
- }
- xen_pfn_to_mfn_frame_list[k][j] =
- VTOMFN(&xen_phys_machine[i]);
- }
- HYPERVISOR_shared_info->arch.max_pfn = max_pfn;
-
- gnttab_resume(NULL);
- intr_resume(suspend_cancelled != 0);
- local_irq_enable();
- xencons_resume();
-
-#ifdef CONFIG_SMP
- for_each_cpu(i)
- vcpu_prepare(i);
-
-#endif
-
- /*
- * Only resume xenbus /after/ we've prepared our VCPUs; otherwise
- * the VCPU hotplug callback can race with our vcpu_prepare
- */
- mtx_lock(&Giant);
- DEVICE_RESUME(root_bus);
- mtx_unlock(&Giant);
-
-#ifdef SMP
- thread_lock(curthread);
- sched_unbind(curthread);
- thread_unlock(curthread);
- if (!CPU_EMPTY(&map))
- restart_cpus(map);
-#endif
- EVENTHANDLER_INVOKE(power_resume);
-}
-
-#else
-
-/* HVM mode suspension. */
static void
xctrl_suspend()
{
@@ -417,7 +288,6 @@ xctrl_suspend()
printf("System resumed after suspension\n");
}
-#endif
static void
xctrl_crash()
diff --git a/sys/dev/xen/grant_table/grant_table.c b/sys/dev/xen/grant_table/grant_table.c
index 25116575c023..ad65fe0113f0 100644
--- a/sys/dev/xen/grant_table/grant_table.c
+++ b/sys/dev/xen/grant_table/grant_table.c
@@ -53,7 +53,6 @@ static int gnttab_free_count;
static grant_ref_t gnttab_free_head;
static struct mtx gnttab_list_lock;
-#ifdef XENHVM
/*
* Resource representing allocated physical address space
* for the grant table metainfo
@@ -62,7 +61,6 @@ static struct resource *gnttab_pseudo_phys_res;
/* Resource id for allocated physical address space. */
static int gnttab_pseudo_phys_res_id;
-#endif
static grant_entry_t *shared;
@@ -510,72 +508,6 @@ unmap_pte_fn(pte_t *pte, struct page *pmd_page,
}
#endif
-#ifndef XENHVM
-
-static int
-gnttab_map(unsigned int start_idx, unsigned int end_idx)
-{
- struct gnttab_setup_table setup;
- u_long *frames;
-
- unsigned int nr_gframes = end_idx + 1;
- int i, rc;
-
- frames = malloc(nr_gframes * sizeof(unsigned long), M_DEVBUF, M_NOWAIT);
- if (!frames)
- return (ENOMEM);
-
- setup.dom = DOMID_SELF;
- setup.nr_frames = nr_gframes;
- set_xen_guest_handle(setup.frame_list, frames);
-
- rc = HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
- if (rc == -ENOSYS) {
- free(frames, M_DEVBUF);
- return (ENOSYS);
- }
- KASSERT(!(rc || setup.status),
- ("unexpected result from grant_table_op"));
-
- if (shared == NULL) {
- vm_offset_t area;
-
- area = kva_alloc(PAGE_SIZE * max_nr_grant_frames());
- KASSERT(area, ("can't allocate VM space for grant table"));
- shared = (grant_entry_t *)area;
- }
-
- for (i = 0; i < nr_gframes; i++)
- PT_SET_MA(((caddr_t)shared) + i*PAGE_SIZE,
- ((vm_paddr_t)frames[i]) << PAGE_SHIFT | PG_RW | PG_V);
-
- free(frames, M_DEVBUF);
-
- return (0);
-}
-
-int
-gnttab_resume(device_t dev)
-{
-
- if (max_nr_grant_frames() < nr_grant_frames)
- return (ENOSYS);
- return (gnttab_map(0, nr_grant_frames - 1));
-}
-
-int
-gnttab_suspend(void)
-{
- int i;
-
- for (i = 0; i < nr_grant_frames; i++)
- pmap_kremove((vm_offset_t) shared + i * PAGE_SIZE);
-
- return (0);
-}
-
-#else /* XENHVM */
-
static vm_paddr_t resume_frames;
static int
@@ -638,8 +570,6 @@ gnttab_resume(device_t dev)
return (gnttab_map(0, nr_gframes - 1));
}
-#endif
-
static int
gnttab_expand(unsigned int req_entries)
{
diff --git a/sys/dev/xen/netback/netback.c b/sys/dev/xen/netback/netback.c
index 63337ad4fdbf..b5c1c1362821 100644
--- a/sys/dev/xen/netback/netback.c
+++ b/sys/dev/xen/netback/netback.c
@@ -473,7 +473,6 @@ struct xnb_softc {
*/
gnttab_copy_table tx_gnttab;
-#ifdef XENHVM
/**
* Resource representing allocated physical address space
* associated with our per-instance kva region.
@@ -482,7 +481,6 @@ struct xnb_softc {
/** Resource id for allocated physical address space. */
int pseudo_phys_res_id;
-#endif
/** Ring mapping and interrupt configuration data. */
struct xnb_ring_config ring_configs[XNB_NUM_RING_TYPES];
@@ -626,16 +624,12 @@ static void
xnb_free_communication_mem(struct xnb_softc *xnb)
{
if (xnb->kva != 0) {
-#ifndef XENHVM
- kva_free(xnb->kva, xnb->kva_size);
-#else
if (xnb->pseudo_phys_res != NULL) {
bus_release_resource(xnb->dev, SYS_RES_MEMORY,
xnb->pseudo_phys_res_id,
xnb->pseudo_phys_res);
xnb->pseudo_phys_res = NULL;
}
-#endif /* XENHVM */
}
xnb->kva = 0;
xnb->gnt_base_addr = 0;
@@ -816,12 +810,7 @@ xnb_alloc_communication_mem(struct xnb_softc *xnb)
for (i=0; i < XNB_NUM_RING_TYPES; i++) {
xnb->kva_size += xnb->ring_configs[i].ring_pages * PAGE_SIZE;
}
-#ifndef XENHVM
- xnb->kva = kva_alloc(xnb->kva_size);
- if (xnb->kva == 0)
- return (ENOMEM);
- xnb->gnt_base_addr = xnb->kva;
-#else /* defined XENHVM */
+
/*
* Reserve a range of pseudo physical memory that we can map
* into kva. These pages will only be backed by machine
@@ -840,7 +829,6 @@ xnb_alloc_communication_mem(struct xnb_softc *xnb)
}
xnb->kva = (vm_offset_t)rman_get_virtual(xnb->pseudo_phys_res);
xnb->gnt_base_addr = rman_get_start(xnb->pseudo_phys_res);
-#endif /* !defined XENHVM */
return (0);
}
diff --git a/sys/dev/xen/netfront/netfront.c b/sys/dev/xen/netfront/netfront.c
index 27900ba69bb7..3c1f9527d65c 100644
--- a/sys/dev/xen/netfront/netfront.c
+++ b/sys/dev/xen/netfront/netfront.c
@@ -879,12 +879,11 @@ refill:
if (sc->copying_receiver == 0) {
gnttab_grant_foreign_transfer_ref(ref,
otherend_id, pfn);
- sc->rx_pfn_array[nr_flips] = PFNTOMFN(pfn);
+ sc->rx_pfn_array[nr_flips] = pfn;
if (!xen_feature(XENFEAT_auto_translated_physmap)) {
/* Remove this page before passing
* back to Xen.
*/
- set_phys_to_machine(pfn, INVALID_P2M_ENTRY);
MULTI_update_va_mapping(&sc->rx_mcl[i],
vaddr, 0, 0);
}
@@ -892,7 +891,7 @@ refill:
} else {
gnttab_grant_foreign_access_ref(ref,
otherend_id,
- PFNTOMFN(pfn), 0);
+ pfn, 0);
}
req->id = id;
req->gref = ref;
@@ -907,7 +906,6 @@ refill:
* We may have allocated buffers which have entries outstanding
* in the page * update queue -- make sure we flush those first!
*/
- PT_UPDATES_FLUSH();
if (nr_flips != 0) {
#ifdef notyet
/* Tell the ballon driver what is going on. */
@@ -1361,8 +1359,6 @@ xennet_get_responses(struct netfront_info *np,
mmu->ptr = ((vm_paddr_t)mfn << PAGE_SHIFT) |
MMU_MACHPHYS_UPDATE;
mmu->val = pfn;
-
- set_phys_to_machine(pfn, mfn);
}
pages_flipped++;
} else {
@@ -1927,7 +1923,7 @@ network_connect(struct netfront_info *np)
} else {
gnttab_grant_foreign_access_ref(ref,
xenbus_get_otherend_id(np->xbdev),
- PFNTOMFN(pfn), 0);
+ pfn, 0);
}
req->gref = ref;
req->id = requeue_idx;
diff --git a/sys/fs/nfs/nfsport.h b/sys/fs/nfs/nfsport.h
index 9f08854c3a2c..42a7f9451ef6 100644
--- a/sys/fs/nfs/nfsport.h
+++ b/sys/fs/nfs/nfsport.h
@@ -950,7 +950,7 @@ struct nfsreq {
};
#ifndef NFS_MAXBSIZE
-#define NFS_MAXBSIZE MAXBSIZE
+#define NFS_MAXBSIZE MAXBCACHEBUF
#endif
/*
diff --git a/sys/fs/nfsclient/nfs_clvfsops.c b/sys/fs/nfsclient/nfs_clvfsops.c
index 964ea1f4f5ac..73c6eb600290 100644
--- a/sys/fs/nfsclient/nfs_clvfsops.c
+++ b/sys/fs/nfsclient/nfs_clvfsops.c
@@ -201,16 +201,16 @@ newnfs_iosize(struct nfsmount *nmp)
}
if (nmp->nm_rsize > maxio || nmp->nm_rsize == 0)
nmp->nm_rsize = maxio;
- if (nmp->nm_rsize > MAXBSIZE)
- nmp->nm_rsize = MAXBSIZE;
+ if (nmp->nm_rsize > NFS_MAXBSIZE)
+ nmp->nm_rsize = NFS_MAXBSIZE;
if (nmp->nm_readdirsize > maxio || nmp->nm_readdirsize == 0)
nmp->nm_readdirsize = maxio;
if (nmp->nm_readdirsize > nmp->nm_rsize)
nmp->nm_readdirsize = nmp->nm_rsize;
if (nmp->nm_wsize > maxio || nmp->nm_wsize == 0)
nmp->nm_wsize = maxio;
- if (nmp->nm_wsize > MAXBSIZE)
- nmp->nm_wsize = MAXBSIZE;
+ if (nmp->nm_wsize > NFS_MAXBSIZE)
+ nmp->nm_wsize = NFS_MAXBSIZE;
/*
* Calculate the size used for io buffers. Use the larger
diff --git a/sys/fs/nfsserver/nfs_nfsdkrpc.c b/sys/fs/nfsserver/nfs_nfsdkrpc.c
index 4fb9c93ccb5e..f9b8eb8e92e1 100644
--- a/sys/fs/nfsserver/nfs_nfsdkrpc.c
+++ b/sys/fs/nfsserver/nfs_nfsdkrpc.c
@@ -117,7 +117,8 @@ nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt)
memset(&nd, 0, sizeof(nd));
if (rqst->rq_vers == NFS_VER2) {
- if (rqst->rq_proc > NFSV2PROC_STATFS) {
+ if (rqst->rq_proc > NFSV2PROC_STATFS ||
+ newnfs_nfsv3_procid[rqst->rq_proc] == NFSPROC_NOOP) {
svcerr_noproc(rqst);
svc_freereq(rqst);
goto out;
diff --git a/sys/geom/uncompress/g_uncompress.c b/sys/geom/uncompress/g_uncompress.c
index d8193711b5e7..8c2d5cb6c929 100644
--- a/sys/geom/uncompress/g_uncompress.c
+++ b/sys/geom/uncompress/g_uncompress.c
@@ -45,10 +45,10 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/malloc.h>
#include <sys/systm.h>
+#include <sys/zlib.h>
#include <geom/geom.h>
-#include <net/zlib.h>
#include <contrib/xz-embedded/linux/include/linux/xz.h>
#ifdef GEOM_UNCOMPRESS_DEBUG
diff --git a/sys/geom/uzip/g_uzip.c b/sys/geom/uzip/g_uzip.c
index c2ed64b365c8..732de9d5e8d0 100644
--- a/sys/geom/uzip/g_uzip.c
+++ b/sys/geom/uzip/g_uzip.c
@@ -38,9 +38,9 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
+#include <sys/zlib.h>
#include <geom/geom.h>
-#include <net/zlib.h>
FEATURE(geom_uzip, "GEOM uzip read-only compressed disks support");
diff --git a/sys/i386/conf/DEFAULTS b/sys/i386/conf/DEFAULTS
index 78d807c3d344..d5bdb1df2522 100644
--- a/sys/i386/conf/DEFAULTS
+++ b/sys/i386/conf/DEFAULTS
@@ -26,7 +26,6 @@ options GEOM_PART_EBR_COMPAT
options GEOM_PART_MBR
# enable support for native hardware
-options NATIVE
device atpic
options NEW_PCIB
diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC
index 086844a87ea1..b1740f32efc2 100644
--- a/sys/i386/conf/GENERIC
+++ b/sys/i386/conf/GENERIC
@@ -358,7 +358,9 @@ device virtio_blk # VirtIO Block device
device virtio_scsi # VirtIO SCSI device
device virtio_balloon # VirtIO Memory Balloon device
-# HyperV drivers
+# HyperV drivers and enchancement support
+# NOTE: HYPERV depends on hyperv. They must be added or removed together.
+options HYPERV # Hyper-V kernel infrastructure
device hyperv # HyperV drivers
# Xen HVM Guest Optimizations
diff --git a/sys/i386/conf/XEN b/sys/i386/conf/XEN
deleted file mode 100644
index dd83670e21b4..000000000000
--- a/sys/i386/conf/XEN
+++ /dev/null
@@ -1,96 +0,0 @@
-#
-# XEN -- Kernel configuration for i386 XEN DomU
-#
-# $FreeBSD$
-
-cpu I686_CPU
-ident XEN
-
-makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
-
-# The following drivers don't build with PAE or XEN enabled.
-makeoptions WITHOUT_MODULES="ctl dpt drm drm2 hptmv ida"
-
-# The following drivers don't work with PAE enabled.
-makeoptions WITHOUT_MODULES+="ncr pst"
-
-options SCHED_ULE # ULE scheduler
-options PREEMPTION # Enable kernel thread preemption
-
-options INET # InterNETworking
-options INET6 # IPv6 communications protocols
-options SCTP # Stream Control Transmission Protocol
-options FFS # Berkeley Fast Filesystem
-options SOFTUPDATES # Enable FFS soft updates support
-options UFS_ACL # Support for access control lists
-options UFS_DIRHASH # Improve performance on big directories
-options UFS_GJOURNAL # Enable gjournal-based UFS journaling
-options NFSCL # Network Filesystem Client
-options NFSD # Network Filesystem Server
-options NFSLOCKD # Network Lock Manager
-options NFS_ROOT # NFS usable as /, requires NFSCL
-options MSDOSFS # MSDOS Filesystem
-options CD9660 # ISO 9660 Filesystem
-options PROCFS # Process filesystem (requires PSEUDOFS)
-options PSEUDOFS # Pseudo-filesystem framework
-options GEOM_PART_GPT # GUID Partition Tables.
-options GEOM_LABEL # Provides labelization
-options COMPAT_FREEBSD4 # Compatible with FreeBSD4
-options COMPAT_FREEBSD5 # Compatible with FreeBSD5
-options COMPAT_FREEBSD6 # Compatible with FreeBSD6
-options COMPAT_FREEBSD7 # Compatible with FreeBSD7
-options COMPAT_FREEBSD9 # Compatible with FreeBSD9
-options COMPAT_FREEBSD10 # Compatible with FreeBSD10
-options KTRACE # ktrace(1) support
-options STACK # stack(9) support
-options SYSVSHM # SYSV-style shared memory
-options SYSVMSG # SYSV-style message queues
-options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
-options KBD_INSTALL_CDEV # install a CDEV entry in /dev
-options AUDIT # Security event auditing
-
-# Debugging for use in -current
-options KDB # Enable kernel debugger support.
-options DDB # Support DDB.
-options GDB # Support remote GDB.
-options DEADLKRES # Enable the deadlock resolver
-options INVARIANTS # Enable calls of extra sanity checking
-options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
-options WITNESS # Enable checks to detect deadlocks and cycles
-options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
-
-options PAE
-nooption NATIVE
-option XEN
-nodevice atpic
-nodevice isa
-options MCLSHIFT=12
-
-# To make an SMP kernel, the next two lines are needed
-options SMP # Symmetric MultiProcessor Kernel
-device apic # I/O APIC
-
-#device atkbdc # AT keyboard controller
-#device atkbd # AT keyboard
-device psm # PS/2 mouse
-device pci
-
-#device kbdmux # keyboard multiplexer
-
-# Pseudo devices.
-device loop # Network loopback
-device random # Entropy device
-device ether # Ethernet support
-device tun # Packet tunnel.
-device md # Memory "disks"
-device gif # IPv6 and IPv4 tunneling
-
-# Wireless cards
-options IEEE80211_SUPPORT_MESH
-options AH_SUPPORT_AR5416
-
-# The `bpf' device enables the Berkeley Packet Filter.
-# Be aware of the administrative consequences of enabling this!
-# Note that 'bpf' is required for DHCP.
-device bpf # Berkeley packet filter
diff --git a/sys/i386/i386/apic_vector.s b/sys/i386/i386/apic_vector.s
index 316bc7a189c2..18b3c5dc2d64 100644
--- a/sys/i386/i386/apic_vector.s
+++ b/sys/i386/i386/apic_vector.s
@@ -181,6 +181,25 @@ IDTVEC(xen_intr_upcall)
jmp doreti
#endif
+#ifdef HYPERV
+/*
+ * This is the Hyper-V vmbus channel direct callback interrupt.
+ * Only used when it is running on Hyper-V.
+ */
+ .text
+ SUPERALIGN_TEXT
+IDTVEC(hv_vmbus_callback)
+ PUSH_FRAME
+ SET_KERNEL_SREGS
+ cld
+ FAKE_MCOUNT(TF_EIP(%esp))
+ pushl %esp
+ call hv_vector_handler
+ add $4, %esp
+ MEXITCOUNT
+ jmp doreti
+#endif
+
#ifdef SMP
/*
* Global address space TLB shootdown.
@@ -247,7 +266,6 @@ IDTVEC(invlcache)
/*
* Handler for IPIs sent via the per-cpu IPI bitmap.
*/
-#ifndef XEN
.text
SUPERALIGN_TEXT
IDTVEC(ipi_intr_bitmap_handler)
@@ -262,7 +280,7 @@ IDTVEC(ipi_intr_bitmap_handler)
call ipi_bitmap_handler
MEXITCOUNT
jmp doreti
-#endif
+
/*
* Executed by a CPU when it receives an IPI_STOP from another CPU.
*/
@@ -282,7 +300,6 @@ IDTVEC(cpustop)
/*
* Executed by a CPU when it receives an IPI_SUSPEND from another CPU.
*/
-#ifndef XEN
.text
SUPERALIGN_TEXT
IDTVEC(cpususpend)
@@ -295,7 +312,6 @@ IDTVEC(cpususpend)
POP_FRAME
jmp doreti_iret
-#endif
/*
* Executed by a CPU when it receives a RENDEZVOUS IPI from another CPU.
diff --git a/sys/i386/i386/genassym.c b/sys/i386/i386/genassym.c
index 97e2e979bd20..7a00740a998c 100644
--- a/sys/i386/i386/genassym.c
+++ b/sys/i386/i386/genassym.c
@@ -238,11 +238,6 @@ ASSYM(BUS_SPACE_HANDLE_BASE, offsetof(struct bus_space_handle, bsh_base));
ASSYM(BUS_SPACE_HANDLE_IAT, offsetof(struct bus_space_handle, bsh_iat));
#endif
-#ifdef XEN
-ASSYM(PC_CR3, offsetof(struct pcpu, pc_cr3));
-ASSYM(XEN_HYPERVISOR_VIRT_START, HYPERVISOR_VIRT_START);
-#endif
-
#ifdef HWPMC_HOOKS
ASSYM(PMC_FN_USER_CALLCHAIN, PMC_FN_USER_CALLCHAIN);
#endif
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index 72f76850b7c0..a5867c43057a 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -160,24 +160,6 @@ int arch_i386_is_xbox = 0;
uint32_t arch_i386_xbox_memsize = 0;
#endif
-#ifdef XEN
-/* XEN includes */
-#include <xen/xen-os.h>
-#include <xen/hypervisor.h>
-#include <machine/xen/xenvar.h>
-#include <machine/xen/xenfunc.h>
-#include <xen/xen_intr.h>
-
-void Xhypervisor_callback(void);
-void failsafe_callback(void);
-
-extern trap_info_t trap_table[];
-struct proc_ldt default_proc_ldt;
-extern int init_first;
-int running_xen = 1;
-extern unsigned long physfree;
-#endif /* XEN */
-
/* Sanity check for __curthread() */
CTASSERT(offsetof(struct pcpu, pc_curthread) == 0);
@@ -356,9 +338,7 @@ cpu_startup(dummy)
*/
bufinit();
vm_pager_bufferinit();
-#ifndef XEN
cpu_setregs();
-#endif
}
/*
@@ -1291,13 +1271,8 @@ SYSCTL_STRING(_machdep, OID_AUTO, bootmethod, CTLFLAG_RD, bootmethod, 0,
int _default_ldt;
-#ifdef XEN
-union descriptor *gdt;
-union descriptor *ldt;
-#else
union descriptor gdt[NGDT * MAXCPU]; /* global descriptor table */
union descriptor ldt[NLDT]; /* local descriptor table */
-#endif
static struct gate_descriptor idt0[NIDT];
struct gate_descriptor *idt = &idt0[0]; /* interrupt descriptor table */
struct region_descriptor r_gdt, r_idt; /* table descriptors */
@@ -1397,7 +1372,6 @@ struct soft_segment_descriptor gdt_segs[] = {
.ssd_xx = 0, .ssd_xx1 = 0,
.ssd_def32 = 1,
.ssd_gran = 1 },
-#ifndef XEN
/* GPROC0_SEL 9 Proc 0 Tss Descriptor */
{
.ssd_base = 0x0,
@@ -1489,7 +1463,6 @@ struct soft_segment_descriptor gdt_segs[] = {
.ssd_xx = 0, .ssd_xx1 = 0,
.ssd_def32 = 0,
.ssd_gran = 0 },
-#endif /* !XEN */
};
static struct soft_segment_descriptor ldt_segs[] = {
@@ -1641,7 +1614,7 @@ sdtossd(sd, ssd)
ssd->ssd_gran = sd->sd_gran;
}
-#if !defined(PC98) && !defined(XEN)
+#if !defined(PC98)
static int
add_physmap_entry(uint64_t base, uint64_t length, vm_paddr_t *physmap,
int *physmap_idxp)
@@ -1748,9 +1721,8 @@ add_smap_entries(struct bios_smap *smapbase, vm_paddr_t *physmap,
if (!add_smap_entry(smap, physmap, physmap_idxp))
break;
}
-#endif /* !PC98 && !XEN */
+#endif /* !PC98 */
-#ifndef XEN
static void
basemem_setup(void)
{
@@ -1798,7 +1770,6 @@ basemem_setup(void)
for (i = basemem / 4; i < 160; i++)
pte[i] = (i << PAGE_SHIFT) | PG_V | PG_RW | PG_U;
}
-#endif /* !XEN */
/*
* Populate the (physmap) array with base/bound pairs describing the
@@ -2074,8 +2045,6 @@ do_next:
for (off = 0; off < round_page(msgbufsize); off += PAGE_SIZE)
pmap_kenter((vm_offset_t)msgbufp + off, phys_avail[pa_indx] +
off);
-
- PT_UPDATES_FLUSH();
}
#else /* PC98 */
static void
@@ -2086,7 +2055,6 @@ getmemsize(int first)
vm_paddr_t physmap[PHYSMAP_SIZE];
pt_entry_t *pte;
quad_t dcons_addr, dcons_size, physmem_tunable;
-#ifndef XEN
int hasbrokenint12, i, res;
u_int extmem;
struct vm86frame vmf;
@@ -2094,17 +2062,8 @@ getmemsize(int first)
vm_paddr_t pa;
struct bios_smap *smap, *smapbase;
caddr_t kmdp;
-#endif
has_smap = 0;
-#if defined(XEN)
- Maxmem = xen_start_info->nr_pages - init_first;
- physmem = Maxmem;
- basemem = 0;
- physmap[0] = init_first << PAGE_SHIFT;
- physmap[1] = ptoa(Maxmem) - round_page(msgbufsize);
- physmap_idx = 0;
-#else
#ifdef XBOX
if (arch_i386_is_xbox) {
/*
@@ -2247,7 +2206,6 @@ have_smap:
physmap[physmap_idx + 1] = physmap[physmap_idx] + extmem * 1024;
physmap_done:
-#endif
/*
* Now, physmap contains a map of physical memory.
*/
@@ -2321,7 +2279,6 @@ physmap_done:
getenv_quad("dcons.size", &dcons_size) == 0)
dcons_addr = 0;
-#ifndef XEN
/*
* physmap is in bytes, so when converting to page boundaries,
* round up the start address and round down the end address.
@@ -2442,13 +2399,6 @@ do_next:
}
*pte = 0;
invltlb();
-#else
- phys_avail[0] = physfree;
- phys_avail[1] = xen_start_info->nr_pages*PAGE_SIZE;
- dump_avail[0] = 0;
- dump_avail[1] = xen_start_info->nr_pages*PAGE_SIZE;
-
-#endif
/*
* XXX
@@ -2472,272 +2422,9 @@ do_next:
for (off = 0; off < round_page(msgbufsize); off += PAGE_SIZE)
pmap_kenter((vm_offset_t)msgbufp + off, phys_avail[pa_indx] +
off);
-
- PT_UPDATES_FLUSH();
}
#endif /* PC98 */
-#ifdef XEN
-#define MTOPSIZE (1<<(14 + PAGE_SHIFT))
-
-register_t
-init386(first)
- int first;
-{
- unsigned long gdtmachpfn;
- int error, gsel_tss, metadata_missing, x, pa;
- struct pcpu *pc;
-#ifdef CPU_ENABLE_SSE
- struct xstate_hdr *xhdr;
-#endif
- struct callback_register event = {
- .type = CALLBACKTYPE_event,
- .address = {GSEL(GCODE_SEL, SEL_KPL), (unsigned long)Xhypervisor_callback },
- };
- struct callback_register failsafe = {
- .type = CALLBACKTYPE_failsafe,
- .address = {GSEL(GCODE_SEL, SEL_KPL), (unsigned long)failsafe_callback },
- };
-
- thread0.td_kstack = proc0kstack;
- thread0.td_kstack_pages = KSTACK_PAGES;
-
- /*
- * This may be done better later if it gets more high level
- * components in it. If so just link td->td_proc here.
- */
- proc_linkup0(&proc0, &thread0);
-
- metadata_missing = 0;
- if (xen_start_info->mod_start) {
- preload_metadata = (caddr_t)xen_start_info->mod_start;
- preload_bootstrap_relocate(KERNBASE);
- } else {
- metadata_missing = 1;
- }
- if (envmode == 1)
- kern_envp = static_env;
- else if ((caddr_t)xen_start_info->cmd_line)
- kern_envp = xen_setbootenv((caddr_t)xen_start_info->cmd_line);
-
- boothowto |= xen_boothowto(kern_envp);
-
- /* Init basic tunables, hz etc */
- init_param1();
-
- /*
- * XEN occupies a portion of the upper virtual address space
- * At its base it manages an array mapping machine page frames
- * to physical page frames - hence we need to be able to
- * access 4GB - (64MB - 4MB + 64k)
- */
- gdt_segs[GPRIV_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE);
- gdt_segs[GUFS_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE);
- gdt_segs[GUGS_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE);
- gdt_segs[GCODE_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE);
- gdt_segs[GDATA_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE);
- gdt_segs[GUCODE_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE);
- gdt_segs[GUDATA_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE);
- gdt_segs[GBIOSLOWMEM_SEL].ssd_limit = atop(HYPERVISOR_VIRT_START + MTOPSIZE);
-
- pc = &__pcpu[0];
- gdt_segs[GPRIV_SEL].ssd_base = (int) pc;
- gdt_segs[GPROC0_SEL].ssd_base = (int) &pc->pc_common_tss;
-
- PT_SET_MA(gdt, xpmap_ptom(VTOP(gdt)) | PG_V | PG_RW);
- bzero(gdt, PAGE_SIZE);
- for (x = 0; x < NGDT; x++)
- ssdtosd(&gdt_segs[x], &gdt[x].sd);
-
- mtx_init(&dt_lock, "descriptor tables", NULL, MTX_SPIN);
-
- gdtmachpfn = vtomach(gdt) >> PAGE_SHIFT;
- PT_SET_MA(gdt, xpmap_ptom(VTOP(gdt)) | PG_V);
- PANIC_IF(HYPERVISOR_set_gdt(&gdtmachpfn, 512) != 0);
- lgdt(&r_gdt);
- gdtset = 1;
-
- if ((error = HYPERVISOR_set_trap_table(trap_table)) != 0) {
- panic("set_trap_table failed - error %d\n", error);
- }
-
- error = HYPERVISOR_callback_op(CALLBACKOP_register, &event);
- if (error == 0)
- error = HYPERVISOR_callback_op(CALLBACKOP_register, &failsafe);
-#if CONFIG_XEN_COMPAT <= 0x030002
- if (error == -ENOXENSYS)
- HYPERVISOR_set_callbacks(GSEL(GCODE_SEL, SEL_KPL),
- (unsigned long)Xhypervisor_callback,
- GSEL(GCODE_SEL, SEL_KPL), (unsigned long)failsafe_callback);
-#endif
- pcpu_init(pc, 0, sizeof(struct pcpu));
- for (pa = first; pa < first + DPCPU_SIZE; pa += PAGE_SIZE)
- pmap_kenter(pa + KERNBASE, pa);
- dpcpu_init((void *)(first + KERNBASE), 0);
- first += DPCPU_SIZE;
- physfree += DPCPU_SIZE;
- init_first += DPCPU_SIZE / PAGE_SIZE;
-
- PCPU_SET(prvspace, pc);
- PCPU_SET(curthread, &thread0);
-
- /*
- * Initialize mutexes.
- *
- * icu_lock: in order to allow an interrupt to occur in a critical
- * section, to set pcpu->ipending (etc...) properly, we
- * must be able to get the icu lock, so it can't be
- * under witness.
- */
- mutex_init();
- mtx_init(&icu_lock, "icu", NULL, MTX_SPIN | MTX_NOWITNESS | MTX_NOPROFILE);
-
- /* make ldt memory segments */
- PT_SET_MA(ldt, xpmap_ptom(VTOP(ldt)) | PG_V | PG_RW);
- bzero(ldt, PAGE_SIZE);
- ldt_segs[LUCODE_SEL].ssd_limit = atop(0 - 1);
- ldt_segs[LUDATA_SEL].ssd_limit = atop(0 - 1);
- for (x = 0; x < sizeof ldt_segs / sizeof ldt_segs[0]; x++)
- ssdtosd(&ldt_segs[x], &ldt[x].sd);
-
- default_proc_ldt.ldt_base = (caddr_t)ldt;
- default_proc_ldt.ldt_len = 6;
- _default_ldt = (int)&default_proc_ldt;
- PCPU_SET(currentldt, _default_ldt);
- PT_SET_MA(ldt, *vtopte((unsigned long)ldt) & ~PG_RW);
- xen_set_ldt((unsigned long) ldt, (sizeof ldt_segs / sizeof ldt_segs[0]));
-
-#if defined(XEN_PRIVILEGED)
- /*
- * Initialize the i8254 before the console so that console
- * initialization can use DELAY().
- */
- i8254_init();
-#endif
-
- /*
- * Initialize the console before we print anything out.
- */
- cninit();
-
- if (metadata_missing)
- printf("WARNING: loader(8) metadata is missing!\n");
-
-#ifdef DEV_ISA
-#ifdef DEV_ATPIC
- elcr_probe();
- atpic_startup();
-#else
- /* Reset and mask the atpics and leave them shut down. */
- atpic_reset();
-
- /*
- * Point the ICU spurious interrupt vectors at the APIC spurious
- * interrupt handler.
- */
- setidt(IDT_IO_INTS + 7, IDTVEC(spuriousint), SDT_SYS386IGT, SEL_KPL,
- GSEL(GCODE_SEL, SEL_KPL));
- setidt(IDT_IO_INTS + 15, IDTVEC(spuriousint), SDT_SYS386IGT, SEL_KPL,
- GSEL(GCODE_SEL, SEL_KPL));
-#endif
-#endif
-
-#ifdef DDB
- db_fetch_ksymtab(bootinfo.bi_symtab, bootinfo.bi_esymtab);
-#endif
-
- kdb_init();
-
-#ifdef KDB
- if (boothowto & RB_KDB)
- kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
-#endif
-
- finishidentcpu(); /* Final stage of CPU initialization */
- setidt(IDT_UD, &IDTVEC(ill), SDT_SYS386TGT, SEL_KPL,
- GSEL(GCODE_SEL, SEL_KPL));
- setidt(IDT_GP, &IDTVEC(prot), SDT_SYS386TGT, SEL_KPL,
- GSEL(GCODE_SEL, SEL_KPL));
- initializecpu(); /* Initialize CPU registers */
- initializecpucache();
-
- /* pointer to selector slot for %fs/%gs */
- PCPU_SET(fsgs_gdt, &gdt[GUFS_SEL].sd);
-
- dblfault_tss.tss_esp = dblfault_tss.tss_esp0 = dblfault_tss.tss_esp1 =
- dblfault_tss.tss_esp2 = (int)&dblfault_stack[sizeof(dblfault_stack)];
- dblfault_tss.tss_ss = dblfault_tss.tss_ss0 = dblfault_tss.tss_ss1 =
- dblfault_tss.tss_ss2 = GSEL(GDATA_SEL, SEL_KPL);
-#if defined(PAE) || defined(PAE_TABLES)
- dblfault_tss.tss_cr3 = (int)IdlePDPT;
-#else
- dblfault_tss.tss_cr3 = (int)IdlePTD;
-#endif
- dblfault_tss.tss_eip = (int)dblfault_handler;
- dblfault_tss.tss_eflags = PSL_KERNEL;
- dblfault_tss.tss_ds = dblfault_tss.tss_es =
- dblfault_tss.tss_gs = GSEL(GDATA_SEL, SEL_KPL);
- dblfault_tss.tss_fs = GSEL(GPRIV_SEL, SEL_KPL);
- dblfault_tss.tss_cs = GSEL(GCODE_SEL, SEL_KPL);
- dblfault_tss.tss_ldt = GSEL(GLDT_SEL, SEL_KPL);
-
- vm86_initialize();
- getmemsize(first);
- init_param2(physmem);
-
- /* now running on new page tables, configured,and u/iom is accessible */
-
- msgbufinit(msgbufp, msgbufsize);
-#ifdef DEV_NPX
- npxinit(true);
-#endif
- /*
- * Set up thread0 pcb after npxinit calculated pcb + fpu save
- * area size. Zero out the extended state header in fpu save
- * area.
- */
- thread0.td_pcb = get_pcb_td(&thread0);
- bzero(get_pcb_user_save_td(&thread0), cpu_max_ext_state_size);
-#ifdef CPU_ENABLE_SSE
- if (use_xsave) {
- xhdr = (struct xstate_hdr *)(get_pcb_user_save_td(&thread0) +
- 1);
- xhdr->xstate_bv = xsave_mask;
- }
-#endif
- PCPU_SET(curpcb, thread0.td_pcb);
- /* make an initial tss so cpu can get interrupt stack on syscall! */
- /* Note: -16 is so we can grow the trapframe if we came from vm86 */
- PCPU_SET(common_tss.tss_esp0, (vm_offset_t)thread0.td_pcb - 16);
- PCPU_SET(common_tss.tss_ss0, GSEL(GDATA_SEL, SEL_KPL));
- gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
- HYPERVISOR_stack_switch(GSEL(GDATA_SEL, SEL_KPL),
- PCPU_GET(common_tss.tss_esp0));
-
- /* transfer to user mode */
-
- _ucodesel = GSEL(GUCODE_SEL, SEL_UPL);
- _udatasel = GSEL(GUDATA_SEL, SEL_UPL);
-
- /* setup proc 0's pcb */
- thread0.td_pcb->pcb_flags = 0;
-#if defined(PAE) || defined(PAE_TABLES)
- thread0.td_pcb->pcb_cr3 = (int)IdlePDPT;
-#else
- thread0.td_pcb->pcb_cr3 = (int)IdlePTD;
-#endif
- thread0.td_pcb->pcb_ext = 0;
- thread0.td_frame = &proc0_tf;
- thread0.td_pcb->pcb_fsd = PCPU_GET(fsgs_gdt)[0];
- thread0.td_pcb->pcb_gsd = PCPU_GET(fsgs_gdt)[1];
-
- cpu_probe_amdc1e();
-
- /* Location of kernel stack for locore */
- return ((register_t)thread0.td_pcb);
-}
-
-#else
register_t
init386(first)
int first;
@@ -3061,7 +2748,6 @@ init386(first)
/* Location of kernel stack for locore */
return ((register_t)thread0.td_pcb);
}
-#endif
void
cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size)
diff --git a/sys/i386/i386/minidump_machdep.c b/sys/i386/i386/minidump_machdep.c
index a7d2a69e3901..8f78abcb585e 100644
--- a/sys/i386/i386/minidump_machdep.c
+++ b/sys/i386/i386/minidump_machdep.c
@@ -68,10 +68,6 @@ static void *dump_va;
static uint64_t counter, progress;
CTASSERT(sizeof(*vm_page_dump) == 4);
-#ifndef XEN
-#define xpmap_mtop(x) (x)
-#define xpmap_ptom(x) (x)
-#endif
static int
@@ -205,7 +201,7 @@ minidumpsys(struct dumperinfo *di)
j = va >> PDRSHIFT;
if ((pd[j] & (PG_PS | PG_V)) == (PG_PS | PG_V)) {
/* This is an entire 2M page. */
- pa = xpmap_mtop(pd[j] & PG_PS_FRAME);
+ pa = pd[j] & PG_PS_FRAME;
for (k = 0; k < NPTEPG; k++) {
if (is_dumpable(pa))
dump_add_page(pa);
@@ -215,10 +211,10 @@ minidumpsys(struct dumperinfo *di)
}
if ((pd[j] & PG_V) == PG_V) {
/* set bit for each valid page in this 2MB block */
- pt = pmap_kenter_temporary(xpmap_mtop(pd[j] & PG_FRAME), 0);
+ pt = pmap_kenter_temporary(pd[j] & PG_FRAME, 0);
for (k = 0; k < NPTEPG; k++) {
if ((pt[k] & PG_V) == PG_V) {
- pa = xpmap_mtop(pt[k] & PG_FRAME);
+ pa = pt[k] & PG_FRAME;
if (is_dumpable(pa))
dump_add_page(pa);
}
@@ -318,24 +314,8 @@ minidumpsys(struct dumperinfo *di)
continue;
}
if ((pd[j] & PG_V) == PG_V) {
- pa = xpmap_mtop(pd[j] & PG_FRAME);
-#ifndef XEN
+ pa = pd[j] & PG_FRAME;
error = blk_write(di, 0, pa, PAGE_SIZE);
-#else
- pt = pmap_kenter_temporary(pa, 0);
- memcpy(fakept, pt, PAGE_SIZE);
- for (i = 0; i < NPTEPG; i++)
- fakept[i] = xpmap_mtop(fakept[i]);
- error = blk_write(di, (char *)&fakept, 0, PAGE_SIZE);
- if (error)
- goto fail;
- /* flush, in case we reuse fakept in the same block */
- error = blk_flush(di);
- if (error)
- goto fail;
- bzero(fakept, sizeof(fakept));
-#endif
-
if (error)
goto fail;
} else {
diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c
index b39675226f98..bad69ee14839 100644
--- a/sys/i386/i386/mp_machdep.c
+++ b/sys/i386/i386/mp_machdep.c
@@ -130,331 +130,23 @@ __FBSDID("$FreeBSD$");
#endif /* CHECK_POINTS */
-/* lock region used by kernel profiling */
-int mcount_lock;
-
-int mp_naps; /* # of Applications processors */
-int boot_cpu_id = -1; /* designated BSP */
-
extern struct pcpu __pcpu[];
-/* AP uses this during bootstrap. Do not staticize. */
-char *bootSTK;
-static int bootAP;
-
-/* Free these after use */
-void *bootstacks[MAXCPU];
-static void *dpcpu;
-
-struct pcb stoppcbs[MAXCPU];
-struct susppcb **susppcbs;
-
/* Variables needed for SMP tlb shootdown. */
vm_offset_t smp_tlb_addr1;
vm_offset_t smp_tlb_addr2;
volatile int smp_tlb_wait;
-#ifdef COUNT_IPIS
-/* Interrupt counts. */
-static u_long *ipi_preempt_counts[MAXCPU];
-static u_long *ipi_ast_counts[MAXCPU];
-u_long *ipi_invltlb_counts[MAXCPU];
-u_long *ipi_invlrng_counts[MAXCPU];
-u_long *ipi_invlpg_counts[MAXCPU];
-u_long *ipi_invlcache_counts[MAXCPU];
-u_long *ipi_rendezvous_counts[MAXCPU];
-static u_long *ipi_hardclock_counts[MAXCPU];
-#endif
-
-/* Default cpu_ops implementation. */
-struct cpu_ops cpu_ops;
-
/*
* Local data and functions.
*/
-static volatile cpuset_t ipi_nmi_pending;
-
-/* used to hold the AP's until we are ready to release them */
-static struct mtx ap_boot_mtx;
-
-/* Set to 1 once we're ready to let the APs out of the pen. */
-static volatile int aps_ready = 0;
-
-/*
- * Store data from cpu_add() until later in the boot when we actually setup
- * the APs.
- */
-struct cpu_info {
- int cpu_present:1;
- int cpu_bsp:1;
- int cpu_disabled:1;
- int cpu_hyperthread:1;
-} static cpu_info[MAX_APIC_ID + 1];
-int cpu_apic_ids[MAXCPU];
-int apic_cpuids[MAX_APIC_ID + 1];
-
-/* Holds pending bitmap based IPIs per CPU */
-volatile u_int cpu_ipi_pending[MAXCPU];
-
-static u_int boot_address;
-static int cpu_logical; /* logical cpus per core */
-static int cpu_cores; /* cores per package */
-
-static void assign_cpu_ids(void);
static void install_ap_tramp(void);
-static void set_interrupt_apic_ids(void);
static int start_all_aps(void);
static int start_ap(int apic_id);
static void release_aps(void *dummy);
-static u_int hyperthreading_cpus; /* logical cpus sharing L1 cache */
-static int hyperthreading_allowed = 1;
-
-static void
-mem_range_AP_init(void)
-{
- if (mem_range_softc.mr_op && mem_range_softc.mr_op->initAP)
- mem_range_softc.mr_op->initAP(&mem_range_softc);
-}
-
-static void
-topo_probe_amd(void)
-{
- int core_id_bits;
- int id;
-
- /* AMD processors do not support HTT. */
- cpu_logical = 1;
-
- if ((amd_feature2 & AMDID2_CMP) == 0) {
- cpu_cores = 1;
- return;
- }
-
- core_id_bits = (cpu_procinfo2 & AMDID_COREID_SIZE) >>
- AMDID_COREID_SIZE_SHIFT;
- if (core_id_bits == 0) {
- cpu_cores = (cpu_procinfo2 & AMDID_CMP_CORES) + 1;
- return;
- }
-
- /* Fam 10h and newer should get here. */
- for (id = 0; id <= MAX_APIC_ID; id++) {
- /* Check logical CPU availability. */
- if (!cpu_info[id].cpu_present || cpu_info[id].cpu_disabled)
- continue;
- /* Check if logical CPU has the same package ID. */
- if ((id >> core_id_bits) != (boot_cpu_id >> core_id_bits))
- continue;
- cpu_cores++;
- }
-}
-
-/*
- * Round up to the next power of two, if necessary, and then
- * take log2.
- * Returns -1 if argument is zero.
- */
-static __inline int
-mask_width(u_int x)
-{
-
- return (fls(x << (1 - powerof2(x))) - 1);
-}
-
-static void
-topo_probe_0x4(void)
-{
- u_int p[4];
- int pkg_id_bits;
- int core_id_bits;
- int max_cores;
- int max_logical;
- int id;
-
- /* Both zero and one here mean one logical processor per package. */
- max_logical = (cpu_feature & CPUID_HTT) != 0 ?
- (cpu_procinfo & CPUID_HTT_CORES) >> 16 : 1;
- if (max_logical <= 1)
- return;
-
- /*
- * Because of uniformity assumption we examine only
- * those logical processors that belong to the same
- * package as BSP. Further, we count number of
- * logical processors that belong to the same core
- * as BSP thus deducing number of threads per core.
- */
- if (cpu_high >= 0x4) {
- cpuid_count(0x04, 0, p);
- max_cores = ((p[0] >> 26) & 0x3f) + 1;
- } else
- max_cores = 1;
- core_id_bits = mask_width(max_logical/max_cores);
- if (core_id_bits < 0)
- return;
- pkg_id_bits = core_id_bits + mask_width(max_cores);
-
- for (id = 0; id <= MAX_APIC_ID; id++) {
- /* Check logical CPU availability. */
- if (!cpu_info[id].cpu_present || cpu_info[id].cpu_disabled)
- continue;
- /* Check if logical CPU has the same package ID. */
- if ((id >> pkg_id_bits) != (boot_cpu_id >> pkg_id_bits))
- continue;
- cpu_cores++;
- /* Check if logical CPU has the same package and core IDs. */
- if ((id >> core_id_bits) == (boot_cpu_id >> core_id_bits))
- cpu_logical++;
- }
-
- KASSERT(cpu_cores >= 1 && cpu_logical >= 1,
- ("topo_probe_0x4 couldn't find BSP"));
-
- cpu_cores /= cpu_logical;
- hyperthreading_cpus = cpu_logical;
-}
-
-static void
-topo_probe_0xb(void)
-{
- u_int p[4];
- int bits;
- int cnt;
- int i;
- int logical;
- int type;
- int x;
-
- /* We only support three levels for now. */
- for (i = 0; i < 3; i++) {
- cpuid_count(0x0b, i, p);
-
- /* Fall back if CPU leaf 11 doesn't really exist. */
- if (i == 0 && p[1] == 0) {
- topo_probe_0x4();
- return;
- }
-
- bits = p[0] & 0x1f;
- logical = p[1] &= 0xffff;
- type = (p[2] >> 8) & 0xff;
- if (type == 0 || logical == 0)
- break;
- /*
- * Because of uniformity assumption we examine only
- * those logical processors that belong to the same
- * package as BSP.
- */
- for (cnt = 0, x = 0; x <= MAX_APIC_ID; x++) {
- if (!cpu_info[x].cpu_present ||
- cpu_info[x].cpu_disabled)
- continue;
- if (x >> bits == boot_cpu_id >> bits)
- cnt++;
- }
- if (type == CPUID_TYPE_SMT)
- cpu_logical = cnt;
- else if (type == CPUID_TYPE_CORE)
- cpu_cores = cnt;
- }
- if (cpu_logical == 0)
- cpu_logical = 1;
- cpu_cores /= cpu_logical;
-}
-
-/*
- * Both topology discovery code and code that consumes topology
- * information assume top-down uniformity of the topology.
- * That is, all physical packages must be identical and each
- * core in a package must have the same number of threads.
- * Topology information is queried only on BSP, on which this
- * code runs and for which it can query CPUID information.
- * Then topology is extrapolated on all packages using the
- * uniformity assumption.
- */
-static void
-topo_probe(void)
-{
- static int cpu_topo_probed = 0;
-
- if (cpu_topo_probed)
- return;
-
- CPU_ZERO(&logical_cpus_mask);
- if (mp_ncpus <= 1)
- cpu_cores = cpu_logical = 1;
- else if (cpu_vendor_id == CPU_VENDOR_AMD)
- topo_probe_amd();
- else if (cpu_vendor_id == CPU_VENDOR_INTEL) {
- /*
- * See Intel(R) 64 Architecture Processor
- * Topology Enumeration article for details.
- *
- * Note that 0x1 <= cpu_high < 4 case should be
- * compatible with topo_probe_0x4() logic when
- * CPUID.1:EBX[23:16] > 0 (cpu_cores will be 1)
- * or it should trigger the fallback otherwise.
- */
- if (cpu_high >= 0xb)
- topo_probe_0xb();
- else if (cpu_high >= 0x1)
- topo_probe_0x4();
- }
-
- /*
- * Fallback: assume each logical CPU is in separate
- * physical package. That is, no multi-core, no SMT.
- */
- if (cpu_cores == 0 || cpu_logical == 0)
- cpu_cores = cpu_logical = 1;
- cpu_topo_probed = 1;
-}
-
-struct cpu_group *
-cpu_topo(void)
-{
- int cg_flags;
-
- /*
- * Determine whether any threading flags are
- * necessry.
- */
- topo_probe();
- if (cpu_logical > 1 && hyperthreading_cpus)
- cg_flags = CG_FLAG_HTT;
- else if (cpu_logical > 1)
- cg_flags = CG_FLAG_SMT;
- else
- cg_flags = 0;
- if (mp_ncpus % (cpu_cores * cpu_logical) != 0) {
- printf("WARNING: Non-uniform processors.\n");
- printf("WARNING: Using suboptimal topology.\n");
- return (smp_topo_none());
- }
- /*
- * No multi-core or hyper-threaded.
- */
- if (cpu_logical * cpu_cores == 1)
- return (smp_topo_none());
- /*
- * Only HTT no multi-core.
- */
- if (cpu_logical > 1 && cpu_cores == 1)
- return (smp_topo_1level(CG_SHARE_L1, cpu_logical, cg_flags));
- /*
- * Only multi-core no HTT.
- */
- if (cpu_cores > 1 && cpu_logical == 1)
- return (smp_topo_1level(CG_SHARE_L2, cpu_cores, cg_flags));
- /*
- * Both HTT and multi-core.
- */
- return (smp_topo_2level(CG_SHARE_L2, cpu_cores,
- CG_SHARE_L1, cpu_logical, cg_flags));
-}
-
+static u_int boot_address;
/*
* Calculate usable address in base memory for AP trampoline code.
@@ -470,85 +162,6 @@ mp_bootaddress(u_int basemem)
return boot_address;
}
-void
-cpu_add(u_int apic_id, char boot_cpu)
-{
-
- if (apic_id > MAX_APIC_ID) {
- panic("SMP: APIC ID %d too high", apic_id);
- return;
- }
- KASSERT(cpu_info[apic_id].cpu_present == 0, ("CPU %d added twice",
- apic_id));
- cpu_info[apic_id].cpu_present = 1;
- if (boot_cpu) {
- KASSERT(boot_cpu_id == -1,
- ("CPU %d claims to be BSP, but CPU %d already is", apic_id,
- boot_cpu_id));
- boot_cpu_id = apic_id;
- cpu_info[apic_id].cpu_bsp = 1;
- }
- if (mp_ncpus < MAXCPU) {
- mp_ncpus++;
- mp_maxid = mp_ncpus - 1;
- }
- if (bootverbose)
- printf("SMP: Added CPU %d (%s)\n", apic_id, boot_cpu ? "BSP" :
- "AP");
-}
-
-void
-cpu_mp_setmaxid(void)
-{
-
- /*
- * mp_maxid should be already set by calls to cpu_add().
- * Just sanity check its value here.
- */
- if (mp_ncpus == 0)
- KASSERT(mp_maxid == 0,
- ("%s: mp_ncpus is zero, but mp_maxid is not", __func__));
- else if (mp_ncpus == 1)
- mp_maxid = 0;
- else
- KASSERT(mp_maxid >= mp_ncpus - 1,
- ("%s: counters out of sync: max %d, count %d", __func__,
- mp_maxid, mp_ncpus));
-}
-
-int
-cpu_mp_probe(void)
-{
-
- /*
- * Always record BSP in CPU map so that the mbuf init code works
- * correctly.
- */
- CPU_SETOF(0, &all_cpus);
- if (mp_ncpus == 0) {
- /*
- * No CPUs were found, so this must be a UP system. Setup
- * the variables to represent a system with a single CPU
- * with an id of 0.
- */
- mp_ncpus = 1;
- return (0);
- }
-
- /* At least one CPU was found. */
- if (mp_ncpus == 1) {
- /*
- * One CPU was found, so this must be a UP system with
- * an I/O APIC.
- */
- mp_maxid = 0;
- return (0);
- }
-
- /* At least two CPUs were found. */
- return (1);
-}
-
/*
* Initialize the IPI handlers and start up the AP's.
*/
@@ -610,48 +223,6 @@ cpu_mp_start(void)
set_interrupt_apic_ids();
}
-
-/*
- * Print various information about the SMP system hardware and setup.
- */
-void
-cpu_mp_announce(void)
-{
- const char *hyperthread;
- int i;
-
- printf("FreeBSD/SMP: %d package(s) x %d core(s)",
- mp_ncpus / (cpu_cores * cpu_logical), cpu_cores);
- if (hyperthreading_cpus > 1)
- printf(" x %d HTT threads", cpu_logical);
- else if (cpu_logical > 1)
- printf(" x %d SMT threads", cpu_logical);
- printf("\n");
-
- /* List active CPUs first. */
- printf(" cpu0 (BSP): APIC ID: %2d\n", boot_cpu_id);
- for (i = 1; i < mp_ncpus; i++) {
- if (cpu_info[cpu_apic_ids[i]].cpu_hyperthread)
- hyperthread = "/HT";
- else
- hyperthread = "";
- printf(" cpu%d (AP%s): APIC ID: %2d\n", i, hyperthread,
- cpu_apic_ids[i]);
- }
-
- /* List disabled CPUs last. */
- for (i = 0; i <= MAX_APIC_ID; i++) {
- if (!cpu_info[i].cpu_present || !cpu_info[i].cpu_disabled)
- continue;
- if (cpu_info[i].cpu_hyperthread)
- hyperthread = "/HT";
- else
- hyperthread = "";
- printf(" cpu (AP%s): APIC ID: %2d (disabled)\n", hyperthread,
- i);
- }
-}
-
/*
* AP CPU's call this to initialize themselves.
*/
@@ -662,7 +233,7 @@ init_secondary(void)
vm_offset_t addr;
int gsel_tss;
int x, myid;
- u_int cpuid, cr0;
+ u_int cr0;
/* bootAP is set in start_ap() to our ID. */
myid = bootAP;
@@ -731,84 +302,7 @@ init_secondary(void)
lidt(&r_idt);
#endif
- /*
- * On real hardware, switch to x2apic mode if possible. Do it
- * after aps_ready was signalled, to avoid manipulating the
- * mode while BSP might still want to send some IPI to us
- * (second startup IPI is ignored on modern hardware etc).
- */
- lapic_xapic_mode();
-
- /* Initialize the PAT MSR if present. */
- pmap_init_pat();
-
- /* set up CPU registers and state */
- cpu_setregs();
-
- /* set up SSE/NX */
- initializecpu();
-
- /* set up FPU state on the AP */
- npxinit(false);
-
- if (cpu_ops.cpu_init)
- cpu_ops.cpu_init();
-
- /* A quick check from sanity claus */
- cpuid = PCPU_GET(cpuid);
- if (PCPU_GET(apic_id) != lapic_id()) {
- printf("SMP: cpuid = %d\n", cpuid);
- printf("SMP: actual apic_id = %d\n", lapic_id());
- printf("SMP: correct apic_id = %d\n", PCPU_GET(apic_id));
- panic("cpuid mismatch! boom!!");
- }
-
- /* Initialize curthread. */
- KASSERT(PCPU_GET(idlethread) != NULL, ("no idle thread"));
- PCPU_SET(curthread, PCPU_GET(idlethread));
-
- mca_init();
-
- mtx_lock_spin(&ap_boot_mtx);
-
- /* Init local apic for irq's */
- lapic_setup(1);
-
- /* Set memory range attributes for this CPU to match the BSP */
- mem_range_AP_init();
-
- smp_cpus++;
-
- CTR1(KTR_SMP, "SMP: AP CPU #%d Launched", cpuid);
- printf("SMP: AP CPU #%d Launched!\n", cpuid);
-
- /* Determine if we are a logical CPU. */
- /* XXX Calculation depends on cpu_logical being a power of 2, e.g. 2 */
- if (cpu_logical > 1 && PCPU_GET(apic_id) % cpu_logical != 0)
- CPU_SET(cpuid, &logical_cpus_mask);
-
- if (bootverbose)
- lapic_dump("AP");
-
- if (smp_cpus == mp_ncpus) {
- /* enable IPI's, tlb shootdown, freezes etc */
- atomic_store_rel_int(&smp_started, 1);
- }
-
- mtx_unlock_spin(&ap_boot_mtx);
-
- /* Wait until all the AP's are up. */
- while (smp_started == 0)
- ia32_pause();
-
- /* Start per-CPU event timers. */
- cpu_initclocks_ap();
-
- /* Enter the scheduler. */
- sched_throw(NULL);
-
- panic("scheduler returned us to %s", __func__);
- /* NOTREACHED */
+ init_secondary_tail();
}
/*******************************************************************
@@ -816,108 +310,6 @@ init_secondary(void)
*/
/*
- * We tell the I/O APIC code about all the CPUs we want to receive
- * interrupts. If we don't want certain CPUs to receive IRQs we
- * can simply not tell the I/O APIC code about them in this function.
- * We also do not tell it about the BSP since it tells itself about
- * the BSP internally to work with UP kernels and on UP machines.
- */
-static void
-set_interrupt_apic_ids(void)
-{
- u_int i, apic_id;
-
- for (i = 0; i < MAXCPU; i++) {
- apic_id = cpu_apic_ids[i];
- if (apic_id == -1)
- continue;
- if (cpu_info[apic_id].cpu_bsp)
- continue;
- if (cpu_info[apic_id].cpu_disabled)
- continue;
-
- /* Don't let hyperthreads service interrupts. */
- if (cpu_logical > 1 &&
- apic_id % cpu_logical != 0)
- continue;
-
- intr_add_cpu(i);
- }
-}
-
-/*
- * Assign logical CPU IDs to local APICs.
- */
-static void
-assign_cpu_ids(void)
-{
- u_int i;
-
- TUNABLE_INT_FETCH("machdep.hyperthreading_allowed",
- &hyperthreading_allowed);
-
- /* Check for explicitly disabled CPUs. */
- for (i = 0; i <= MAX_APIC_ID; i++) {
- if (!cpu_info[i].cpu_present || cpu_info[i].cpu_bsp)
- continue;
-
- if (hyperthreading_cpus > 1 && i % hyperthreading_cpus != 0) {
- cpu_info[i].cpu_hyperthread = 1;
-
- /*
- * Don't use HT CPU if it has been disabled by a
- * tunable.
- */
- if (hyperthreading_allowed == 0) {
- cpu_info[i].cpu_disabled = 1;
- continue;
- }
- }
-
- /* Don't use this CPU if it has been disabled by a tunable. */
- if (resource_disabled("lapic", i)) {
- cpu_info[i].cpu_disabled = 1;
- continue;
- }
- }
-
- if (hyperthreading_allowed == 0 && hyperthreading_cpus > 1) {
- hyperthreading_cpus = 0;
- cpu_logical = 1;
- }
-
- /*
- * Assign CPU IDs to local APIC IDs and disable any CPUs
- * beyond MAXCPU. CPU 0 is always assigned to the BSP.
- *
- * To minimize confusion for userland, we attempt to number
- * CPUs such that all threads and cores in a package are
- * grouped together. For now we assume that the BSP is always
- * the first thread in a package and just start adding APs
- * starting with the BSP's APIC ID.
- */
- mp_ncpus = 1;
- cpu_apic_ids[0] = boot_cpu_id;
- apic_cpuids[boot_cpu_id] = 0;
- for (i = boot_cpu_id + 1; i != boot_cpu_id;
- i == MAX_APIC_ID ? i = 0 : i++) {
- if (!cpu_info[i].cpu_present || cpu_info[i].cpu_bsp ||
- cpu_info[i].cpu_disabled)
- continue;
-
- if (mp_ncpus < MAXCPU) {
- cpu_apic_ids[mp_ncpus] = i;
- apic_cpuids[i] = mp_ncpus;
- mp_ncpus++;
- } else
- cpu_info[i].cpu_disabled = 1;
- }
- KASSERT(mp_maxid >= mp_ncpus - 1,
- ("%s: counters out of sync: max %d, count %d", __func__, mp_maxid,
- mp_ncpus));
-}
-
-/*
* start each AP in our list
*/
/* Lowest 1MB is already mapped: don't touch*/
@@ -1094,129 +486,6 @@ start_ap(int apic_id)
return 0; /* return FAILURE */
}
-#ifdef COUNT_XINVLTLB_HITS
-u_int xhits_gbl[MAXCPU];
-u_int xhits_pg[MAXCPU];
-u_int xhits_rng[MAXCPU];
-static SYSCTL_NODE(_debug, OID_AUTO, xhits, CTLFLAG_RW, 0, "");
-SYSCTL_OPAQUE(_debug_xhits, OID_AUTO, global, CTLFLAG_RW, &xhits_gbl,
- sizeof(xhits_gbl), "IU", "");
-SYSCTL_OPAQUE(_debug_xhits, OID_AUTO, page, CTLFLAG_RW, &xhits_pg,
- sizeof(xhits_pg), "IU", "");
-SYSCTL_OPAQUE(_debug_xhits, OID_AUTO, range, CTLFLAG_RW, &xhits_rng,
- sizeof(xhits_rng), "IU", "");
-
-u_int ipi_global;
-u_int ipi_page;
-u_int ipi_range;
-u_int ipi_range_size;
-SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_global, CTLFLAG_RW, &ipi_global, 0, "");
-SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_page, CTLFLAG_RW, &ipi_page, 0, "");
-SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_range, CTLFLAG_RW, &ipi_range, 0, "");
-SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_range_size, CTLFLAG_RW, &ipi_range_size,
- 0, "");
-
-u_int ipi_masked_global;
-u_int ipi_masked_page;
-u_int ipi_masked_range;
-u_int ipi_masked_range_size;
-SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_masked_global, CTLFLAG_RW,
- &ipi_masked_global, 0, "");
-SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_masked_page, CTLFLAG_RW,
- &ipi_masked_page, 0, "");
-SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_masked_range, CTLFLAG_RW,
- &ipi_masked_range, 0, "");
-SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_masked_range_size, CTLFLAG_RW,
- &ipi_masked_range_size, 0, "");
-#endif /* COUNT_XINVLTLB_HITS */
-
-/*
- * Init and startup IPI.
- */
-void
-ipi_startup(int apic_id, int vector)
-{
-
- /*
- * This attempts to follow the algorithm described in the
- * Intel Multiprocessor Specification v1.4 in section B.4.
- * For each IPI, we allow the local APIC ~20us to deliver the
- * IPI. If that times out, we panic.
- */
-
- /*
- * first we do an INIT IPI: this INIT IPI might be run, resetting
- * and running the target CPU. OR this INIT IPI might be latched (P5
- * bug), CPU waiting for STARTUP IPI. OR this INIT IPI might be
- * ignored.
- */
- lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_LEVEL |
- APIC_LEVEL_ASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_INIT, apic_id);
- lapic_ipi_wait(100);
-
- /* Explicitly deassert the INIT IPI. */
- lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_LEVEL |
- APIC_LEVEL_DEASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_INIT,
- apic_id);
-
- DELAY(10000); /* wait ~10mS */
-
- /*
- * next we do a STARTUP IPI: the previous INIT IPI might still be
- * latched, (P5 bug) this 1st STARTUP would then terminate
- * immediately, and the previously started INIT IPI would continue. OR
- * the previous INIT IPI has already run. and this STARTUP IPI will
- * run. OR the previous INIT IPI was ignored. and this STARTUP IPI
- * will run.
- */
- lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_EDGE |
- APIC_LEVEL_ASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_STARTUP |
- vector, apic_id);
- if (!lapic_ipi_wait(100))
- panic("Failed to deliver first STARTUP IPI to APIC %d",
- apic_id);
- DELAY(200); /* wait ~200uS */
-
- /*
- * finally we do a 2nd STARTUP IPI: this 2nd STARTUP IPI should run IF
- * the previous STARTUP IPI was cancelled by a latched INIT IPI. OR
- * this STARTUP IPI will be ignored, as only ONE STARTUP IPI is
- * recognized after hardware RESET or INIT IPI.
- */
- lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_EDGE |
- APIC_LEVEL_ASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_STARTUP |
- vector, apic_id);
- if (!lapic_ipi_wait(100))
- panic("Failed to deliver second STARTUP IPI to APIC %d",
- apic_id);
-
- DELAY(200); /* wait ~200uS */
-}
-
-/*
- * Send an IPI to specified CPU handling the bitmap logic.
- */
-static void
-ipi_send_cpu(int cpu, u_int ipi)
-{
- u_int bitmap, old_pending, new_pending;
-
- KASSERT(cpu_apic_ids[cpu] != -1, ("IPI to non-existent CPU %d", cpu));
-
- if (IPI_IS_BITMAPED(ipi)) {
- bitmap = 1 << ipi;
- ipi = IPI_BITMAP_VECTOR;
- do {
- old_pending = cpu_ipi_pending[cpu];
- new_pending = old_pending | bitmap;
- } while (!atomic_cmpset_int(&cpu_ipi_pending[cpu],
- old_pending, new_pending));
- if (old_pending)
- return;
- }
- lapic_ipi_vectored(ipi, cpu_apic_ids[cpu]);
-}
-
/*
* Flush the TLB on all other CPU's
*/
@@ -1280,14 +549,6 @@ smp_targeted_tlb_shootdown(cpuset_t mask, u_int vector, vm_offset_t addr1, vm_of
}
void
-smp_cache_flush(void)
-{
-
- if (smp_started)
- smp_tlb_shootdown(IPI_INVLCACHE, 0, 0);
-}
-
-void
smp_invltlb(void)
{
@@ -1362,203 +623,11 @@ smp_masked_invlpg_range(cpuset_t mask, vm_offset_t addr1, vm_offset_t addr2)
}
void
-ipi_bitmap_handler(struct trapframe frame)
-{
- struct trapframe *oldframe;
- struct thread *td;
- int cpu = PCPU_GET(cpuid);
- u_int ipi_bitmap;
-
- critical_enter();
- td = curthread;
- td->td_intr_nesting_level++;
- oldframe = td->td_intr_frame;
- td->td_intr_frame = &frame;
- ipi_bitmap = atomic_readandclear_int(&cpu_ipi_pending[cpu]);
- if (ipi_bitmap & (1 << IPI_PREEMPT)) {
-#ifdef COUNT_IPIS
- (*ipi_preempt_counts[cpu])++;
-#endif
- sched_preempt(td);
- }
- if (ipi_bitmap & (1 << IPI_AST)) {
-#ifdef COUNT_IPIS
- (*ipi_ast_counts[cpu])++;
-#endif
- /* Nothing to do for AST */
- }
- if (ipi_bitmap & (1 << IPI_HARDCLOCK)) {
-#ifdef COUNT_IPIS
- (*ipi_hardclock_counts[cpu])++;
-#endif
- hardclockintr();
- }
- td->td_intr_frame = oldframe;
- td->td_intr_nesting_level--;
- critical_exit();
-}
-
-/*
- * send an IPI to a set of cpus.
- */
-void
-ipi_selected(cpuset_t cpus, u_int ipi)
-{
- int cpu;
-
- /*
- * IPI_STOP_HARD maps to a NMI and the trap handler needs a bit
- * of help in order to understand what is the source.
- * Set the mask of receiving CPUs for this purpose.
- */
- if (ipi == IPI_STOP_HARD)
- CPU_OR_ATOMIC(&ipi_nmi_pending, &cpus);
-
- while ((cpu = CPU_FFS(&cpus)) != 0) {
- cpu--;
- CPU_CLR(cpu, &cpus);
- CTR3(KTR_SMP, "%s: cpu: %d ipi: %x", __func__, cpu, ipi);
- ipi_send_cpu(cpu, ipi);
- }
-}
-
-/*
- * send an IPI to a specific CPU.
- */
-void
-ipi_cpu(int cpu, u_int ipi)
-{
-
- /*
- * IPI_STOP_HARD maps to a NMI and the trap handler needs a bit
- * of help in order to understand what is the source.
- * Set the mask of receiving CPUs for this purpose.
- */
- if (ipi == IPI_STOP_HARD)
- CPU_SET_ATOMIC(cpu, &ipi_nmi_pending);
-
- CTR3(KTR_SMP, "%s: cpu: %d ipi: %x", __func__, cpu, ipi);
- ipi_send_cpu(cpu, ipi);
-}
-
-/*
- * send an IPI to all CPUs EXCEPT myself
- */
-void
-ipi_all_but_self(u_int ipi)
-{
- cpuset_t other_cpus;
-
- other_cpus = all_cpus;
- CPU_CLR(PCPU_GET(cpuid), &other_cpus);
- if (IPI_IS_BITMAPED(ipi)) {
- ipi_selected(other_cpus, ipi);
- return;
- }
-
- /*
- * IPI_STOP_HARD maps to a NMI and the trap handler needs a bit
- * of help in order to understand what is the source.
- * Set the mask of receiving CPUs for this purpose.
- */
- if (ipi == IPI_STOP_HARD)
- CPU_OR_ATOMIC(&ipi_nmi_pending, &other_cpus);
-
- CTR2(KTR_SMP, "%s: ipi: %x", __func__, ipi);
- lapic_ipi_vectored(ipi, APIC_IPI_DEST_OTHERS);
-}
-
-int
-ipi_nmi_handler()
-{
- u_int cpuid;
-
- /*
- * As long as there is not a simple way to know about a NMI's
- * source, if the bitmask for the current CPU is present in
- * the global pending bitword an IPI_STOP_HARD has been issued
- * and should be handled.
- */
- cpuid = PCPU_GET(cpuid);
- if (!CPU_ISSET(cpuid, &ipi_nmi_pending))
- return (1);
-
- CPU_CLR_ATOMIC(cpuid, &ipi_nmi_pending);
- cpustop_handler();
- return (0);
-}
-
-/*
- * Handle an IPI_STOP by saving our current context and spinning until we
- * are resumed.
- */
-void
-cpustop_handler(void)
-{
- u_int cpu;
-
- cpu = PCPU_GET(cpuid);
-
- savectx(&stoppcbs[cpu]);
-
- /* Indicate that we are stopped */
- CPU_SET_ATOMIC(cpu, &stopped_cpus);
-
- /* Wait for restart */
- while (!CPU_ISSET(cpu, &started_cpus))
- ia32_pause();
-
- CPU_CLR_ATOMIC(cpu, &started_cpus);
- CPU_CLR_ATOMIC(cpu, &stopped_cpus);
-
- if (cpu == 0 && cpustop_restartfunc != NULL) {
- cpustop_restartfunc();
- cpustop_restartfunc = NULL;
- }
-}
-
-/*
- * Handle an IPI_SUSPEND by saving our current context and spinning until we
- * are resumed.
- */
-void
-cpususpend_handler(void)
+smp_cache_flush(void)
{
- u_int cpu;
-
- mtx_assert(&smp_ipi_mtx, MA_NOTOWNED);
-
- cpu = PCPU_GET(cpuid);
- if (savectx(&susppcbs[cpu]->sp_pcb)) {
- npxsuspend(susppcbs[cpu]->sp_fpususpend);
- wbinvd();
- CPU_SET_ATOMIC(cpu, &suspended_cpus);
- } else {
- npxresume(susppcbs[cpu]->sp_fpususpend);
- pmap_init_pat();
- initializecpu();
- PCPU_SET(switchtime, 0);
- PCPU_SET(switchticks, ticks);
-
- /* Indicate that we are resumed */
- CPU_CLR_ATOMIC(cpu, &suspended_cpus);
- }
-
- /* Wait for resume */
- while (!CPU_ISSET(cpu, &started_cpus))
- ia32_pause();
-
- if (cpu_ops.cpu_resume)
- cpu_ops.cpu_resume();
- /* Resume MCA and local APIC */
- lapic_xapic_mode();
- mca_resume();
- lapic_setup(0);
-
- /* Indicate that we are resumed */
- CPU_CLR_ATOMIC(cpu, &suspended_cpus);
- CPU_CLR_ATOMIC(cpu, &started_cpus);
+ if (smp_started)
+ smp_tlb_shootdown(IPI_INVLCACHE, 0, 0);
}
/*
@@ -1614,62 +683,3 @@ invlrng_handler(void)
atomic_add_int(&smp_tlb_wait, 1);
}
-
-void
-invlcache_handler(void)
-{
-#ifdef COUNT_IPIS
- (*ipi_invlcache_counts[PCPU_GET(cpuid)])++;
-#endif /* COUNT_IPIS */
-
- wbinvd();
- atomic_add_int(&smp_tlb_wait, 1);
-}
-
-/*
- * This is called once the rest of the system is up and running and we're
- * ready to let the AP's out of the pen.
- */
-static void
-release_aps(void *dummy __unused)
-{
-
- if (mp_ncpus == 1)
- return;
- atomic_store_rel_int(&aps_ready, 1);
- while (smp_started == 0)
- ia32_pause();
-}
-SYSINIT(start_aps, SI_SUB_SMP, SI_ORDER_FIRST, release_aps, NULL);
-
-#ifdef COUNT_IPIS
-/*
- * Setup interrupt counters for IPI handlers.
- */
-static void
-mp_ipi_intrcnt(void *dummy)
-{
- char buf[64];
- int i;
-
- CPU_FOREACH(i) {
- snprintf(buf, sizeof(buf), "cpu%d:invltlb", i);
- intrcnt_add(buf, &ipi_invltlb_counts[i]);
- snprintf(buf, sizeof(buf), "cpu%d:invlrng", i);
- intrcnt_add(buf, &ipi_invlrng_counts[i]);
- snprintf(buf, sizeof(buf), "cpu%d:invlpg", i);
- intrcnt_add(buf, &ipi_invlpg_counts[i]);
- snprintf(buf, sizeof(buf), "cpu%d:invlcache", i);
- intrcnt_add(buf, &ipi_invlcache_counts[i]);
- snprintf(buf, sizeof(buf), "cpu%d:preempt", i);
- intrcnt_add(buf, &ipi_preempt_counts[i]);
- snprintf(buf, sizeof(buf), "cpu%d:ast", i);
- intrcnt_add(buf, &ipi_ast_counts[i]);
- snprintf(buf, sizeof(buf), "cpu%d:rendezvous", i);
- intrcnt_add(buf, &ipi_rendezvous_counts[i]);
- snprintf(buf, sizeof(buf), "cpu%d:hardclock", i);
- intrcnt_add(buf, &ipi_hardclock_counts[i]);
- }
-}
-SYSINIT(mp_ipi_intrcnt, SI_SUB_INTR, SI_ORDER_MIDDLE, mp_ipi_intrcnt, NULL);
-#endif
diff --git a/sys/i386/i386/support.s b/sys/i386/i386/support.s
index 0a08012e0ec0..78d76efd5c42 100644
--- a/sys/i386/i386/support.s
+++ b/sys/i386/i386/support.s
@@ -695,11 +695,9 @@ END(bcmp)
*/
/* void lgdt(struct region_descriptor *rdp); */
ENTRY(lgdt)
-#ifndef XEN
/* reload the descriptor table */
movl 4(%esp),%eax
lgdt (%eax)
-#endif
/* flush the prefetch q */
jmp 1f
diff --git a/sys/i386/i386/swtch.s b/sys/i386/i386/swtch.s
index 26bfd3b1e120..6bedb48c3647 100644
--- a/sys/i386/i386/swtch.s
+++ b/sys/i386/i386/swtch.s
@@ -88,7 +88,7 @@ ENTRY(cpu_throw)
movl 8(%esp),%ecx /* New thread */
movl TD_PCB(%ecx),%edx
movl PCB_CR3(%edx),%eax
- LOAD_CR3(%eax)
+ movl %eax,%cr3
/* set bit in new pm_active */
movl TD_PROC(%ecx),%eax
movl P_VMSPACE(%eax), %ebx
@@ -174,10 +174,10 @@ ENTRY(cpu_switch)
/* switch address space */
movl PCB_CR3(%edx),%eax
- READ_CR3(%ebx) /* The same address space? */
+ movl %cr3,%ebx /* The same address space? */
cmpl %ebx,%eax
je sw0
- LOAD_CR3(%eax) /* new address space */
+ movl %eax,%cr3 /* new address space */
movl %esi,%eax
movl PCPU(CPUID),%esi
SETOP %eax,TD_LOCK(%edi) /* Switchout td_lock */
@@ -204,18 +204,6 @@ sw0:
SETOP %esi,TD_LOCK(%edi) /* Switchout td_lock */
sw1:
BLOCK_SPIN(%ecx)
-#ifdef XEN
- pushl %eax
- pushl %ecx
- pushl %edx
- call xen_handle_thread_switch
- popl %edx
- popl %ecx
- popl %eax
- /*
- * XXX set IOPL
- */
-#else
/*
* At this point, we've switched address spaces and are ready
* to load up the rest of the next context.
@@ -264,7 +252,7 @@ sw1:
movl 12(%esi), %ebx
movl %eax, 8(%edi)
movl %ebx, 12(%edi)
-#endif
+
/* Restore context. */
movl PCB_EBX(%edx),%ebx
movl PCB_ESP(%edx),%esp
@@ -290,7 +278,7 @@ sw1:
movl _default_ldt,%eax
cmpl PCPU(CURRENTLDT),%eax
je 2f
- LLDT(_default_ldt)
+ lldt _default_ldt
movl %eax,PCPU(CURRENTLDT)
jmp 2f
1:
diff --git a/sys/i386/i386/sys_machdep.c b/sys/i386/i386/sys_machdep.c
index 951886273107..9044d19b2654 100644
--- a/sys/i386/i386/sys_machdep.c
+++ b/sys/i386/i386/sys_machdep.c
@@ -59,20 +59,6 @@ __FBSDID("$FreeBSD$");
#include <security/audit/audit.h>
-#ifdef XEN
-#include <machine/xen/xenfunc.h>
-
-void i386_reset_ldt(struct proc_ldt *pldt);
-
-void
-i386_reset_ldt(struct proc_ldt *pldt)
-{
- xen_set_ldt((vm_offset_t)pldt->ldt_base, pldt->ldt_len);
-}
-#else
-#define i386_reset_ldt(x)
-#endif
-
#include <vm/vm_kern.h> /* for kernel_map */
#define MAX_LD 8192
@@ -211,12 +197,7 @@ sysarch(td, uap)
*/
sd.sd_lobase = base & 0xffffff;
sd.sd_hibase = (base >> 24) & 0xff;
-#ifdef XEN
- /* need to do nosegneg like Linux */
- sd.sd_lolimit = (HYPERVISOR_VIRT_START >> 12) & 0xffff;
-#else
sd.sd_lolimit = 0xffff; /* 4GB limit, wraps around */
-#endif
sd.sd_hilimit = 0xf;
sd.sd_type = SDT_MEMRWA;
sd.sd_dpl = SEL_UPL;
@@ -226,12 +207,7 @@ sysarch(td, uap)
sd.sd_gran = 1;
critical_enter();
td->td_pcb->pcb_fsd = sd;
-#ifdef XEN
- HYPERVISOR_update_descriptor(vtomach(&PCPU_GET(fsgs_gdt)[0]),
- *(uint64_t *)&sd);
-#else
PCPU_GET(fsgs_gdt)[0] = sd;
-#endif
critical_exit();
td->td_frame->tf_fs = GSEL(GUFS_SEL, SEL_UPL);
}
@@ -252,12 +228,7 @@ sysarch(td, uap)
sd.sd_lobase = base & 0xffffff;
sd.sd_hibase = (base >> 24) & 0xff;
-#ifdef XEN
- /* need to do nosegneg like Linux */
- sd.sd_lolimit = (HYPERVISOR_VIRT_START >> 12) & 0xffff;
-#else
sd.sd_lolimit = 0xffff; /* 4GB limit, wraps around */
-#endif
sd.sd_hilimit = 0xf;
sd.sd_type = SDT_MEMRWA;
sd.sd_dpl = SEL_UPL;
@@ -267,12 +238,7 @@ sysarch(td, uap)
sd.sd_gran = 1;
critical_enter();
td->td_pcb->pcb_gsd = sd;
-#ifdef XEN
- HYPERVISOR_update_descriptor(vtomach(&PCPU_GET(fsgs_gdt)[1]),
- *(uint64_t *)&sd);
-#else
PCPU_GET(fsgs_gdt)[1] = sd;
-#endif
critical_exit();
load_gs(GSEL(GUGS_SEL, SEL_UPL));
}
@@ -434,10 +400,6 @@ set_user_ldt(struct mdproc *mdp)
}
pldt = mdp->md_ldt;
-#ifdef XEN
- i386_reset_ldt(pldt);
- PCPU_SET(currentldt, (int)pldt);
-#else
#ifdef SMP
gdt[PCPU_GET(cpuid) * NGDT + GUSERLDT_SEL].sd = pldt->ldt_sd;
#else
@@ -445,7 +407,6 @@ set_user_ldt(struct mdproc *mdp)
#endif
lldt(GSEL(GUSERLDT_SEL, SEL_KPL));
PCPU_SET(currentldt, GSEL(GUSERLDT_SEL, SEL_KPL));
-#endif /* XEN */
if (dtlocked)
mtx_unlock_spin(&dt_lock);
}
@@ -464,43 +425,6 @@ set_user_ldt_rv(struct vmspace *vmsp)
}
#endif
-#ifdef XEN
-
-/*
- * dt_lock must be held. Returns with dt_lock held.
- */
-struct proc_ldt *
-user_ldt_alloc(struct mdproc *mdp, int len)
-{
- struct proc_ldt *pldt, *new_ldt;
-
- mtx_assert(&dt_lock, MA_OWNED);
- mtx_unlock_spin(&dt_lock);
- new_ldt = malloc(sizeof(struct proc_ldt),
- M_SUBPROC, M_WAITOK);
-
- new_ldt->ldt_len = len = NEW_MAX_LD(len);
- new_ldt->ldt_base = (caddr_t)kmem_malloc(kernel_arena,
- round_page(len * sizeof(union descriptor)), M_WAITOK);
- new_ldt->ldt_refcnt = 1;
- new_ldt->ldt_active = 0;
-
- mtx_lock_spin(&dt_lock);
- if ((pldt = mdp->md_ldt)) {
- if (len > pldt->ldt_len)
- len = pldt->ldt_len;
- bcopy(pldt->ldt_base, new_ldt->ldt_base,
- len * sizeof(union descriptor));
- } else {
- bcopy(ldt, new_ldt->ldt_base, PAGE_SIZE);
- }
- mtx_unlock_spin(&dt_lock); /* XXX kill once pmap locking fixed. */
- pmap_map_readonly(kernel_pmap, (vm_offset_t)new_ldt->ldt_base,
- new_ldt->ldt_len*sizeof(union descriptor));
- mtx_lock_spin(&dt_lock); /* XXX kill once pmap locking fixed. */
- return (new_ldt);
-}
-#else
/*
* dt_lock must be held. Returns with dt_lock held.
*/
@@ -535,7 +459,6 @@ user_ldt_alloc(struct mdproc *mdp, int len)
return (new_ldt);
}
-#endif /* !XEN */
/*
* Must be called with dt_lock held. Returns with dt_lock unheld.
@@ -553,13 +476,8 @@ user_ldt_free(struct thread *td)
}
if (td == curthread) {
-#ifdef XEN
- i386_reset_ldt(&default_proc_ldt);
- PCPU_SET(currentldt, (int)&default_proc_ldt);
-#else
lldt(_default_ldt);
PCPU_SET(currentldt, _default_ldt);
-#endif
}
mdp->md_ldt = NULL;
@@ -785,27 +703,7 @@ again:
td->td_retval[0] = uap->start;
return (error);
}
-#ifdef XEN
-static int
-i386_set_ldt_data(struct thread *td, int start, int num,
- union descriptor *descs)
-{
- struct mdproc *mdp = &td->td_proc->p_md;
- struct proc_ldt *pldt = mdp->md_ldt;
- mtx_assert(&dt_lock, MA_OWNED);
-
- while (num) {
- xen_update_descriptor(
- &((union descriptor *)(pldt->ldt_base))[start],
- descs);
- num--;
- start++;
- descs++;
- }
- return (0);
-}
-#else
static int
i386_set_ldt_data(struct thread *td, int start, int num,
union descriptor *descs)
@@ -821,7 +719,6 @@ i386_set_ldt_data(struct thread *td, int start, int num,
num * sizeof(union descriptor));
return (0);
}
-#endif /* !XEN */
static int
i386_ldt_grow(struct thread *td, int len)
diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c
index 5fd4a16030c4..5671dc916b78 100644
--- a/sys/i386/i386/vm_machdep.c
+++ b/sys/i386/i386/vm_machdep.c
@@ -89,9 +89,6 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_map.h>
#include <vm/vm_param.h>
-#ifdef XEN
-#include <xen/hypervisor.h>
-#endif
#ifdef PC98
#include <pc98/cbus/cbus.h>
#else
@@ -304,10 +301,8 @@ cpu_fork(td1, p2, td2, flags)
/* Setup to release spin count in fork_exit(). */
td2->td_md.md_spinlock_count = 1;
- /*
- * XXX XEN need to check on PSL_USER is handled
- */
td2->td_md.md_saved_flags = PSL_KERNEL | PSL_I;
+
/*
* Now, cpu_switch() can schedule the new process.
* pcb_esp is loaded pointing to the cpu_switch() stack frame
@@ -698,12 +693,6 @@ cpu_reset_real()
#endif
disable_intr();
-#ifdef XEN
- if (smp_processor_id() == 0)
- HYPERVISOR_shutdown(SHUTDOWN_reboot);
- else
- HYPERVISOR_shutdown(SHUTDOWN_poweroff);
-#endif
#ifdef CPU_ELAN
if (elan_mmcr != NULL)
elan_mmcr->RESCFG = 1;
@@ -797,13 +786,8 @@ sf_buf_map(struct sf_buf *sf, int flags)
*/
ptep = vtopte(sf->kva);
opte = *ptep;
-#ifdef XEN
- PT_SET_MA(sf->kva, xpmap_ptom(VM_PAGE_TO_PHYS(sf->m)) | pgeflag
- | PG_RW | PG_V | pmap_cache_bits(sf->m->md.pat_mode, 0));
-#else
*ptep = VM_PAGE_TO_PHYS(sf->m) | pgeflag | PG_RW | PG_V |
pmap_cache_bits(sf->m->md.pat_mode, 0);
-#endif
/*
* Avoid unnecessary TLB invalidations: If the sf_buf's old
@@ -854,15 +838,8 @@ sf_buf_shootdown(struct sf_buf *sf, int flags)
int
sf_buf_unmap(struct sf_buf *sf)
{
-#ifdef XEN
- /*
- * Xen doesn't like having dangling R/W mappings
- */
- pmap_qremove(sf->kva, 1);
- return (1);
-#else
+
return (0);
-#endif
}
static void
diff --git a/sys/i386/include/asmacros.h b/sys/i386/include/asmacros.h
index c1c3f645cbf5..716915c36616 100644
--- a/sys/i386/include/asmacros.h
+++ b/sys/i386/include/asmacros.h
@@ -176,37 +176,6 @@
movl $KPSEL, %eax ; /* reload with per-CPU data segment */ \
movl %eax, %fs
-#ifdef XEN
-#define LOAD_CR3(reg) \
- movl reg,PCPU(CR3); \
- pushl %ecx ; \
- pushl %edx ; \
- pushl %esi ; \
- pushl reg ; \
- call xen_load_cr3 ; \
- addl $4,%esp ; \
- popl %esi ; \
- popl %edx ; \
- popl %ecx ; \
-
-#define READ_CR3(reg) movl PCPU(CR3),reg;
-#define LLDT(arg) \
- pushl %edx ; \
- pushl %eax ; \
- xorl %eax,%eax ; \
- movl %eax,%gs ; \
- call i386_reset_ldt ; \
- popl %eax ; \
- popl %edx
-#define CLI call ni_cli
-#else
-#define LOAD_CR3(reg) movl reg,%cr3;
-#define READ_CR3(reg) movl %cr3,reg;
-#define LLDT(arg) lldt arg;
-#define CLI cli
-#endif /* !XEN */
-
-
#endif /* LOCORE */
#ifdef __STDC__
diff --git a/sys/i386/include/cpufunc.h b/sys/i386/include/cpufunc.h
index f80a8983ab29..3bc25d42116e 100644
--- a/sys/i386/include/cpufunc.h
+++ b/sys/i386/include/cpufunc.h
@@ -42,17 +42,6 @@
#error this file needs sys/cdefs.h as a prerequisite
#endif
-#ifdef XEN
-extern void xen_cli(void);
-extern void xen_sti(void);
-extern u_int xen_rcr2(void);
-extern void xen_load_cr3(u_int data);
-extern void xen_tlb_flush(void);
-extern void xen_invlpg(u_int addr);
-extern void write_eflags(u_int eflags);
-extern u_int read_eflags(void);
-#endif
-
struct region_descriptor;
#define readb(va) (*(volatile uint8_t *) (va))
@@ -106,11 +95,8 @@ clts(void)
static __inline void
disable_intr(void)
{
-#ifdef XEN
- xen_cli();
-#else
+
__asm __volatile("cli" : : : "memory");
-#endif
}
static __inline void
@@ -132,11 +118,8 @@ cpuid_count(u_int ax, u_int cx, u_int *p)
static __inline void
enable_intr(void)
{
-#ifdef XEN
- xen_sti();
-#else
+
__asm __volatile("sti");
-#endif
}
static __inline void
@@ -325,11 +308,7 @@ ia32_pause(void)
}
static __inline u_int
-#ifdef XEN
-_read_eflags(void)
-#else
read_eflags(void)
-#endif
{
u_int ef;
@@ -389,11 +368,7 @@ wbinvd(void)
}
static __inline void
-#ifdef XEN
-_write_eflags(u_int ef)
-#else
write_eflags(u_int ef)
-#endif
{
__asm __volatile("pushl %0; popfl" : : "r" (ef));
}
@@ -425,9 +400,6 @@ rcr2(void)
{
u_int data;
-#ifdef XEN
- return (xen_rcr2());
-#endif
__asm __volatile("movl %%cr2,%0" : "=r" (data));
return (data);
}
@@ -435,11 +407,8 @@ rcr2(void)
static __inline void
load_cr3(u_int data)
{
-#ifdef XEN
- xen_load_cr3(data);
-#else
+
__asm __volatile("movl %0,%%cr3" : : "r" (data) : "memory");
-#endif
}
static __inline u_int
@@ -491,11 +460,8 @@ load_xcr(u_int reg, uint64_t val)
static __inline void
invltlb(void)
{
-#ifdef XEN
- xen_tlb_flush();
-#else
+
load_cr3(rcr3());
-#endif
}
/*
@@ -506,11 +472,7 @@ static __inline void
invlpg(u_int addr)
{
-#ifdef XEN
- xen_invlpg(addr);
-#else
__asm __volatile("invlpg %0" : : "m" (*(char *)addr) : "memory");
-#endif
}
static __inline u_short
diff --git a/sys/i386/include/intr_machdep.h b/sys/i386/include/intr_machdep.h
index 082b649242c6..96ac06a5c514 100644
--- a/sys/i386/include/intr_machdep.h
+++ b/sys/i386/include/intr_machdep.h
@@ -58,13 +58,7 @@
(FIRST_MSI_INT + NUM_MSI_INTS)
#define LAST_EVTCHN_INT \
(FIRST_EVTCHN_INT + NUM_EVTCHN_INTS - 1)
-#elif defined(XEN)
-#include <xen/xen-os.h>
-#define NUM_EVTCHN_INTS NR_EVENT_CHANNELS
-#define FIRST_EVTCHN_INT 0
-#define LAST_EVTCHN_INT \
- (FIRST_EVTCHN_INT + NUM_EVTCHN_INTS - 1)
-#else /* !XEN && !XENHVM */
+#else /* !XENHVM */
#define NUM_EVTCHN_INTS 0
#endif
#define NUM_IO_INTS (FIRST_MSI_INT + NUM_MSI_INTS + NUM_EVTCHN_INTS)
diff --git a/sys/i386/include/pcpu.h b/sys/i386/include/pcpu.h
index dc29b6dad247..231f80f6a303 100644
--- a/sys/i386/include/pcpu.h
+++ b/sys/i386/include/pcpu.h
@@ -44,34 +44,6 @@
* other processors"
*/
-#if defined(XEN)
-
-/* These are peridically updated in shared_info, and then copied here. */
-struct shadow_time_info {
- uint64_t tsc_timestamp; /* TSC at last update of time vals. */
- uint64_t system_timestamp; /* Time, in nanosecs, since boot. */
- uint32_t tsc_to_nsec_mul;
- uint32_t tsc_to_usec_mul;
- int tsc_shift;
- uint32_t version;
-};
-
-#define PCPU_XEN_FIELDS \
- ; \
- u_int pc_cr3; /* track cr3 for R1/R3*/ \
- vm_paddr_t *pc_pdir_shadow; \
- uint64_t pc_processed_system_time; \
- struct shadow_time_info pc_shadow_time; \
- char __pad[185]
-
-#else /* !XEN */
-
-#define PCPU_XEN_FIELDS \
- ; \
- char __pad[233]
-
-#endif
-
#define PCPU_MD_FIELDS \
char pc_monitorbuf[128] __aligned(128); /* cache line */ \
struct pcpu *pc_prvspace; /* Self-reference */ \
@@ -85,8 +57,8 @@ struct shadow_time_info {
u_int pc_apic_id; \
int pc_private_tss; /* Flag indicating private tss*/\
u_int pc_cmci_mask; /* MCx banks for CMCI */ \
- u_int pc_vcpu_id /* Xen vCPU ID */ \
- PCPU_XEN_FIELDS
+ u_int pc_vcpu_id; /* Xen vCPU ID */ \
+ char __pad[233]
#ifdef _KERNEL
diff --git a/sys/i386/include/pmap.h b/sys/i386/include/pmap.h
index 0d8057f7c481..76822b142338 100644
--- a/sys/i386/include/pmap.h
+++ b/sys/i386/include/pmap.h
@@ -219,76 +219,6 @@ extern pd_entry_t *IdlePTD; /* physical address of "Idle" state directory */
*/
#define vtophys(va) pmap_kextract((vm_offset_t)(va))
-#if defined(XEN)
-#include <sys/param.h>
-
-#include <xen/xen-os.h>
-
-#include <machine/xen/xenvar.h>
-#include <machine/xen/xenpmap.h>
-
-extern pt_entry_t pg_nx;
-
-#define PG_KERNEL (PG_V | PG_A | PG_RW | PG_M)
-
-#define MACH_TO_VM_PAGE(ma) PHYS_TO_VM_PAGE(xpmap_mtop((ma)))
-#define VM_PAGE_TO_MACH(m) xpmap_ptom(VM_PAGE_TO_PHYS((m)))
-
-#define VTOM(va) xpmap_ptom(VTOP(va))
-
-static __inline vm_paddr_t
-pmap_kextract_ma(vm_offset_t va)
-{
- vm_paddr_t ma;
- if ((ma = PTD[va >> PDRSHIFT]) & PG_PS) {
- ma = (ma & ~(NBPDR - 1)) | (va & (NBPDR - 1));
- } else {
- ma = (*vtopte(va) & PG_FRAME) | (va & PAGE_MASK);
- }
- return ma;
-}
-
-static __inline vm_paddr_t
-pmap_kextract(vm_offset_t va)
-{
- return xpmap_mtop(pmap_kextract_ma(va));
-}
-#define vtomach(va) pmap_kextract_ma(((vm_offset_t) (va)))
-
-vm_paddr_t pmap_extract_ma(struct pmap *pmap, vm_offset_t va);
-
-void pmap_kenter_ma(vm_offset_t va, vm_paddr_t pa);
-void pmap_map_readonly(struct pmap *pmap, vm_offset_t va, int len);
-void pmap_map_readwrite(struct pmap *pmap, vm_offset_t va, int len);
-
-static __inline pt_entry_t
-pte_load_store(pt_entry_t *ptep, pt_entry_t v)
-{
- pt_entry_t r;
-
- r = *ptep;
- PT_SET_VA(ptep, v, TRUE);
- return (r);
-}
-
-static __inline pt_entry_t
-pte_load_store_ma(pt_entry_t *ptep, pt_entry_t v)
-{
- pt_entry_t r;
-
- r = *ptep;
- PT_SET_VA_MA(ptep, v, TRUE);
- return (r);
-}
-
-#define pte_load_clear(ptep) pte_load_store((ptep), (pt_entry_t)0ULL)
-
-#define pte_store(ptep, pte) pte_load_store((ptep), (pt_entry_t)pte)
-#define pte_store_ma(ptep, pte) pte_load_store_ma((ptep), (pt_entry_t)pte)
-#define pde_store_ma(ptep, pte) pte_load_store_ma((ptep), (pt_entry_t)pte)
-
-#elif !defined(XEN)
-
/*
* KPTmap is a linear mapping of the kernel page table. It differs from the
* recursive mapping in two ways: (1) it only provides access to kernel page
@@ -328,13 +258,8 @@ pmap_kextract(vm_offset_t va)
}
return (pa);
}
-#endif
-
-#if !defined(XEN)
-#define PT_UPDATES_FLUSH()
-#endif
-#if (defined(PAE) || defined(PAE_TABLES)) && !defined(XEN)
+#if (defined(PAE) || defined(PAE_TABLES))
#define pde_cmpset(pdep, old, new) atomic_cmpset_64_i586(pdep, old, new)
#define pte_load_store(ptep, pte) atomic_swap_64_i586(ptep, pte)
@@ -343,7 +268,7 @@ pmap_kextract(vm_offset_t va)
extern pt_entry_t pg_nx;
-#elif !defined(PAE) && !defined(PAE_TABLES) && !defined(XEN)
+#else /* !(PAE || PAE_TABLES) */
#define pde_cmpset(pdep, old, new) atomic_cmpset_int(pdep, old, new)
#define pte_load_store(ptep, pte) atomic_swap_int(ptep, pte)
@@ -352,7 +277,7 @@ extern pt_entry_t pg_nx;
*(u_int *)(ptep) = (u_int)(pte); \
} while (0)
-#endif /* PAE */
+#endif /* !(PAE || PAE_TABLES) */
#define pte_clear(ptep) pte_store(ptep, 0)
diff --git a/sys/i386/include/segments.h b/sys/i386/include/segments.h
index d67f2e0dc3e2..635dffc48f34 100644
--- a/sys/i386/include/segments.h
+++ b/sys/i386/include/segments.h
@@ -82,14 +82,8 @@ struct region_descriptor {
#ifdef _KERNEL
extern int _default_ldt;
-#ifdef XEN
-extern struct proc_ldt default_proc_ldt;
-extern union descriptor *gdt;
-extern union descriptor *ldt;
-#else
extern union descriptor gdt[];
extern union descriptor ldt[NLDT];
-#endif
extern struct soft_segment_descriptor gdt_segs[];
extern struct gate_descriptor *idt;
extern struct region_descriptor r_gdt, r_idt;
diff --git a/sys/i386/include/smp.h b/sys/i386/include/smp.h
index 0abbca4158ff..71c830ea895a 100644
--- a/sys/i386/include/smp.h
+++ b/sys/i386/include/smp.h
@@ -36,6 +36,37 @@ extern int mp_naps;
extern int boot_cpu_id;
extern struct pcb stoppcbs[];
extern int cpu_apic_ids[];
+extern int bootAP;
+extern void *dpcpu;
+extern char *bootSTK;
+extern int bootAP;
+extern void *bootstacks[];
+extern volatile u_int cpu_ipi_pending[];
+extern volatile int aps_ready;
+extern struct mtx ap_boot_mtx;
+extern int cpu_logical;
+extern int cpu_cores;
+extern volatile int smp_tlb_wait;
+extern u_int xhits_gbl[];
+extern u_int xhits_pg[];
+extern u_int xhits_rng[];
+extern u_int ipi_global;
+extern u_int ipi_page;
+extern u_int ipi_range;
+extern u_int ipi_range_size;
+extern u_int ipi_masked_global;
+extern u_int ipi_masked_page;
+extern u_int ipi_masked_range;
+extern u_int ipi_masked_range_size;
+
+struct cpu_info {
+ int cpu_present:1;
+ int cpu_bsp:1;
+ int cpu_disabled:1;
+ int cpu_hyperthread:1;
+};
+extern struct cpu_info cpu_info[];
+
#ifdef COUNT_IPIS
extern u_long *ipi_invltlb_counts[MAXCPU];
extern u_long *ipi_invlrng_counts[MAXCPU];
@@ -56,11 +87,11 @@ inthand_t
IDTVEC(rendezvous); /* handle CPU rendezvous */
/* functions in mp_machdep.c */
+void assign_cpu_ids(void);
void cpu_add(u_int apic_id, char boot_cpu);
void cpustop_handler(void);
-#ifndef XEN
void cpususpend_handler(void);
-#endif
+void init_secondary_tail(void);
void invltlb_handler(void);
void invlpg_handler(void);
void invlrng_handler(void);
@@ -68,13 +99,12 @@ void invlcache_handler(void);
void init_secondary(void);
void ipi_startup(int apic_id, int vector);
void ipi_all_but_self(u_int ipi);
-#ifndef XEN
void ipi_bitmap_handler(struct trapframe frame);
-#endif
void ipi_cpu(int cpu, u_int ipi);
int ipi_nmi_handler(void);
void ipi_selected(cpuset_t cpus, u_int ipi);
u_int mp_bootaddress(u_int);
+void set_interrupt_apic_ids(void);
void smp_cache_flush(void);
void smp_invlpg(vm_offset_t addr);
void smp_masked_invlpg(cpuset_t mask, vm_offset_t addr);
@@ -83,10 +113,10 @@ void smp_masked_invlpg_range(cpuset_t mask, vm_offset_t startva,
vm_offset_t endva);
void smp_invltlb(void);
void smp_masked_invltlb(cpuset_t mask);
+void mem_range_AP_init(void);
+void topo_probe(void);
+void ipi_send_cpu(int cpu, u_int ipi);
-#ifdef XEN
-void ipi_to_irq_init(void);
-#endif
#endif /* !LOCORE */
#endif /* SMP */
diff --git a/sys/i386/include/vm.h b/sys/i386/include/vm.h
index 6573e3784616..22d2ecafe211 100644
--- a/sys/i386/include/vm.h
+++ b/sys/i386/include/vm.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2009 Advanced Computing Technologies LLC
+ * Copyright (c) 2009 Hudson River Trading LLC
* Written by: John H. Baldwin <jhb@FreeBSD.org>
* All rights reserved.
*
diff --git a/sys/i386/include/vmparam.h b/sys/i386/include/vmparam.h
index 777566914556..cb23b0595649 100644
--- a/sys/i386/include/vmparam.h
+++ b/sys/i386/include/vmparam.h
@@ -135,11 +135,7 @@
* Kernel physical load address.
*/
#ifndef KERNLOAD
-#if defined(XEN) && !defined(XEN_PRIVILEGED_GUEST)
-#define KERNLOAD 0
-#else
#define KERNLOAD (1 << PDRSHIFT)
-#endif
#endif /* !defined(KERNLOAD) */
/*
@@ -149,11 +145,7 @@
* messy at times, but hey, we'll do anything to save a page :-)
*/
-#ifdef XEN
-#define VM_MAX_KERNEL_ADDRESS HYPERVISOR_VIRT_START
-#else
#define VM_MAX_KERNEL_ADDRESS VADDR(KPTDI+NKPDE-1, NPTEPG-1)
-#endif
#define VM_MIN_KERNEL_ADDRESS VADDR(PTDPTDI, PTDPTDI)
diff --git a/sys/i386/include/xen/features.h b/sys/i386/include/xen/features.h
deleted file mode 100644
index fb4f68008144..000000000000
--- a/sys/i386/include/xen/features.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/******************************************************************************
- * features.h
- *
- * Query the features reported by Xen.
- *
- * Copyright (c) 2006, Ian Campbell
- *
- * $FreeBSD$
- */
-
-#ifndef __ASM_XEN_FEATURES_H__
-#define __ASM_XEN_FEATURES_H__
-
-#include <xen/interface/version.h>
-
-extern void setup_xen_features(void);
-
-extern uint8_t xen_features[XENFEAT_NR_SUBMAPS * 32];
-
-#define xen_feature(flag) (xen_features[flag])
-
-#endif /* __ASM_XEN_FEATURES_H__ */
diff --git a/sys/i386/include/xen/hypercall.h b/sys/i386/include/xen/hypercall.h
index c7e2a00ef23d..1c4d52904a46 100644
--- a/sys/i386/include/xen/hypercall.h
+++ b/sys/i386/include/xen/hypercall.h
@@ -246,14 +246,8 @@ HYPERVISOR_memory_op(
return _hypercall2(int, memory_op, cmd, arg);
}
-#if defined(XEN)
-int HYPERVISOR_multicall(multicall_entry_t *, int);
-static inline int
-_HYPERVISOR_multicall(
-#else /* XENHVM */
static inline int
HYPERVISOR_multicall(
-#endif
void *call_list, int nr_calls)
{
return _hypercall2(int, multicall, call_list, nr_calls);
diff --git a/sys/i386/include/xen/xen-os.h b/sys/i386/include/xen/xen-os.h
index 3d1ef049cca7..9b9b63ff0a58 100644
--- a/sys/i386/include/xen/xen-os.h
+++ b/sys/i386/include/xen/xen-os.h
@@ -44,105 +44,6 @@ static inline void rep_nop(void)
}
#define cpu_relax() rep_nop()
-#ifndef XENHVM
-
-#ifdef SMP
-extern int gdtset;
-
-#include <sys/time.h> /* XXX for pcpu.h */
-#include <sys/pcpu.h> /* XXX for PCPU_GET */
-static inline int
-smp_processor_id(void)
-{
- if (__predict_true(gdtset))
- return PCPU_GET(cpuid);
- return 0;
-}
-
-#else
-#define smp_processor_id() 0
-#endif
-
-#ifndef PANIC_IF
-#define PANIC_IF(exp) if (__predict_false(exp)) {printf("panic - %s: %s:%d\n",#exp, __FILE__, __LINE__); panic("%s: %s:%d", #exp, __FILE__, __LINE__);}
-#endif
-
-/*
- * Crude memory allocator for memory allocation early in boot.
- */
-void *bootmem_alloc(unsigned int size);
-void bootmem_free(void *ptr, unsigned int size);
-
-/*
- * STI/CLI equivalents. These basically set and clear the virtual
- * event_enable flag in the shared_info structure. Note that when
- * the enable bit is set, there may be pending events to be handled.
- * We may therefore call into do_hypervisor_callback() directly.
- */
-
-#define __cli() \
-do { \
- vcpu_info_t *_vcpu; \
- _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
- _vcpu->evtchn_upcall_mask = 1; \
- barrier(); \
-} while (0)
-
-#define __sti() \
-do { \
- vcpu_info_t *_vcpu; \
- barrier(); \
- _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
- _vcpu->evtchn_upcall_mask = 0; \
- barrier(); /* unmask then check (avoid races) */ \
- if (__predict_false(_vcpu->evtchn_upcall_pending)) \
- force_evtchn_callback(); \
-} while (0)
-
-#define __restore_flags(x) \
-do { \
- vcpu_info_t *_vcpu; \
- barrier(); \
- _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
- if ((_vcpu->evtchn_upcall_mask = (x)) == 0) { \
- barrier(); /* unmask then check (avoid races) */ \
- if (__predict_false(_vcpu->evtchn_upcall_pending)) \
- force_evtchn_callback(); \
- } \
-} while (0)
-
-/*
- * Add critical_{enter, exit}?
- *
- */
-#define __save_and_cli(x) \
-do { \
- vcpu_info_t *_vcpu; \
- _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
- (x) = _vcpu->evtchn_upcall_mask; \
- _vcpu->evtchn_upcall_mask = 1; \
- barrier(); \
-} while (0)
-
-
-#define cli() __cli()
-#define sti() __sti()
-#define save_flags(x) __save_flags(x)
-#define restore_flags(x) __restore_flags(x)
-#define save_and_cli(x) __save_and_cli(x)
-
-#define local_irq_save(x) __save_and_cli(x)
-#define local_irq_restore(x) __restore_flags(x)
-#define local_irq_disable() __cli()
-#define local_irq_enable() __sti()
-
-#define mtx_lock_irqsave(lock, x) {local_irq_save((x)); mtx_lock_spin((lock));}
-#define mtx_unlock_irqrestore(lock, x) {mtx_unlock_spin((lock)); local_irq_restore((x)); }
-#define spin_lock_irqsave mtx_lock_irqsave
-#define spin_unlock_irqrestore mtx_unlock_irqrestore
-
-#endif /* !XENHVM */
-
/* This is a barrier for the compiler only, NOT the processor! */
#define barrier() __asm__ __volatile__("": : :"memory")
diff --git a/sys/i386/include/xen/xenfunc.h b/sys/i386/include/xen/xenfunc.h
index f02ee1212e32..f48b1f14719d 100644
--- a/sys/i386/include/xen/xenfunc.h
+++ b/sys/i386/include/xen/xenfunc.h
@@ -34,7 +34,6 @@
#include <vm/pmap.h>
-#include <machine/xen/xenpmap.h>
#include <machine/segments.h>
#include <sys/pcpu.h>
diff --git a/sys/i386/include/xen/xenpmap.h b/sys/i386/include/xen/xenpmap.h
deleted file mode 100644
index 8287e723a7e9..000000000000
--- a/sys/i386/include/xen/xenpmap.h
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- *
- * Copyright (c) 2004 Christian Limpach.
- * Copyright (c) 2004,2005 Kip Macy
- * 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 Christian Limpach.
- * 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.
- *
- *
- * $FreeBSD$
- */
-
-#ifndef _XEN_XENPMAP_H_
-#define _XEN_XENPMAP_H_
-
-#if defined(XEN)
-void _xen_queue_pt_update(vm_paddr_t, vm_paddr_t, char *, int);
-void xen_pt_switch(vm_paddr_t);
-void xen_set_ldt(vm_paddr_t, unsigned long);
-void xen_pgdpt_pin(vm_paddr_t);
-void xen_pgd_pin(vm_paddr_t);
-void xen_pgd_unpin(vm_paddr_t);
-void xen_pt_pin(vm_paddr_t);
-void xen_pt_unpin(vm_paddr_t);
-void xen_flush_queue(void);
-void pmap_ref(pt_entry_t *pte, vm_paddr_t ma);
-void pmap_suspend(void);
-void pmap_resume(void);
-void xen_check_queue(void);
-
-#ifdef INVARIANTS
-#define xen_queue_pt_update(a, b) _xen_queue_pt_update((a), (b), __FILE__, __LINE__)
-#else
-#define xen_queue_pt_update(a, b) _xen_queue_pt_update((a), (b), NULL, 0)
-#endif
-
-
-#include <sys/param.h>
-#include <sys/pcpu.h>
-
-#ifdef PMAP_DEBUG
-#define PMAP_REF pmap_ref
-#define PMAP_DEC_REF_PAGE pmap_dec_ref_page
-#define PMAP_MARK_PRIV pmap_mark_privileged
-#define PMAP_MARK_UNPRIV pmap_mark_unprivileged
-#else
-#define PMAP_MARK_PRIV(a)
-#define PMAP_MARK_UNPRIV(a)
-#define PMAP_REF(a, b)
-#define PMAP_DEC_REF_PAGE(a)
-#endif
-
-#define ALWAYS_SYNC 0
-
-#ifdef PT_DEBUG
-#define PT_LOG() printk("WP PT_SET %s:%d\n", __FILE__, __LINE__)
-#else
-#define PT_LOG()
-#endif
-
-#define INVALID_P2M_ENTRY (~0UL)
-
-#define pmap_valid_entry(E) ((E) & PG_V) /* is PDE or PTE valid? */
-
-#define SH_PD_SET_VA 1
-#define SH_PD_SET_VA_MA 2
-#define SH_PD_SET_VA_CLEAR 3
-
-struct pmap;
-void pd_set(struct pmap *pmap, int ptepindex, vm_paddr_t val, int type);
-#ifdef notyet
-static vm_paddr_t
-vptetomachpte(vm_paddr_t *pte)
-{
- vm_offset_t offset, ppte;
- vm_paddr_t pgoffset, retval, *pdir_shadow_ptr;
- int pgindex;
-
- ppte = (vm_offset_t)pte;
- pgoffset = (ppte & PAGE_MASK);
- offset = ppte - (vm_offset_t)PTmap;
- pgindex = ppte >> PDRSHIFT;
-
- pdir_shadow_ptr = (vm_paddr_t *)PCPU_GET(pdir_shadow);
- retval = (pdir_shadow_ptr[pgindex] & ~PAGE_MASK) + pgoffset;
- return (retval);
-}
-#endif
-#define PT_GET(_ptp) \
- (pmap_valid_entry(*(_ptp)) ? xpmap_mtop(*(_ptp)) : (0))
-
-#ifdef WRITABLE_PAGETABLES
-
-#define PT_SET_VA(_ptp,_npte,sync) do { \
- PMAP_REF((_ptp), xpmap_ptom(_npte)); \
- PT_LOG(); \
- *(_ptp) = xpmap_ptom((_npte)); \
-} while (/*CONSTCOND*/0)
-#define PT_SET_VA_MA(_ptp,_npte,sync) do { \
- PMAP_REF((_ptp), (_npte)); \
- PT_LOG(); \
- *(_ptp) = (_npte); \
-} while (/*CONSTCOND*/0)
-#define PT_CLEAR_VA(_ptp, sync) do { \
- PMAP_REF((pt_entry_t *)(_ptp), 0); \
- PT_LOG(); \
- *(_ptp) = 0; \
-} while (/*CONSTCOND*/0)
-
-#define PD_SET_VA(_pmap, _ptp, _npte, sync) do { \
- PMAP_REF((_ptp), xpmap_ptom(_npte)); \
- pd_set((_pmap),(_ptp),(_npte), SH_PD_SET_VA); \
- if (sync || ALWAYS_SYNC) xen_flush_queue(); \
-} while (/*CONSTCOND*/0)
-#define PD_SET_VA_MA(_pmap, _ptp, _npte, sync) do { \
- PMAP_REF((_ptp), (_npte)); \
- pd_set((_pmap),(_ptp),(_npte), SH_PD_SET_VA_MA); \
- if (sync || ALWAYS_SYNC) xen_flush_queue(); \
-} while (/*CONSTCOND*/0)
-#define PD_CLEAR_VA(_pmap, _ptp, sync) do { \
- PMAP_REF((pt_entry_t *)(_ptp), 0); \
- pd_set((_pmap),(_ptp), 0, SH_PD_SET_VA_CLEAR); \
- if (sync || ALWAYS_SYNC) xen_flush_queue(); \
-} while (/*CONSTCOND*/0)
-
-#else /* !WRITABLE_PAGETABLES */
-
-#define PT_SET_VA(_ptp,_npte,sync) do { \
- PMAP_REF((_ptp), xpmap_ptom(_npte)); \
- xen_queue_pt_update(vtomach(_ptp), \
- xpmap_ptom(_npte)); \
- if (sync || ALWAYS_SYNC) xen_flush_queue(); \
-} while (/*CONSTCOND*/0)
-#define PT_SET_VA_MA(_ptp,_npte,sync) do { \
- PMAP_REF((_ptp), (_npte)); \
- xen_queue_pt_update(vtomach(_ptp), _npte); \
- if (sync || ALWAYS_SYNC) xen_flush_queue(); \
-} while (/*CONSTCOND*/0)
-#define PT_CLEAR_VA(_ptp, sync) do { \
- PMAP_REF((pt_entry_t *)(_ptp), 0); \
- xen_queue_pt_update(vtomach(_ptp), 0); \
- if (sync || ALWAYS_SYNC) \
- xen_flush_queue(); \
-} while (/*CONSTCOND*/0)
-
-#define PD_SET_VA(_pmap, _ptepindex,_npte,sync) do { \
- PMAP_REF((_ptp), xpmap_ptom(_npte)); \
- pd_set((_pmap),(_ptepindex),(_npte), SH_PD_SET_VA); \
- if (sync || ALWAYS_SYNC) xen_flush_queue(); \
-} while (/*CONSTCOND*/0)
-#define PD_SET_VA_MA(_pmap, _ptepindex,_npte,sync) do { \
- PMAP_REF((_ptp), (_npte)); \
- pd_set((_pmap),(_ptepindex),(_npte), SH_PD_SET_VA_MA); \
- if (sync || ALWAYS_SYNC) xen_flush_queue(); \
-} while (/*CONSTCOND*/0)
-#define PD_CLEAR_VA(_pmap, _ptepindex, sync) do { \
- PMAP_REF((pt_entry_t *)(_ptp), 0); \
- pd_set((_pmap),(_ptepindex), 0, SH_PD_SET_VA_CLEAR); \
- if (sync || ALWAYS_SYNC) xen_flush_queue(); \
-} while (/*CONSTCOND*/0)
-
-#endif
-
-#define PT_SET_MA(_va, _ma) \
-do { \
- PANIC_IF(HYPERVISOR_update_va_mapping(((unsigned long)(_va)),\
- (_ma), \
- UVMF_INVLPG| UVMF_ALL) < 0); \
-} while (/*CONSTCOND*/0)
-
-#define PT_UPDATES_FLUSH() do { \
- xen_flush_queue(); \
-} while (/*CONSTCOND*/0)
-
-static __inline vm_paddr_t
-xpmap_mtop(vm_paddr_t mpa)
-{
- vm_paddr_t tmp = (mpa & PG_FRAME);
-
- return machtophys(tmp) | (mpa & ~PG_FRAME);
-}
-
-static __inline vm_paddr_t
-xpmap_ptom(vm_paddr_t ppa)
-{
- vm_paddr_t tmp = (ppa & PG_FRAME);
-
- return phystomach(tmp) | (ppa & ~PG_FRAME);
-}
-
-static __inline void
-set_phys_to_machine(unsigned long pfn, unsigned long mfn)
-{
-#ifdef notyet
- PANIC_IF(max_mapnr && pfn >= max_mapnr);
-#endif
- if (xen_feature(XENFEAT_auto_translated_physmap)) {
-#ifdef notyet
- PANIC_IF((pfn != mfn && mfn != INVALID_P2M_ENTRY));
-#endif
- return;
- }
- xen_phys_machine[pfn] = mfn;
-}
-
-static __inline int
-phys_to_machine_mapping_valid(unsigned long pfn)
-{
- return xen_phys_machine[pfn] != INVALID_P2M_ENTRY;
-}
-
-#endif /* !XEN */
-
-#endif /* _XEN_XENPMAP_H_ */
diff --git a/sys/i386/include/xen/xenstored.h b/sys/i386/include/xen/xenstored.h
deleted file mode 100644
index e584fa523e39..000000000000
--- a/sys/i386/include/xen/xenstored.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Simple prototyle Xen Store Daemon providing simple tree-like database.
- * Copyright (C) 2005 Rusty Russell IBM Corporation
- *
- * This file may be distributed separately from the Linux kernel, or
- * incorporated into other software packages, subject to the following license:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this source file (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy, modify,
- * merge, publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#ifndef _XENSTORED_H
-#define _XENSTORED_H
-
-enum xsd_sockmsg_type
-{
- XS_DEBUG,
- XS_SHUTDOWN,
- XS_DIRECTORY,
- XS_READ,
- XS_GET_PERMS,
- XS_WATCH,
- XS_WATCH_ACK,
- XS_UNWATCH,
- XS_TRANSACTION_START,
- XS_TRANSACTION_END,
- XS_OP_READ_ONLY = XS_TRANSACTION_END,
- XS_INTRODUCE,
- XS_RELEASE,
- XS_GETDOMAINPATH,
- XS_WRITE,
- XS_MKDIR,
- XS_RM,
- XS_SET_PERMS,
- XS_WATCH_EVENT,
- XS_ERROR,
-};
-
-#define XS_WRITE_NONE "NONE"
-#define XS_WRITE_CREATE "CREATE"
-#define XS_WRITE_CREATE_EXCL "CREATE|EXCL"
-
-/* We hand errors as strings, for portability. */
-struct xsd_errors
-{
- int errnum;
- const char *errstring;
-};
-#define XSD_ERROR(x) { x, #x }
-static struct xsd_errors xsd_errors[] __attribute__((unused)) = {
- XSD_ERROR(EINVAL),
- XSD_ERROR(EACCES),
- XSD_ERROR(EEXIST),
- XSD_ERROR(EISDIR),
- XSD_ERROR(ENOENT),
- XSD_ERROR(ENOMEM),
- XSD_ERROR(ENOSPC),
- XSD_ERROR(EIO),
- XSD_ERROR(ENOTEMPTY),
- XSD_ERROR(ENOSYS),
- XSD_ERROR(EROFS),
- XSD_ERROR(EBUSY),
- XSD_ERROR(ETIMEDOUT),
- XSD_ERROR(EISCONN),
-};
-struct xsd_sockmsg
-{
- uint32_t type;
- uint32_t len; /* Length of data following this. */
-
- /* Generally followed by nul-terminated string(s). */
-};
-
-#endif /* _XENSTORED_H */
diff --git a/sys/i386/include/xen/xenvar.h b/sys/i386/include/xen/xenvar.h
index 569460723240..484c279c0ff1 100644
--- a/sys/i386/include/xen/xenvar.h
+++ b/sys/i386/include/xen/xenvar.h
@@ -29,91 +29,8 @@
#ifndef XENVAR_H_
#define XENVAR_H_
-#include <machine/xen/features.h>
-
-#if defined(XEN)
-
-#define XBOOTUP 0x1
-#define XPMAP 0x2
-extern int xendebug_flags;
-#ifndef NOXENDEBUG
-/* Print directly to the Xen console during debugging. */
-#define XENPRINTF xc_printf
-#else
-#define XENPRINTF printf
-#endif
-
-extern xen_pfn_t *xen_phys_machine;
-extern xen_pfn_t *xen_pfn_to_mfn_frame_list[16];
-extern xen_pfn_t *xen_pfn_to_mfn_frame_list_list;
-
-#if 0
-#define TRACE_ENTER XENPRINTF("(file=%s, line=%d) entered %s\n", __FILE__, __LINE__, __FUNCTION__)
-#define TRACE_EXIT XENPRINTF("(file=%s, line=%d) exiting %s\n", __FILE__, __LINE__, __FUNCTION__)
-#define TRACE_DEBUG(argflags, _f, _a...) \
-if (xendebug_flags & argflags) XENPRINTF("(file=%s, line=%d) " _f "\n", __FILE__, __LINE__, ## _a);
-#else
-#define TRACE_ENTER
-#define TRACE_EXIT
-#define TRACE_DEBUG(argflags, _f, _a...)
-#endif
-
-extern xen_pfn_t *xen_machine_phys;
-/* Xen starts physical pages after the 4MB ISA hole -
- * FreeBSD doesn't
- */
-
-
-#undef ADD_ISA_HOLE /* XXX */
-
-#ifdef ADD_ISA_HOLE
-#define ISA_INDEX_OFFSET 1024
-#define ISA_PDR_OFFSET 1
-#else
-#define ISA_INDEX_OFFSET 0
-#define ISA_PDR_OFFSET 0
-#endif
-
-
-#define PFNTOMFN(i) (xen_phys_machine[(i)])
-#define MFNTOPFN(i) ((vm_paddr_t)xen_machine_phys[(i)])
-
-#define VTOP(x) ((((uintptr_t)(x))) - KERNBASE)
-#define PTOV(x) (((uintptr_t)(x)) + KERNBASE)
-
-#define VTOPFN(x) (VTOP(x) >> PAGE_SHIFT)
-#define PFNTOV(x) PTOV((vm_paddr_t)(x) << PAGE_SHIFT)
-
-#define VTOMFN(va) (vtomach(va) >> PAGE_SHIFT)
-#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
-
-#define phystomach(pa) (((vm_paddr_t)(PFNTOMFN((pa) >> PAGE_SHIFT))) << PAGE_SHIFT)
-#define machtophys(ma) (((vm_paddr_t)(MFNTOPFN((ma) >> PAGE_SHIFT))) << PAGE_SHIFT)
-
-
-void xpq_init(void);
-
-#define BITS_PER_LONG 32
-#define NR_CPUS XEN_LEGACY_MAX_VCPUS
-
-#define BITS_TO_LONGS(bits) \
- (((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)
-#define DECLARE_BITMAP(name,bits) \
- unsigned long name[BITS_TO_LONGS(bits)]
-
-int xen_create_contiguous_region(vm_page_t pages, int npages);
-
-void xen_destroy_contiguous_region(void * addr, int npages);
-
-#elif defined(XENHVM)
+#include <xen/features.h>
#define vtomach(va) pmap_kextract((vm_offset_t) (va))
-#define PFNTOMFN(pa) (pa)
-#define MFNTOPFN(ma) (ma)
-
-#define set_phys_to_machine(pfn, mfn) ((void)0)
-#define phys_to_machine_mapping_valid(pfn) (TRUE)
-
-#endif /* !XEN && !XENHVM */
#endif
diff --git a/sys/i386/isa/npx.c b/sys/i386/isa/npx.c
index b0ea4e762474..a7113e20da27 100644
--- a/sys/i386/isa/npx.c
+++ b/sys/i386/isa/npx.c
@@ -69,10 +69,6 @@ __FBSDID("$FreeBSD$");
#include <machine/ucontext.h>
#include <machine/intr_machdep.h>
-#ifdef XEN
-#include <xen/xen-os.h>
-#include <xen/hypervisor.h>
-#endif
#ifdef DEV_ISA
#include <isa/isavar.h>
@@ -157,13 +153,8 @@ void xsaveopt(char *addr, uint64_t mask);
#endif /* __GNUCLIKE_ASM && !lint */
-#ifdef XEN
-#define start_emulating() (HYPERVISOR_fpu_taskswitch(1))
-#define stop_emulating() (HYPERVISOR_fpu_taskswitch(0))
-#else
#define start_emulating() load_cr0(rcr0() | CR0_TS)
#define stop_emulating() clts()
-#endif
#ifdef CPU_ENABLE_SSE
#define GET_FPU_CW(thread) \
diff --git a/sys/i386/pci/pci_cfgreg.c b/sys/i386/pci/pci_cfgreg.c
index 5d57e89334a1..2716a7a23ce6 100644
--- a/sys/i386/pci/pci_cfgreg.c
+++ b/sys/i386/pci/pci_cfgreg.c
@@ -93,9 +93,7 @@ static uint32_t pci_docfgregread(int bus, int slot, int func, int reg,
int bytes);
static int pcireg_cfgread(int bus, int slot, int func, int reg, int bytes);
static void pcireg_cfgwrite(int bus, int slot, int func, int reg, int data, int bytes);
-#ifndef XEN
static int pcireg_cfgopen(void);
-#endif
static int pciereg_cfgread(int bus, unsigned slot, unsigned func,
unsigned reg, unsigned bytes);
static void pciereg_cfgwrite(int bus, unsigned slot, unsigned func,
@@ -116,7 +114,6 @@ pci_i386_map_intline(int line)
return (line);
}
-#ifndef XEN
static u_int16_t
pcibios_get_version(void)
{
@@ -137,7 +134,6 @@ pcibios_get_version(void)
}
return (args.ebx & 0xffff);
}
-#endif
/*
* Initialise access to PCI configuration space
@@ -145,9 +141,6 @@ pcibios_get_version(void)
int
pci_cfgregopen(void)
{
-#ifdef XEN
- return (0);
-#else
static int opened = 0;
uint64_t pciebar;
u_int16_t vid, did;
@@ -202,7 +195,6 @@ pci_cfgregopen(void)
}
return(1);
-#endif
}
static uint32_t
@@ -390,7 +382,6 @@ pcireg_cfgwrite(int bus, int slot, int func, int reg, int data, int bytes)
mtx_unlock_spin(&pcicfg_mtx);
}
-#ifndef XEN
/* check whether the configuration mechanism has been correctly identified */
static int
pci_cfgcheck(int maxdev)
@@ -607,7 +598,6 @@ pcie_cfgregopen(uint64_t base, uint8_t minbus, uint8_t maxbus)
return (1);
}
-#endif /* !XEN */
#define PCIE_PADDR(base, reg, bus, slot, func) \
((base) + \
diff --git a/sys/i386/pci/pci_pir.c b/sys/i386/pci/pci_pir.c
index 0d64cabf4aab..6aeaae3502be 100644
--- a/sys/i386/pci/pci_pir.c
+++ b/sys/i386/pci/pci_pir.c
@@ -137,9 +137,6 @@ pci_pir_open(void)
int i;
uint8_t ck, *cv;
-#ifdef XEN
- return;
-#else
/* Don't try if we've already found a table. */
if (pci_route_table != NULL)
return;
@@ -150,7 +147,7 @@ pci_pir_open(void)
sigaddr = bios_sigsearch(0, "_PIR", 4, 16, 0);
if (sigaddr == 0)
return;
-#endif
+
/* If we found something, check the checksum and length. */
/* XXX - Use pmap_mapdev()? */
pt = (struct PIR_table *)(uintptr_t)BIOS_PADDRTOVADDR(sigaddr);
@@ -481,11 +478,7 @@ pci_pir_biosroute(int bus, int device, int func, int pin, int irq)
args.eax = PCIBIOS_ROUTE_INTERRUPT;
args.ebx = (bus << 8) | (device << 3) | func;
args.ecx = (irq << 8) | (0xa + pin);
-#ifdef XEN
- return (0);
-#else
return (bios32(&args, PCIbios.ventry, GSEL(GCODE_SEL, SEL_KPL)));
-#endif
}
diff --git a/sys/i386/xen/clock.c b/sys/i386/xen/clock.c
deleted file mode 100644
index ffb436e4d15d..000000000000
--- a/sys/i386/xen/clock.c
+++ /dev/null
@@ -1,570 +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
- * William Jolitz and Don Ahn.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)clock.c 7.2 (Berkeley) 5/12/91
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/* #define DELAYDEBUG */
-/*
- * Routines to handle clock hardware.
- */
-
-#include "opt_ddb.h"
-#include "opt_clock.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/clock.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/proc.h>
-#include <sys/time.h>
-#include <sys/timeet.h>
-#include <sys/timetc.h>
-#include <sys/kernel.h>
-#include <sys/limits.h>
-#include <sys/sysctl.h>
-#include <sys/cons.h>
-#include <sys/power.h>
-
-#include <machine/clock.h>
-#include <machine/cputypes.h>
-#include <machine/frame.h>
-#include <machine/intr_machdep.h>
-#include <machine/md_var.h>
-#include <machine/psl.h>
-#include <machine/pvclock.h>
-#if defined(SMP)
-#include <machine/smp.h>
-#endif
-#include <machine/specialreg.h>
-#include <machine/timerreg.h>
-
-#include <x86/isa/icu.h>
-#include <isa/isareg.h>
-#include <isa/rtc.h>
-
-#include <vm/vm.h>
-#include <vm/pmap.h>
-#include <machine/pmap.h>
-#include <xen/hypervisor.h>
-#include <xen/xen-os.h>
-#include <machine/xen/xenfunc.h>
-#include <xen/interface/vcpu.h>
-#include <machine/cpu.h>
-#include <xen/xen_intr.h>
-
-/*
- * 32-bit time_t's can't reach leap years before 1904 or after 2036, so we
- * can use a simple formula for leap years.
- */
-#define LEAPYEAR(y) (!((y) % 4))
-#define DAYSPERYEAR (28+30*4+31*7)
-
-#ifndef TIMER_FREQ
-#define TIMER_FREQ 1193182
-#endif
-
-#ifdef CYC2NS_SCALE_FACTOR
-#undef CYC2NS_SCALE_FACTOR
-#endif
-#define CYC2NS_SCALE_FACTOR 10
-
-/* Values for timerX_state: */
-#define RELEASED 0
-#define RELEASE_PENDING 1
-#define ACQUIRED 2
-#define ACQUIRE_PENDING 3
-
-struct mtx clock_lock;
-#define RTC_LOCK_INIT \
- mtx_init(&clock_lock, "clk", NULL, MTX_SPIN | MTX_NOPROFILE)
-#define RTC_LOCK mtx_lock_spin(&clock_lock)
-#define RTC_UNLOCK mtx_unlock_spin(&clock_lock)
-#define NS_PER_TICK (1000000000ULL/hz)
-
-int adjkerntz; /* local offset from UTC in seconds */
-int clkintr_pending;
-int pscnt = 1;
-int psdiv = 1;
-int wall_cmos_clock;
-u_int timer_freq = TIMER_FREQ;
-static u_long cyc2ns_scale;
-static uint64_t processed_system_time; /* stime (ns) at last processing. */
-
-#define do_div(n,base) ({ \
- unsigned long __upper, __low, __high, __mod, __base; \
- __base = (base); \
- __asm("":"=a" (__low), "=d" (__high):"A" (n)); \
- __upper = __high; \
- if (__high) { \
- __upper = __high % (__base); \
- __high = __high / (__base); \
- } \
- __asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (__base), "0" (__low), "1" (__upper)); \
- __asm("":"=A" (n):"a" (__low),"d" (__high)); \
- __mod; \
-})
-
-
-/* convert from cycles(64bits) => nanoseconds (64bits)
- * basic equation:
- * ns = cycles / (freq / ns_per_sec)
- * ns = cycles * (ns_per_sec / freq)
- * ns = cycles * (10^9 / (cpu_mhz * 10^6))
- * ns = cycles * (10^3 / cpu_mhz)
- *
- * Then we use scaling math (suggested by george@mvista.com) to get:
- * ns = cycles * (10^3 * SC / cpu_mhz) / SC
- * ns = cycles * cyc2ns_scale / SC
- *
- * And since SC is a constant power of two, we can convert the div
- * into a shift.
- * -johnstul@us.ibm.com "math is hard, lets go shopping!"
- */
-static inline void set_cyc2ns_scale(unsigned long cpu_mhz)
-{
- cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz;
-}
-
-static inline unsigned long long cycles_2_ns(unsigned long long cyc)
-{
- return ((cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR);
-}
-
-static uint32_t
-getit(void)
-{
- return (pvclock_get_last_cycles());
-}
-
-
-/*
- * XXX: timer needs more SMP work.
- */
-void
-i8254_init(void)
-{
-
- RTC_LOCK_INIT;
-}
-
-/*
- * Wait "n" microseconds.
- * Relies on timer 1 counting down from (timer_freq / hz)
- * Note: timer had better have been programmed before this is first used!
- */
-void
-i8254_delay(int n)
-{
- int delta, ticks_left;
- uint32_t tick, prev_tick;
-#ifdef DELAYDEBUG
- int getit_calls = 1;
- int n1;
- static int state = 0;
-
- if (state == 0) {
- state = 1;
- for (n1 = 1; n1 <= 10000000; n1 *= 10)
- DELAY(n1);
- state = 2;
- }
- if (state == 1)
- printf("DELAY(%d)...", n);
-#endif
- /*
- * Read the counter first, so that the rest of the setup overhead is
- * counted. Guess the initial overhead is 20 usec (on most systems it
- * takes about 1.5 usec for each of the i/o's in getit(). The loop
- * takes about 6 usec on a 486/33 and 13 usec on a 386/20. The
- * multiplications and divisions to scale the count take a while).
- *
- * However, if ddb is active then use a fake counter since reading
- * the i8254 counter involves acquiring a lock. ddb must not go
- * locking for many reasons, but it calls here for at least atkbd
- * input.
- */
- prev_tick = getit();
-
- n -= 0; /* XXX actually guess no initial overhead */
- /*
- * Calculate (n * (timer_freq / 1e6)) without using floating point
- * and without any avoidable overflows.
- */
- if (n <= 0)
- ticks_left = 0;
- else if (n < 256)
- /*
- * Use fixed point to avoid a slow division by 1000000.
- * 39099 = 1193182 * 2^15 / 10^6 rounded to nearest.
- * 2^15 is the first power of 2 that gives exact results
- * for n between 0 and 256.
- */
- ticks_left = ((u_int)n * 39099 + (1 << 15) - 1) >> 15;
- else
- /*
- * Don't bother using fixed point, although gcc-2.7.2
- * generates particularly poor code for the long long
- * division, since even the slow way will complete long
- * before the delay is up (unless we're interrupted).
- */
- ticks_left = ((u_int)n * (long long)timer_freq + 999999)
- / 1000000;
-
- while (ticks_left > 0) {
- tick = getit();
-#ifdef DELAYDEBUG
- ++getit_calls;
-#endif
- delta = tick - prev_tick;
- prev_tick = tick;
- if (delta < 0) {
- /*
- * Guard against timer0_max_count being wrong.
- * This shouldn't happen in normal operation,
- * but it may happen if set_timer_freq() is
- * traced.
- */
- /* delta += timer0_max_count; ??? */
- if (delta < 0)
- delta = 0;
- }
- ticks_left -= delta;
- }
-#ifdef DELAYDEBUG
- if (state == 1)
- printf(" %d calls to getit() at %d usec each\n",
- getit_calls, (n + 5) / getit_calls);
-#endif
-}
-
-void
-startrtclock()
-{
- uint64_t __cpu_khz;
- uint32_t cpu_khz;
- struct vcpu_time_info *info;
-
- __cpu_khz = 1000000ULL << 32;
- info = &HYPERVISOR_shared_info->vcpu_info[0].time;
-
- (void)do_div(__cpu_khz, info->tsc_to_system_mul);
- if ( info->tsc_shift < 0 )
- cpu_khz = __cpu_khz << -info->tsc_shift;
- else
- cpu_khz = __cpu_khz >> info->tsc_shift;
-
- printf("Xen reported: %u.%03u MHz processor.\n",
- cpu_khz / 1000, cpu_khz % 1000);
-
- /* (10^6 * 2^32) / cpu_hz = (10^3 * 2^32) / cpu_khz =
- (2^32 * 1 / (clocks/us)) */
-
- set_cyc2ns_scale(cpu_khz/1000);
- tsc_freq = cpu_khz * 1000;
-}
-
-/*
- * RTC support routines
- */
-
-
-static __inline int
-readrtc(int port)
-{
- return(bcd2bin(rtcin(port)));
-}
-
-
-#ifdef XEN_PRIVILEGED_GUEST
-
-/*
- * Initialize the time of day register, based on the time base which is, e.g.
- * from a filesystem.
- */
-static void
-domu_inittodr(time_t base)
-{
- unsigned long sec;
- int s, y;
- struct timespec ts;
-
- update_wallclock();
- add_uptime_to_wallclock();
-
- RTC_LOCK;
-
- if (base) {
- ts.tv_sec = base;
- ts.tv_nsec = 0;
- tc_setclock(&ts);
- }
-
- sec += tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
-
- y = time_second - shadow_tv.tv_sec;
- if (y <= -2 || y >= 2) {
- /* badly off, adjust it */
- tc_setclock(&shadow_tv);
- }
- RTC_UNLOCK;
-}
-
-/*
- * Write system time back to RTC.
- */
-static void
-domu_resettodr(void)
-{
- unsigned long tm;
- int s;
- dom0_op_t op;
- struct shadow_time_info *shadow;
- struct pcpu *pc;
-
- pc = pcpu_find(smp_processor_id());
- shadow = &pc->pc_shadow_time;
- if (xen_disable_rtc_set)
- return;
-
- s = splclock();
- tm = time_second;
- splx(s);
-
- tm -= tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
-
- if ((xen_start_info->flags & SIF_INITDOMAIN) &&
- !independent_wallclock)
- {
- op.cmd = DOM0_SETTIME;
- op.u.settime.secs = tm;
- op.u.settime.nsecs = 0;
- op.u.settime.system_time = shadow->system_timestamp;
- HYPERVISOR_dom0_op(&op);
- update_wallclock();
- add_uptime_to_wallclock();
- } else if (independent_wallclock) {
- /* notyet */
- ;
- }
-}
-
-/*
- * Initialize the time of day register, based on the time base which is, e.g.
- * from a filesystem.
- */
-void
-inittodr(time_t base)
-{
- unsigned long sec, days;
- int year, month;
- int y, m, s;
- struct timespec ts;
-
- if (!(xen_start_info->flags & SIF_INITDOMAIN)) {
- domu_inittodr(base);
- return;
- }
-
- if (base) {
- s = splclock();
- ts.tv_sec = base;
- ts.tv_nsec = 0;
- tc_setclock(&ts);
- splx(s);
- }
-
- /* Look if we have a RTC present and the time is valid */
- if (!(rtcin(RTC_STATUSD) & RTCSD_PWR))
- goto wrong_time;
-
- /* wait for time update to complete */
- /* If RTCSA_TUP is zero, we have at least 244us before next update */
- s = splhigh();
- while (rtcin(RTC_STATUSA) & RTCSA_TUP) {
- splx(s);
- s = splhigh();
- }
-
- days = 0;
-#ifdef USE_RTC_CENTURY
- year = readrtc(RTC_YEAR) + readrtc(RTC_CENTURY) * 100;
-#else
- year = readrtc(RTC_YEAR) + 1900;
- if (year < 1970)
- year += 100;
-#endif
- if (year < 1970) {
- splx(s);
- goto wrong_time;
- }
- month = readrtc(RTC_MONTH);
- for (m = 1; m < month; m++)
- days += daysinmonth[m-1];
- if ((month > 2) && LEAPYEAR(year))
- days ++;
- days += readrtc(RTC_DAY) - 1;
- for (y = 1970; y < year; y++)
- days += DAYSPERYEAR + LEAPYEAR(y);
- sec = ((( days * 24 +
- readrtc(RTC_HRS)) * 60 +
- readrtc(RTC_MIN)) * 60 +
- readrtc(RTC_SEC));
- /* sec now contains the number of seconds, since Jan 1 1970,
- in the local time zone */
-
- sec += tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
-
- y = time_second - sec;
- if (y <= -2 || y >= 2) {
- /* badly off, adjust it */
- ts.tv_sec = sec;
- ts.tv_nsec = 0;
- tc_setclock(&ts);
- }
- splx(s);
- return;
-
- wrong_time:
- printf("Invalid time in real time clock.\n");
- printf("Check and reset the date immediately!\n");
-}
-
-
-/*
- * Write system time back to RTC
- */
-void
-resettodr()
-{
- unsigned long tm;
- int y, m, s;
-
- if (!(xen_start_info->flags & SIF_INITDOMAIN)) {
- domu_resettodr();
- return;
- }
-
- if (xen_disable_rtc_set)
- return;
-
- s = splclock();
- tm = time_second;
- splx(s);
-
- /* Disable RTC updates and interrupts. */
- writertc(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR);
-
- /* Calculate local time to put in RTC */
-
- tm -= tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
-
- writertc(RTC_SEC, bin2bcd(tm%60)); tm /= 60; /* Write back Seconds */
- writertc(RTC_MIN, bin2bcd(tm%60)); tm /= 60; /* Write back Minutes */
- writertc(RTC_HRS, bin2bcd(tm%24)); tm /= 24; /* Write back Hours */
-
- /* We have now the days since 01-01-1970 in tm */
- writertc(RTC_WDAY, (tm + 4) % 7 + 1); /* Write back Weekday */
- for (y = 1970, m = DAYSPERYEAR + LEAPYEAR(y);
- tm >= m;
- y++, m = DAYSPERYEAR + LEAPYEAR(y))
- tm -= m;
-
- /* Now we have the years in y and the day-of-the-year in tm */
- writertc(RTC_YEAR, bin2bcd(y%100)); /* Write back Year */
-#ifdef USE_RTC_CENTURY
- writertc(RTC_CENTURY, bin2bcd(y/100)); /* ... and Century */
-#endif
- for (m = 0; ; m++) {
- int ml;
-
- ml = daysinmonth[m];
- if (m == 1 && LEAPYEAR(y))
- ml++;
- if (tm < ml)
- break;
- tm -= ml;
- }
-
- writertc(RTC_MONTH, bin2bcd(m + 1)); /* Write back Month */
- writertc(RTC_DAY, bin2bcd(tm + 1)); /* Write back Month Day */
-
- /* Reenable RTC updates and interrupts. */
- writertc(RTC_STATUSB, RTCSB_24HR);
- rtcin(RTC_INTR);
-}
-#endif
-
-/*
- * Start clocks running.
- */
-void
-cpu_initclocks(void)
-{
- cpu_initclocks_bsp();
-}
-
-/* Return system time offset by ticks */
-uint64_t
-get_system_time(int ticks)
-{
- return (processed_system_time + (ticks * NS_PER_TICK));
-}
-
-int
-timer_spkr_acquire(void)
-{
-
- return (0);
-}
-
-int
-timer_spkr_release(void)
-{
-
- return (0);
-}
-
-void
-timer_spkr_setfreq(int freq)
-{
-
-}
-
diff --git a/sys/i386/xen/exception.s b/sys/i386/xen/exception.s
deleted file mode 100644
index 95f1c0e6703f..000000000000
--- a/sys/i386/xen/exception.s
+++ /dev/null
@@ -1,494 +0,0 @@
-/*-
- * Copyright (c) 1989, 1990 William F. Jolitz.
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include "opt_apic.h"
-#include "opt_npx.h"
-
-#include <machine/asmacros.h>
-#include <machine/psl.h>
-#include <machine/trap.h>
-
-#include "assym.s"
-
-#define SEL_RPL_MASK 0x0002
-#define __HYPERVISOR_iret 23
-
-/* Offsets into shared_info_t. */
-
-#define evtchn_upcall_pending /* 0 */
-#define evtchn_upcall_mask 1
-
-#define sizeof_vcpu_shift 6
-
-
-#ifdef SMP
-#define GET_VCPU_INFO(reg) movl PCPU(CPUID),reg ; \
- shl $sizeof_vcpu_shift,reg ; \
- addl HYPERVISOR_shared_info,reg
-#else
-#define GET_VCPU_INFO(reg) movl HYPERVISOR_shared_info,reg
-#endif
-
-#define __DISABLE_INTERRUPTS(reg) movb $1,evtchn_upcall_mask(reg)
-#define __ENABLE_INTERRUPTS(reg) movb $0,evtchn_upcall_mask(reg)
-#define DISABLE_INTERRUPTS(reg) GET_VCPU_INFO(reg) ; \
- __DISABLE_INTERRUPTS(reg)
-#define ENABLE_INTERRUPTS(reg) GET_VCPU_INFO(reg) ; \
- __ENABLE_INTERRUPTS(reg)
-#define __TEST_PENDING(reg) testb $0xFF,evtchn_upcall_pending(reg)
-
-#define POPA \
- popl %edi; \
- popl %esi; \
- popl %ebp; \
- popl %ebx; \
- popl %ebx; \
- popl %edx; \
- popl %ecx; \
- popl %eax;
-
- .text
-
-/*****************************************************************************/
-/* Trap handling */
-/*****************************************************************************/
-/*
- * Trap and fault vector routines.
- *
- * Most traps are 'trap gates', SDT_SYS386TGT. A trap gate pushes state on
- * the stack that mostly looks like an interrupt, but does not disable
- * interrupts. A few of the traps we are use are interrupt gates,
- * SDT_SYS386IGT, which are nearly the same thing except interrupts are
- * disabled on entry.
- *
- * The cpu will push a certain amount of state onto the kernel stack for
- * the current process. The amount of state depends on the type of trap
- * and whether the trap crossed rings or not. See i386/include/frame.h.
- * At the very least the current EFLAGS (status register, which includes
- * the interrupt disable state prior to the trap), the code segment register,
- * and the return instruction pointer are pushed by the cpu. The cpu
- * will also push an 'error' code for certain traps. We push a dummy
- * error code for those traps where the cpu doesn't in order to maintain
- * a consistent frame. We also push a contrived 'trap number'.
- *
- * The cpu does not push the general registers, we must do that, and we
- * must restore them prior to calling 'iret'. The cpu adjusts the %cs and
- * %ss segment registers, but does not mess with %ds, %es, or %fs. Thus we
- * must load them with appropriate values for supervisor mode operation.
- */
-
-MCOUNT_LABEL(user)
-MCOUNT_LABEL(btrap)
-
-#define TRAP(a) pushl $(a) ; jmp alltraps
-
-IDTVEC(div)
- pushl $0; TRAP(T_DIVIDE)
-IDTVEC(dbg)
- pushl $0; TRAP(T_TRCTRAP)
-IDTVEC(nmi)
- pushl $0; TRAP(T_NMI)
-IDTVEC(bpt)
- pushl $0; TRAP(T_BPTFLT)
-IDTVEC(ofl)
- pushl $0; TRAP(T_OFLOW)
-IDTVEC(bnd)
- pushl $0; TRAP(T_BOUND)
-IDTVEC(ill)
- pushl $0; TRAP(T_PRIVINFLT)
-IDTVEC(dna)
- pushl $0; TRAP(T_DNA)
-IDTVEC(fpusegm)
- pushl $0; TRAP(T_FPOPFLT)
-IDTVEC(tss)
- TRAP(T_TSSFLT)
-IDTVEC(missing)
- TRAP(T_SEGNPFLT)
-IDTVEC(stk)
- TRAP(T_STKFLT)
-IDTVEC(prot)
- TRAP(T_PROTFLT)
-IDTVEC(page)
- TRAP(T_PAGEFLT)
-IDTVEC(mchk)
- pushl $0; TRAP(T_MCHK)
-IDTVEC(rsvd)
- pushl $0; TRAP(T_RESERVED)
-IDTVEC(fpu)
- pushl $0; TRAP(T_ARITHTRAP)
-IDTVEC(align)
- TRAP(T_ALIGNFLT)
-IDTVEC(xmm)
- pushl $0; TRAP(T_XMMFLT)
-
-IDTVEC(hypervisor_callback)
- pushl $0;
- pushl $0;
- pushal
- pushl %ds
- pushl %es
- pushl %fs
-upcall_with_regs_pushed:
- SET_KERNEL_SREGS
- FAKE_MCOUNT(TF_EIP(%esp))
-call_evtchn_upcall:
- movl TF_EIP(%esp),%eax
- cmpl $scrit,%eax
- jb 10f
- cmpl $ecrit,%eax
- jb critical_region_fixup
-
-10: pushl %esp
- call xen_intr_handle_upcall
- addl $4,%esp
-
- /*
- * Return via doreti to handle ASTs.
- */
- MEXITCOUNT
- jmp doreti
-
-
-hypervisor_callback_pending:
- DISABLE_INTERRUPTS(%esi) /* cli */
- jmp 10b
- /*
- * alltraps entry point. Interrupts are enabled if this was a trap
- * gate (TGT), else disabled if this was an interrupt gate (IGT).
- * Note that int0x80_syscall is a trap gate. Only page faults
- * use an interrupt gate.
- */
- SUPERALIGN_TEXT
- .globl alltraps
- .type alltraps,@function
-alltraps:
- pushal
- pushl %ds
- pushl %es
- pushl %fs
-
-alltraps_with_regs_pushed:
- SET_KERNEL_SREGS
- FAKE_MCOUNT(TF_EIP(%esp))
-
-calltrap:
- push %esp
- call trap
- add $4, %esp
-
- /*
- * Return via doreti to handle ASTs.
- */
- MEXITCOUNT
- jmp doreti
-
-/*
- * SYSCALL CALL GATE (old entry point for a.out binaries)
- *
- * The intersegment call has been set up to specify one dummy parameter.
- *
- * This leaves a place to put eflags so that the call frame can be
- * converted to a trap frame. Note that the eflags is (semi-)bogusly
- * pushed into (what will be) tf_err and then copied later into the
- * final spot. It has to be done this way because esp can't be just
- * temporarily altered for the pushfl - an interrupt might come in
- * and clobber the saved cs/eip.
- */
- SUPERALIGN_TEXT
-IDTVEC(lcall_syscall)
- pushfl /* save eflags */
- popl 8(%esp) /* shuffle into tf_eflags */
- pushl $7 /* sizeof "lcall 7,0" */
- subl $4,%esp /* skip over tf_trapno */
- pushal
- pushl %ds
- pushl %es
- pushl %fs
- SET_KERNEL_SREGS
- FAKE_MCOUNT(TF_EIP(%esp))
- pushl %esp
- call syscall
- add $4, %esp
- MEXITCOUNT
- jmp doreti
-
-/*
- * Call gate entry for FreeBSD ELF and Linux/NetBSD syscall (int 0x80)
- *
- * Even though the name says 'int0x80', this is actually a TGT (trap gate)
- * rather then an IGT (interrupt gate). Thus interrupts are enabled on
- * entry just as they are for a normal syscall.
- */
- SUPERALIGN_TEXT
-IDTVEC(int0x80_syscall)
- pushl $2 /* sizeof "int 0x80" */
- pushl $0xBEEF /* for debug */
- pushal
- pushl %ds
- pushl %es
- pushl %fs
- SET_KERNEL_SREGS
- FAKE_MCOUNT(TF_EIP(%esp))
- pushl %esp
- call syscall
- add $4, %esp
- MEXITCOUNT
- jmp doreti
-
-ENTRY(fork_trampoline)
- pushl %esp /* trapframe pointer */
- pushl %ebx /* arg1 */
- pushl %esi /* function */
- call fork_exit
- addl $12,%esp
- /* cut from syscall */
-
- /*
- * Return via doreti to handle ASTs.
- */
- MEXITCOUNT
- jmp doreti
-
-
-/*
- * To efficiently implement classification of trap and interrupt handlers
- * for profiling, there must be only trap handlers between the labels btrap
- * and bintr, and only interrupt handlers between the labels bintr and
- * eintr. This is implemented (partly) by including files that contain
- * some of the handlers. Before including the files, set up a normal asm
- * environment so that the included files doen't need to know that they are
- * included.
- */
-
- .data
- .p2align 4
- .text
- SUPERALIGN_TEXT
-MCOUNT_LABEL(bintr)
-
-#ifdef DEV_APIC
- .data
- .p2align 4
- .text
- SUPERALIGN_TEXT
-
-#include <i386/i386/apic_vector.s>
-#endif
-
- .data
- .p2align 4
- .text
- SUPERALIGN_TEXT
-#include <i386/i386/vm86bios.s>
-
- .text
-MCOUNT_LABEL(eintr)
-
-/*
- * void doreti(struct trapframe)
- *
- * Handle return from interrupts, traps and syscalls.
- */
- .text
- SUPERALIGN_TEXT
- .type doreti,@function
-doreti:
- FAKE_MCOUNT($bintr) /* init "from" bintr -> doreti */
-doreti_next:
-#ifdef notyet
- /*
- * Check if ASTs can be handled now. PSL_VM must be checked first
- * since segment registers only have an RPL in non-VM86 mode.
- */
- testl $PSL_VM,TF_EFLAGS(%esp) /* are we in vm86 mode? */
- jz doreti_notvm86
- movl PCPU(CURPCB),%ecx
- testl $PCB_VM86CALL,PCB_FLAGS(%ecx) /* are we in a vm86 call? */
- jz doreti_ast /* can handle ASTS now if not */
- jmp doreti_exit
-
-doreti_notvm86:
-#endif
- testb $SEL_RPL_MASK,TF_CS(%esp) /* are we returning to user mode? */
- jz doreti_exit /* can't handle ASTs now if not */
-
-doreti_ast:
- /*
- * Check for ASTs atomically with returning. Disabling CPU
- * interrupts provides sufficient locking even in the SMP case,
- * since we will be informed of any new ASTs by an IPI.
- */
- DISABLE_INTERRUPTS(%esi) /* cli */
- movl PCPU(CURTHREAD),%eax
- testl $TDF_ASTPENDING | TDF_NEEDRESCHED,TD_FLAGS(%eax)
- je doreti_exit
- ENABLE_INTERRUPTS(%esi) /* sti */
- pushl %esp /* pass a pointer to the trapframe */
- call ast
- add $4,%esp
- jmp doreti_ast
-
- /*
- * doreti_exit: pop registers, iret.
- *
- * The segment register pop is a special case, since it may
- * fault if (for example) a sigreturn specifies bad segment
- * registers. The fault is handled in trap.c.
- */
-doreti_exit:
- ENABLE_INTERRUPTS(%esi) # reenable event callbacks (sti)
-
- .globl scrit
-scrit:
- __TEST_PENDING(%esi)
- jnz hypervisor_callback_pending /* More to go */
-
- MEXITCOUNT
-
- .globl doreti_popl_fs
-doreti_popl_fs:
- popl %fs
- .globl doreti_popl_es
-doreti_popl_es:
- popl %es
- .globl doreti_popl_ds
-doreti_popl_ds:
- popl %ds
-
- /*
- * This is important: as nothing is atomic over here (we can get
- * interrupted any time), we use the critical_region_fixup() in
- * order to figure out where out stack is. Therefore, do NOT use
- * 'popal' here without fixing up the table!
- */
- POPA
- addl $8,%esp
- .globl doreti_iret
-doreti_iret:
- jmp hypercall_page + (__HYPERVISOR_iret * 32)
- .globl ecrit
-ecrit:
- /*
- * doreti_iret_fault and friends. Alternative return code for
- * the case where we get a fault in the doreti_exit code
- * above. trap() (i386/i386/trap.c) catches this specific
- * case, sends the process a signal and continues in the
- * corresponding place in the code below.
- */
- ALIGN_TEXT
- .globl doreti_iret_fault
-doreti_iret_fault:
- subl $8,%esp
- pushal
- pushl %ds
- .globl doreti_popl_ds_fault
-doreti_popl_ds_fault:
- pushl %es
- .globl doreti_popl_es_fault
-doreti_popl_es_fault:
- pushl %fs
- .globl doreti_popl_fs_fault
-doreti_popl_fs_fault:
- movl $0,TF_ERR(%esp) /* XXX should be the error code */
- movl $T_PROTFLT,TF_TRAPNO(%esp)
- jmp alltraps_with_regs_pushed
-
- /*
-# [How we do the fixup]. We want to merge the current stack frame with the
-# just-interrupted frame. How we do this depends on where in the critical
-# region the interrupted handler was executing, and so how many saved
-# registers are in each frame. We do this quickly using the lookup table
-# 'critical_fixup_table'. For each byte offset in the critical region, it
-# provides the number of bytes which have already been popped from the
-# interrupted stack frame.
-*/
-
-.globl critical_region_fixup
-critical_region_fixup:
- addl $critical_fixup_table-scrit,%eax
- movzbl (%eax),%eax # %eax contains num bytes popped
- movl %esp,%esi
- add %eax,%esi # %esi points at end of src region
- movl %esp,%edi
- add $0x40,%edi # %edi points at end of dst region
- movl %eax,%ecx
- shr $2,%ecx # convert bytes to words
- je 16f # skip loop if nothing to copy
-15: subl $4,%esi # pre-decrementing copy loop
- subl $4,%edi
- movl (%esi),%eax
- movl %eax,(%edi)
- loop 15b
-16: movl %edi,%esp # final %edi is top of merged stack
- jmp hypervisor_callback_pending
-
-
-critical_fixup_table:
-.byte 0x0,0x0,0x0 #testb $0x1,(%esi)
-.byte 0x0,0x0,0x0,0x0,0x0,0x0 #jne ea
-.byte 0x0,0x0 #pop %fs
-.byte 0x04 #pop %es
-.byte 0x08 #pop %ds
-.byte 0x0c #pop %edi
-.byte 0x10 #pop %esi
-.byte 0x14 #pop %ebp
-.byte 0x18 #pop %ebx
-.byte 0x1c #pop %ebx
-.byte 0x20 #pop %edx
-.byte 0x24 #pop %ecx
-.byte 0x28 #pop %eax
-.byte 0x2c,0x2c,0x2c #add $0x8,%esp
-#if 0
- .byte 0x34 #iret
-#endif
-.byte 0x34,0x34,0x34,0x34,0x34 #HYPERVISOR_iret
-
-
-/* # Hypervisor uses this for application faults while it executes.*/
-ENTRY(failsafe_callback)
- pushal
- call xen_failsafe_handler
-/*# call install_safe_pf_handler */
- movl 28(%esp),%ebx
-1: movl %ebx,%ds
- movl 32(%esp),%ebx
-2: movl %ebx,%es
- movl 36(%esp),%ebx
-3: movl %ebx,%fs
- movl 40(%esp),%ebx
-4: movl %ebx,%gs
-/*# call install_normal_pf_handler */
- popal
- addl $12,%esp
- iret
-
-
diff --git a/sys/i386/xen/locore.s b/sys/i386/xen/locore.s
deleted file mode 100644
index 7e6768463213..000000000000
--- a/sys/i386/xen/locore.s
+++ /dev/null
@@ -1,360 +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
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)locore.s 7.3 (Berkeley) 5/13/91
- * $FreeBSD$
- *
- * originally from: locore.s, by William F. Jolitz
- *
- * Substantially rewritten by David Greenman, Rod Grimes,
- * Bruce Evans, Wolfgang Solfrank, Poul-Henning Kamp
- * and many others.
- */
-
-#include "opt_bootp.h"
-#include "opt_compat.h"
-#include "opt_nfsroot.h"
-#include "opt_pmap.h"
-
-#include <sys/syscall.h>
-#include <sys/reboot.h>
-
-#include <machine/asmacros.h>
-#include <machine/cputypes.h>
-#include <machine/psl.h>
-#include <machine/pmap.h>
-#include <machine/specialreg.h>
-
-#define __ASSEMBLY__
-#include <xen/interface/elfnote.h>
-
-/* The defines below have been lifted out of <machine/xen-public/arch-x86_32.h> */
-#define FLAT_RING1_CS 0xe019 /* GDT index 259 */
-#define FLAT_RING1_DS 0xe021 /* GDT index 260 */
-#define KERNEL_CS FLAT_RING1_CS
-#define KERNEL_DS FLAT_RING1_DS
-
-#include "assym.s"
-
-.section __xen_guest
- .ascii "LOADER=generic,GUEST_OS=freebsd,GUEST_VER=7.0,XEN_VER=xen-3.0,BSD_SYMTAB,VIRT_BASE=0xc0000000"
- .byte 0
-
- ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz, "FreeBSD")
- ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz, "HEAD")
- ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz, "xen-3.0")
- ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE, .long, KERNBASE)
- ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET, .long, KERNBASE)
- ELFNOTE(Xen, XEN_ELFNOTE_ENTRY, .long, btext)
- ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .long, hypercall_page)
- ELFNOTE(Xen, XEN_ELFNOTE_HV_START_LOW, .long, XEN_HYPERVISOR_VIRT_START)
-#if 0
- ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .asciz, "writable_page_tables|writable_descriptor_tables|auto_translated_physmap|pae_pgdir_above_4gb|supervisor_mode_kernel")
-#endif
- ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .asciz, "writable_page_tables|supervisor_mode_kernel|writable_descriptor_tables")
-
-#ifdef PAE
- ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz, "yes")
- ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID, .long, PG_V, PG_V)
-#else
- ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz, "no")
- ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID, .long, PG_V, PG_V)
-#endif
- ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz, "generic")
- ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long, 1)
-
-
-
-/*
- * XXX
- *
- * Note: This version greatly munged to avoid various assembler errors
- * that may be fixed in newer versions of gas. Perhaps newer versions
- * will have more pleasant appearance.
- */
-
-/*
- * PTmap is recursive pagemap at top of virtual address space.
- * Within PTmap, the page directory can be found (third indirection).
- */
- .globl PTmap,PTD,PTDpde
- .set PTmap,(PTDPTDI << PDRSHIFT)
- .set PTD,PTmap + (PTDPTDI * PAGE_SIZE)
- .set PTDpde,PTD + (PTDPTDI * PDESIZE)
-
-/*
- * Compiled KERNBASE location and the kernel load address
- */
- .globl kernbase
- .set kernbase,KERNBASE
- .globl kernload
- .set kernload,KERNLOAD
-
-/*
- * Globals
- */
- .data
- ALIGN_DATA /* just to be sure */
-
- .space 0x2000 /* space for tmpstk - temporary stack */
-tmpstk:
-
- .globl bootinfo
-bootinfo: .space BOOTINFO_SIZE /* bootinfo that we can handle */
-
- .globl KERNend
-KERNend: .long 0 /* phys addr end of kernel (just after bss) */
- .globl physfree
-physfree: .long 0 /* phys addr of next free page */
-
- .globl IdlePTD
-IdlePTD: .long 0 /* phys addr of kernel PTD */
-
-#ifdef PAE
- .globl IdlePDPT
-IdlePDPT: .long 0 /* phys addr of kernel PDPT */
-#endif
-
-#ifdef SMP
- .globl KPTphys
-#endif
-KPTphys: .long 0 /* phys addr of kernel page tables */
- .globl gdtset
-gdtset: .long 0 /* GDT is valid */
-
- .globl proc0kstack
-proc0kstack: .long 0 /* address of proc 0 kstack space */
-p0kpa: .long 0 /* phys addr of proc0's STACK */
-
-vm86phystk: .long 0 /* PA of vm86/bios stack */
-
- .globl vm86paddr, vm86pa
-vm86paddr: .long 0 /* address of vm86 region */
-vm86pa: .long 0 /* phys addr of vm86 region */
-
-#ifdef PC98
- .globl pc98_system_parameter
-pc98_system_parameter:
- .space 0x240
-#endif
-
- .globl avail_space
-avail_space: .long 0
-
-/**********************************************************************
- *
- * Some handy macros
- *
- */
-
-/*
- * We're already in protected mode, so no remapping is needed.
- */
-#define R(foo) (foo)
-
-#define ALLOCPAGES(foo) \
- movl R(physfree), %esi ; \
- movl $((foo)*PAGE_SIZE), %eax ; \
- addl %esi, %eax ; \
- movl %eax, R(physfree) ; \
- movl %esi, %edi ; \
- movl $((foo)*PAGE_SIZE),%ecx ; \
- xorl %eax,%eax ; \
- cld ; \
- rep ; \
- stosb
-
-/*
- * fillkpt
- * eax = page frame address
- * ebx = index into page table
- * ecx = how many pages to map
- * base = base address of page dir/table
- * prot = protection bits
- */
-#define fillkpt(base, prot) \
- shll $PTESHIFT,%ebx ; \
- addl base,%ebx ; \
- orl $PG_V,%eax ; \
- orl prot,%eax ; \
-1: movl %eax,(%ebx) ; \
- addl $PAGE_SIZE,%eax ; /* increment physical address */ \
- addl $PTESIZE,%ebx ; /* next pte */ \
- loop 1b
-
-/*
- * fillkptphys(prot)
- * eax = physical address
- * ecx = how many pages to map
- * prot = protection bits
- */
-#define fillkptphys(prot) \
- movl %eax, %ebx ; \
- shrl $PAGE_SHIFT, %ebx ; \
- fillkpt(R(KPTphys), prot)
-
-/* Temporary stack */
-.space 8192
-tmpstack:
- .long tmpstack, KERNEL_DS
-
- .text
-
-.p2align 12, 0x90
-
-#define HYPERCALL_PAGE_OFFSET 0x1000
-.org HYPERCALL_PAGE_OFFSET
-ENTRY(hypercall_page)
- .cfi_startproc
- .skip 0x1000
- .cfi_endproc
-
-/**********************************************************************
- *
- * This is where the bootblocks start us, set the ball rolling...
- *
- */
-NON_GPROF_ENTRY(btext)
- /* At the end of our stack, we shall have free space - so store it */
- movl %esp,%ebx
- movl %ebx,R(avail_space)
-
- lss tmpstack,%esp
-
- pushl %esi
- call initvalues
- popl %esi
-
- /* Store the CPUID information */
- xorl %eax,%eax
- cpuid # cpuid 0
- movl %eax,R(cpu_high) # highest capability
- movl %ebx,R(cpu_vendor) # store vendor string
- movl %edx,R(cpu_vendor+4)
- movl %ecx,R(cpu_vendor+8)
- movb $0,R(cpu_vendor+12)
-
- movl $1,%eax
- cpuid # cpuid 1
- movl %eax,R(cpu_id) # store cpu_id
- movl %ebx,R(cpu_procinfo) # store cpu_procinfo
- movl %edx,R(cpu_feature) # store cpu_feature
- movl %ecx,R(cpu_feature2) # store cpu_feature2
- rorl $8,%eax # extract family type
- andl $15,%eax
- cmpl $5,%eax
- movl $CPU_686,R(cpu)
-
- movl proc0kstack,%eax
- leal (KSTACK_PAGES*PAGE_SIZE-PCB_SIZE)(%eax),%esp
- xorl %ebp,%ebp /* mark end of frames */
-#ifdef PAE
- movl IdlePDPT,%esi
-#else
- movl IdlePTD,%esi
-#endif
- movl %esi,(KSTACK_PAGES*PAGE_SIZE-PCB_SIZE+PCB_CR3)(%eax)
- pushl physfree
- call init386
- addl $4, %esp
- call mi_startup
- /* NOTREACHED */
- int $3
-
-/*
- * Signal trampoline, copied to top of user stack
- */
-NON_GPROF_ENTRY(sigcode)
- calll *SIGF_HANDLER(%esp)
- leal SIGF_UC(%esp),%eax /* get ucontext */
- pushl %eax
- testl $PSL_VM,UC_EFLAGS(%eax)
- jne 1f
- mov UC_GS(%eax), %gs /* restore %gs */
-1:
- movl $SYS_sigreturn,%eax
- pushl %eax /* junk to fake return addr. */
- int $0x80 /* enter kernel with args */
- /* on stack */
-1:
- jmp 1b
-
-#ifdef COMPAT_FREEBSD4
- ALIGN_TEXT
-freebsd4_sigcode:
- calll *SIGF_HANDLER(%esp)
- leal SIGF_UC4(%esp),%eax /* get ucontext */
- pushl %eax
- testl $PSL_VM,UC4_EFLAGS(%eax)
- jne 1f
- mov UC4_GS(%eax),%gs /* restore %gs */
-1:
- movl $344,%eax /* 4.x SYS_sigreturn */
- pushl %eax /* junk to fake return addr. */
- int $0x80 /* enter kernel with args */
- /* on stack */
-1:
- jmp 1b
-#endif
-
-#ifdef COMPAT_43
- ALIGN_TEXT
-osigcode:
- call *SIGF_HANDLER(%esp) /* call signal handler */
- lea SIGF_SC(%esp),%eax /* get sigcontext */
- pushl %eax
- testl $PSL_VM,SC_PS(%eax)
- jne 9f
- movl SC_GS(%eax),%gs /* restore %gs */
-9:
- movl $103,%eax /* 3.x SYS_sigreturn */
- pushl %eax /* junk to fake return addr. */
- int $0x80 /* enter kernel with args */
-0: jmp 0b
-#endif /* COMPAT_43 */
-
- ALIGN_TEXT
-esigcode:
-
- .data
- .globl szsigcode
-szsigcode:
- .long esigcode-sigcode
-#ifdef COMPAT_FREEBSD4
- .globl szfreebsd4_sigcode
-szfreebsd4_sigcode:
- .long esigcode-freebsd4_sigcode
-#endif
-#ifdef COMPAT_43
- .globl szosigcode
-szosigcode:
- .long esigcode-osigcode
-#endif
diff --git a/sys/i386/xen/mp_machdep.c b/sys/i386/xen/mp_machdep.c
deleted file mode 100644
index 329bba11ef65..000000000000
--- a/sys/i386/xen/mp_machdep.c
+++ /dev/null
@@ -1,1300 +0,0 @@
-/*-
- * Copyright (c) 1996, by Steve Passe
- * Copyright (c) 2008, by Kip Macy
- * 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. The name of the developer 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 AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "opt_apic.h"
-#include "opt_cpu.h"
-#include "opt_kstack_pages.h"
-#include "opt_mp_watchdog.h"
-#include "opt_pmap.h"
-#include "opt_sched.h"
-#include "opt_smp.h"
-
-#if !defined(lint)
-#if !defined(SMP)
-#error How did you get here?
-#endif
-
-#ifndef DEV_APIC
-#error The apic device is required for SMP, add "device apic" to your config file.
-#endif
-#if defined(CPU_DISABLE_CMPXCHG) && !defined(COMPILING_LINT)
-#error SMP not supported with CPU_DISABLE_CMPXCHG
-#endif
-#endif /* not lint */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/cons.h> /* cngetc() */
-#include <sys/cpuset.h>
-#ifdef GPROF
-#include <sys/gmon.h>
-#endif
-#include <sys/kernel.h>
-#include <sys/ktr.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/memrange.h>
-#include <sys/mutex.h>
-#include <sys/pcpu.h>
-#include <sys/proc.h>
-#include <sys/rwlock.h>
-#include <sys/sched.h>
-#include <sys/smp.h>
-#include <sys/sysctl.h>
-
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/pmap.h>
-#include <vm/vm_kern.h>
-#include <vm/vm_extern.h>
-#include <vm/vm_page.h>
-
-#include <x86/apicreg.h>
-#include <machine/md_var.h>
-#include <machine/mp_watchdog.h>
-#include <machine/pcb.h>
-#include <machine/psl.h>
-#include <machine/smp.h>
-#include <machine/specialreg.h>
-#include <machine/pcpu.h>
-
-#include <xen/xen-os.h>
-#include <xen/evtchn.h>
-#include <xen/xen_intr.h>
-#include <xen/hypervisor.h>
-#include <xen/interface/vcpu.h>
-
-/*---------------------------- Extern Declarations ---------------------------*/
-extern struct pcpu __pcpu[];
-
-extern void Xhypervisor_callback(void);
-extern void failsafe_callback(void);
-
-/*--------------------------- Forward Declarations ---------------------------*/
-static driver_filter_t smp_reschedule_interrupt;
-static driver_filter_t smp_call_function_interrupt;
-static void assign_cpu_ids(void);
-static void set_interrupt_apic_ids(void);
-static int start_all_aps(void);
-static int start_ap(int apic_id);
-static void release_aps(void *dummy);
-
-/*---------------------------------- Macros ----------------------------------*/
-#define IPI_TO_IDX(ipi) ((ipi) - APIC_IPI_INTS)
-
-/*-------------------------------- Local Types -------------------------------*/
-typedef void call_data_func_t(uintptr_t , uintptr_t);
-
-struct cpu_info {
- int cpu_present:1;
- int cpu_bsp:1;
- int cpu_disabled:1;
-};
-
-struct xen_ipi_handler
-{
- driver_filter_t *filter;
- const char *description;
-};
-
-enum {
- RESCHEDULE_VECTOR,
- CALL_FUNCTION_VECTOR,
-};
-
-/*-------------------------------- Global Data -------------------------------*/
-static u_int hyperthreading_cpus;
-static cpuset_t hyperthreading_cpus_mask;
-
-int mp_naps; /* # of Applications processors */
-int boot_cpu_id = -1; /* designated BSP */
-
-static int bootAP;
-static union descriptor *bootAPgdt;
-
-/* Free these after use */
-void *bootstacks[MAXCPU];
-
-struct pcb stoppcbs[MAXCPU];
-
-/* Variables needed for SMP tlb shootdown. */
-vm_offset_t smp_tlb_addr1;
-vm_offset_t smp_tlb_addr2;
-volatile int smp_tlb_wait;
-
-static u_int logical_cpus;
-static volatile cpuset_t ipi_nmi_pending;
-
-/* used to hold the AP's until we are ready to release them */
-static struct mtx ap_boot_mtx;
-
-/* Set to 1 once we're ready to let the APs out of the pen. */
-static volatile int aps_ready = 0;
-
-/*
- * Store data from cpu_add() until later in the boot when we actually setup
- * the APs.
- */
-static struct cpu_info cpu_info[MAX_APIC_ID + 1];
-int cpu_apic_ids[MAXCPU];
-int apic_cpuids[MAX_APIC_ID + 1];
-
-/* Holds pending bitmap based IPIs per CPU */
-static volatile u_int cpu_ipi_pending[MAXCPU];
-
-static int cpu_logical;
-static int cpu_cores;
-
-static const struct xen_ipi_handler xen_ipis[] =
-{
- [RESCHEDULE_VECTOR] = { smp_reschedule_interrupt, "resched" },
- [CALL_FUNCTION_VECTOR] = { smp_call_function_interrupt,"callfunc" }
-};
-
-/*------------------------------- Per-CPU Data -------------------------------*/
-DPCPU_DEFINE(xen_intr_handle_t, ipi_handle[nitems(xen_ipis)]);
-DPCPU_DEFINE(struct vcpu_info *, vcpu_info);
-
-/*------------------------------ Implementation ------------------------------*/
-struct cpu_group *
-cpu_topo(void)
-{
- if (cpu_cores == 0)
- cpu_cores = 1;
- if (cpu_logical == 0)
- cpu_logical = 1;
- if (mp_ncpus % (cpu_cores * cpu_logical) != 0) {
- printf("WARNING: Non-uniform processors.\n");
- printf("WARNING: Using suboptimal topology.\n");
- return (smp_topo_none());
- }
- /*
- * No multi-core or hyper-threaded.
- */
- if (cpu_logical * cpu_cores == 1)
- return (smp_topo_none());
- /*
- * Only HTT no multi-core.
- */
- if (cpu_logical > 1 && cpu_cores == 1)
- return (smp_topo_1level(CG_SHARE_L1, cpu_logical, CG_FLAG_HTT));
- /*
- * Only multi-core no HTT.
- */
- if (cpu_cores > 1 && cpu_logical == 1)
- return (smp_topo_1level(CG_SHARE_NONE, cpu_cores, 0));
- /*
- * Both HTT and multi-core.
- */
- return (smp_topo_2level(CG_SHARE_NONE, cpu_cores,
- CG_SHARE_L1, cpu_logical, CG_FLAG_HTT));
-}
-
-/*
- * Calculate usable address in base memory for AP trampoline code.
- */
-u_int
-mp_bootaddress(u_int basemem)
-{
-
- return (basemem);
-}
-
-void
-cpu_add(u_int apic_id, char boot_cpu)
-{
-
- if (apic_id > MAX_APIC_ID) {
- panic("SMP: APIC ID %d too high", apic_id);
- return;
- }
- KASSERT(cpu_info[apic_id].cpu_present == 0, ("CPU %d added twice",
- apic_id));
- cpu_info[apic_id].cpu_present = 1;
- if (boot_cpu) {
- KASSERT(boot_cpu_id == -1,
- ("CPU %d claims to be BSP, but CPU %d already is", apic_id,
- boot_cpu_id));
- boot_cpu_id = apic_id;
- cpu_info[apic_id].cpu_bsp = 1;
- }
- if (mp_ncpus < MAXCPU)
- mp_ncpus++;
- if (bootverbose)
- printf("SMP: Added CPU %d (%s)\n", apic_id, boot_cpu ? "BSP" :
- "AP");
-}
-
-void
-cpu_mp_setmaxid(void)
-{
-
- mp_maxid = MAXCPU - 1;
-}
-
-int
-cpu_mp_probe(void)
-{
-
- /*
- * Always record BSP in CPU map so that the mbuf init code works
- * correctly.
- */
- CPU_SETOF(0, &all_cpus);
- if (mp_ncpus == 0) {
- /*
- * No CPUs were found, so this must be a UP system. Setup
- * the variables to represent a system with a single CPU
- * with an id of 0.
- */
- mp_ncpus = 1;
- return (0);
- }
-
- /* At least one CPU was found. */
- if (mp_ncpus == 1) {
- /*
- * One CPU was found, so this must be a UP system with
- * an I/O APIC.
- */
- return (0);
- }
-
- /* At least two CPUs were found. */
- return (1);
-}
-
-/*
- * Initialize the IPI handlers and start up the AP's.
- */
-void
-cpu_mp_start(void)
-{
- int i;
-
- /* Initialize the logical ID to APIC ID table. */
- for (i = 0; i < MAXCPU; i++) {
- cpu_apic_ids[i] = -1;
- cpu_ipi_pending[i] = 0;
- }
-
- /* Set boot_cpu_id if needed. */
- if (boot_cpu_id == -1) {
- boot_cpu_id = PCPU_GET(apic_id);
- cpu_info[boot_cpu_id].cpu_bsp = 1;
- } else
- KASSERT(boot_cpu_id == PCPU_GET(apic_id),
- ("BSP's APIC ID doesn't match boot_cpu_id"));
- cpu_apic_ids[0] = boot_cpu_id;
- apic_cpuids[boot_cpu_id] = 0;
-
- assign_cpu_ids();
-
- /* Start each Application Processor */
- start_all_aps();
-
- /* Setup the initial logical CPUs info. */
- logical_cpus = 0;
- CPU_ZERO(&logical_cpus_mask);
- if (cpu_feature & CPUID_HTT)
- logical_cpus = (cpu_procinfo & CPUID_HTT_CORES) >> 16;
-
- set_interrupt_apic_ids();
-}
-
-
-static void
-iv_rendezvous(uintptr_t a, uintptr_t b)
-{
- smp_rendezvous_action();
-}
-
-static void
-iv_invltlb(uintptr_t a, uintptr_t b)
-{
- xen_tlb_flush();
-}
-
-static void
-iv_invlpg(uintptr_t a, uintptr_t b)
-{
- xen_invlpg(a);
-}
-
-static void
-iv_invlrng(uintptr_t a, uintptr_t b)
-{
- vm_offset_t start = (vm_offset_t)a;
- vm_offset_t end = (vm_offset_t)b;
-
- while (start < end) {
- xen_invlpg(start);
- start += PAGE_SIZE;
- }
-}
-
-
-static void
-iv_invlcache(uintptr_t a, uintptr_t b)
-{
-
- wbinvd();
- atomic_add_int(&smp_tlb_wait, 1);
-}
-
-/*
- * These start from "IPI offset" APIC_IPI_INTS
- */
-static call_data_func_t *ipi_vectors[5] =
-{
- iv_rendezvous,
- iv_invltlb,
- iv_invlpg,
- iv_invlrng,
- iv_invlcache,
-};
-
-/*
- * Reschedule call back. Nothing to do,
- * all the work is done automatically when
- * we return from the interrupt.
- */
-static int
-smp_reschedule_interrupt(void *unused)
-{
- int cpu = PCPU_GET(cpuid);
- u_int ipi_bitmap;
-
- ipi_bitmap = atomic_readandclear_int(&cpu_ipi_pending[cpu]);
-
- if (ipi_bitmap & (1 << IPI_PREEMPT)) {
-#ifdef COUNT_IPIS
- (*ipi_preempt_counts[cpu])++;
-#endif
- sched_preempt(curthread);
- }
-
- if (ipi_bitmap & (1 << IPI_AST)) {
-#ifdef COUNT_IPIS
- (*ipi_ast_counts[cpu])++;
-#endif
- /* Nothing to do for AST */
- }
- return (FILTER_HANDLED);
-}
-
-struct _call_data {
- uint16_t func_id;
- uint16_t wait;
- uintptr_t arg1;
- uintptr_t arg2;
- atomic_t started;
- atomic_t finished;
-};
-
-static struct _call_data *call_data;
-
-static int
-smp_call_function_interrupt(void *unused)
-{
- call_data_func_t *func;
- uintptr_t arg1 = call_data->arg1;
- uintptr_t arg2 = call_data->arg2;
- int wait = call_data->wait;
- atomic_t *started = &call_data->started;
- atomic_t *finished = &call_data->finished;
-
- /* We only handle function IPIs, not bitmap IPIs */
- if (call_data->func_id < APIC_IPI_INTS ||
- call_data->func_id > IPI_BITMAP_VECTOR)
- panic("invalid function id %u", call_data->func_id);
-
- func = ipi_vectors[IPI_TO_IDX(call_data->func_id)];
- /*
- * Notify initiating CPU that I've grabbed the data and am
- * about to execute the function
- */
- mb();
- atomic_inc(started);
- /*
- * At this point the info structure may be out of scope unless wait==1
- */
- (*func)(arg1, arg2);
-
- if (wait) {
- mb();
- atomic_inc(finished);
- }
- atomic_add_int(&smp_tlb_wait, 1);
- return (FILTER_HANDLED);
-}
-
-/*
- * Print various information about the SMP system hardware and setup.
- */
-void
-cpu_mp_announce(void)
-{
- int i, x;
-
- /* List CPUs */
- printf(" cpu0 (BSP): APIC ID: %2d\n", boot_cpu_id);
- for (i = 1, x = 0; x <= MAX_APIC_ID; x++) {
- if (!cpu_info[x].cpu_present || cpu_info[x].cpu_bsp)
- continue;
- if (cpu_info[x].cpu_disabled)
- printf(" cpu (AP): APIC ID: %2d (disabled)\n", x);
- else {
- KASSERT(i < mp_ncpus,
- ("mp_ncpus and actual cpus are out of whack"));
- printf(" cpu%d (AP): APIC ID: %2d\n", i++, x);
- }
- }
-}
-
-static int
-xen_smp_cpu_init(unsigned int cpu)
-{
- xen_intr_handle_t *ipi_handle;
- const struct xen_ipi_handler *ipi;
- int idx, rc;
-
- ipi_handle = DPCPU_ID_GET(cpu, ipi_handle);
- for (ipi = xen_ipis, idx = 0; idx < nitems(xen_ipis); ipi++, idx++) {
-
- /*
- * The PCPU variable pc_device is not initialized on i386 PV,
- * so we have to use the root_bus device in order to setup
- * the IPIs.
- */
- rc = xen_intr_alloc_and_bind_ipi(root_bus, cpu,
- ipi->filter, INTR_TYPE_TTY, &ipi_handle[idx]);
- if (rc != 0) {
- printf("Unable to allocate a XEN IPI port. "
- "Error %d\n", rc);
- break;
- }
- xen_intr_describe(ipi_handle[idx], "%s", ipi->description);
- }
-
- for (;idx < nitems(xen_ipis); idx++)
- ipi_handle[idx] = NULL;
-
- if (rc == 0)
- return (0);
-
- /* Either all are successfully mapped, or none at all. */
- for (idx = 0; idx < nitems(xen_ipis); idx++) {
- if (ipi_handle[idx] == NULL)
- continue;
-
- xen_intr_unbind(ipi_handle[idx]);
- ipi_handle[idx] = NULL;
- }
-
- return (rc);
-}
-
-static void
-xen_smp_intr_init_cpus(void *unused)
-{
- int i;
-
- for (i = 0; i < mp_ncpus; i++)
- xen_smp_cpu_init(i);
-}
-
-static void
-xen_smp_intr_setup_cpus(void *unused)
-{
- int i;
-
- for (i = 0; i < mp_ncpus; i++)
- DPCPU_ID_SET(i, vcpu_info,
- &HYPERVISOR_shared_info->vcpu_info[i]);
-}
-
-#define MTOPSIZE (1<<(14 + PAGE_SHIFT))
-
-/*
- * AP CPU's call this to initialize themselves.
- */
-void
-init_secondary(void)
-{
- vm_offset_t addr;
- u_int cpuid;
- int gsel_tss;
-
-
- /* bootAP is set in start_ap() to our ID. */
- PCPU_SET(currentldt, _default_ldt);
- gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
-#if 0
- gdt[bootAP * NGDT + GPROC0_SEL].sd.sd_type = SDT_SYS386TSS;
-#endif
- PCPU_SET(common_tss.tss_esp0, 0); /* not used until after switch */
- PCPU_SET(common_tss.tss_ss0, GSEL(GDATA_SEL, SEL_KPL));
- PCPU_SET(common_tss.tss_ioopt, (sizeof (struct i386tss)) << 16);
-#if 0
- PCPU_SET(tss_gdt, &gdt[bootAP * NGDT + GPROC0_SEL].sd);
-
- PCPU_SET(common_tssd, *PCPU_GET(tss_gdt));
-#endif
- PCPU_SET(fsgs_gdt, &gdt[GUFS_SEL].sd);
-
- /*
- * Set to a known state:
- * Set by mpboot.s: CR0_PG, CR0_PE
- * Set by cpu_setregs: CR0_NE, CR0_MP, CR0_TS, CR0_WP, CR0_AM
- */
- /*
- * signal our startup to the BSP.
- */
- mp_naps++;
-
- /* Spin until the BSP releases the AP's. */
- while (!aps_ready)
- ia32_pause();
-
- /* BSP may have changed PTD while we were waiting */
- invltlb();
- for (addr = 0; addr < NKPT * NBPDR - 1; addr += PAGE_SIZE)
- invlpg(addr);
-
-#if 0
- /* set up SSE/NX */
- initializecpu();
-#endif
-
- /* set up FPU state on the AP */
- npxinit(false);
-#if 0
- /* A quick check from sanity claus */
- if (PCPU_GET(apic_id) != lapic_id()) {
- printf("SMP: cpuid = %d\n", PCPU_GET(cpuid));
- printf("SMP: actual apic_id = %d\n", lapic_id());
- printf("SMP: correct apic_id = %d\n", PCPU_GET(apic_id));
- panic("cpuid mismatch! boom!!");
- }
-#endif
-
- /* Initialize curthread. */
- KASSERT(PCPU_GET(idlethread) != NULL, ("no idle thread"));
- PCPU_SET(curthread, PCPU_GET(idlethread));
-
- mtx_lock_spin(&ap_boot_mtx);
-#if 0
-
- /* Init local apic for irq's */
- lapic_setup(1);
-#endif
- smp_cpus++;
-
- cpuid = PCPU_GET(cpuid);
- CTR1(KTR_SMP, "SMP: AP CPU #%d Launched", cpuid);
- printf("SMP: AP CPU #%d Launched!\n", cpuid);
-
- /* Determine if we are a logical CPU. */
- if (logical_cpus > 1 && PCPU_GET(apic_id) % logical_cpus != 0)
- CPU_SET(cpuid, &logical_cpus_mask);
-
- /* Determine if we are a hyperthread. */
- if (hyperthreading_cpus > 1 &&
- PCPU_GET(apic_id) % hyperthreading_cpus != 0)
- CPU_SET(cpuid, &hyperthreading_cpus_mask);
-#if 0
- if (bootverbose)
- lapic_dump("AP");
-#endif
- if (smp_cpus == mp_ncpus) {
- /* enable IPI's, tlb shootdown, freezes etc */
- atomic_store_rel_int(&smp_started, 1);
- }
-
- mtx_unlock_spin(&ap_boot_mtx);
-
- /* wait until all the AP's are up */
- while (smp_started == 0)
- ia32_pause();
-
- PCPU_SET(curthread, PCPU_GET(idlethread));
-
- /* Start per-CPU event timers. */
- cpu_initclocks_ap();
-
- /* enter the scheduler */
- sched_throw(NULL);
-
- panic("scheduler returned us to %s", __func__);
- /* NOTREACHED */
-}
-
-/*******************************************************************
- * local functions and data
- */
-
-/*
- * We tell the I/O APIC code about all the CPUs we want to receive
- * interrupts. If we don't want certain CPUs to receive IRQs we
- * can simply not tell the I/O APIC code about them in this function.
- * We also do not tell it about the BSP since it tells itself about
- * the BSP internally to work with UP kernels and on UP machines.
- */
-static void
-set_interrupt_apic_ids(void)
-{
- u_int i, apic_id;
-
- for (i = 0; i < MAXCPU; i++) {
- apic_id = cpu_apic_ids[i];
- if (apic_id == -1)
- continue;
- if (cpu_info[apic_id].cpu_bsp)
- continue;
- if (cpu_info[apic_id].cpu_disabled)
- continue;
-
- /* Don't let hyperthreads service interrupts. */
- if (hyperthreading_cpus > 1 &&
- apic_id % hyperthreading_cpus != 0)
- continue;
-
- intr_add_cpu(i);
- }
-}
-
-/*
- * Assign logical CPU IDs to local APICs.
- */
-static void
-assign_cpu_ids(void)
-{
- u_int i;
-
- /* Check for explicitly disabled CPUs. */
- for (i = 0; i <= MAX_APIC_ID; i++) {
- if (!cpu_info[i].cpu_present || cpu_info[i].cpu_bsp)
- continue;
-
- /* Don't use this CPU if it has been disabled by a tunable. */
- if (resource_disabled("lapic", i)) {
- cpu_info[i].cpu_disabled = 1;
- continue;
- }
- }
-
- /*
- * Assign CPU IDs to local APIC IDs and disable any CPUs
- * beyond MAXCPU. CPU 0 has already been assigned to the BSP,
- * so we only have to assign IDs for APs.
- */
- mp_ncpus = 1;
- for (i = 0; i <= MAX_APIC_ID; i++) {
- if (!cpu_info[i].cpu_present || cpu_info[i].cpu_bsp ||
- cpu_info[i].cpu_disabled)
- continue;
-
- if (mp_ncpus < MAXCPU) {
- cpu_apic_ids[mp_ncpus] = i;
- apic_cpuids[i] = mp_ncpus;
- mp_ncpus++;
- } else
- cpu_info[i].cpu_disabled = 1;
- }
- KASSERT(mp_maxid >= mp_ncpus - 1,
- ("%s: counters out of sync: max %d, count %d", __func__, mp_maxid,
- mp_ncpus));
-}
-
-/*
- * start each AP in our list
- */
-/* Lowest 1MB is already mapped: don't touch*/
-#define TMPMAP_START 1
-int
-start_all_aps(void)
-{
- int x,apic_id, cpu;
- struct pcpu *pc;
-
- mtx_init(&ap_boot_mtx, "ap boot", NULL, MTX_SPIN);
-
- /* set up temporary P==V mapping for AP boot */
- /* XXX this is a hack, we should boot the AP on its own stack/PTD */
-
- /* start each AP */
- for (cpu = 1; cpu < mp_ncpus; cpu++) {
- apic_id = cpu_apic_ids[cpu];
-
-
- bootAP = cpu;
- bootAPgdt = gdt + (512*cpu);
-
- /* Get per-cpu data */
- pc = &__pcpu[bootAP];
- pcpu_init(pc, bootAP, sizeof(struct pcpu));
- dpcpu_init((void *)kmem_malloc(kernel_arena, DPCPU_SIZE,
- M_WAITOK | M_ZERO), bootAP);
- pc->pc_apic_id = cpu_apic_ids[bootAP];
- pc->pc_vcpu_id = cpu_apic_ids[bootAP];
- pc->pc_prvspace = pc;
- pc->pc_curthread = 0;
-
- gdt_segs[GPRIV_SEL].ssd_base = (int) pc;
- gdt_segs[GPROC0_SEL].ssd_base = (int) &pc->pc_common_tss;
-
- PT_SET_MA(bootAPgdt, VTOM(bootAPgdt) | PG_V | PG_RW);
- bzero(bootAPgdt, PAGE_SIZE);
- for (x = 0; x < NGDT; x++)
- ssdtosd(&gdt_segs[x], &bootAPgdt[x].sd);
- PT_SET_MA(bootAPgdt, vtomach(bootAPgdt) | PG_V);
-#ifdef notyet
-
- if (HYPERVISOR_vcpu_op(VCPUOP_get_physid, cpu, &cpu_id) == 0) {
- apicid = xen_vcpu_physid_to_x86_apicid(cpu_id.phys_id);
- acpiid = xen_vcpu_physid_to_x86_acpiid(cpu_id.phys_id);
-#ifdef CONFIG_ACPI
- if (acpiid != 0xff)
- x86_acpiid_to_apicid[acpiid] = apicid;
-#endif
- }
-#endif
-
- /* attempt to start the Application Processor */
- if (!start_ap(cpu)) {
- printf("AP #%d (PHY# %d) failed!\n", cpu, apic_id);
- /* better panic as the AP may be running loose */
- printf("panic y/n? [y] ");
- if (cngetc() != 'n')
- panic("bye-bye");
- }
-
- CPU_SET(cpu, &all_cpus); /* record AP in CPU map */
- }
-
-
- pmap_invalidate_range(kernel_pmap, 0, NKPT * NBPDR - 1);
-
- /* number of APs actually started */
- return (mp_naps);
-}
-
-extern uint8_t *pcpu_boot_stack;
-extern trap_info_t trap_table[];
-
-static void
-smp_trap_init(trap_info_t *trap_ctxt)
-{
- const trap_info_t *t = trap_table;
-
- for (t = trap_table; t->address; t++) {
- trap_ctxt[t->vector].flags = t->flags;
- trap_ctxt[t->vector].cs = t->cs;
- trap_ctxt[t->vector].address = t->address;
- }
-}
-
-extern struct rwlock pvh_global_lock;
-extern int nkpt;
-static void
-cpu_initialize_context(unsigned int cpu)
-{
- /* vcpu_guest_context_t is too large to allocate on the stack.
- * Hence we allocate statically and protect it with a lock */
- vm_page_t m[NPGPTD + 2];
- static vcpu_guest_context_t ctxt;
- vm_offset_t boot_stack;
- vm_offset_t newPTD;
- vm_paddr_t ma[NPGPTD];
- int i;
-
- /*
- * Page 0,[0-3] PTD
- * Page 1, [4] boot stack
- * Page [5] PDPT
- *
- */
- for (i = 0; i < NPGPTD + 2; i++) {
- m[i] = vm_page_alloc(NULL, 0,
- VM_ALLOC_NORMAL | VM_ALLOC_NOOBJ | VM_ALLOC_WIRED |
- VM_ALLOC_ZERO);
-
- pmap_zero_page(m[i]);
-
- }
- boot_stack = kva_alloc(PAGE_SIZE);
- newPTD = kva_alloc(NPGPTD * PAGE_SIZE);
- ma[0] = VM_PAGE_TO_MACH(m[0])|PG_V;
-
-#ifdef PAE
- pmap_kenter(boot_stack, VM_PAGE_TO_PHYS(m[NPGPTD + 1]));
- for (i = 0; i < NPGPTD; i++) {
- ((vm_paddr_t *)boot_stack)[i] =
- ma[i] = VM_PAGE_TO_MACH(m[i])|PG_V;
- }
-#endif
-
- /*
- * Copy cpu0 IdlePTD to new IdlePTD - copying only
- * kernel mappings
- */
- pmap_qenter(newPTD, m, 4);
-
- memcpy((uint8_t *)newPTD + KPTDI*sizeof(vm_paddr_t),
- (uint8_t *)PTOV(IdlePTD) + KPTDI*sizeof(vm_paddr_t),
- nkpt*sizeof(vm_paddr_t));
-
- pmap_qremove(newPTD, 4);
- kva_free(newPTD, 4 * PAGE_SIZE);
- /*
- * map actual idle stack to boot_stack
- */
- pmap_kenter(boot_stack, VM_PAGE_TO_PHYS(m[NPGPTD]));
-
-
- xen_pgdpt_pin(VM_PAGE_TO_MACH(m[NPGPTD + 1]));
- rw_wlock(&pvh_global_lock);
- for (i = 0; i < 4; i++) {
- int pdir = (PTDPTDI + i) / NPDEPG;
- int curoffset = (PTDPTDI + i) % NPDEPG;
-
- xen_queue_pt_update((vm_paddr_t)
- ((ma[pdir] & ~PG_V) + (curoffset*sizeof(vm_paddr_t))),
- ma[i]);
- }
- PT_UPDATES_FLUSH();
- rw_wunlock(&pvh_global_lock);
-
- memset(&ctxt, 0, sizeof(ctxt));
- ctxt.flags = VGCF_IN_KERNEL;
- ctxt.user_regs.ds = GSEL(GDATA_SEL, SEL_KPL);
- ctxt.user_regs.es = GSEL(GDATA_SEL, SEL_KPL);
- ctxt.user_regs.fs = GSEL(GPRIV_SEL, SEL_KPL);
- ctxt.user_regs.gs = GSEL(GDATA_SEL, SEL_KPL);
- ctxt.user_regs.cs = GSEL(GCODE_SEL, SEL_KPL);
- ctxt.user_regs.ss = GSEL(GDATA_SEL, SEL_KPL);
- ctxt.user_regs.eip = (unsigned long)init_secondary;
- ctxt.user_regs.eflags = PSL_KERNEL | 0x1000; /* IOPL_RING1 */
-
- memset(&ctxt.fpu_ctxt, 0, sizeof(ctxt.fpu_ctxt));
-
- smp_trap_init(ctxt.trap_ctxt);
-
- ctxt.ldt_ents = 0;
- ctxt.gdt_frames[0] =
- (uint32_t)((uint64_t)vtomach(bootAPgdt) >> PAGE_SHIFT);
- ctxt.gdt_ents = 512;
-
-#ifdef __i386__
- ctxt.user_regs.esp = boot_stack + PAGE_SIZE;
-
- ctxt.kernel_ss = GSEL(GDATA_SEL, SEL_KPL);
- ctxt.kernel_sp = boot_stack + PAGE_SIZE;
-
- ctxt.event_callback_cs = GSEL(GCODE_SEL, SEL_KPL);
- ctxt.event_callback_eip = (unsigned long)Xhypervisor_callback;
- ctxt.failsafe_callback_cs = GSEL(GCODE_SEL, SEL_KPL);
- ctxt.failsafe_callback_eip = (unsigned long)failsafe_callback;
-
- ctxt.ctrlreg[3] = VM_PAGE_TO_MACH(m[NPGPTD + 1]);
-#else /* __x86_64__ */
- ctxt.user_regs.esp = idle->thread.rsp0 - sizeof(struct pt_regs);
- ctxt.kernel_ss = GSEL(GDATA_SEL, SEL_KPL);
- ctxt.kernel_sp = idle->thread.rsp0;
-
- ctxt.event_callback_eip = (unsigned long)hypervisor_callback;
- ctxt.failsafe_callback_eip = (unsigned long)failsafe_callback;
- ctxt.syscall_callback_eip = (unsigned long)system_call;
-
- ctxt.ctrlreg[3] = xen_pfn_to_cr3(virt_to_mfn(init_level4_pgt));
-
- ctxt.gs_base_kernel = (unsigned long)(cpu_pda(cpu));
-#endif
-
- printf("gdtpfn=%lx pdptpfn=%lx\n",
- ctxt.gdt_frames[0],
- ctxt.ctrlreg[3] >> PAGE_SHIFT);
-
- PANIC_IF(HYPERVISOR_vcpu_op(VCPUOP_initialise, cpu, &ctxt));
- DELAY(3000);
- PANIC_IF(HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL));
-}
-
-/*
- * This function starts the AP (application processor) identified
- * by the APIC ID 'physicalCpu'. It does quite a "song and dance"
- * to accomplish this. This is necessary because of the nuances
- * of the different hardware we might encounter. It isn't pretty,
- * but it seems to work.
- */
-
-int cpus;
-static int
-start_ap(int apic_id)
-{
- int ms;
-
- /* used as a watchpoint to signal AP startup */
- cpus = mp_naps;
-
- cpu_initialize_context(apic_id);
-
- /* Wait up to 5 seconds for it to start. */
- for (ms = 0; ms < 5000; ms++) {
- if (mp_naps > cpus)
- return (1); /* return SUCCESS */
- DELAY(1000);
- }
- return (0); /* return FAILURE */
-}
-
-static void
-ipi_pcpu(int cpu, u_int ipi)
-{
- KASSERT((ipi <= nitems(xen_ipis)), ("invalid IPI"));
- xen_intr_signal(DPCPU_ID_GET(cpu, ipi_handle[ipi]));
-}
-
-/*
- * send an IPI to a specific CPU.
- */
-static void
-ipi_send_cpu(int cpu, u_int ipi)
-{
- u_int bitmap, old_pending, new_pending;
-
- if (IPI_IS_BITMAPED(ipi)) {
- bitmap = 1 << ipi;
- ipi = IPI_BITMAP_VECTOR;
- do {
- old_pending = cpu_ipi_pending[cpu];
- new_pending = old_pending | bitmap;
- } while (!atomic_cmpset_int(&cpu_ipi_pending[cpu],
- old_pending, new_pending));
- if (!old_pending)
- ipi_pcpu(cpu, RESCHEDULE_VECTOR);
- } else {
- KASSERT(call_data != NULL, ("call_data not set"));
- ipi_pcpu(cpu, CALL_FUNCTION_VECTOR);
- }
-}
-
-/*
- * Flush the TLB on all other CPU's
- */
-static void
-smp_tlb_shootdown(u_int vector, vm_offset_t addr1, vm_offset_t addr2)
-{
- u_int ncpu;
- struct _call_data data;
-
- ncpu = mp_ncpus - 1; /* does not shootdown self */
- if (ncpu < 1)
- return; /* no other cpus */
- if (!(read_eflags() & PSL_I))
- panic("%s: interrupts disabled", __func__);
- mtx_lock_spin(&smp_ipi_mtx);
- KASSERT(call_data == NULL, ("call_data isn't null?!"));
- call_data = &data;
- call_data->func_id = vector;
- call_data->arg1 = addr1;
- call_data->arg2 = addr2;
- atomic_store_rel_int(&smp_tlb_wait, 0);
- ipi_all_but_self(vector);
- while (smp_tlb_wait < ncpu)
- ia32_pause();
- call_data = NULL;
- mtx_unlock_spin(&smp_ipi_mtx);
-}
-
-static void
-smp_targeted_tlb_shootdown(cpuset_t mask, u_int vector, vm_offset_t addr1,
- vm_offset_t addr2)
-{
- int cpu, ncpu, othercpus;
- struct _call_data data;
-
- othercpus = mp_ncpus - 1;
- if (CPU_ISFULLSET(&mask)) {
- if (othercpus < 1)
- return;
- } else {
- CPU_CLR(PCPU_GET(cpuid), &mask);
- if (CPU_EMPTY(&mask))
- return;
- }
- if (!(read_eflags() & PSL_I))
- panic("%s: interrupts disabled", __func__);
- mtx_lock_spin(&smp_ipi_mtx);
- KASSERT(call_data == NULL, ("call_data isn't null?!"));
- call_data = &data;
- call_data->func_id = vector;
- call_data->arg1 = addr1;
- call_data->arg2 = addr2;
- atomic_store_rel_int(&smp_tlb_wait, 0);
- if (CPU_ISFULLSET(&mask)) {
- ncpu = othercpus;
- ipi_all_but_self(vector);
- } else {
- ncpu = 0;
- while ((cpu = CPU_FFS(&mask)) != 0) {
- cpu--;
- CPU_CLR(cpu, &mask);
- CTR3(KTR_SMP, "%s: cpu: %d ipi: %x", __func__, cpu,
- vector);
- ipi_send_cpu(cpu, vector);
- ncpu++;
- }
- }
- while (smp_tlb_wait < ncpu)
- ia32_pause();
- call_data = NULL;
- mtx_unlock_spin(&smp_ipi_mtx);
-}
-
-void
-smp_cache_flush(void)
-{
-
- if (smp_started)
- smp_tlb_shootdown(IPI_INVLCACHE, 0, 0);
-}
-
-void
-smp_invltlb(void)
-{
-
- if (smp_started) {
- smp_tlb_shootdown(IPI_INVLTLB, 0, 0);
- }
-}
-
-void
-smp_invlpg(vm_offset_t addr)
-{
-
- if (smp_started) {
- smp_tlb_shootdown(IPI_INVLPG, addr, 0);
- }
-}
-
-void
-smp_invlpg_range(vm_offset_t addr1, vm_offset_t addr2)
-{
-
- if (smp_started) {
- smp_tlb_shootdown(IPI_INVLRNG, addr1, addr2);
- }
-}
-
-void
-smp_masked_invltlb(cpuset_t mask)
-{
-
- if (smp_started) {
- smp_targeted_tlb_shootdown(mask, IPI_INVLTLB, 0, 0);
- }
-}
-
-void
-smp_masked_invlpg(cpuset_t mask, vm_offset_t addr)
-{
-
- if (smp_started) {
- smp_targeted_tlb_shootdown(mask, IPI_INVLPG, addr, 0);
- }
-}
-
-void
-smp_masked_invlpg_range(cpuset_t mask, vm_offset_t addr1, vm_offset_t addr2)
-{
-
- if (smp_started) {
- smp_targeted_tlb_shootdown(mask, IPI_INVLRNG, addr1, addr2);
- }
-}
-
-/*
- * send an IPI to a set of cpus.
- */
-void
-ipi_selected(cpuset_t cpus, u_int ipi)
-{
- int cpu;
-
- /*
- * IPI_STOP_HARD maps to a NMI and the trap handler needs a bit
- * of help in order to understand what is the source.
- * Set the mask of receiving CPUs for this purpose.
- */
- if (ipi == IPI_STOP_HARD)
- CPU_OR_ATOMIC(&ipi_nmi_pending, &cpus);
-
- while ((cpu = CPU_FFS(&cpus)) != 0) {
- cpu--;
- CPU_CLR(cpu, &cpus);
- CTR3(KTR_SMP, "%s: cpu: %d ipi: %x", __func__, cpu, ipi);
- ipi_send_cpu(cpu, ipi);
- }
-}
-
-/*
- * send an IPI to a specific CPU.
- */
-void
-ipi_cpu(int cpu, u_int ipi)
-{
-
- /*
- * IPI_STOP_HARD maps to a NMI and the trap handler needs a bit
- * of help in order to understand what is the source.
- * Set the mask of receiving CPUs for this purpose.
- */
- if (ipi == IPI_STOP_HARD)
- CPU_SET_ATOMIC(cpu, &ipi_nmi_pending);
-
- CTR3(KTR_SMP, "%s: cpu: %d ipi: %x", __func__, cpu, ipi);
- ipi_send_cpu(cpu, ipi);
-}
-
-/*
- * send an IPI to all CPUs EXCEPT myself
- */
-void
-ipi_all_but_self(u_int ipi)
-{
- cpuset_t other_cpus;
-
- /*
- * IPI_STOP_HARD maps to a NMI and the trap handler needs a bit
- * of help in order to understand what is the source.
- * Set the mask of receiving CPUs for this purpose.
- */
- other_cpus = all_cpus;
- CPU_CLR(PCPU_GET(cpuid), &other_cpus);
- if (ipi == IPI_STOP_HARD)
- CPU_OR_ATOMIC(&ipi_nmi_pending, &other_cpus);
-
- CTR2(KTR_SMP, "%s: ipi: %x", __func__, ipi);
- ipi_selected(other_cpus, ipi);
-}
-
-int
-ipi_nmi_handler()
-{
- u_int cpuid;
-
- /*
- * As long as there is not a simple way to know about a NMI's
- * source, if the bitmask for the current CPU is present in
- * the global pending bitword an IPI_STOP_HARD has been issued
- * and should be handled.
- */
- cpuid = PCPU_GET(cpuid);
- if (!CPU_ISSET(cpuid, &ipi_nmi_pending))
- return (1);
-
- CPU_CLR_ATOMIC(cpuid, &ipi_nmi_pending);
- cpustop_handler();
- return (0);
-}
-
-/*
- * Handle an IPI_STOP by saving our current context and spinning until we
- * are resumed.
- */
-void
-cpustop_handler(void)
-{
- int cpu;
-
- cpu = PCPU_GET(cpuid);
-
- savectx(&stoppcbs[cpu]);
-
- /* Indicate that we are stopped */
- CPU_SET_ATOMIC(cpu, &stopped_cpus);
-
- /* Wait for restart */
- while (!CPU_ISSET(cpu, &started_cpus))
- ia32_pause();
-
- CPU_CLR_ATOMIC(cpu, &started_cpus);
- CPU_CLR_ATOMIC(cpu, &stopped_cpus);
-
- if (cpu == 0 && cpustop_restartfunc != NULL) {
- cpustop_restartfunc();
- cpustop_restartfunc = NULL;
- }
-}
-
-/*
- * Handlers for TLB related IPIs
- *
- * On i386 Xen PV this are no-ops since this port doesn't support SMP.
- */
-void
-invltlb_handler(void)
-{
-}
-
-void
-invlpg_handler(void)
-{
-}
-
-void
-invlrng_handler(void)
-{
-}
-
-void
-invlcache_handler(void)
-{
-}
-
-/*
- * This is called once the rest of the system is up and running and we're
- * ready to let the AP's out of the pen.
- */
-static void
-release_aps(void *dummy __unused)
-{
-
- if (mp_ncpus == 1)
- return;
- atomic_store_rel_int(&aps_ready, 1);
- while (smp_started == 0)
- ia32_pause();
-}
-SYSINIT(start_aps, SI_SUB_SMP, SI_ORDER_FIRST, release_aps, NULL);
-SYSINIT(start_ipis, SI_SUB_SMP, SI_ORDER_ANY, xen_smp_intr_init_cpus, NULL);
-SYSINIT(start_cpu, SI_SUB_INTR, SI_ORDER_ANY, xen_smp_intr_setup_cpus, NULL);
diff --git a/sys/i386/xen/mptable.c b/sys/i386/xen/mptable.c
deleted file mode 100644
index 81d7c1bafc64..000000000000
--- a/sys/i386/xen/mptable.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*-
- * Copyright (c) 2003 John Baldwin <jhb@FreeBSD.org>
- * Copyright (c) 1996, by Steve Passe
- * 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. The name of the developer 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 AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
-
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/pmap.h>
-
-#include <machine/frame.h>
-#include <machine/intr_machdep.h>
-#include <x86/apicvar.h>
-
-#include <xen/hypervisor.h>
-#include <xen/xen-os.h>
-#include <machine/smp.h>
-#include <xen/interface/vcpu.h>
-
-
-static int mptable_probe(void);
-static int mptable_probe_cpus(void);
-static void mptable_register(void *dummy);
-static int mptable_setup_local(void);
-static int mptable_setup_io(void);
-
-static struct apic_enumerator mptable_enumerator = {
- "MPTable",
- mptable_probe,
- mptable_probe_cpus,
- mptable_setup_local,
- mptable_setup_io
-};
-
-static int
-mptable_probe(void)
-{
-
- return (-100);
-}
-
-static int
-mptable_probe_cpus(void)
-{
- int i, rc;
-
- for (i = 0; i < MAXCPU; i++) {
- rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL);
- if (rc >= 0)
- cpu_add(i, (i == 0));
- }
-
- return (0);
-}
-
-/*
- * Initialize the local APIC on the BSP.
- */
-static int
-mptable_setup_local(void)
-{
-
- PCPU_SET(apic_id, 0);
- PCPU_SET(vcpu_id, 0);
- return (0);
-}
-
-static int
-mptable_setup_io(void)
-{
-
- return (0);
-}
-
-static void
-mptable_register(void *dummy __unused)
-{
-
- apic_register_enumerator(&mptable_enumerator);
-}
-SYSINIT(mptable_register, SI_SUB_TUNABLES - 1, SI_ORDER_FIRST, mptable_register,
- NULL);
diff --git a/sys/i386/xen/pmap.c b/sys/i386/xen/pmap.c
deleted file mode 100644
index 757fc36bb3d4..000000000000
--- a/sys/i386/xen/pmap.c
+++ /dev/null
@@ -1,4420 +0,0 @@
-/*-
- * Copyright (c) 1991 Regents of the University of California.
- * All rights reserved.
- * Copyright (c) 1994 John S. Dyson
- * All rights reserved.
- * Copyright (c) 1994 David Greenman
- * All rights reserved.
- * Copyright (c) 2005 Alan L. Cox <alc@cs.rice.edu>
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * the Systems Programming Group of the University of Utah Computer
- * Science Department and William Jolitz of UUNET Technologies Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)pmap.c 7.7 (Berkeley) 5/12/91
- */
-/*-
- * Copyright (c) 2003 Networks Associates Technology, Inc.
- * All rights reserved.
- *
- * This software was developed for the FreeBSD Project by Jake Burkholder,
- * Safeport Network Services, and Network Associates Laboratories, the
- * Security Research Division of Network Associates, Inc. under
- * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA
- * CHATS research program.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * Manages physical address maps.
- *
- * Since the information managed by this module is
- * also stored by the logical address mapping module,
- * this module may throw away valid virtual-to-physical
- * mappings at almost any time. However, invalidations
- * of virtual-to-physical mappings must be done as
- * requested.
- *
- * In order to cope with hardware architectures which
- * make virtual-to-physical map invalidates expensive,
- * this module may delay invalidate or reduced protection
- * operations until such time as they are actually
- * necessary. This module is given full information as
- * to which processors are currently using which maps,
- * and to when physical maps must be made correct.
- */
-
-#include "opt_cpu.h"
-#include "opt_pmap.h"
-#include "opt_smp.h"
-#include "opt_xbox.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/ktr.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mman.h>
-#include <sys/msgbuf.h>
-#include <sys/mutex.h>
-#include <sys/proc.h>
-#include <sys/rwlock.h>
-#include <sys/sf_buf.h>
-#include <sys/sx.h>
-#include <sys/vmmeter.h>
-#include <sys/sched.h>
-#include <sys/sysctl.h>
-#ifdef SMP
-#include <sys/smp.h>
-#else
-#include <sys/cpuset.h>
-#endif
-
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/vm_kern.h>
-#include <vm/vm_page.h>
-#include <vm/vm_map.h>
-#include <vm/vm_object.h>
-#include <vm/vm_extern.h>
-#include <vm/vm_pageout.h>
-#include <vm/vm_pager.h>
-#include <vm/uma.h>
-
-#include <machine/cpu.h>
-#include <machine/cputypes.h>
-#include <machine/md_var.h>
-#include <machine/pcb.h>
-#include <machine/specialreg.h>
-#ifdef SMP
-#include <machine/smp.h>
-#endif
-
-#ifdef XBOX
-#include <machine/xbox.h>
-#endif
-
-#include <xen/interface/xen.h>
-#include <xen/hypervisor.h>
-#include <machine/xen/hypercall.h>
-#include <machine/xen/xenvar.h>
-#include <machine/xen/xenfunc.h>
-
-#if !defined(CPU_DISABLE_SSE) && defined(I686_CPU)
-#define CPU_ENABLE_SSE
-#endif
-
-#ifndef PMAP_SHPGPERPROC
-#define PMAP_SHPGPERPROC 200
-#endif
-
-#define DIAGNOSTIC
-
-#if !defined(DIAGNOSTIC)
-#ifdef __GNUC_GNU_INLINE__
-#define PMAP_INLINE __attribute__((__gnu_inline__)) inline
-#else
-#define PMAP_INLINE extern inline
-#endif
-#else
-#define PMAP_INLINE
-#endif
-
-#ifdef PV_STATS
-#define PV_STAT(x) do { x ; } while (0)
-#else
-#define PV_STAT(x) do { } while (0)
-#endif
-
-/*
- * Get PDEs and PTEs for user/kernel address space
- */
-#define pmap_pde(m, v) (&((m)->pm_pdir[(vm_offset_t)(v) >> PDRSHIFT]))
-#define pdir_pde(m, v) (m[(vm_offset_t)(v) >> PDRSHIFT])
-
-#define pmap_pde_v(pte) ((*(int *)pte & PG_V) != 0)
-#define pmap_pte_w(pte) ((*(int *)pte & PG_W) != 0)
-#define pmap_pte_m(pte) ((*(int *)pte & PG_M) != 0)
-#define pmap_pte_u(pte) ((*(int *)pte & PG_A) != 0)
-#define pmap_pte_v(pte) ((*(int *)pte & PG_V) != 0)
-
-#define pmap_pte_set_prot(pte, v) ((*(int *)pte &= ~PG_PROT), (*(int *)pte |= (v)))
-
-#define HAMFISTED_LOCKING
-#ifdef HAMFISTED_LOCKING
-static struct mtx createdelete_lock;
-#endif
-
-struct pmap kernel_pmap_store;
-LIST_HEAD(pmaplist, pmap);
-static struct pmaplist allpmaps;
-static struct mtx allpmaps_lock;
-
-vm_offset_t virtual_avail; /* VA of first avail page (after kernel bss) */
-vm_offset_t virtual_end; /* VA of last avail page (end of kernel AS) */
-int pgeflag = 0; /* PG_G or-in */
-int pseflag = 0; /* PG_PS or-in */
-
-int nkpt;
-vm_offset_t kernel_vm_end;
-extern u_int32_t KERNend;
-
-#ifdef PAE
-pt_entry_t pg_nx;
-#endif
-
-static SYSCTL_NODE(_vm, OID_AUTO, pmap, CTLFLAG_RD, 0, "VM/pmap parameters");
-
-static int pat_works; /* Is page attribute table sane? */
-
-/*
- * This lock is defined as static in other pmap implementations. It cannot,
- * however, be defined as static here, because it is (ab)used to serialize
- * queued page table changes in other sources files.
- */
-struct rwlock pvh_global_lock;
-
-/*
- * Data for the pv entry allocation mechanism
- */
-static TAILQ_HEAD(pch, pv_chunk) pv_chunks = TAILQ_HEAD_INITIALIZER(pv_chunks);
-static int pv_entry_count = 0, pv_entry_max = 0, pv_entry_high_water = 0;
-static int shpgperproc = PMAP_SHPGPERPROC;
-
-struct pv_chunk *pv_chunkbase; /* KVA block for pv_chunks */
-int pv_maxchunks; /* How many chunks we have KVA for */
-vm_offset_t pv_vafree; /* freelist stored in the PTE */
-
-/*
- * All those kernel PT submaps that BSD is so fond of
- */
-struct sysmaps {
- struct mtx lock;
- pt_entry_t *CMAP1;
- pt_entry_t *CMAP2;
- caddr_t CADDR1;
- caddr_t CADDR2;
-};
-static struct sysmaps sysmaps_pcpu[MAXCPU];
-pt_entry_t *CMAP3;
-caddr_t ptvmmap = 0;
-caddr_t CADDR3;
-struct msgbuf *msgbufp = 0;
-
-/*
- * Crashdump maps.
- */
-static caddr_t crashdumpmap;
-
-static pt_entry_t *PMAP1 = 0, *PMAP2;
-static pt_entry_t *PADDR1 = 0, *PADDR2;
-#ifdef SMP
-static int PMAP1cpu;
-static int PMAP1changedcpu;
-SYSCTL_INT(_debug, OID_AUTO, PMAP1changedcpu, CTLFLAG_RD,
- &PMAP1changedcpu, 0,
- "Number of times pmap_pte_quick changed CPU with same PMAP1");
-#endif
-static int PMAP1changed;
-SYSCTL_INT(_debug, OID_AUTO, PMAP1changed, CTLFLAG_RD,
- &PMAP1changed, 0,
- "Number of times pmap_pte_quick changed PMAP1");
-static int PMAP1unchanged;
-SYSCTL_INT(_debug, OID_AUTO, PMAP1unchanged, CTLFLAG_RD,
- &PMAP1unchanged, 0,
- "Number of times pmap_pte_quick didn't change PMAP1");
-static struct mtx PMAP2mutex;
-
-static void free_pv_chunk(struct pv_chunk *pc);
-static void free_pv_entry(pmap_t pmap, pv_entry_t pv);
-static pv_entry_t get_pv_entry(pmap_t pmap, boolean_t try);
-static void pmap_pvh_free(struct md_page *pvh, pmap_t pmap, vm_offset_t va);
-static pv_entry_t pmap_pvh_remove(struct md_page *pvh, pmap_t pmap,
- vm_offset_t va);
-
-static vm_page_t pmap_enter_quick_locked(multicall_entry_t **mcl, int *count, pmap_t pmap, vm_offset_t va,
- vm_page_t m, vm_prot_t prot, vm_page_t mpte);
-static void pmap_flush_page(vm_page_t m);
-static void pmap_kenter_attr(vm_offset_t va, vm_paddr_t pa, int mode);
-static int pmap_remove_pte(pmap_t pmap, pt_entry_t *ptq, vm_offset_t sva,
- vm_page_t *free);
-static void pmap_remove_page(struct pmap *pmap, vm_offset_t va,
- vm_page_t *free);
-static void pmap_remove_entry(struct pmap *pmap, vm_page_t m,
- vm_offset_t va);
-static boolean_t pmap_try_insert_pv_entry(pmap_t pmap, vm_offset_t va,
- vm_page_t m);
-
-static vm_page_t pmap_allocpte(pmap_t pmap, vm_offset_t va, u_int flags);
-
-static vm_page_t _pmap_allocpte(pmap_t pmap, u_int ptepindex, u_int flags);
-static void _pmap_unwire_ptp(pmap_t pmap, vm_page_t m, vm_page_t *free);
-static pt_entry_t *pmap_pte_quick(pmap_t pmap, vm_offset_t va);
-static void pmap_pte_release(pt_entry_t *pte);
-static int pmap_unuse_pt(pmap_t, vm_offset_t, vm_page_t *);
-static boolean_t pmap_is_prefaultable_locked(pmap_t pmap, vm_offset_t addr);
-
-static __inline void pagezero(void *page);
-
-CTASSERT(1 << PDESHIFT == sizeof(pd_entry_t));
-CTASSERT(1 << PTESHIFT == sizeof(pt_entry_t));
-
-/*
- * If you get an error here, then you set KVA_PAGES wrong! See the
- * description of KVA_PAGES in sys/i386/include/pmap.h. It must be
- * multiple of 4 for a normal kernel, or a multiple of 8 for a PAE.
- */
-CTASSERT(KERNBASE % (1 << 24) == 0);
-
-void
-pd_set(struct pmap *pmap, int ptepindex, vm_paddr_t val, int type)
-{
- vm_paddr_t pdir_ma = vtomach(&pmap->pm_pdir[ptepindex]);
-
- switch (type) {
- case SH_PD_SET_VA:
-#if 0
- xen_queue_pt_update(shadow_pdir_ma,
- xpmap_ptom(val & ~(PG_RW)));
-#endif
- xen_queue_pt_update(pdir_ma,
- xpmap_ptom(val));
- break;
- case SH_PD_SET_VA_MA:
-#if 0
- xen_queue_pt_update(shadow_pdir_ma,
- val & ~(PG_RW));
-#endif
- xen_queue_pt_update(pdir_ma, val);
- break;
- case SH_PD_SET_VA_CLEAR:
-#if 0
- xen_queue_pt_update(shadow_pdir_ma, 0);
-#endif
- xen_queue_pt_update(pdir_ma, 0);
- break;
- }
-}
-
-/*
- * Bootstrap the system enough to run with virtual memory.
- *
- * On the i386 this is called after mapping has already been enabled
- * and just syncs the pmap module with what has already been done.
- * [We can't call it easily with mapping off since the kernel is not
- * mapped with PA == VA, hence we would have to relocate every address
- * from the linked base (virtual) address "KERNBASE" to the actual
- * (physical) address starting relative to 0]
- */
-void
-pmap_bootstrap(vm_paddr_t firstaddr)
-{
- vm_offset_t va;
- pt_entry_t *pte, *unused;
- struct sysmaps *sysmaps;
- int i;
-
- /*
- * Initialize the first available kernel virtual address. However,
- * using "firstaddr" may waste a few pages of the kernel virtual
- * address space, because locore may not have mapped every physical
- * page that it allocated. Preferably, locore would provide a first
- * unused virtual address in addition to "firstaddr".
- */
- virtual_avail = (vm_offset_t) KERNBASE + firstaddr;
-
- virtual_end = VM_MAX_KERNEL_ADDRESS;
-
- /*
- * Initialize the kernel pmap (which is statically allocated).
- */
- PMAP_LOCK_INIT(kernel_pmap);
- kernel_pmap->pm_pdir = (pd_entry_t *) (KERNBASE + (u_int)IdlePTD);
-#ifdef PAE
- kernel_pmap->pm_pdpt = (pdpt_entry_t *) (KERNBASE + (u_int)IdlePDPT);
-#endif
- CPU_FILL(&kernel_pmap->pm_active); /* don't allow deactivation */
- TAILQ_INIT(&kernel_pmap->pm_pvchunk);
-
- /*
- * Initialize the global pv list lock.
- */
- rw_init_flags(&pvh_global_lock, "pmap pv global", RW_RECURSE);
-
- LIST_INIT(&allpmaps);
- mtx_init(&allpmaps_lock, "allpmaps", NULL, MTX_SPIN);
- mtx_lock_spin(&allpmaps_lock);
- LIST_INSERT_HEAD(&allpmaps, kernel_pmap, pm_list);
- mtx_unlock_spin(&allpmaps_lock);
- if (nkpt == 0)
- nkpt = NKPT;
-
- /*
- * Reserve some special page table entries/VA space for temporary
- * mapping of pages.
- */
-#define SYSMAP(c, p, v, n) \
- v = (c)va; va += ((n)*PAGE_SIZE); p = pte; pte += (n);
-
- va = virtual_avail;
- pte = vtopte(va);
-
- /*
- * CMAP1/CMAP2 are used for zeroing and copying pages.
- * CMAP3 is used for the idle process page zeroing.
- */
- for (i = 0; i < MAXCPU; i++) {
- sysmaps = &sysmaps_pcpu[i];
- mtx_init(&sysmaps->lock, "SYSMAPS", NULL, MTX_DEF);
- SYSMAP(caddr_t, sysmaps->CMAP1, sysmaps->CADDR1, 1)
- SYSMAP(caddr_t, sysmaps->CMAP2, sysmaps->CADDR2, 1)
- PT_SET_MA(sysmaps->CADDR1, 0);
- PT_SET_MA(sysmaps->CADDR2, 0);
- }
- SYSMAP(caddr_t, CMAP3, CADDR3, 1)
- PT_SET_MA(CADDR3, 0);
-
- /*
- * Crashdump maps.
- */
- SYSMAP(caddr_t, unused, crashdumpmap, MAXDUMPPGS)
-
- /*
- * ptvmmap is used for reading arbitrary physical pages via /dev/mem.
- */
- SYSMAP(caddr_t, unused, ptvmmap, 1)
-
- /*
- * msgbufp is used to map the system message buffer.
- */
- SYSMAP(struct msgbuf *, unused, msgbufp, atop(round_page(msgbufsize)))
-
- /*
- * PADDR1 and PADDR2 are used by pmap_pte_quick() and pmap_pte(),
- * respectively.
- */
- SYSMAP(pt_entry_t *, PMAP1, PADDR1, 1)
- SYSMAP(pt_entry_t *, PMAP2, PADDR2, 1)
-
- mtx_init(&PMAP2mutex, "PMAP2", NULL, MTX_DEF);
-
- virtual_avail = va;
-
- /*
- * Leave in place an identity mapping (virt == phys) for the low 1 MB
- * physical memory region that is used by the ACPI wakeup code. This
- * mapping must not have PG_G set.
- */
-#ifndef XEN
- /*
- * leave here deliberately to show that this is not supported
- */
-#ifdef XBOX
- /* FIXME: This is gross, but needed for the XBOX. Since we are in such
- * an early stadium, we cannot yet neatly map video memory ... :-(
- * Better fixes are very welcome! */
- if (!arch_i386_is_xbox)
-#endif
- for (i = 1; i < NKPT; i++)
- PTD[i] = 0;
-
- /* Initialize the PAT MSR if present. */
- pmap_init_pat();
-
- /* Turn on PG_G on kernel page(s) */
- pmap_set_pg();
-#endif
-
-#ifdef HAMFISTED_LOCKING
- mtx_init(&createdelete_lock, "pmap create/delete", NULL, MTX_DEF);
-#endif
-}
-
-/*
- * Setup the PAT MSR.
- */
-void
-pmap_init_pat(void)
-{
- uint64_t pat_msr;
-
- /* Bail if this CPU doesn't implement PAT. */
- if (!(cpu_feature & CPUID_PAT))
- return;
-
- if (cpu_vendor_id != CPU_VENDOR_INTEL ||
- (CPUID_TO_FAMILY(cpu_id) == 6 && CPUID_TO_MODEL(cpu_id) >= 0xe)) {
- /*
- * Leave the indices 0-3 at the default of WB, WT, UC, and UC-.
- * Program 4 and 5 as WP and WC.
- * Leave 6 and 7 as UC and UC-.
- */
- pat_msr = rdmsr(MSR_PAT);
- pat_msr &= ~(PAT_MASK(4) | PAT_MASK(5));
- pat_msr |= PAT_VALUE(4, PAT_WRITE_PROTECTED) |
- PAT_VALUE(5, PAT_WRITE_COMBINING);
- pat_works = 1;
- } else {
- /*
- * Due to some Intel errata, we can only safely use the lower 4
- * PAT entries. Thus, just replace PAT Index 2 with WC instead
- * of UC-.
- *
- * Intel Pentium III Processor Specification Update
- * Errata E.27 (Upper Four PAT Entries Not Usable With Mode B
- * or Mode C Paging)
- *
- * Intel Pentium IV Processor Specification Update
- * Errata N46 (PAT Index MSB May Be Calculated Incorrectly)
- */
- pat_msr = rdmsr(MSR_PAT);
- pat_msr &= ~PAT_MASK(2);
- pat_msr |= PAT_VALUE(2, PAT_WRITE_COMBINING);
- pat_works = 0;
- }
- wrmsr(MSR_PAT, pat_msr);
-}
-
-/*
- * Initialize a vm_page's machine-dependent fields.
- */
-void
-pmap_page_init(vm_page_t m)
-{
-
- TAILQ_INIT(&m->md.pv_list);
- m->md.pat_mode = PAT_WRITE_BACK;
-}
-
-/*
- * ABuse the pte nodes for unmapped kva to thread a kva freelist through.
- * Requirements:
- * - Must deal with pages in order to ensure that none of the PG_* bits
- * are ever set, PG_V in particular.
- * - Assumes we can write to ptes without pte_store() atomic ops, even
- * on PAE systems. This should be ok.
- * - Assumes nothing will ever test these addresses for 0 to indicate
- * no mapping instead of correctly checking PG_V.
- * - Assumes a vm_offset_t will fit in a pte (true for i386).
- * Because PG_V is never set, there can be no mappings to invalidate.
- */
-static int ptelist_count = 0;
-static vm_offset_t
-pmap_ptelist_alloc(vm_offset_t *head)
-{
- vm_offset_t va;
- vm_offset_t *phead = (vm_offset_t *)*head;
-
- if (ptelist_count == 0) {
- printf("out of memory!!!!!!\n");
- return (0); /* Out of memory */
- }
- ptelist_count--;
- va = phead[ptelist_count];
- return (va);
-}
-
-static void
-pmap_ptelist_free(vm_offset_t *head, vm_offset_t va)
-{
- vm_offset_t *phead = (vm_offset_t *)*head;
-
- phead[ptelist_count++] = va;
-}
-
-static void
-pmap_ptelist_init(vm_offset_t *head, void *base, int npages)
-{
- int i, nstackpages;
- vm_offset_t va;
- vm_page_t m;
-
- nstackpages = (npages + PAGE_SIZE/sizeof(vm_offset_t) - 1)/ (PAGE_SIZE/sizeof(vm_offset_t));
- for (i = 0; i < nstackpages; i++) {
- va = (vm_offset_t)base + i * PAGE_SIZE;
- m = vm_page_alloc(NULL, i,
- VM_ALLOC_NORMAL | VM_ALLOC_NOOBJ | VM_ALLOC_WIRED |
- VM_ALLOC_ZERO);
- pmap_qenter(va, &m, 1);
- }
-
- *head = (vm_offset_t)base;
- for (i = npages - 1; i >= nstackpages; i--) {
- va = (vm_offset_t)base + i * PAGE_SIZE;
- pmap_ptelist_free(head, va);
- }
-}
-
-
-/*
- * Initialize the pmap module.
- * Called by vm_init, to initialize any structures that the pmap
- * system needs to map virtual memory.
- */
-void
-pmap_init(void)
-{
-
- /*
- * Initialize the address space (zone) for the pv entries. Set a
- * high water mark so that the system can recover from excessive
- * numbers of pv entries.
- */
- TUNABLE_INT_FETCH("vm.pmap.shpgperproc", &shpgperproc);
- pv_entry_max = shpgperproc * maxproc + vm_cnt.v_page_count;
- TUNABLE_INT_FETCH("vm.pmap.pv_entries", &pv_entry_max);
- pv_entry_max = roundup(pv_entry_max, _NPCPV);
- pv_entry_high_water = 9 * (pv_entry_max / 10);
-
- pv_maxchunks = MAX(pv_entry_max / _NPCPV, maxproc);
- pv_chunkbase = (struct pv_chunk *)kva_alloc(PAGE_SIZE * pv_maxchunks);
- if (pv_chunkbase == NULL)
- panic("pmap_init: not enough kvm for pv chunks");
- pmap_ptelist_init(&pv_vafree, pv_chunkbase, pv_maxchunks);
-}
-
-
-SYSCTL_INT(_vm_pmap, OID_AUTO, pv_entry_max, CTLFLAG_RD, &pv_entry_max, 0,
- "Max number of PV entries");
-SYSCTL_INT(_vm_pmap, OID_AUTO, shpgperproc, CTLFLAG_RD, &shpgperproc, 0,
- "Page share factor per proc");
-
-static SYSCTL_NODE(_vm_pmap, OID_AUTO, pde, CTLFLAG_RD, 0,
- "2/4MB page mapping counters");
-
-static u_long pmap_pde_mappings;
-SYSCTL_ULONG(_vm_pmap_pde, OID_AUTO, mappings, CTLFLAG_RD,
- &pmap_pde_mappings, 0, "2/4MB page mappings");
-
-/***************************************************
- * Low level helper routines.....
- ***************************************************/
-
-/*
- * Determine the appropriate bits to set in a PTE or PDE for a specified
- * caching mode.
- */
-int
-pmap_cache_bits(int mode, boolean_t is_pde)
-{
- int pat_flag, pat_index, cache_bits;
-
- /* The PAT bit is different for PTE's and PDE's. */
- pat_flag = is_pde ? PG_PDE_PAT : PG_PTE_PAT;
-
- /* If we don't support PAT, map extended modes to older ones. */
- if (!(cpu_feature & CPUID_PAT)) {
- switch (mode) {
- case PAT_UNCACHEABLE:
- case PAT_WRITE_THROUGH:
- case PAT_WRITE_BACK:
- break;
- case PAT_UNCACHED:
- case PAT_WRITE_COMBINING:
- case PAT_WRITE_PROTECTED:
- mode = PAT_UNCACHEABLE;
- break;
- }
- }
-
- /* Map the caching mode to a PAT index. */
- if (pat_works) {
- switch (mode) {
- case PAT_UNCACHEABLE:
- pat_index = 3;
- break;
- case PAT_WRITE_THROUGH:
- pat_index = 1;
- break;
- case PAT_WRITE_BACK:
- pat_index = 0;
- break;
- case PAT_UNCACHED:
- pat_index = 2;
- break;
- case PAT_WRITE_COMBINING:
- pat_index = 5;
- break;
- case PAT_WRITE_PROTECTED:
- pat_index = 4;
- break;
- default:
- panic("Unknown caching mode %d\n", mode);
- }
- } else {
- switch (mode) {
- case PAT_UNCACHED:
- case PAT_UNCACHEABLE:
- case PAT_WRITE_PROTECTED:
- pat_index = 3;
- break;
- case PAT_WRITE_THROUGH:
- pat_index = 1;
- break;
- case PAT_WRITE_BACK:
- pat_index = 0;
- break;
- case PAT_WRITE_COMBINING:
- pat_index = 2;
- break;
- default:
- panic("Unknown caching mode %d\n", mode);
- }
- }
-
- /* Map the 3-bit index value into the PAT, PCD, and PWT bits. */
- cache_bits = 0;
- if (pat_index & 0x4)
- cache_bits |= pat_flag;
- if (pat_index & 0x2)
- cache_bits |= PG_NC_PCD;
- if (pat_index & 0x1)
- cache_bits |= PG_NC_PWT;
- return (cache_bits);
-}
-#ifdef SMP
-/*
- * For SMP, these functions have to use the IPI mechanism for coherence.
- *
- * N.B.: Before calling any of the following TLB invalidation functions,
- * the calling processor must ensure that all stores updating a non-
- * kernel page table are globally performed. Otherwise, another
- * processor could cache an old, pre-update entry without being
- * invalidated. This can happen one of two ways: (1) The pmap becomes
- * active on another processor after its pm_active field is checked by
- * one of the following functions but before a store updating the page
- * table is globally performed. (2) The pmap becomes active on another
- * processor before its pm_active field is checked but due to
- * speculative loads one of the following functions stills reads the
- * pmap as inactive on the other processor.
- *
- * The kernel page table is exempt because its pm_active field is
- * immutable. The kernel page table is always active on every
- * processor.
- */
-void
-pmap_invalidate_page(pmap_t pmap, vm_offset_t va)
-{
- cpuset_t other_cpus;
- u_int cpuid;
-
- CTR2(KTR_PMAP, "pmap_invalidate_page: pmap=%p va=0x%x",
- pmap, va);
-
- sched_pin();
- if (pmap == kernel_pmap || !CPU_CMP(&pmap->pm_active, &all_cpus)) {
- invlpg(va);
- smp_invlpg(va);
- } else {
- cpuid = PCPU_GET(cpuid);
- other_cpus = all_cpus;
- CPU_CLR(cpuid, &other_cpus);
- if (CPU_ISSET(cpuid, &pmap->pm_active))
- invlpg(va);
- CPU_AND(&other_cpus, &pmap->pm_active);
- if (!CPU_EMPTY(&other_cpus))
- smp_masked_invlpg(other_cpus, va);
- }
- sched_unpin();
- PT_UPDATES_FLUSH();
-}
-
-void
-pmap_invalidate_range(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
-{
- cpuset_t other_cpus;
- vm_offset_t addr;
- u_int cpuid;
-
- CTR3(KTR_PMAP, "pmap_invalidate_page: pmap=%p eva=0x%x sva=0x%x",
- pmap, sva, eva);
-
- sched_pin();
- if (pmap == kernel_pmap || !CPU_CMP(&pmap->pm_active, &all_cpus)) {
- for (addr = sva; addr < eva; addr += PAGE_SIZE)
- invlpg(addr);
- smp_invlpg_range(sva, eva);
- } else {
- cpuid = PCPU_GET(cpuid);
- other_cpus = all_cpus;
- CPU_CLR(cpuid, &other_cpus);
- if (CPU_ISSET(cpuid, &pmap->pm_active))
- for (addr = sva; addr < eva; addr += PAGE_SIZE)
- invlpg(addr);
- CPU_AND(&other_cpus, &pmap->pm_active);
- if (!CPU_EMPTY(&other_cpus))
- smp_masked_invlpg_range(other_cpus, sva, eva);
- }
- sched_unpin();
- PT_UPDATES_FLUSH();
-}
-
-void
-pmap_invalidate_all(pmap_t pmap)
-{
- cpuset_t other_cpus;
- u_int cpuid;
-
- CTR1(KTR_PMAP, "pmap_invalidate_page: pmap=%p", pmap);
-
- sched_pin();
- if (pmap == kernel_pmap || !CPU_CMP(&pmap->pm_active, &all_cpus)) {
- invltlb();
- smp_invltlb();
- } else {
- cpuid = PCPU_GET(cpuid);
- other_cpus = all_cpus;
- CPU_CLR(cpuid, &other_cpus);
- if (CPU_ISSET(cpuid, &pmap->pm_active))
- invltlb();
- CPU_AND(&other_cpus, &pmap->pm_active);
- if (!CPU_EMPTY(&other_cpus))
- smp_masked_invltlb(other_cpus);
- }
- sched_unpin();
-}
-
-void
-pmap_invalidate_cache(void)
-{
-
- sched_pin();
- wbinvd();
- smp_cache_flush();
- sched_unpin();
-}
-#else /* !SMP */
-/*
- * Normal, non-SMP, 486+ invalidation functions.
- * We inline these within pmap.c for speed.
- */
-PMAP_INLINE void
-pmap_invalidate_page(pmap_t pmap, vm_offset_t va)
-{
- CTR2(KTR_PMAP, "pmap_invalidate_page: pmap=%p va=0x%x",
- pmap, va);
-
- if (pmap == kernel_pmap || !CPU_EMPTY(&pmap->pm_active))
- invlpg(va);
- PT_UPDATES_FLUSH();
-}
-
-PMAP_INLINE void
-pmap_invalidate_range(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
-{
- vm_offset_t addr;
-
- if (eva - sva > PAGE_SIZE)
- CTR3(KTR_PMAP, "pmap_invalidate_range: pmap=%p sva=0x%x eva=0x%x",
- pmap, sva, eva);
-
- if (pmap == kernel_pmap || !CPU_EMPTY(&pmap->pm_active))
- for (addr = sva; addr < eva; addr += PAGE_SIZE)
- invlpg(addr);
- PT_UPDATES_FLUSH();
-}
-
-PMAP_INLINE void
-pmap_invalidate_all(pmap_t pmap)
-{
-
- CTR1(KTR_PMAP, "pmap_invalidate_all: pmap=%p", pmap);
-
- if (pmap == kernel_pmap || !CPU_EMPTY(&pmap->pm_active))
- invltlb();
-}
-
-PMAP_INLINE void
-pmap_invalidate_cache(void)
-{
-
- wbinvd();
-}
-#endif /* !SMP */
-
-#define PMAP_CLFLUSH_THRESHOLD (2 * 1024 * 1024)
-
-void
-pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva, boolean_t force)
-{
-
- if (force) {
- sva &= ~(vm_offset_t)cpu_clflush_line_size;
- } else {
- KASSERT((sva & PAGE_MASK) == 0,
- ("pmap_invalidate_cache_range: sva not page-aligned"));
- KASSERT((eva & PAGE_MASK) == 0,
- ("pmap_invalidate_cache_range: eva not page-aligned"));
- }
-
- if ((cpu_feature & CPUID_SS) != 0 && !force)
- ; /* If "Self Snoop" is supported, do nothing. */
- else if ((cpu_feature & CPUID_CLFSH) != 0 &&
- eva - sva < PMAP_CLFLUSH_THRESHOLD) {
-
- /*
- * Otherwise, do per-cache line flush. Use the mfence
- * instruction to insure that previous stores are
- * included in the write-back. The processor
- * propagates flush to other processors in the cache
- * coherence domain.
- */
- mfence();
- for (; sva < eva; sva += cpu_clflush_line_size)
- clflush(sva);
- mfence();
- } else {
-
- /*
- * No targeted cache flush methods are supported by CPU,
- * or the supplied range is bigger than 2MB.
- * Globally invalidate cache.
- */
- pmap_invalidate_cache();
- }
-}
-
-void
-pmap_invalidate_cache_pages(vm_page_t *pages, int count)
-{
- int i;
-
- if (count >= PMAP_CLFLUSH_THRESHOLD / PAGE_SIZE ||
- (cpu_feature & CPUID_CLFSH) == 0) {
- pmap_invalidate_cache();
- } else {
- for (i = 0; i < count; i++)
- pmap_flush_page(pages[i]);
- }
-}
-
-/*
- * Are we current address space or kernel? N.B. We return FALSE when
- * a pmap's page table is in use because a kernel thread is borrowing
- * it. The borrowed page table can change spontaneously, making any
- * dependence on its continued use subject to a race condition.
- */
-static __inline int
-pmap_is_current(pmap_t pmap)
-{
-
- return (pmap == kernel_pmap ||
- (pmap == vmspace_pmap(curthread->td_proc->p_vmspace) &&
- (pmap->pm_pdir[PTDPTDI] & PG_FRAME) == (PTDpde[0] & PG_FRAME)));
-}
-
-/*
- * If the given pmap is not the current or kernel pmap, the returned pte must
- * be released by passing it to pmap_pte_release().
- */
-pt_entry_t *
-pmap_pte(pmap_t pmap, vm_offset_t va)
-{
- pd_entry_t newpf;
- pd_entry_t *pde;
-
- pde = pmap_pde(pmap, va);
- if (*pde & PG_PS)
- return (pde);
- if (*pde != 0) {
- /* are we current address space or kernel? */
- if (pmap_is_current(pmap))
- return (vtopte(va));
- mtx_lock(&PMAP2mutex);
- newpf = *pde & PG_FRAME;
- if ((*PMAP2 & PG_FRAME) != newpf) {
- PT_SET_MA(PADDR2, newpf | PG_V | PG_A | PG_M);
- CTR3(KTR_PMAP, "pmap_pte: pmap=%p va=0x%x newpte=0x%08x",
- pmap, va, (*PMAP2 & 0xffffffff));
- }
- return (PADDR2 + (i386_btop(va) & (NPTEPG - 1)));
- }
- return (NULL);
-}
-
-/*
- * Releases a pte that was obtained from pmap_pte(). Be prepared for the pte
- * being NULL.
- */
-static __inline void
-pmap_pte_release(pt_entry_t *pte)
-{
-
- if ((pt_entry_t *)((vm_offset_t)pte & ~PAGE_MASK) == PADDR2) {
- CTR1(KTR_PMAP, "pmap_pte_release: pte=0x%jx",
- *PMAP2);
- rw_wlock(&pvh_global_lock);
- PT_SET_VA(PMAP2, 0, TRUE);
- rw_wunlock(&pvh_global_lock);
- mtx_unlock(&PMAP2mutex);
- }
-}
-
-static __inline void
-invlcaddr(void *caddr)
-{
-
- invlpg((u_int)caddr);
- PT_UPDATES_FLUSH();
-}
-
-/*
- * Super fast pmap_pte routine best used when scanning
- * the pv lists. This eliminates many coarse-grained
- * invltlb calls. Note that many of the pv list
- * scans are across different pmaps. It is very wasteful
- * to do an entire invltlb for checking a single mapping.
- *
- * If the given pmap is not the current pmap, pvh_global_lock
- * must be held and curthread pinned to a CPU.
- */
-static pt_entry_t *
-pmap_pte_quick(pmap_t pmap, vm_offset_t va)
-{
- pd_entry_t newpf;
- pd_entry_t *pde;
-
- pde = pmap_pde(pmap, va);
- if (*pde & PG_PS)
- return (pde);
- if (*pde != 0) {
- /* are we current address space or kernel? */
- if (pmap_is_current(pmap))
- return (vtopte(va));
- rw_assert(&pvh_global_lock, RA_WLOCKED);
- KASSERT(curthread->td_pinned > 0, ("curthread not pinned"));
- newpf = *pde & PG_FRAME;
- if ((*PMAP1 & PG_FRAME) != newpf) {
- PT_SET_MA(PADDR1, newpf | PG_V | PG_A | PG_M);
- CTR3(KTR_PMAP, "pmap_pte_quick: pmap=%p va=0x%x newpte=0x%08x",
- pmap, va, (u_long)*PMAP1);
-
-#ifdef SMP
- PMAP1cpu = PCPU_GET(cpuid);
-#endif
- PMAP1changed++;
- } else
-#ifdef SMP
- if (PMAP1cpu != PCPU_GET(cpuid)) {
- PMAP1cpu = PCPU_GET(cpuid);
- invlcaddr(PADDR1);
- PMAP1changedcpu++;
- } else
-#endif
- PMAP1unchanged++;
- return (PADDR1 + (i386_btop(va) & (NPTEPG - 1)));
- }
- return (0);
-}
-
-/*
- * Routine: pmap_extract
- * Function:
- * Extract the physical page address associated
- * with the given map/virtual_address pair.
- */
-vm_paddr_t
-pmap_extract(pmap_t pmap, vm_offset_t va)
-{
- vm_paddr_t rtval;
- pt_entry_t *pte;
- pd_entry_t pde;
- pt_entry_t pteval;
-
- rtval = 0;
- PMAP_LOCK(pmap);
- pde = pmap->pm_pdir[va >> PDRSHIFT];
- if (pde != 0) {
- if ((pde & PG_PS) != 0) {
- rtval = xpmap_mtop(pde & PG_PS_FRAME) | (va & PDRMASK);
- PMAP_UNLOCK(pmap);
- return rtval;
- }
- pte = pmap_pte(pmap, va);
- pteval = *pte ? xpmap_mtop(*pte) : 0;
- rtval = (pteval & PG_FRAME) | (va & PAGE_MASK);
- pmap_pte_release(pte);
- }
- PMAP_UNLOCK(pmap);
- return (rtval);
-}
-
-/*
- * Routine: pmap_extract_ma
- * Function:
- * Like pmap_extract, but returns machine address
- */
-vm_paddr_t
-pmap_extract_ma(pmap_t pmap, vm_offset_t va)
-{
- vm_paddr_t rtval;
- pt_entry_t *pte;
- pd_entry_t pde;
-
- rtval = 0;
- PMAP_LOCK(pmap);
- pde = pmap->pm_pdir[va >> PDRSHIFT];
- if (pde != 0) {
- if ((pde & PG_PS) != 0) {
- rtval = (pde & ~PDRMASK) | (va & PDRMASK);
- PMAP_UNLOCK(pmap);
- return rtval;
- }
- pte = pmap_pte(pmap, va);
- rtval = (*pte & PG_FRAME) | (va & PAGE_MASK);
- pmap_pte_release(pte);
- }
- PMAP_UNLOCK(pmap);
- return (rtval);
-}
-
-/*
- * Routine: pmap_extract_and_hold
- * Function:
- * Atomically extract and hold the physical page
- * with the given pmap and virtual address pair
- * if that mapping permits the given protection.
- */
-vm_page_t
-pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot)
-{
- pd_entry_t pde;
- pt_entry_t pte, *ptep;
- vm_page_t m;
- vm_paddr_t pa;
-
- pa = 0;
- m = NULL;
- PMAP_LOCK(pmap);
-retry:
- pde = PT_GET(pmap_pde(pmap, va));
- if (pde != 0) {
- if (pde & PG_PS) {
- if ((pde & PG_RW) || (prot & VM_PROT_WRITE) == 0) {
- if (vm_page_pa_tryrelock(pmap, (pde &
- PG_PS_FRAME) | (va & PDRMASK), &pa))
- goto retry;
- m = PHYS_TO_VM_PAGE((pde & PG_PS_FRAME) |
- (va & PDRMASK));
- vm_page_hold(m);
- }
- } else {
- ptep = pmap_pte(pmap, va);
- pte = PT_GET(ptep);
- pmap_pte_release(ptep);
- if (pte != 0 &&
- ((pte & PG_RW) || (prot & VM_PROT_WRITE) == 0)) {
- if (vm_page_pa_tryrelock(pmap, pte & PG_FRAME,
- &pa))
- goto retry;
- m = PHYS_TO_VM_PAGE(pte & PG_FRAME);
- vm_page_hold(m);
- }
- }
- }
- PA_UNLOCK_COND(pa);
- PMAP_UNLOCK(pmap);
- return (m);
-}
-
-/***************************************************
- * Low level mapping routines.....
- ***************************************************/
-
-/*
- * Add a wired page to the kva.
- * Note: not SMP coherent.
- *
- * This function may be used before pmap_bootstrap() is called.
- */
-void
-pmap_kenter(vm_offset_t va, vm_paddr_t pa)
-{
-
- PT_SET_MA(va, xpmap_ptom(pa)| PG_RW | PG_V | pgeflag);
-}
-
-void
-pmap_kenter_ma(vm_offset_t va, vm_paddr_t ma)
-{
- pt_entry_t *pte;
-
- pte = vtopte(va);
- pte_store_ma(pte, ma | PG_RW | PG_V | pgeflag);
-}
-
-static __inline void
-pmap_kenter_attr(vm_offset_t va, vm_paddr_t pa, int mode)
-{
-
- PT_SET_MA(va, pa | PG_RW | PG_V | pgeflag | pmap_cache_bits(mode, 0));
-}
-
-/*
- * Remove a page from the kernel pagetables.
- * Note: not SMP coherent.
- *
- * This function may be used before pmap_bootstrap() is called.
- */
-PMAP_INLINE void
-pmap_kremove(vm_offset_t va)
-{
- pt_entry_t *pte;
-
- pte = vtopte(va);
- PT_CLEAR_VA(pte, FALSE);
-}
-
-/*
- * Used to map a range of physical addresses into kernel
- * virtual address space.
- *
- * The value passed in '*virt' is a suggested virtual address for
- * the mapping. Architectures which can support a direct-mapped
- * physical to virtual region can return the appropriate address
- * within that region, leaving '*virt' unchanged. Other
- * architectures should map the pages starting at '*virt' and
- * update '*virt' with the first usable address after the mapped
- * region.
- */
-vm_offset_t
-pmap_map(vm_offset_t *virt, vm_paddr_t start, vm_paddr_t end, int prot)
-{
- vm_offset_t va, sva;
-
- va = sva = *virt;
- CTR4(KTR_PMAP, "pmap_map: va=0x%x start=0x%jx end=0x%jx prot=0x%x",
- va, start, end, prot);
- while (start < end) {
- pmap_kenter(va, start);
- va += PAGE_SIZE;
- start += PAGE_SIZE;
- }
- pmap_invalidate_range(kernel_pmap, sva, va);
- *virt = va;
- return (sva);
-}
-
-
-/*
- * Add a list of wired pages to the kva
- * this routine is only used for temporary
- * kernel mappings that do not need to have
- * page modification or references recorded.
- * Note that old mappings are simply written
- * over. The page *must* be wired.
- * Note: SMP coherent. Uses a ranged shootdown IPI.
- */
-void
-pmap_qenter(vm_offset_t sva, vm_page_t *ma, int count)
-{
- pt_entry_t *endpte, *pte;
- vm_paddr_t pa;
- vm_offset_t va = sva;
- int mclcount = 0;
- multicall_entry_t mcl[16];
- multicall_entry_t *mclp = mcl;
- int error;
-
- CTR2(KTR_PMAP, "pmap_qenter:sva=0x%x count=%d", va, count);
- pte = vtopte(sva);
- endpte = pte + count;
- while (pte < endpte) {
- pa = VM_PAGE_TO_MACH(*ma) | pgeflag | PG_RW | PG_V | PG_M | PG_A;
-
- mclp->op = __HYPERVISOR_update_va_mapping;
- mclp->args[0] = va;
- mclp->args[1] = (uint32_t)(pa & 0xffffffff);
- mclp->args[2] = (uint32_t)(pa >> 32);
- mclp->args[3] = (*pte & PG_V) ? UVMF_INVLPG|UVMF_ALL : 0;
-
- va += PAGE_SIZE;
- pte++;
- ma++;
- mclp++;
- mclcount++;
- if (mclcount == 16) {
- error = HYPERVISOR_multicall(mcl, mclcount);
- mclp = mcl;
- mclcount = 0;
- KASSERT(error == 0, ("bad multicall %d", error));
- }
- }
- if (mclcount) {
- error = HYPERVISOR_multicall(mcl, mclcount);
- KASSERT(error == 0, ("bad multicall %d", error));
- }
-
-#ifdef INVARIANTS
- for (pte = vtopte(sva), mclcount = 0; mclcount < count; mclcount++, pte++)
- KASSERT(*pte, ("pte not set for va=0x%x", sva + mclcount*PAGE_SIZE));
-#endif
-}
-
-/*
- * This routine tears out page mappings from the
- * kernel -- it is meant only for temporary mappings.
- * Note: SMP coherent. Uses a ranged shootdown IPI.
- */
-void
-pmap_qremove(vm_offset_t sva, int count)
-{
- vm_offset_t va;
-
- CTR2(KTR_PMAP, "pmap_qremove: sva=0x%x count=%d", sva, count);
- va = sva;
- rw_wlock(&pvh_global_lock);
- critical_enter();
- while (count-- > 0) {
- pmap_kremove(va);
- va += PAGE_SIZE;
- }
- PT_UPDATES_FLUSH();
- pmap_invalidate_range(kernel_pmap, sva, va);
- critical_exit();
- rw_wunlock(&pvh_global_lock);
-}
-
-/***************************************************
- * Page table page management routines.....
- ***************************************************/
-static __inline void
-pmap_free_zero_pages(vm_page_t free)
-{
- vm_page_t m;
-
- while (free != NULL) {
- m = free;
- free = (void *)m->object;
- m->object = NULL;
- vm_page_free_zero(m);
- }
-}
-
-/*
- * Decrements a page table page's wire count, which is used to record the
- * number of valid page table entries within the page. If the wire count
- * drops to zero, then the page table page is unmapped. Returns TRUE if the
- * page table page was unmapped and FALSE otherwise.
- */
-static inline boolean_t
-pmap_unwire_ptp(pmap_t pmap, vm_page_t m, vm_page_t *free)
-{
-
- --m->wire_count;
- if (m->wire_count == 0) {
- _pmap_unwire_ptp(pmap, m, free);
- return (TRUE);
- } else
- return (FALSE);
-}
-
-static void
-_pmap_unwire_ptp(pmap_t pmap, vm_page_t m, vm_page_t *free)
-{
- vm_offset_t pteva;
-
- PT_UPDATES_FLUSH();
- /*
- * unmap the page table page
- */
- xen_pt_unpin(pmap->pm_pdir[m->pindex]);
- /*
- * page *might* contain residual mapping :-/
- */
- PD_CLEAR_VA(pmap, m->pindex, TRUE);
- pmap_zero_page(m);
- --pmap->pm_stats.resident_count;
-
- /*
- * This is a release store so that the ordinary store unmapping
- * the page table page is globally performed before TLB shoot-
- * down is begun.
- */
- atomic_subtract_rel_int(&vm_cnt.v_wire_count, 1);
-
- /*
- * Do an invltlb to make the invalidated mapping
- * take effect immediately.
- */
- pteva = VM_MAXUSER_ADDRESS + i386_ptob(m->pindex);
- pmap_invalidate_page(pmap, pteva);
-
- /*
- * Put page on a list so that it is released after
- * *ALL* TLB shootdown is done
- */
- m->object = (void *)*free;
- *free = m;
-}
-
-/*
- * After removing a page table entry, this routine is used to
- * conditionally free the page, and manage the hold/wire counts.
- */
-static int
-pmap_unuse_pt(pmap_t pmap, vm_offset_t va, vm_page_t *free)
-{
- pd_entry_t ptepde;
- vm_page_t mpte;
-
- if (va >= VM_MAXUSER_ADDRESS)
- return (0);
- ptepde = PT_GET(pmap_pde(pmap, va));
- mpte = PHYS_TO_VM_PAGE(ptepde & PG_FRAME);
- return (pmap_unwire_ptp(pmap, mpte, free));
-}
-
-/*
- * Initialize the pmap for the swapper process.
- */
-void
-pmap_pinit0(pmap_t pmap)
-{
-
- PMAP_LOCK_INIT(pmap);
- /*
- * Since the page table directory is shared with the kernel pmap,
- * which is already included in the list "allpmaps", this pmap does
- * not need to be inserted into that list.
- */
- pmap->pm_pdir = (pd_entry_t *)(KERNBASE + (vm_offset_t)IdlePTD);
-#ifdef PAE
- pmap->pm_pdpt = (pdpt_entry_t *)(KERNBASE + (vm_offset_t)IdlePDPT);
-#endif
- CPU_ZERO(&pmap->pm_active);
- PCPU_SET(curpmap, pmap);
- TAILQ_INIT(&pmap->pm_pvchunk);
- bzero(&pmap->pm_stats, sizeof pmap->pm_stats);
-}
-
-/*
- * Initialize a preallocated and zeroed pmap structure,
- * such as one in a vmspace structure.
- */
-int
-pmap_pinit(pmap_t pmap)
-{
- vm_page_t m, ptdpg[NPGPTD + 1];
- int npgptd = NPGPTD + 1;
- int i;
-
-#ifdef HAMFISTED_LOCKING
- mtx_lock(&createdelete_lock);
-#endif
-
- /*
- * No need to allocate page table space yet but we do need a valid
- * page directory table.
- */
- if (pmap->pm_pdir == NULL) {
- pmap->pm_pdir = (pd_entry_t *)kva_alloc(NBPTD);
- if (pmap->pm_pdir == NULL) {
-#ifdef HAMFISTED_LOCKING
- mtx_unlock(&createdelete_lock);
-#endif
- return (0);
- }
-#ifdef PAE
- pmap->pm_pdpt = (pd_entry_t *)kva_alloc(1);
-#endif
- }
-
- /*
- * allocate the page directory page(s)
- */
- for (i = 0; i < npgptd;) {
- m = vm_page_alloc(NULL, 0, VM_ALLOC_NORMAL | VM_ALLOC_NOOBJ |
- VM_ALLOC_WIRED | VM_ALLOC_ZERO);
- if (m == NULL)
- VM_WAIT;
- else {
- ptdpg[i++] = m;
- }
- }
-
- pmap_qenter((vm_offset_t)pmap->pm_pdir, ptdpg, NPGPTD);
-
- for (i = 0; i < NPGPTD; i++)
- if ((ptdpg[i]->flags & PG_ZERO) == 0)
- pagezero(pmap->pm_pdir + (i * NPDEPG));
-
- mtx_lock_spin(&allpmaps_lock);
- LIST_INSERT_HEAD(&allpmaps, pmap, pm_list);
- /* Copy the kernel page table directory entries. */
- bcopy(PTD + KPTDI, pmap->pm_pdir + KPTDI, nkpt * sizeof(pd_entry_t));
- mtx_unlock_spin(&allpmaps_lock);
-
-#ifdef PAE
- pmap_qenter((vm_offset_t)pmap->pm_pdpt, &ptdpg[NPGPTD], 1);
- if ((ptdpg[NPGPTD]->flags & PG_ZERO) == 0)
- bzero(pmap->pm_pdpt, PAGE_SIZE);
- for (i = 0; i < NPGPTD; i++) {
- vm_paddr_t ma;
-
- ma = VM_PAGE_TO_MACH(ptdpg[i]);
- pmap->pm_pdpt[i] = ma | PG_V;
-
- }
-#endif
- for (i = 0; i < NPGPTD; i++) {
- pt_entry_t *pd;
- vm_paddr_t ma;
-
- ma = VM_PAGE_TO_MACH(ptdpg[i]);
- pd = pmap->pm_pdir + (i * NPDEPG);
- PT_SET_MA(pd, *vtopte((vm_offset_t)pd) & ~(PG_M|PG_A|PG_U|PG_RW));
-#if 0
- xen_pgd_pin(ma);
-#endif
- }
-
-#ifdef PAE
- PT_SET_MA(pmap->pm_pdpt, *vtopte((vm_offset_t)pmap->pm_pdpt) & ~PG_RW);
-#endif
- rw_wlock(&pvh_global_lock);
- xen_flush_queue();
- xen_pgdpt_pin(VM_PAGE_TO_MACH(ptdpg[NPGPTD]));
- for (i = 0; i < NPGPTD; i++) {
- vm_paddr_t ma = VM_PAGE_TO_MACH(ptdpg[i]);
- PT_SET_VA_MA(&pmap->pm_pdir[PTDPTDI + i], ma | PG_V | PG_A, FALSE);
- }
- xen_flush_queue();
- rw_wunlock(&pvh_global_lock);
- CPU_ZERO(&pmap->pm_active);
- TAILQ_INIT(&pmap->pm_pvchunk);
- bzero(&pmap->pm_stats, sizeof pmap->pm_stats);
-
-#ifdef HAMFISTED_LOCKING
- mtx_unlock(&createdelete_lock);
-#endif
- return (1);
-}
-
-/*
- * this routine is called if the page table page is not
- * mapped correctly.
- */
-static vm_page_t
-_pmap_allocpte(pmap_t pmap, u_int ptepindex, u_int flags)
-{
- vm_paddr_t ptema;
- vm_page_t m;
-
- /*
- * Allocate a page table page.
- */
- if ((m = vm_page_alloc(NULL, ptepindex, VM_ALLOC_NOOBJ |
- VM_ALLOC_WIRED | VM_ALLOC_ZERO)) == NULL) {
- if ((flags & PMAP_ENTER_NOSLEEP) == 0) {
- PMAP_UNLOCK(pmap);
- rw_wunlock(&pvh_global_lock);
- VM_WAIT;
- rw_wlock(&pvh_global_lock);
- PMAP_LOCK(pmap);
- }
-
- /*
- * Indicate the need to retry. While waiting, the page table
- * page may have been allocated.
- */
- return (NULL);
- }
- if ((m->flags & PG_ZERO) == 0)
- pmap_zero_page(m);
-
- /*
- * Map the pagetable page into the process address space, if
- * it isn't already there.
- */
-
- pmap->pm_stats.resident_count++;
-
- ptema = VM_PAGE_TO_MACH(m);
- xen_pt_pin(ptema);
- PT_SET_VA_MA(&pmap->pm_pdir[ptepindex],
- (ptema | PG_U | PG_RW | PG_V | PG_A | PG_M), TRUE);
-
- KASSERT(pmap->pm_pdir[ptepindex],
- ("_pmap_allocpte: ptepindex=%d did not get mapped", ptepindex));
- return (m);
-}
-
-static vm_page_t
-pmap_allocpte(pmap_t pmap, vm_offset_t va, u_int flags)
-{
- u_int ptepindex;
- pd_entry_t ptema;
- vm_page_t m;
-
- /*
- * Calculate pagetable page index
- */
- ptepindex = va >> PDRSHIFT;
-retry:
- /*
- * Get the page directory entry
- */
- ptema = pmap->pm_pdir[ptepindex];
-
- /*
- * This supports switching from a 4MB page to a
- * normal 4K page.
- */
- if (ptema & PG_PS) {
- /*
- * XXX
- */
- pmap->pm_pdir[ptepindex] = 0;
- ptema = 0;
- pmap->pm_stats.resident_count -= NBPDR / PAGE_SIZE;
- pmap_invalidate_all(kernel_pmap);
- }
-
- /*
- * If the page table page is mapped, we just increment the
- * hold count, and activate it.
- */
- if (ptema & PG_V) {
- m = PHYS_TO_VM_PAGE(xpmap_mtop(ptema) & PG_FRAME);
- m->wire_count++;
- } else {
- /*
- * Here if the pte page isn't mapped, or if it has
- * been deallocated.
- */
- CTR3(KTR_PMAP, "pmap_allocpte: pmap=%p va=0x%08x flags=0x%x",
- pmap, va, flags);
- m = _pmap_allocpte(pmap, ptepindex, flags);
- if (m == NULL && (flags & PMAP_ENTER_NOSLEEP) == 0)
- goto retry;
-
- KASSERT(pmap->pm_pdir[ptepindex], ("ptepindex=%d did not get mapped", ptepindex));
- }
- return (m);
-}
-
-
-/***************************************************
-* Pmap allocation/deallocation routines.
- ***************************************************/
-
-
-/*
- * Release any resources held by the given physical map.
- * Called when a pmap initialized by pmap_pinit is being released.
- * Should only be called if the map contains no valid mappings.
- */
-void
-pmap_release(pmap_t pmap)
-{
- vm_page_t m, ptdpg[2*NPGPTD+1];
- vm_paddr_t ma;
- int i;
-#ifdef PAE
- int npgptd = NPGPTD + 1;
-#else
- int npgptd = NPGPTD;
-#endif
-
- KASSERT(pmap->pm_stats.resident_count == 0,
- ("pmap_release: pmap resident count %ld != 0",
- pmap->pm_stats.resident_count));
- PT_UPDATES_FLUSH();
-
-#ifdef HAMFISTED_LOCKING
- mtx_lock(&createdelete_lock);
-#endif
-
- KASSERT(CPU_EMPTY(&pmap->pm_active),
- ("releasing active pmap %p", pmap));
- mtx_lock_spin(&allpmaps_lock);
- LIST_REMOVE(pmap, pm_list);
- mtx_unlock_spin(&allpmaps_lock);
-
- for (i = 0; i < NPGPTD; i++)
- ptdpg[i] = PHYS_TO_VM_PAGE(vtophys(pmap->pm_pdir + (i*NPDEPG)) & PG_FRAME);
- pmap_qremove((vm_offset_t)pmap->pm_pdir, NPGPTD);
-#ifdef PAE
- ptdpg[NPGPTD] = PHYS_TO_VM_PAGE(vtophys(pmap->pm_pdpt));
-#endif
-
- for (i = 0; i < npgptd; i++) {
- m = ptdpg[i];
- ma = VM_PAGE_TO_MACH(m);
- /* unpinning L1 and L2 treated the same */
-#if 0
- xen_pgd_unpin(ma);
-#else
- if (i == NPGPTD)
- xen_pgd_unpin(ma);
-#endif
-#ifdef PAE
- if (i < NPGPTD)
- KASSERT(VM_PAGE_TO_MACH(m) == (pmap->pm_pdpt[i] & PG_FRAME),
- ("pmap_release: got wrong ptd page"));
-#endif
- m->wire_count--;
- atomic_subtract_int(&vm_cnt.v_wire_count, 1);
- vm_page_free(m);
- }
-#ifdef PAE
- pmap_qremove((vm_offset_t)pmap->pm_pdpt, 1);
-#endif
-
-#ifdef HAMFISTED_LOCKING
- mtx_unlock(&createdelete_lock);
-#endif
-}
-
-static int
-kvm_size(SYSCTL_HANDLER_ARGS)
-{
- unsigned long ksize = VM_MAX_KERNEL_ADDRESS - KERNBASE;
-
- return (sysctl_handle_long(oidp, &ksize, 0, req));
-}
-SYSCTL_PROC(_vm, OID_AUTO, kvm_size, CTLTYPE_LONG|CTLFLAG_RD,
- 0, 0, kvm_size, "IU", "Size of KVM");
-
-static int
-kvm_free(SYSCTL_HANDLER_ARGS)
-{
- unsigned long kfree = VM_MAX_KERNEL_ADDRESS - kernel_vm_end;
-
- return (sysctl_handle_long(oidp, &kfree, 0, req));
-}
-SYSCTL_PROC(_vm, OID_AUTO, kvm_free, CTLTYPE_LONG|CTLFLAG_RD,
- 0, 0, kvm_free, "IU", "Amount of KVM free");
-
-/*
- * grow the number of kernel page table entries, if needed
- */
-void
-pmap_growkernel(vm_offset_t addr)
-{
- struct pmap *pmap;
- vm_paddr_t ptppaddr;
- vm_page_t nkpg;
- pd_entry_t newpdir;
-
- mtx_assert(&kernel_map->system_mtx, MA_OWNED);
- if (kernel_vm_end == 0) {
- kernel_vm_end = KERNBASE;
- nkpt = 0;
- while (pdir_pde(PTD, kernel_vm_end)) {
- kernel_vm_end = (kernel_vm_end + PAGE_SIZE * NPTEPG) & ~(PAGE_SIZE * NPTEPG - 1);
- nkpt++;
- if (kernel_vm_end - 1 >= kernel_map->max_offset) {
- kernel_vm_end = kernel_map->max_offset;
- break;
- }
- }
- }
- addr = roundup2(addr, NBPDR);
- if (addr - 1 >= kernel_map->max_offset)
- addr = kernel_map->max_offset;
- while (kernel_vm_end < addr) {
- if (pdir_pde(PTD, kernel_vm_end)) {
- kernel_vm_end = (kernel_vm_end + NBPDR) & ~PDRMASK;
- if (kernel_vm_end - 1 >= kernel_map->max_offset) {
- kernel_vm_end = kernel_map->max_offset;
- break;
- }
- continue;
- }
-
- nkpg = vm_page_alloc(NULL, kernel_vm_end >> PDRSHIFT,
- VM_ALLOC_INTERRUPT | VM_ALLOC_NOOBJ | VM_ALLOC_WIRED |
- VM_ALLOC_ZERO);
- if (nkpg == NULL)
- panic("pmap_growkernel: no memory to grow kernel");
-
- nkpt++;
-
- if ((nkpg->flags & PG_ZERO) == 0)
- pmap_zero_page(nkpg);
- ptppaddr = VM_PAGE_TO_PHYS(nkpg);
- newpdir = (pd_entry_t) (ptppaddr | PG_V | PG_RW | PG_A | PG_M);
- rw_wlock(&pvh_global_lock);
- PD_SET_VA(kernel_pmap, (kernel_vm_end >> PDRSHIFT), newpdir, TRUE);
- mtx_lock_spin(&allpmaps_lock);
- LIST_FOREACH(pmap, &allpmaps, pm_list)
- PD_SET_VA(pmap, (kernel_vm_end >> PDRSHIFT), newpdir, TRUE);
-
- mtx_unlock_spin(&allpmaps_lock);
- rw_wunlock(&pvh_global_lock);
-
- kernel_vm_end = (kernel_vm_end + NBPDR) & ~PDRMASK;
- if (kernel_vm_end - 1 >= kernel_map->max_offset) {
- kernel_vm_end = kernel_map->max_offset;
- break;
- }
- }
-}
-
-
-/***************************************************
- * page management routines.
- ***************************************************/
-
-CTASSERT(sizeof(struct pv_chunk) == PAGE_SIZE);
-CTASSERT(_NPCM == 11);
-CTASSERT(_NPCPV == 336);
-
-static __inline struct pv_chunk *
-pv_to_chunk(pv_entry_t pv)
-{
-
- return ((struct pv_chunk *)((uintptr_t)pv & ~(uintptr_t)PAGE_MASK));
-}
-
-#define PV_PMAP(pv) (pv_to_chunk(pv)->pc_pmap)
-
-#define PC_FREE0_9 0xfffffffful /* Free values for index 0 through 9 */
-#define PC_FREE10 0x0000fffful /* Free values for index 10 */
-
-static const uint32_t pc_freemask[_NPCM] = {
- PC_FREE0_9, PC_FREE0_9, PC_FREE0_9,
- PC_FREE0_9, PC_FREE0_9, PC_FREE0_9,
- PC_FREE0_9, PC_FREE0_9, PC_FREE0_9,
- PC_FREE0_9, PC_FREE10
-};
-
-SYSCTL_INT(_vm_pmap, OID_AUTO, pv_entry_count, CTLFLAG_RD, &pv_entry_count, 0,
- "Current number of pv entries");
-
-#ifdef PV_STATS
-static int pc_chunk_count, pc_chunk_allocs, pc_chunk_frees, pc_chunk_tryfail;
-
-SYSCTL_INT(_vm_pmap, OID_AUTO, pc_chunk_count, CTLFLAG_RD, &pc_chunk_count, 0,
- "Current number of pv entry chunks");
-SYSCTL_INT(_vm_pmap, OID_AUTO, pc_chunk_allocs, CTLFLAG_RD, &pc_chunk_allocs, 0,
- "Current number of pv entry chunks allocated");
-SYSCTL_INT(_vm_pmap, OID_AUTO, pc_chunk_frees, CTLFLAG_RD, &pc_chunk_frees, 0,
- "Current number of pv entry chunks frees");
-SYSCTL_INT(_vm_pmap, OID_AUTO, pc_chunk_tryfail, CTLFLAG_RD, &pc_chunk_tryfail, 0,
- "Number of times tried to get a chunk page but failed.");
-
-static long pv_entry_frees, pv_entry_allocs;
-static int pv_entry_spare;
-
-SYSCTL_LONG(_vm_pmap, OID_AUTO, pv_entry_frees, CTLFLAG_RD, &pv_entry_frees, 0,
- "Current number of pv entry frees");
-SYSCTL_LONG(_vm_pmap, OID_AUTO, pv_entry_allocs, CTLFLAG_RD, &pv_entry_allocs, 0,
- "Current number of pv entry allocs");
-SYSCTL_INT(_vm_pmap, OID_AUTO, pv_entry_spare, CTLFLAG_RD, &pv_entry_spare, 0,
- "Current number of spare pv entries");
-#endif
-
-/*
- * We are in a serious low memory condition. Resort to
- * drastic measures to free some pages so we can allocate
- * another pv entry chunk.
- */
-static vm_page_t
-pmap_pv_reclaim(pmap_t locked_pmap)
-{
- struct pch newtail;
- struct pv_chunk *pc;
- pmap_t pmap;
- pt_entry_t *pte, tpte;
- pv_entry_t pv;
- vm_offset_t va;
- vm_page_t free, m, m_pc;
- uint32_t inuse;
- int bit, field, freed;
-
- PMAP_LOCK_ASSERT(locked_pmap, MA_OWNED);
- pmap = NULL;
- free = m_pc = NULL;
- TAILQ_INIT(&newtail);
- while ((pc = TAILQ_FIRST(&pv_chunks)) != NULL && (pv_vafree == 0 ||
- free == NULL)) {
- TAILQ_REMOVE(&pv_chunks, pc, pc_lru);
- if (pmap != pc->pc_pmap) {
- if (pmap != NULL) {
- pmap_invalidate_all(pmap);
- if (pmap != locked_pmap)
- PMAP_UNLOCK(pmap);
- }
- pmap = pc->pc_pmap;
- /* Avoid deadlock and lock recursion. */
- if (pmap > locked_pmap)
- PMAP_LOCK(pmap);
- else if (pmap != locked_pmap && !PMAP_TRYLOCK(pmap)) {
- pmap = NULL;
- TAILQ_INSERT_TAIL(&newtail, pc, pc_lru);
- continue;
- }
- }
-
- /*
- * Destroy every non-wired, 4 KB page mapping in the chunk.
- */
- freed = 0;
- for (field = 0; field < _NPCM; field++) {
- for (inuse = ~pc->pc_map[field] & pc_freemask[field];
- inuse != 0; inuse &= ~(1UL << bit)) {
- bit = bsfl(inuse);
- pv = &pc->pc_pventry[field * 32 + bit];
- va = pv->pv_va;
- pte = pmap_pte(pmap, va);
- tpte = *pte;
- if ((tpte & PG_W) == 0)
- tpte = pte_load_clear(pte);
- pmap_pte_release(pte);
- if ((tpte & PG_W) != 0)
- continue;
- KASSERT(tpte != 0,
- ("pmap_pv_reclaim: pmap %p va %x zero pte",
- pmap, va));
- if ((tpte & PG_G) != 0)
- pmap_invalidate_page(pmap, va);
- m = PHYS_TO_VM_PAGE(tpte & PG_FRAME);
- if ((tpte & (PG_M | PG_RW)) == (PG_M | PG_RW))
- vm_page_dirty(m);
- if ((tpte & PG_A) != 0)
- vm_page_aflag_set(m, PGA_REFERENCED);
- TAILQ_REMOVE(&m->md.pv_list, pv, pv_next);
- if (TAILQ_EMPTY(&m->md.pv_list))
- vm_page_aflag_clear(m, PGA_WRITEABLE);
- pc->pc_map[field] |= 1UL << bit;
- pmap_unuse_pt(pmap, va, &free);
- freed++;
- }
- }
- if (freed == 0) {
- TAILQ_INSERT_TAIL(&newtail, pc, pc_lru);
- continue;
- }
- /* Every freed mapping is for a 4 KB page. */
- pmap->pm_stats.resident_count -= freed;
- PV_STAT(pv_entry_frees += freed);
- PV_STAT(pv_entry_spare += freed);
- pv_entry_count -= freed;
- TAILQ_REMOVE(&pmap->pm_pvchunk, pc, pc_list);
- for (field = 0; field < _NPCM; field++)
- if (pc->pc_map[field] != pc_freemask[field]) {
- TAILQ_INSERT_HEAD(&pmap->pm_pvchunk, pc,
- pc_list);
- TAILQ_INSERT_TAIL(&newtail, pc, pc_lru);
-
- /*
- * One freed pv entry in locked_pmap is
- * sufficient.
- */
- if (pmap == locked_pmap)
- goto out;
- break;
- }
- if (field == _NPCM) {
- PV_STAT(pv_entry_spare -= _NPCPV);
- PV_STAT(pc_chunk_count--);
- PV_STAT(pc_chunk_frees++);
- /* Entire chunk is free; return it. */
- m_pc = PHYS_TO_VM_PAGE(pmap_kextract((vm_offset_t)pc));
- pmap_qremove((vm_offset_t)pc, 1);
- pmap_ptelist_free(&pv_vafree, (vm_offset_t)pc);
- break;
- }
- }
-out:
- TAILQ_CONCAT(&pv_chunks, &newtail, pc_lru);
- if (pmap != NULL) {
- pmap_invalidate_all(pmap);
- if (pmap != locked_pmap)
- PMAP_UNLOCK(pmap);
- }
- if (m_pc == NULL && pv_vafree != 0 && free != NULL) {
- m_pc = free;
- free = (void *)m_pc->object;
- /* Recycle a freed page table page. */
- m_pc->wire_count = 1;
- atomic_add_int(&vm_cnt.v_wire_count, 1);
- }
- pmap_free_zero_pages(free);
- return (m_pc);
-}
-
-/*
- * free the pv_entry back to the free list
- */
-static void
-free_pv_entry(pmap_t pmap, pv_entry_t pv)
-{
- struct pv_chunk *pc;
- int idx, field, bit;
-
- rw_assert(&pvh_global_lock, RA_WLOCKED);
- PMAP_LOCK_ASSERT(pmap, MA_OWNED);
- PV_STAT(pv_entry_frees++);
- PV_STAT(pv_entry_spare++);
- pv_entry_count--;
- pc = pv_to_chunk(pv);
- idx = pv - &pc->pc_pventry[0];
- field = idx / 32;
- bit = idx % 32;
- pc->pc_map[field] |= 1ul << bit;
- for (idx = 0; idx < _NPCM; idx++)
- if (pc->pc_map[idx] != pc_freemask[idx]) {
- /*
- * 98% of the time, pc is already at the head of the
- * list. If it isn't already, move it to the head.
- */
- if (__predict_false(TAILQ_FIRST(&pmap->pm_pvchunk) !=
- pc)) {
- TAILQ_REMOVE(&pmap->pm_pvchunk, pc, pc_list);
- TAILQ_INSERT_HEAD(&pmap->pm_pvchunk, pc,
- pc_list);
- }
- return;
- }
- TAILQ_REMOVE(&pmap->pm_pvchunk, pc, pc_list);
- free_pv_chunk(pc);
-}
-
-static void
-free_pv_chunk(struct pv_chunk *pc)
-{
- vm_page_t m;
-
- TAILQ_REMOVE(&pv_chunks, pc, pc_lru);
- PV_STAT(pv_entry_spare -= _NPCPV);
- PV_STAT(pc_chunk_count--);
- PV_STAT(pc_chunk_frees++);
- /* entire chunk is free, return it */
- m = PHYS_TO_VM_PAGE(pmap_kextract((vm_offset_t)pc));
- pmap_qremove((vm_offset_t)pc, 1);
- vm_page_unwire(m, PQ_INACTIVE);
- vm_page_free(m);
- pmap_ptelist_free(&pv_vafree, (vm_offset_t)pc);
-}
-
-/*
- * get a new pv_entry, allocating a block from the system
- * when needed.
- */
-static pv_entry_t
-get_pv_entry(pmap_t pmap, boolean_t try)
-{
- static const struct timeval printinterval = { 60, 0 };
- static struct timeval lastprint;
- int bit, field;
- pv_entry_t pv;
- struct pv_chunk *pc;
- vm_page_t m;
-
- PMAP_LOCK_ASSERT(pmap, MA_OWNED);
- rw_assert(&pvh_global_lock, RA_WLOCKED);
- PV_STAT(pv_entry_allocs++);
- pv_entry_count++;
- if (pv_entry_count > pv_entry_high_water)
- if (ratecheck(&lastprint, &printinterval))
- printf("Approaching the limit on PV entries, consider "
- "increasing either the vm.pmap.shpgperproc or the "
- "vm.pmap.pv_entry_max tunable.\n");
-retry:
- pc = TAILQ_FIRST(&pmap->pm_pvchunk);
- if (pc != NULL) {
- for (field = 0; field < _NPCM; field++) {
- if (pc->pc_map[field]) {
- bit = bsfl(pc->pc_map[field]);
- break;
- }
- }
- if (field < _NPCM) {
- pv = &pc->pc_pventry[field * 32 + bit];
- pc->pc_map[field] &= ~(1ul << bit);
- /* If this was the last item, move it to tail */
- for (field = 0; field < _NPCM; field++)
- if (pc->pc_map[field] != 0) {
- PV_STAT(pv_entry_spare--);
- return (pv); /* not full, return */
- }
- TAILQ_REMOVE(&pmap->pm_pvchunk, pc, pc_list);
- TAILQ_INSERT_TAIL(&pmap->pm_pvchunk, pc, pc_list);
- PV_STAT(pv_entry_spare--);
- return (pv);
- }
- }
- /*
- * Access to the ptelist "pv_vafree" is synchronized by the page
- * queues lock. If "pv_vafree" is currently non-empty, it will
- * remain non-empty until pmap_ptelist_alloc() completes.
- */
- if (pv_vafree == 0 || (m = vm_page_alloc(NULL, 0, VM_ALLOC_NORMAL |
- VM_ALLOC_NOOBJ | VM_ALLOC_WIRED)) == NULL) {
- if (try) {
- pv_entry_count--;
- PV_STAT(pc_chunk_tryfail++);
- return (NULL);
- }
- m = pmap_pv_reclaim(pmap);
- if (m == NULL)
- goto retry;
- }
- PV_STAT(pc_chunk_count++);
- PV_STAT(pc_chunk_allocs++);
- pc = (struct pv_chunk *)pmap_ptelist_alloc(&pv_vafree);
- pmap_qenter((vm_offset_t)pc, &m, 1);
- if ((m->flags & PG_ZERO) == 0)
- pagezero(pc);
- pc->pc_pmap = pmap;
- pc->pc_map[0] = pc_freemask[0] & ~1ul; /* preallocated bit 0 */
- for (field = 1; field < _NPCM; field++)
- pc->pc_map[field] = pc_freemask[field];
- TAILQ_INSERT_TAIL(&pv_chunks, pc, pc_lru);
- pv = &pc->pc_pventry[0];
- TAILQ_INSERT_HEAD(&pmap->pm_pvchunk, pc, pc_list);
- PV_STAT(pv_entry_spare += _NPCPV - 1);
- return (pv);
-}
-
-static __inline pv_entry_t
-pmap_pvh_remove(struct md_page *pvh, pmap_t pmap, vm_offset_t va)
-{
- pv_entry_t pv;
-
- rw_assert(&pvh_global_lock, RA_WLOCKED);
- TAILQ_FOREACH(pv, &pvh->pv_list, pv_next) {
- if (pmap == PV_PMAP(pv) && va == pv->pv_va) {
- TAILQ_REMOVE(&pvh->pv_list, pv, pv_next);
- break;
- }
- }
- return (pv);
-}
-
-static void
-pmap_pvh_free(struct md_page *pvh, pmap_t pmap, vm_offset_t va)
-{
- pv_entry_t pv;
-
- pv = pmap_pvh_remove(pvh, pmap, va);
- KASSERT(pv != NULL, ("pmap_pvh_free: pv not found"));
- free_pv_entry(pmap, pv);
-}
-
-static void
-pmap_remove_entry(pmap_t pmap, vm_page_t m, vm_offset_t va)
-{
-
- rw_assert(&pvh_global_lock, RA_WLOCKED);
- pmap_pvh_free(&m->md, pmap, va);
- if (TAILQ_EMPTY(&m->md.pv_list))
- vm_page_aflag_clear(m, PGA_WRITEABLE);
-}
-
-/*
- * Conditionally create a pv entry.
- */
-static boolean_t
-pmap_try_insert_pv_entry(pmap_t pmap, vm_offset_t va, vm_page_t m)
-{
- pv_entry_t pv;
-
- PMAP_LOCK_ASSERT(pmap, MA_OWNED);
- rw_assert(&pvh_global_lock, RA_WLOCKED);
- if (pv_entry_count < pv_entry_high_water &&
- (pv = get_pv_entry(pmap, TRUE)) != NULL) {
- pv->pv_va = va;
- TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_next);
- return (TRUE);
- } else
- return (FALSE);
-}
-
-/*
- * pmap_remove_pte: do the things to unmap a page in a process
- */
-static int
-pmap_remove_pte(pmap_t pmap, pt_entry_t *ptq, vm_offset_t va, vm_page_t *free)
-{
- pt_entry_t oldpte;
- vm_page_t m;
-
- CTR3(KTR_PMAP, "pmap_remove_pte: pmap=%p *ptq=0x%x va=0x%x",
- pmap, (u_long)*ptq, va);
-
- rw_assert(&pvh_global_lock, RA_WLOCKED);
- PMAP_LOCK_ASSERT(pmap, MA_OWNED);
- oldpte = *ptq;
- PT_SET_VA_MA(ptq, 0, TRUE);
- KASSERT(oldpte != 0,
- ("pmap_remove_pte: pmap %p va %x zero pte", pmap, va));
- if (oldpte & PG_W)
- pmap->pm_stats.wired_count -= 1;
- /*
- * Machines that don't support invlpg, also don't support
- * PG_G.
- */
- if (oldpte & PG_G)
- pmap_invalidate_page(kernel_pmap, va);
- pmap->pm_stats.resident_count -= 1;
- if (oldpte & PG_MANAGED) {
- m = PHYS_TO_VM_PAGE(xpmap_mtop(oldpte) & PG_FRAME);
- if ((oldpte & (PG_M | PG_RW)) == (PG_M | PG_RW))
- vm_page_dirty(m);
- if (oldpte & PG_A)
- vm_page_aflag_set(m, PGA_REFERENCED);
- pmap_remove_entry(pmap, m, va);
- }
- return (pmap_unuse_pt(pmap, va, free));
-}
-
-/*
- * Remove a single page from a process address space
- */
-static void
-pmap_remove_page(pmap_t pmap, vm_offset_t va, vm_page_t *free)
-{
- pt_entry_t *pte;
-
- CTR2(KTR_PMAP, "pmap_remove_page: pmap=%p va=0x%x",
- pmap, va);
-
- rw_assert(&pvh_global_lock, RA_WLOCKED);
- KASSERT(curthread->td_pinned > 0, ("curthread not pinned"));
- PMAP_LOCK_ASSERT(pmap, MA_OWNED);
- if ((pte = pmap_pte_quick(pmap, va)) == NULL || (*pte & PG_V) == 0)
- return;
- pmap_remove_pte(pmap, pte, va, free);
- pmap_invalidate_page(pmap, va);
- if (*PMAP1)
- PT_SET_MA(PADDR1, 0);
-
-}
-
-/*
- * Remove the given range of addresses from the specified map.
- *
- * It is assumed that the start and end are properly
- * rounded to the page size.
- */
-void
-pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
-{
- vm_offset_t pdnxt;
- pd_entry_t ptpaddr;
- pt_entry_t *pte;
- vm_page_t free = NULL;
- int anyvalid;
-
- CTR3(KTR_PMAP, "pmap_remove: pmap=%p sva=0x%x eva=0x%x",
- pmap, sva, eva);
-
- /*
- * Perform an unsynchronized read. This is, however, safe.
- */
- if (pmap->pm_stats.resident_count == 0)
- return;
-
- anyvalid = 0;
-
- rw_wlock(&pvh_global_lock);
- sched_pin();
- PMAP_LOCK(pmap);
-
- /*
- * special handling of removing one page. a very
- * common operation and easy to short circuit some
- * code.
- */
- if ((sva + PAGE_SIZE == eva) &&
- ((pmap->pm_pdir[(sva >> PDRSHIFT)] & PG_PS) == 0)) {
- pmap_remove_page(pmap, sva, &free);
- goto out;
- }
-
- for (; sva < eva; sva = pdnxt) {
- u_int pdirindex;
-
- /*
- * Calculate index for next page table.
- */
- pdnxt = (sva + NBPDR) & ~PDRMASK;
- if (pdnxt < sva)
- pdnxt = eva;
- if (pmap->pm_stats.resident_count == 0)
- break;
-
- pdirindex = sva >> PDRSHIFT;
- ptpaddr = pmap->pm_pdir[pdirindex];
-
- /*
- * Weed out invalid mappings. Note: we assume that the page
- * directory table is always allocated, and in kernel virtual.
- */
- if (ptpaddr == 0)
- continue;
-
- /*
- * Check for large page.
- */
- if ((ptpaddr & PG_PS) != 0) {
- PD_CLEAR_VA(pmap, pdirindex, TRUE);
- pmap->pm_stats.resident_count -= NBPDR / PAGE_SIZE;
- anyvalid = 1;
- continue;
- }
-
- /*
- * Limit our scan to either the end of the va represented
- * by the current page table page, or to the end of the
- * range being removed.
- */
- if (pdnxt > eva)
- pdnxt = eva;
-
- for (pte = pmap_pte_quick(pmap, sva); sva != pdnxt; pte++,
- sva += PAGE_SIZE) {
- if ((*pte & PG_V) == 0)
- continue;
-
- /*
- * The TLB entry for a PG_G mapping is invalidated
- * by pmap_remove_pte().
- */
- if ((*pte & PG_G) == 0)
- anyvalid = 1;
- if (pmap_remove_pte(pmap, pte, sva, &free))
- break;
- }
- }
- PT_UPDATES_FLUSH();
- if (*PMAP1)
- PT_SET_VA_MA(PMAP1, 0, TRUE);
-out:
- if (anyvalid)
- pmap_invalidate_all(pmap);
- sched_unpin();
- rw_wunlock(&pvh_global_lock);
- PMAP_UNLOCK(pmap);
- pmap_free_zero_pages(free);
-}
-
-/*
- * Routine: pmap_remove_all
- * Function:
- * Removes this physical page from
- * all physical maps in which it resides.
- * Reflects back modify bits to the pager.
- *
- * Notes:
- * Original versions of this routine were very
- * inefficient because they iteratively called
- * pmap_remove (slow...)
- */
-
-void
-pmap_remove_all(vm_page_t m)
-{
- pv_entry_t pv;
- pmap_t pmap;
- pt_entry_t *pte, tpte;
- vm_page_t free;
-
- KASSERT((m->oflags & VPO_UNMANAGED) == 0,
- ("pmap_remove_all: page %p is not managed", m));
- free = NULL;
- rw_wlock(&pvh_global_lock);
- sched_pin();
- while ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) {
- pmap = PV_PMAP(pv);
- PMAP_LOCK(pmap);
- pmap->pm_stats.resident_count--;
- pte = pmap_pte_quick(pmap, pv->pv_va);
- tpte = *pte;
- PT_SET_VA_MA(pte, 0, TRUE);
- KASSERT(tpte != 0, ("pmap_remove_all: pmap %p va %x zero pte",
- pmap, pv->pv_va));
- if (tpte & PG_W)
- pmap->pm_stats.wired_count--;
- if (tpte & PG_A)
- vm_page_aflag_set(m, PGA_REFERENCED);
-
- /*
- * Update the vm_page_t clean and reference bits.
- */
- if ((tpte & (PG_M | PG_RW)) == (PG_M | PG_RW))
- vm_page_dirty(m);
- pmap_unuse_pt(pmap, pv->pv_va, &free);
- pmap_invalidate_page(pmap, pv->pv_va);
- TAILQ_REMOVE(&m->md.pv_list, pv, pv_next);
- free_pv_entry(pmap, pv);
- PMAP_UNLOCK(pmap);
- }
- vm_page_aflag_clear(m, PGA_WRITEABLE);
- PT_UPDATES_FLUSH();
- if (*PMAP1)
- PT_SET_MA(PADDR1, 0);
- sched_unpin();
- rw_wunlock(&pvh_global_lock);
- pmap_free_zero_pages(free);
-}
-
-/*
- * Set the physical protection on the
- * specified range of this map as requested.
- */
-void
-pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot)
-{
- vm_offset_t pdnxt;
- pd_entry_t ptpaddr;
- pt_entry_t *pte;
- int anychanged;
-
- CTR4(KTR_PMAP, "pmap_protect: pmap=%p sva=0x%x eva=0x%x prot=0x%x",
- pmap, sva, eva, prot);
-
- if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
- pmap_remove(pmap, sva, eva);
- return;
- }
-
-#ifdef PAE
- if ((prot & (VM_PROT_WRITE|VM_PROT_EXECUTE)) ==
- (VM_PROT_WRITE|VM_PROT_EXECUTE))
- return;
-#else
- if (prot & VM_PROT_WRITE)
- return;
-#endif
-
- anychanged = 0;
-
- rw_wlock(&pvh_global_lock);
- sched_pin();
- PMAP_LOCK(pmap);
- for (; sva < eva; sva = pdnxt) {
- pt_entry_t obits, pbits;
- u_int pdirindex;
-
- pdnxt = (sva + NBPDR) & ~PDRMASK;
- if (pdnxt < sva)
- pdnxt = eva;
-
- pdirindex = sva >> PDRSHIFT;
- ptpaddr = pmap->pm_pdir[pdirindex];
-
- /*
- * Weed out invalid mappings. Note: we assume that the page
- * directory table is always allocated, and in kernel virtual.
- */
- if (ptpaddr == 0)
- continue;
-
- /*
- * Check for large page.
- */
- if ((ptpaddr & PG_PS) != 0) {
- if ((prot & VM_PROT_WRITE) == 0)
- pmap->pm_pdir[pdirindex] &= ~(PG_M|PG_RW);
-#ifdef PAE
- if ((prot & VM_PROT_EXECUTE) == 0)
- pmap->pm_pdir[pdirindex] |= pg_nx;
-#endif
- anychanged = 1;
- continue;
- }
-
- if (pdnxt > eva)
- pdnxt = eva;
-
- for (pte = pmap_pte_quick(pmap, sva); sva != pdnxt; pte++,
- sva += PAGE_SIZE) {
- vm_page_t m;
-
-retry:
- /*
- * Regardless of whether a pte is 32 or 64 bits in
- * size, PG_RW, PG_A, and PG_M are among the least
- * significant 32 bits.
- */
- obits = pbits = *pte;
- if ((pbits & PG_V) == 0)
- continue;
-
- if ((prot & VM_PROT_WRITE) == 0) {
- if ((pbits & (PG_MANAGED | PG_M | PG_RW)) ==
- (PG_MANAGED | PG_M | PG_RW)) {
- m = PHYS_TO_VM_PAGE(xpmap_mtop(pbits) &
- PG_FRAME);
- vm_page_dirty(m);
- }
- pbits &= ~(PG_RW | PG_M);
- }
-#ifdef PAE
- if ((prot & VM_PROT_EXECUTE) == 0)
- pbits |= pg_nx;
-#endif
-
- if (pbits != obits) {
- obits = *pte;
- PT_SET_VA_MA(pte, pbits, TRUE);
- if (*pte != pbits)
- goto retry;
- if (obits & PG_G)
- pmap_invalidate_page(pmap, sva);
- else
- anychanged = 1;
- }
- }
- }
- PT_UPDATES_FLUSH();
- if (*PMAP1)
- PT_SET_VA_MA(PMAP1, 0, TRUE);
- if (anychanged)
- pmap_invalidate_all(pmap);
- sched_unpin();
- rw_wunlock(&pvh_global_lock);
- PMAP_UNLOCK(pmap);
-}
-
-/*
- * Insert the given physical page (p) at
- * the specified virtual address (v) in the
- * target physical map with the protection requested.
- *
- * If specified, the page will be wired down, meaning
- * that the related pte can not be reclaimed.
- *
- * NB: This is the only routine which MAY NOT lazy-evaluate
- * or lose information. That is, this routine must actually
- * insert this page into the given map NOW.
- */
-int
-pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
- u_int flags, int8_t psind __unused)
-{
- pd_entry_t *pde;
- pt_entry_t *pte;
- pt_entry_t newpte, origpte;
- pv_entry_t pv;
- vm_paddr_t opa, pa;
- vm_page_t mpte, om;
- boolean_t invlva, wired;
-
- CTR5(KTR_PMAP,
- "pmap_enter: pmap=%08p va=0x%08x ma=0x%08x prot=0x%x flags=0x%x",
- pmap, va, VM_PAGE_TO_MACH(m), prot, flags);
- va = trunc_page(va);
- KASSERT(va <= VM_MAX_KERNEL_ADDRESS, ("pmap_enter: toobig"));
- KASSERT(va < UPT_MIN_ADDRESS || va >= UPT_MAX_ADDRESS,
- ("pmap_enter: invalid to pmap_enter page table pages (va: 0x%x)",
- va));
- if ((m->oflags & VPO_UNMANAGED) == 0 && !vm_page_xbusied(m))
- VM_OBJECT_ASSERT_LOCKED(m->object);
-
- mpte = NULL;
- wired = (flags & PMAP_ENTER_WIRED) != 0;
-
- rw_wlock(&pvh_global_lock);
- PMAP_LOCK(pmap);
- sched_pin();
-
- /*
- * In the case that a page table page is not
- * resident, we are creating it here.
- */
- if (va < VM_MAXUSER_ADDRESS) {
- mpte = pmap_allocpte(pmap, va, flags);
- if (mpte == NULL) {
- KASSERT((flags & PMAP_ENTER_NOSLEEP) != 0,
- ("pmap_allocpte failed with sleep allowed"));
- sched_unpin();
- rw_wunlock(&pvh_global_lock);
- PMAP_UNLOCK(pmap);
- return (KERN_RESOURCE_SHORTAGE);
- }
- }
-
- 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
- */
- if (pte == NULL) {
- panic("pmap_enter: invalid page directory pdir=%#jx, va=%#x",
- (uintmax_t)pmap->pm_pdir[va >> PDRSHIFT], va);
- }
-
- pa = VM_PAGE_TO_PHYS(m);
- om = NULL;
- opa = origpte = 0;
-
-#if 0
- KASSERT((*pte & PG_V) || (*pte == 0), ("address set but not valid pte=%p *pte=0x%016jx",
- pte, *pte));
-#endif
- origpte = *pte;
- if (origpte)
- origpte = xpmap_mtop(origpte);
- opa = origpte & PG_FRAME;
-
- /*
- * Mapping has not changed, must be protection or wiring change.
- */
- if (origpte && (opa == pa)) {
- /*
- * Wiring change, just update stats. We don't worry about
- * wiring PT pages as they remain resident as long as there
- * are valid mappings in them. Hence, if a user page is wired,
- * the PT page will be also.
- */
- if (wired && ((origpte & PG_W) == 0))
- pmap->pm_stats.wired_count++;
- else if (!wired && (origpte & PG_W))
- pmap->pm_stats.wired_count--;
-
- /*
- * Remove extra pte reference
- */
- if (mpte)
- mpte->wire_count--;
-
- if (origpte & PG_MANAGED) {
- om = m;
- pa |= PG_MANAGED;
- }
- goto validate;
- }
-
- pv = NULL;
-
- /*
- * Mapping has changed, invalidate old range and fall through to
- * handle validating new mapping.
- */
- if (opa) {
- if (origpte & PG_W)
- pmap->pm_stats.wired_count--;
- if (origpte & PG_MANAGED) {
- om = PHYS_TO_VM_PAGE(opa);
- pv = pmap_pvh_remove(&om->md, pmap, va);
- } else if (va < VM_MAXUSER_ADDRESS)
- printf("va=0x%x is unmanaged :-( \n", va);
-
- if (mpte != NULL) {
- mpte->wire_count--;
- KASSERT(mpte->wire_count > 0,
- ("pmap_enter: missing reference to page table page,"
- " va: 0x%x", va));
- }
- } else
- pmap->pm_stats.resident_count++;
-
- /*
- * Enter on the PV list if part of our managed memory.
- */
- if ((m->oflags & VPO_UNMANAGED) == 0) {
- KASSERT(va < kmi.clean_sva || va >= kmi.clean_eva,
- ("pmap_enter: managed mapping within the clean submap"));
- if (pv == NULL)
- pv = get_pv_entry(pmap, FALSE);
- pv->pv_va = va;
- TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_next);
- pa |= PG_MANAGED;
- } else if (pv != NULL)
- free_pv_entry(pmap, pv);
-
- /*
- * Increment counters
- */
- if (wired)
- pmap->pm_stats.wired_count++;
-
-validate:
- /*
- * Now validate mapping with desired protection/wiring.
- */
- newpte = (pt_entry_t)(pa | PG_V);
- if ((prot & VM_PROT_WRITE) != 0) {
- newpte |= PG_RW;
- if ((newpte & PG_MANAGED) != 0)
- vm_page_aflag_set(m, PGA_WRITEABLE);
- }
-#ifdef PAE
- if ((prot & VM_PROT_EXECUTE) == 0)
- newpte |= pg_nx;
-#endif
- if (wired)
- newpte |= PG_W;
- if (va < VM_MAXUSER_ADDRESS)
- newpte |= PG_U;
- if (pmap == kernel_pmap)
- newpte |= pgeflag;
-
- critical_enter();
- /*
- * if the mapping or permission bits are different, we need
- * to update the pte.
- */
- if ((origpte & ~(PG_M|PG_A)) != newpte) {
- if (origpte) {
- invlva = FALSE;
- origpte = *pte;
- PT_SET_VA(pte, newpte | PG_A, FALSE);
- if (origpte & PG_A) {
- if (origpte & PG_MANAGED)
- vm_page_aflag_set(om, PGA_REFERENCED);
- if (opa != VM_PAGE_TO_PHYS(m))
- invlva = TRUE;
-#ifdef PAE
- if ((origpte & PG_NX) == 0 &&
- (newpte & PG_NX) != 0)
- invlva = TRUE;
-#endif
- }
- if ((origpte & (PG_M | PG_RW)) == (PG_M | PG_RW)) {
- if ((origpte & PG_MANAGED) != 0)
- vm_page_dirty(om);
- if ((prot & VM_PROT_WRITE) == 0)
- invlva = TRUE;
- }
- if ((origpte & PG_MANAGED) != 0 &&
- TAILQ_EMPTY(&om->md.pv_list))
- vm_page_aflag_clear(om, PGA_WRITEABLE);
- if (invlva)
- pmap_invalidate_page(pmap, va);
- } else{
- PT_SET_VA(pte, newpte | PG_A, FALSE);
- }
-
- }
- PT_UPDATES_FLUSH();
- critical_exit();
- if (*PMAP1)
- PT_SET_VA_MA(PMAP1, 0, TRUE);
- sched_unpin();
- rw_wunlock(&pvh_global_lock);
- PMAP_UNLOCK(pmap);
- return (KERN_SUCCESS);
-}
-
-/*
- * Maps a sequence of resident pages belonging to the same object.
- * The sequence begins with the given page m_start. This page is
- * mapped at the given virtual address start. Each subsequent page is
- * mapped at a virtual address that is offset from start by the same
- * amount as the page is offset from m_start within the object. The
- * last page in the sequence is the page with the largest offset from
- * m_start that can be mapped at a virtual address less than the given
- * virtual address end. Not every virtual page between start and end
- * is mapped; only those for which a resident page exists with the
- * corresponding offset from m_start are mapped.
- */
-void
-pmap_enter_object(pmap_t pmap, vm_offset_t start, vm_offset_t end,
- vm_page_t m_start, vm_prot_t prot)
-{
- vm_page_t m, mpte;
- vm_pindex_t diff, psize;
- multicall_entry_t mcl[16];
- multicall_entry_t *mclp = mcl;
- int error, count = 0;
-
- VM_OBJECT_ASSERT_LOCKED(m_start->object);
-
- psize = atop(end - start);
- mpte = NULL;
- m = m_start;
- rw_wlock(&pvh_global_lock);
- PMAP_LOCK(pmap);
- while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) {
- mpte = pmap_enter_quick_locked(&mclp, &count, pmap, start + ptoa(diff), m,
- prot, mpte);
- m = TAILQ_NEXT(m, listq);
- if (count == 16) {
- error = HYPERVISOR_multicall(mcl, count);
- KASSERT(error == 0, ("bad multicall %d", error));
- mclp = mcl;
- count = 0;
- }
- }
- if (count) {
- error = HYPERVISOR_multicall(mcl, count);
- KASSERT(error == 0, ("bad multicall %d", error));
- }
- rw_wunlock(&pvh_global_lock);
- PMAP_UNLOCK(pmap);
-}
-
-/*
- * this code makes some *MAJOR* assumptions:
- * 1. Current pmap & pmap exists.
- * 2. Not wired.
- * 3. Read access.
- * 4. No page table pages.
- * but is *MUCH* faster than pmap_enter...
- */
-
-void
-pmap_enter_quick(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot)
-{
- multicall_entry_t mcl, *mclp;
- int count = 0;
- mclp = &mcl;
-
- CTR4(KTR_PMAP, "pmap_enter_quick: pmap=%p va=0x%x m=%p prot=0x%x",
- pmap, va, m, prot);
-
- rw_wlock(&pvh_global_lock);
- PMAP_LOCK(pmap);
- (void)pmap_enter_quick_locked(&mclp, &count, pmap, va, m, prot, NULL);
- if (count)
- HYPERVISOR_multicall(&mcl, count);
- rw_wunlock(&pvh_global_lock);
- PMAP_UNLOCK(pmap);
-}
-
-#ifdef notyet
-void
-pmap_enter_quick_range(pmap_t pmap, vm_offset_t *addrs, vm_page_t *pages, vm_prot_t *prots, int count)
-{
- int i, error, index = 0;
- multicall_entry_t mcl[16];
- multicall_entry_t *mclp = mcl;
-
- PMAP_LOCK(pmap);
- for (i = 0; i < count; i++, addrs++, pages++, prots++) {
- if (!pmap_is_prefaultable_locked(pmap, *addrs))
- continue;
-
- (void) pmap_enter_quick_locked(&mclp, &index, pmap, *addrs, *pages, *prots, NULL);
- if (index == 16) {
- error = HYPERVISOR_multicall(mcl, index);
- mclp = mcl;
- index = 0;
- KASSERT(error == 0, ("bad multicall %d", error));
- }
- }
- if (index) {
- error = HYPERVISOR_multicall(mcl, index);
- KASSERT(error == 0, ("bad multicall %d", error));
- }
-
- PMAP_UNLOCK(pmap);
-}
-#endif
-
-static vm_page_t
-pmap_enter_quick_locked(multicall_entry_t **mclpp, int *count, pmap_t pmap, vm_offset_t va, vm_page_t m,
- vm_prot_t prot, vm_page_t mpte)
-{
- pt_entry_t *pte;
- vm_paddr_t pa;
- vm_page_t free;
- multicall_entry_t *mcl = *mclpp;
-
- KASSERT(va < kmi.clean_sva || va >= kmi.clean_eva ||
- (m->oflags & VPO_UNMANAGED) != 0,
- ("pmap_enter_quick_locked: managed mapping within the clean submap"));
- rw_assert(&pvh_global_lock, RA_WLOCKED);
- PMAP_LOCK_ASSERT(pmap, MA_OWNED);
-
- /*
- * In the case that a page table page is not
- * resident, we are creating it here.
- */
- if (va < VM_MAXUSER_ADDRESS) {
- u_int ptepindex;
- pd_entry_t ptema;
-
- /*
- * Calculate pagetable page index
- */
- ptepindex = va >> PDRSHIFT;
- if (mpte && (mpte->pindex == ptepindex)) {
- mpte->wire_count++;
- } else {
- /*
- * Get the page directory entry
- */
- ptema = pmap->pm_pdir[ptepindex];
-
- /*
- * If the page table page is mapped, we just increment
- * the hold count, and activate it.
- */
- if (ptema & PG_V) {
- if (ptema & PG_PS)
- panic("pmap_enter_quick: unexpected mapping into 4MB page");
- mpte = PHYS_TO_VM_PAGE(xpmap_mtop(ptema) & PG_FRAME);
- mpte->wire_count++;
- } else {
- mpte = _pmap_allocpte(pmap, ptepindex,
- PMAP_ENTER_NOSLEEP);
- if (mpte == NULL)
- return (mpte);
- }
- }
- } else {
- mpte = NULL;
- }
-
- /*
- * This call to vtopte makes the assumption that we are
- * entering the page into the current pmap. In order to support
- * quick entry into any pmap, one would likely use pmap_pte_quick.
- * But that isn't as quick as vtopte.
- */
- KASSERT(pmap_is_current(pmap), ("entering pages in non-current pmap"));
- pte = vtopte(va);
- if (*pte & PG_V) {
- if (mpte != NULL) {
- mpte->wire_count--;
- mpte = NULL;
- }
- return (mpte);
- }
-
- /*
- * Enter on the PV list if part of our managed memory.
- */
- if ((m->oflags & VPO_UNMANAGED) == 0 &&
- !pmap_try_insert_pv_entry(pmap, va, m)) {
- if (mpte != NULL) {
- free = NULL;
- if (pmap_unwire_ptp(pmap, mpte, &free)) {
- pmap_invalidate_page(pmap, va);
- pmap_free_zero_pages(free);
- }
-
- mpte = NULL;
- }
- return (mpte);
- }
-
- /*
- * Increment counters
- */
- pmap->pm_stats.resident_count++;
-
- pa = VM_PAGE_TO_PHYS(m);
-#ifdef PAE
- if ((prot & VM_PROT_EXECUTE) == 0)
- pa |= pg_nx;
-#endif
-
-#if 0
- /*
- * Now validate mapping with RO protection
- */
- if ((m->oflags & VPO_UNMANAGED) != 0)
- pte_store(pte, pa | PG_V | PG_U);
- else
- pte_store(pte, pa | PG_V | PG_U | PG_MANAGED);
-#else
- /*
- * Now validate mapping with RO protection
- */
- if ((m->oflags & VPO_UNMANAGED) != 0)
- pa = xpmap_ptom(pa | PG_V | PG_U);
- else
- pa = xpmap_ptom(pa | PG_V | PG_U | PG_MANAGED);
-
- mcl->op = __HYPERVISOR_update_va_mapping;
- mcl->args[0] = va;
- mcl->args[1] = (uint32_t)(pa & 0xffffffff);
- mcl->args[2] = (uint32_t)(pa >> 32);
- mcl->args[3] = 0;
- *mclpp = mcl + 1;
- *count = *count + 1;
-#endif
- return (mpte);
-}
-
-/*
- * Make a temporary mapping for a physical address. This is only intended
- * to be used for panic dumps.
- */
-void *
-pmap_kenter_temporary(vm_paddr_t pa, int i)
-{
- vm_offset_t va;
- vm_paddr_t ma = xpmap_ptom(pa);
-
- va = (vm_offset_t)crashdumpmap + (i * PAGE_SIZE);
- PT_SET_MA(va, (ma & ~PAGE_MASK) | PG_V | pgeflag);
- invlpg(va);
- return ((void *)crashdumpmap);
-}
-
-/*
- * This code maps large physical mmap regions into the
- * processor address space. Note that some shortcuts
- * are taken, but the code works.
- */
-void
-pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_object_t object,
- vm_pindex_t pindex, vm_size_t size)
-{
- pd_entry_t *pde;
- vm_paddr_t pa, ptepa;
- vm_page_t p;
- int pat_mode;
-
- VM_OBJECT_ASSERT_WLOCKED(object);
- KASSERT(object->type == OBJT_DEVICE || object->type == OBJT_SG,
- ("pmap_object_init_pt: non-device object"));
- if (pseflag &&
- (addr & (NBPDR - 1)) == 0 && (size & (NBPDR - 1)) == 0) {
- if (!vm_object_populate(object, pindex, pindex + atop(size)))
- return;
- p = vm_page_lookup(object, pindex);
- KASSERT(p->valid == VM_PAGE_BITS_ALL,
- ("pmap_object_init_pt: invalid page %p", p));
- pat_mode = p->md.pat_mode;
-
- /*
- * Abort the mapping if the first page is not physically
- * aligned to a 2/4MB page boundary.
- */
- ptepa = VM_PAGE_TO_PHYS(p);
- if (ptepa & (NBPDR - 1))
- return;
-
- /*
- * Skip the first page. Abort the mapping if the rest of
- * the pages are not physically contiguous or have differing
- * memory attributes.
- */
- p = TAILQ_NEXT(p, listq);
- for (pa = ptepa + PAGE_SIZE; pa < ptepa + size;
- pa += PAGE_SIZE) {
- KASSERT(p->valid == VM_PAGE_BITS_ALL,
- ("pmap_object_init_pt: invalid page %p", p));
- if (pa != VM_PAGE_TO_PHYS(p) ||
- pat_mode != p->md.pat_mode)
- return;
- p = TAILQ_NEXT(p, listq);
- }
-
- /*
- * Map using 2/4MB pages. Since "ptepa" is 2/4M aligned and
- * "size" is a multiple of 2/4M, adding the PAT setting to
- * "pa" will not affect the termination of this loop.
- */
- PMAP_LOCK(pmap);
- for (pa = ptepa | pmap_cache_bits(pat_mode, 1); pa < ptepa +
- size; pa += NBPDR) {
- pde = pmap_pde(pmap, addr);
- if (*pde == 0) {
- pde_store(pde, pa | PG_PS | PG_M | PG_A |
- PG_U | PG_RW | PG_V);
- pmap->pm_stats.resident_count += NBPDR /
- PAGE_SIZE;
- pmap_pde_mappings++;
- }
- /* Else continue on if the PDE is already valid. */
- addr += NBPDR;
- }
- PMAP_UNLOCK(pmap);
- }
-}
-
-/*
- * Clear the wired attribute from the mappings for the specified range of
- * addresses in the given pmap. Every valid mapping within that range
- * must have the wired attribute set. In contrast, invalid mappings
- * cannot have the wired attribute set, so they are ignored.
- *
- * The wired attribute of the page table entry is not a hardware feature,
- * so there is no need to invalidate any TLB entries.
- */
-void
-pmap_unwire(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
-{
- vm_offset_t pdnxt;
- pd_entry_t *pde;
- pt_entry_t *pte;
-
- CTR3(KTR_PMAP, "pmap_unwire: pmap=%p sva=0x%x eva=0x%x", pmap, sva,
- eva);
- rw_wlock(&pvh_global_lock);
- sched_pin();
- PMAP_LOCK(pmap);
- for (; sva < eva; sva = pdnxt) {
- pdnxt = (sva + NBPDR) & ~PDRMASK;
- if (pdnxt < sva)
- pdnxt = eva;
- pde = pmap_pde(pmap, sva);
- if ((*pde & PG_V) == 0)
- continue;
- if ((*pde & PG_PS) != 0)
- panic("pmap_unwire: unexpected PG_PS in pde %#jx",
- (uintmax_t)*pde);
- if (pdnxt > eva)
- pdnxt = eva;
- for (pte = pmap_pte_quick(pmap, sva); sva != pdnxt; pte++,
- sva += PAGE_SIZE) {
- if ((*pte & PG_V) == 0)
- continue;
- if ((*pte & PG_W) == 0)
- panic("pmap_unwire: pte %#jx is missing PG_W",
- (uintmax_t)*pte);
- PT_SET_VA_MA(pte, *pte & ~PG_W, FALSE);
- pmap->pm_stats.wired_count--;
- }
- }
- if (*PMAP1)
- PT_CLEAR_VA(PMAP1, FALSE);
- PT_UPDATES_FLUSH();
- sched_unpin();
- rw_wunlock(&pvh_global_lock);
- PMAP_UNLOCK(pmap);
-}
-
-
-/*
- * Copy the range specified by src_addr/len
- * from the source map to the range dst_addr/len
- * in the destination map.
- *
- * This routine is only advisory and need not do anything.
- */
-
-void
-pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len,
- vm_offset_t src_addr)
-{
- vm_page_t free;
- vm_offset_t addr;
- vm_offset_t end_addr = src_addr + len;
- vm_offset_t pdnxt;
-
- if (dst_addr != src_addr)
- return;
-
- if (!pmap_is_current(src_pmap)) {
- CTR2(KTR_PMAP,
- "pmap_copy, skipping: pdir[PTDPTDI]=0x%jx PTDpde[0]=0x%jx",
- (src_pmap->pm_pdir[PTDPTDI] & PG_FRAME), (PTDpde[0] & PG_FRAME));
-
- return;
- }
- CTR5(KTR_PMAP, "pmap_copy: dst_pmap=%p src_pmap=%p dst_addr=0x%x len=%d src_addr=0x%x",
- dst_pmap, src_pmap, dst_addr, len, src_addr);
-
-#ifdef HAMFISTED_LOCKING
- mtx_lock(&createdelete_lock);
-#endif
-
- rw_wlock(&pvh_global_lock);
- if (dst_pmap < src_pmap) {
- PMAP_LOCK(dst_pmap);
- PMAP_LOCK(src_pmap);
- } else {
- PMAP_LOCK(src_pmap);
- PMAP_LOCK(dst_pmap);
- }
- sched_pin();
- for (addr = src_addr; addr < end_addr; addr = pdnxt) {
- pt_entry_t *src_pte, *dst_pte;
- vm_page_t dstmpte, srcmpte;
- pd_entry_t srcptepaddr;
- u_int ptepindex;
-
- KASSERT(addr < UPT_MIN_ADDRESS,
- ("pmap_copy: invalid to pmap_copy page tables"));
-
- pdnxt = (addr + NBPDR) & ~PDRMASK;
- if (pdnxt < addr)
- pdnxt = end_addr;
- ptepindex = addr >> PDRSHIFT;
-
- srcptepaddr = PT_GET(&src_pmap->pm_pdir[ptepindex]);
- if (srcptepaddr == 0)
- continue;
-
- if (srcptepaddr & PG_PS) {
- if (dst_pmap->pm_pdir[ptepindex] == 0) {
- PD_SET_VA(dst_pmap, ptepindex, srcptepaddr & ~PG_W, TRUE);
- dst_pmap->pm_stats.resident_count +=
- NBPDR / PAGE_SIZE;
- }
- continue;
- }
-
- srcmpte = PHYS_TO_VM_PAGE(srcptepaddr & PG_FRAME);
- KASSERT(srcmpte->wire_count > 0,
- ("pmap_copy: source page table page is unused"));
-
- if (pdnxt > end_addr)
- pdnxt = end_addr;
-
- src_pte = vtopte(addr);
- while (addr < pdnxt) {
- pt_entry_t ptetemp;
- ptetemp = *src_pte;
- /*
- * we only virtual copy managed pages
- */
- if ((ptetemp & PG_MANAGED) != 0) {
- dstmpte = pmap_allocpte(dst_pmap, addr,
- PMAP_ENTER_NOSLEEP);
- if (dstmpte == NULL)
- goto out;
- dst_pte = pmap_pte_quick(dst_pmap, addr);
- if (*dst_pte == 0 &&
- pmap_try_insert_pv_entry(dst_pmap, addr,
- PHYS_TO_VM_PAGE(xpmap_mtop(ptetemp) & PG_FRAME))) {
- /*
- * Clear the wired, modified, and
- * accessed (referenced) bits
- * during the copy.
- */
- KASSERT(ptetemp != 0, ("src_pte not set"));
- PT_SET_VA_MA(dst_pte, ptetemp & ~(PG_W | PG_M | PG_A), TRUE /* XXX debug */);
- KASSERT(*dst_pte == (ptetemp & ~(PG_W | PG_M | PG_A)),
- ("no pmap copy expected: 0x%jx saw: 0x%jx",
- ptetemp & ~(PG_W | PG_M | PG_A), *dst_pte));
- dst_pmap->pm_stats.resident_count++;
- } else {
- free = NULL;
- if (pmap_unwire_ptp(dst_pmap, dstmpte,
- &free)) {
- pmap_invalidate_page(dst_pmap,
- addr);
- pmap_free_zero_pages(free);
- }
- goto out;
- }
- if (dstmpte->wire_count >= srcmpte->wire_count)
- break;
- }
- addr += PAGE_SIZE;
- src_pte++;
- }
- }
-out:
- PT_UPDATES_FLUSH();
- sched_unpin();
- rw_wunlock(&pvh_global_lock);
- PMAP_UNLOCK(src_pmap);
- PMAP_UNLOCK(dst_pmap);
-
-#ifdef HAMFISTED_LOCKING
- mtx_unlock(&createdelete_lock);
-#endif
-}
-
-static __inline void
-pagezero(void *page)
-{
-#if defined(I686_CPU)
- if (cpu_class == CPUCLASS_686) {
-#if defined(CPU_ENABLE_SSE)
- if (cpu_feature & CPUID_SSE2)
- sse2_pagezero(page);
- else
-#endif
- i686_pagezero(page);
- } else
-#endif
- bzero(page, PAGE_SIZE);
-}
-
-/*
- * pmap_zero_page zeros the specified hardware page by mapping
- * the page into KVM and using bzero to clear its contents.
- */
-void
-pmap_zero_page(vm_page_t m)
-{
- struct sysmaps *sysmaps;
-
- sysmaps = &sysmaps_pcpu[PCPU_GET(cpuid)];
- mtx_lock(&sysmaps->lock);
- if (*sysmaps->CMAP2)
- panic("pmap_zero_page: CMAP2 busy");
- sched_pin();
- PT_SET_MA(sysmaps->CADDR2, PG_V | PG_RW | VM_PAGE_TO_MACH(m) | PG_A | PG_M);
- pagezero(sysmaps->CADDR2);
- PT_SET_MA(sysmaps->CADDR2, 0);
- sched_unpin();
- mtx_unlock(&sysmaps->lock);
-}
-
-/*
- * pmap_zero_page_area zeros the specified hardware page by mapping
- * the page into KVM and using bzero to clear its contents.
- *
- * off and size may not cover an area beyond a single hardware page.
- */
-void
-pmap_zero_page_area(vm_page_t m, int off, int size)
-{
- struct sysmaps *sysmaps;
-
- sysmaps = &sysmaps_pcpu[PCPU_GET(cpuid)];
- mtx_lock(&sysmaps->lock);
- if (*sysmaps->CMAP2)
- panic("pmap_zero_page_area: CMAP2 busy");
- sched_pin();
- PT_SET_MA(sysmaps->CADDR2, PG_V | PG_RW | VM_PAGE_TO_MACH(m) | PG_A | PG_M);
-
- if (off == 0 && size == PAGE_SIZE)
- pagezero(sysmaps->CADDR2);
- else
- bzero((char *)sysmaps->CADDR2 + off, size);
- PT_SET_MA(sysmaps->CADDR2, 0);
- sched_unpin();
- mtx_unlock(&sysmaps->lock);
-}
-
-/*
- * pmap_zero_page_idle zeros the specified hardware page by mapping
- * the page into KVM and using bzero to clear its contents. This
- * is intended to be called from the vm_pagezero process only and
- * outside of Giant.
- */
-void
-pmap_zero_page_idle(vm_page_t m)
-{
-
- if (*CMAP3)
- panic("pmap_zero_page_idle: CMAP3 busy");
- sched_pin();
- PT_SET_MA(CADDR3, PG_V | PG_RW | VM_PAGE_TO_MACH(m) | PG_A | PG_M);
- pagezero(CADDR3);
- PT_SET_MA(CADDR3, 0);
- sched_unpin();
-}
-
-/*
- * pmap_copy_page copies the specified (machine independent)
- * page by mapping the page into virtual memory and using
- * bcopy to copy the page, one machine dependent page at a
- * time.
- */
-void
-pmap_copy_page(vm_page_t src, vm_page_t dst)
-{
- struct sysmaps *sysmaps;
-
- sysmaps = &sysmaps_pcpu[PCPU_GET(cpuid)];
- mtx_lock(&sysmaps->lock);
- if (*sysmaps->CMAP1)
- panic("pmap_copy_page: CMAP1 busy");
- if (*sysmaps->CMAP2)
- panic("pmap_copy_page: CMAP2 busy");
- sched_pin();
- PT_SET_MA(sysmaps->CADDR1, PG_V | VM_PAGE_TO_MACH(src) | PG_A);
- PT_SET_MA(sysmaps->CADDR2, PG_V | PG_RW | VM_PAGE_TO_MACH(dst) | PG_A | PG_M);
- bcopy(sysmaps->CADDR1, sysmaps->CADDR2, PAGE_SIZE);
- PT_SET_MA(sysmaps->CADDR1, 0);
- PT_SET_MA(sysmaps->CADDR2, 0);
- sched_unpin();
- mtx_unlock(&sysmaps->lock);
-}
-
-int unmapped_buf_allowed = 1;
-
-void
-pmap_copy_pages(vm_page_t ma[], vm_offset_t a_offset, vm_page_t mb[],
- vm_offset_t b_offset, int xfersize)
-{
- struct sysmaps *sysmaps;
- vm_page_t a_pg, b_pg;
- char *a_cp, *b_cp;
- vm_offset_t a_pg_offset, b_pg_offset;
- int cnt;
-
- sysmaps = &sysmaps_pcpu[PCPU_GET(cpuid)];
- mtx_lock(&sysmaps->lock);
- if (*sysmaps->CMAP1 != 0)
- panic("pmap_copy_pages: CMAP1 busy");
- if (*sysmaps->CMAP2 != 0)
- panic("pmap_copy_pages: CMAP2 busy");
- sched_pin();
- while (xfersize > 0) {
- a_pg = ma[a_offset >> PAGE_SHIFT];
- a_pg_offset = a_offset & PAGE_MASK;
- cnt = min(xfersize, PAGE_SIZE - a_pg_offset);
- b_pg = mb[b_offset >> PAGE_SHIFT];
- b_pg_offset = b_offset & PAGE_MASK;
- cnt = min(cnt, PAGE_SIZE - b_pg_offset);
- PT_SET_MA(sysmaps->CADDR1, PG_V | VM_PAGE_TO_MACH(a_pg) | PG_A);
- PT_SET_MA(sysmaps->CADDR2, PG_V | PG_RW |
- VM_PAGE_TO_MACH(b_pg) | PG_A | PG_M);
- a_cp = sysmaps->CADDR1 + a_pg_offset;
- b_cp = sysmaps->CADDR2 + b_pg_offset;
- bcopy(a_cp, b_cp, cnt);
- a_offset += cnt;
- b_offset += cnt;
- xfersize -= cnt;
- }
- PT_SET_MA(sysmaps->CADDR1, 0);
- PT_SET_MA(sysmaps->CADDR2, 0);
- sched_unpin();
- mtx_unlock(&sysmaps->lock);
-}
-
-/*
- * Returns true if the pmap's pv is one of the first
- * 16 pvs linked to from this page. This count may
- * be changed upwards or downwards in the future; it
- * is only necessary that true be returned for a small
- * subset of pmaps for proper page aging.
- */
-boolean_t
-pmap_page_exists_quick(pmap_t pmap, vm_page_t m)
-{
- pv_entry_t pv;
- int loops = 0;
- boolean_t rv;
-
- KASSERT((m->oflags & VPO_UNMANAGED) == 0,
- ("pmap_page_exists_quick: page %p is not managed", m));
- rv = FALSE;
- rw_wlock(&pvh_global_lock);
- TAILQ_FOREACH(pv, &m->md.pv_list, pv_next) {
- if (PV_PMAP(pv) == pmap) {
- rv = TRUE;
- break;
- }
- loops++;
- if (loops >= 16)
- break;
- }
- rw_wunlock(&pvh_global_lock);
- return (rv);
-}
-
-/*
- * pmap_page_wired_mappings:
- *
- * Return the number of managed mappings to the given physical page
- * that are wired.
- */
-int
-pmap_page_wired_mappings(vm_page_t m)
-{
- pv_entry_t pv;
- pt_entry_t *pte;
- pmap_t pmap;
- int count;
-
- count = 0;
- if ((m->oflags & VPO_UNMANAGED) != 0)
- return (count);
- rw_wlock(&pvh_global_lock);
- sched_pin();
- TAILQ_FOREACH(pv, &m->md.pv_list, pv_next) {
- pmap = PV_PMAP(pv);
- PMAP_LOCK(pmap);
- pte = pmap_pte_quick(pmap, pv->pv_va);
- if ((*pte & PG_W) != 0)
- count++;
- PMAP_UNLOCK(pmap);
- }
- sched_unpin();
- rw_wunlock(&pvh_global_lock);
- return (count);
-}
-
-/*
- * Returns TRUE if the given page is mapped. Otherwise, returns FALSE.
- */
-boolean_t
-pmap_page_is_mapped(vm_page_t m)
-{
-
- if ((m->oflags & VPO_UNMANAGED) != 0)
- return (FALSE);
- return (!TAILQ_EMPTY(&m->md.pv_list));
-}
-
-/*
- * Remove all pages from specified address space
- * this aids process exit speeds. Also, this code
- * is special cased for current process only, but
- * can have the more generic (and slightly slower)
- * mode enabled. This is much faster than pmap_remove
- * in the case of running down an entire address space.
- */
-void
-pmap_remove_pages(pmap_t pmap)
-{
- pt_entry_t *pte, tpte;
- vm_page_t m, free = NULL;
- pv_entry_t pv;
- struct pv_chunk *pc, *npc;
- int field, idx;
- int32_t bit;
- uint32_t inuse, bitmask;
- int allfree;
-
- CTR1(KTR_PMAP, "pmap_remove_pages: pmap=%p", pmap);
-
- if (pmap != vmspace_pmap(curthread->td_proc->p_vmspace)) {
- printf("warning: pmap_remove_pages called with non-current pmap\n");
- return;
- }
- rw_wlock(&pvh_global_lock);
- KASSERT(pmap_is_current(pmap), ("removing pages from non-current pmap"));
- PMAP_LOCK(pmap);
- sched_pin();
- TAILQ_FOREACH_SAFE(pc, &pmap->pm_pvchunk, pc_list, npc) {
- KASSERT(pc->pc_pmap == pmap, ("Wrong pmap %p %p", pmap,
- pc->pc_pmap));
- allfree = 1;
- for (field = 0; field < _NPCM; field++) {
- inuse = ~pc->pc_map[field] & pc_freemask[field];
- while (inuse != 0) {
- bit = bsfl(inuse);
- bitmask = 1UL << bit;
- idx = field * 32 + bit;
- pv = &pc->pc_pventry[idx];
- inuse &= ~bitmask;
-
- pte = vtopte(pv->pv_va);
- tpte = *pte ? xpmap_mtop(*pte) : 0;
-
- if (tpte == 0) {
- printf(
- "TPTE at %p IS ZERO @ VA %08x\n",
- pte, pv->pv_va);
- panic("bad pte");
- }
-
-/*
- * We cannot remove wired pages from a process' mapping at this time
- */
- if (tpte & PG_W) {
- allfree = 0;
- continue;
- }
-
- m = PHYS_TO_VM_PAGE(tpte & PG_FRAME);
- KASSERT(m->phys_addr == (tpte & PG_FRAME),
- ("vm_page_t %p phys_addr mismatch %016jx %016jx",
- m, (uintmax_t)m->phys_addr,
- (uintmax_t)tpte));
-
- KASSERT(m < &vm_page_array[vm_page_array_size],
- ("pmap_remove_pages: bad tpte %#jx",
- (uintmax_t)tpte));
-
-
- PT_CLEAR_VA(pte, FALSE);
-
- /*
- * Update the vm_page_t clean/reference bits.
- */
- if (tpte & PG_M)
- vm_page_dirty(m);
-
- TAILQ_REMOVE(&m->md.pv_list, pv, pv_next);
- if (TAILQ_EMPTY(&m->md.pv_list))
- vm_page_aflag_clear(m, PGA_WRITEABLE);
-
- pmap_unuse_pt(pmap, pv->pv_va, &free);
-
- /* Mark free */
- PV_STAT(pv_entry_frees++);
- PV_STAT(pv_entry_spare++);
- pv_entry_count--;
- pc->pc_map[field] |= bitmask;
- pmap->pm_stats.resident_count--;
- }
- }
- PT_UPDATES_FLUSH();
- if (allfree) {
- TAILQ_REMOVE(&pmap->pm_pvchunk, pc, pc_list);
- free_pv_chunk(pc);
- }
- }
- PT_UPDATES_FLUSH();
- if (*PMAP1)
- PT_SET_MA(PADDR1, 0);
-
- sched_unpin();
- pmap_invalidate_all(pmap);
- rw_wunlock(&pvh_global_lock);
- PMAP_UNLOCK(pmap);
- pmap_free_zero_pages(free);
-}
-
-/*
- * pmap_is_modified:
- *
- * Return whether or not the specified physical page was modified
- * in any physical maps.
- */
-boolean_t
-pmap_is_modified(vm_page_t m)
-{
- pv_entry_t pv;
- pt_entry_t *pte;
- pmap_t pmap;
- boolean_t rv;
-
- KASSERT((m->oflags & VPO_UNMANAGED) == 0,
- ("pmap_is_modified: page %p is not managed", m));
- rv = FALSE;
-
- /*
- * If the page is not exclusive busied, then PGA_WRITEABLE cannot be
- * concurrently set while the object is locked. Thus, if PGA_WRITEABLE
- * is clear, no PTEs can have PG_M set.
- */
- VM_OBJECT_ASSERT_WLOCKED(m->object);
- if (!vm_page_xbusied(m) && (m->aflags & PGA_WRITEABLE) == 0)
- return (rv);
- rw_wlock(&pvh_global_lock);
- sched_pin();
- TAILQ_FOREACH(pv, &m->md.pv_list, pv_next) {
- pmap = PV_PMAP(pv);
- PMAP_LOCK(pmap);
- pte = pmap_pte_quick(pmap, pv->pv_va);
- rv = (*pte & PG_M) != 0;
- PMAP_UNLOCK(pmap);
- if (rv)
- break;
- }
- if (*PMAP1)
- PT_SET_MA(PADDR1, 0);
- sched_unpin();
- rw_wunlock(&pvh_global_lock);
- return (rv);
-}
-
-/*
- * pmap_is_prefaultable:
- *
- * Return whether or not the specified virtual address is elgible
- * for prefault.
- */
-static boolean_t
-pmap_is_prefaultable_locked(pmap_t pmap, vm_offset_t addr)
-{
- pt_entry_t *pte;
- boolean_t rv = FALSE;
-
- return (rv);
-
- if (pmap_is_current(pmap) && *pmap_pde(pmap, addr)) {
- pte = vtopte(addr);
- rv = (*pte == 0);
- }
- return (rv);
-}
-
-boolean_t
-pmap_is_prefaultable(pmap_t pmap, vm_offset_t addr)
-{
- boolean_t rv;
-
- PMAP_LOCK(pmap);
- rv = pmap_is_prefaultable_locked(pmap, addr);
- PMAP_UNLOCK(pmap);
- return (rv);
-}
-
-boolean_t
-pmap_is_referenced(vm_page_t m)
-{
- pv_entry_t pv;
- pt_entry_t *pte;
- pmap_t pmap;
- boolean_t rv;
-
- KASSERT((m->oflags & VPO_UNMANAGED) == 0,
- ("pmap_is_referenced: page %p is not managed", m));
- rv = FALSE;
- rw_wlock(&pvh_global_lock);
- sched_pin();
- TAILQ_FOREACH(pv, &m->md.pv_list, pv_next) {
- pmap = PV_PMAP(pv);
- PMAP_LOCK(pmap);
- pte = pmap_pte_quick(pmap, pv->pv_va);
- rv = (*pte & (PG_A | PG_V)) == (PG_A | PG_V);
- PMAP_UNLOCK(pmap);
- if (rv)
- break;
- }
- if (*PMAP1)
- PT_SET_MA(PADDR1, 0);
- sched_unpin();
- rw_wunlock(&pvh_global_lock);
- return (rv);
-}
-
-void
-pmap_map_readonly(pmap_t pmap, vm_offset_t va, int len)
-{
- int i, npages = round_page(len) >> PAGE_SHIFT;
- for (i = 0; i < npages; i++) {
- pt_entry_t *pte;
- pte = pmap_pte(pmap, (vm_offset_t)(va + i*PAGE_SIZE));
- rw_wlock(&pvh_global_lock);
- pte_store(pte, xpmap_mtop(*pte & ~(PG_RW|PG_M)));
- rw_wunlock(&pvh_global_lock);
- PMAP_MARK_PRIV(xpmap_mtop(*pte));
- pmap_pte_release(pte);
- }
-}
-
-void
-pmap_map_readwrite(pmap_t pmap, vm_offset_t va, int len)
-{
- int i, npages = round_page(len) >> PAGE_SHIFT;
- for (i = 0; i < npages; i++) {
- pt_entry_t *pte;
- pte = pmap_pte(pmap, (vm_offset_t)(va + i*PAGE_SIZE));
- PMAP_MARK_UNPRIV(xpmap_mtop(*pte));
- rw_wlock(&pvh_global_lock);
- pte_store(pte, xpmap_mtop(*pte) | (PG_RW|PG_M));
- rw_wunlock(&pvh_global_lock);
- pmap_pte_release(pte);
- }
-}
-
-/*
- * Clear the write and modified bits in each of the given page's mappings.
- */
-void
-pmap_remove_write(vm_page_t m)
-{
- pv_entry_t pv;
- pmap_t pmap;
- pt_entry_t oldpte, *pte;
-
- KASSERT((m->oflags & VPO_UNMANAGED) == 0,
- ("pmap_remove_write: page %p is not managed", m));
-
- /*
- * If the page is not exclusive busied, then PGA_WRITEABLE cannot be
- * set by another thread while the object is locked. Thus,
- * if PGA_WRITEABLE is clear, no page table entries need updating.
- */
- VM_OBJECT_ASSERT_WLOCKED(m->object);
- if (!vm_page_xbusied(m) && (m->aflags & PGA_WRITEABLE) == 0)
- return;
- rw_wlock(&pvh_global_lock);
- sched_pin();
- TAILQ_FOREACH(pv, &m->md.pv_list, pv_next) {
- pmap = PV_PMAP(pv);
- PMAP_LOCK(pmap);
- pte = pmap_pte_quick(pmap, pv->pv_va);
-retry:
- oldpte = *pte;
- if ((oldpte & PG_RW) != 0) {
- vm_paddr_t newpte = oldpte & ~(PG_RW | PG_M);
-
- /*
- * Regardless of whether a pte is 32 or 64 bits
- * in size, PG_RW and PG_M are among the least
- * significant 32 bits.
- */
- PT_SET_VA_MA(pte, newpte, TRUE);
- if (*pte != newpte)
- goto retry;
-
- if ((oldpte & PG_M) != 0)
- vm_page_dirty(m);
- pmap_invalidate_page(pmap, pv->pv_va);
- }
- PMAP_UNLOCK(pmap);
- }
- vm_page_aflag_clear(m, PGA_WRITEABLE);
- PT_UPDATES_FLUSH();
- if (*PMAP1)
- PT_SET_MA(PADDR1, 0);
- sched_unpin();
- rw_wunlock(&pvh_global_lock);
-}
-
-/*
- * pmap_ts_referenced:
- *
- * Return a count of reference bits for a page, clearing those bits.
- * It is not necessary for every reference bit to be cleared, but it
- * is necessary that 0 only be returned when there are truly no
- * reference bits set.
- *
- * XXX: The exact number of bits to check and clear is a matter that
- * should be tested and standardized at some point in the future for
- * optimal aging of shared pages.
- */
-int
-pmap_ts_referenced(vm_page_t m)
-{
- pv_entry_t pv, pvf, pvn;
- pmap_t pmap;
- pt_entry_t *pte;
- int rtval = 0;
-
- KASSERT((m->oflags & VPO_UNMANAGED) == 0,
- ("pmap_ts_referenced: page %p is not managed", m));
- rw_wlock(&pvh_global_lock);
- sched_pin();
- if ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) {
- pvf = pv;
- do {
- pvn = TAILQ_NEXT(pv, pv_next);
- TAILQ_REMOVE(&m->md.pv_list, pv, pv_next);
- TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_next);
- pmap = PV_PMAP(pv);
- PMAP_LOCK(pmap);
- pte = pmap_pte_quick(pmap, pv->pv_va);
- if ((*pte & PG_A) != 0) {
- PT_SET_VA_MA(pte, *pte & ~PG_A, FALSE);
- pmap_invalidate_page(pmap, pv->pv_va);
- rtval++;
- if (rtval > 4)
- pvn = NULL;
- }
- PMAP_UNLOCK(pmap);
- } while ((pv = pvn) != NULL && pv != pvf);
- }
- PT_UPDATES_FLUSH();
- if (*PMAP1)
- PT_SET_MA(PADDR1, 0);
- sched_unpin();
- rw_wunlock(&pvh_global_lock);
- return (rtval);
-}
-
-/*
- * Apply the given advice to the specified range of addresses within the
- * given pmap. Depending on the advice, clear the referenced and/or
- * modified flags in each mapping and set the mapped page's dirty field.
- */
-void
-pmap_advise(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, int advice)
-{
- pd_entry_t oldpde;
- pt_entry_t *pte;
- vm_offset_t pdnxt;
- vm_page_t m;
- boolean_t anychanged;
-
- if (advice != MADV_DONTNEED && advice != MADV_FREE)
- return;
- anychanged = FALSE;
- rw_wlock(&pvh_global_lock);
- sched_pin();
- PMAP_LOCK(pmap);
- for (; sva < eva; sva = pdnxt) {
- pdnxt = (sva + NBPDR) & ~PDRMASK;
- if (pdnxt < sva)
- pdnxt = eva;
- oldpde = pmap->pm_pdir[sva >> PDRSHIFT];
- if ((oldpde & (PG_PS | PG_V)) != PG_V)
- continue;
- if (pdnxt > eva)
- pdnxt = eva;
- for (pte = pmap_pte_quick(pmap, sva); sva != pdnxt; pte++,
- sva += PAGE_SIZE) {
- if ((*pte & (PG_MANAGED | PG_V)) != (PG_MANAGED |
- PG_V))
- continue;
- else if ((*pte & (PG_M | PG_RW)) == (PG_M | PG_RW)) {
- if (advice == MADV_DONTNEED) {
- /*
- * Future calls to pmap_is_modified()
- * can be avoided by making the page
- * dirty now.
- */
- m = PHYS_TO_VM_PAGE(xpmap_mtop(*pte) &
- PG_FRAME);
- vm_page_dirty(m);
- }
- PT_SET_VA_MA(pte, *pte & ~(PG_M | PG_A), TRUE);
- } else if ((*pte & PG_A) != 0)
- PT_SET_VA_MA(pte, *pte & ~PG_A, TRUE);
- else
- continue;
- if ((*pte & PG_G) != 0)
- pmap_invalidate_page(pmap, sva);
- else
- anychanged = TRUE;
- }
- }
- PT_UPDATES_FLUSH();
- if (*PMAP1)
- PT_SET_VA_MA(PMAP1, 0, TRUE);
- if (anychanged)
- pmap_invalidate_all(pmap);
- sched_unpin();
- rw_wunlock(&pvh_global_lock);
- PMAP_UNLOCK(pmap);
-}
-
-/*
- * Clear the modify bits on the specified physical page.
- */
-void
-pmap_clear_modify(vm_page_t m)
-{
- pv_entry_t pv;
- pmap_t pmap;
- pt_entry_t *pte;
-
- KASSERT((m->oflags & VPO_UNMANAGED) == 0,
- ("pmap_clear_modify: page %p is not managed", m));
- VM_OBJECT_ASSERT_WLOCKED(m->object);
- KASSERT(!vm_page_xbusied(m),
- ("pmap_clear_modify: page %p is exclusive busied", m));
-
- /*
- * If the page is not PGA_WRITEABLE, then no PTEs can have PG_M set.
- * If the object containing the page is locked and the page is not
- * exclusive busied, then PGA_WRITEABLE cannot be concurrently set.
- */
- if ((m->aflags & PGA_WRITEABLE) == 0)
- return;
- rw_wlock(&pvh_global_lock);
- sched_pin();
- TAILQ_FOREACH(pv, &m->md.pv_list, pv_next) {
- pmap = PV_PMAP(pv);
- PMAP_LOCK(pmap);
- pte = pmap_pte_quick(pmap, pv->pv_va);
- if ((*pte & (PG_M | PG_RW)) == (PG_M | PG_RW)) {
- /*
- * Regardless of whether a pte is 32 or 64 bits
- * in size, PG_M is among the least significant
- * 32 bits.
- */
- PT_SET_VA_MA(pte, *pte & ~PG_M, FALSE);
- pmap_invalidate_page(pmap, pv->pv_va);
- }
- PMAP_UNLOCK(pmap);
- }
- sched_unpin();
- rw_wunlock(&pvh_global_lock);
-}
-
-/*
- * Miscellaneous support routines follow
- */
-
-/*
- * Map a set of physical memory pages into the kernel virtual
- * address space. Return a pointer to where it is mapped. This
- * routine is intended to be used for mapping device memory,
- * NOT real memory.
- */
-void *
-pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, int mode)
-{
- vm_offset_t va, offset;
- vm_size_t tmpsize;
-
- offset = pa & PAGE_MASK;
- size = round_page(offset + size);
- pa = pa & PG_FRAME;
-
- if (pa < KERNLOAD && pa + size <= KERNLOAD)
- va = KERNBASE + pa;
- else
- va = kva_alloc(size);
- if (!va)
- panic("pmap_mapdev: Couldn't alloc kernel virtual memory");
-
- for (tmpsize = 0; tmpsize < size; tmpsize += PAGE_SIZE)
- pmap_kenter_attr(va + tmpsize, pa + tmpsize, mode);
- pmap_invalidate_range(kernel_pmap, va, va + tmpsize);
- pmap_invalidate_cache_range(va, va + size, FALSE);
- return ((void *)(va + offset));
-}
-
-void *
-pmap_mapdev(vm_paddr_t pa, vm_size_t size)
-{
-
- return (pmap_mapdev_attr(pa, size, PAT_UNCACHEABLE));
-}
-
-void *
-pmap_mapbios(vm_paddr_t pa, vm_size_t size)
-{
-
- return (pmap_mapdev_attr(pa, size, PAT_WRITE_BACK));
-}
-
-void
-pmap_unmapdev(vm_offset_t va, vm_size_t size)
-{
- vm_offset_t base, offset;
-
- if (va >= KERNBASE && va + size <= KERNBASE + KERNLOAD)
- return;
- base = trunc_page(va);
- offset = va & PAGE_MASK;
- size = round_page(offset + size);
- kva_free(base, size);
-}
-
-/*
- * Sets the memory attribute for the specified page.
- */
-void
-pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma)
-{
-
- m->md.pat_mode = ma;
- if ((m->flags & PG_FICTITIOUS) != 0)
- return;
-
- /*
- * If "m" is a normal page, flush it from the cache.
- * See pmap_invalidate_cache_range().
- *
- * First, try to find an existing mapping of the page by sf
- * buffer. sf_buf_invalidate_cache() modifies mapping and
- * flushes the cache.
- */
- if (sf_buf_invalidate_cache(m))
- return;
-
- /*
- * If page is not mapped by sf buffer, but CPU does not
- * support self snoop, map the page transient and do
- * invalidation. In the worst case, whole cache is flushed by
- * pmap_invalidate_cache_range().
- */
- if ((cpu_feature & CPUID_SS) == 0)
- pmap_flush_page(m);
-}
-
-static void
-pmap_flush_page(vm_page_t m)
-{
- struct sysmaps *sysmaps;
- vm_offset_t sva, eva;
-
- if ((cpu_feature & CPUID_CLFSH) != 0) {
- sysmaps = &sysmaps_pcpu[PCPU_GET(cpuid)];
- mtx_lock(&sysmaps->lock);
- if (*sysmaps->CMAP2)
- panic("pmap_flush_page: CMAP2 busy");
- sched_pin();
- PT_SET_MA(sysmaps->CADDR2, PG_V | PG_RW |
- VM_PAGE_TO_MACH(m) | PG_A | PG_M |
- pmap_cache_bits(m->md.pat_mode, 0));
- invlcaddr(sysmaps->CADDR2);
- sva = (vm_offset_t)sysmaps->CADDR2;
- eva = sva + PAGE_SIZE;
-
- /*
- * Use mfence despite the ordering implied by
- * mtx_{un,}lock() because clflush is not guaranteed
- * to be ordered by any other instruction.
- */
- mfence();
- for (; sva < eva; sva += cpu_clflush_line_size)
- clflush(sva);
- mfence();
- PT_SET_MA(sysmaps->CADDR2, 0);
- sched_unpin();
- mtx_unlock(&sysmaps->lock);
- } else
- pmap_invalidate_cache();
-}
-
-/*
- * Changes the specified virtual address range's memory type to that given by
- * the parameter "mode". The specified virtual address range must be
- * completely contained within either the kernel map.
- *
- * Returns zero if the change completed successfully, and either EINVAL or
- * ENOMEM if the change failed. Specifically, EINVAL is returned if some part
- * of the virtual address range was not mapped, and ENOMEM is returned if
- * there was insufficient memory available to complete the change.
- */
-int
-pmap_change_attr(vm_offset_t va, vm_size_t size, int mode)
-{
- vm_offset_t base, offset, tmpva;
- pt_entry_t *pte;
- u_int opte, npte;
- pd_entry_t *pde;
- boolean_t changed;
-
- base = trunc_page(va);
- offset = va & PAGE_MASK;
- size = round_page(offset + size);
-
- /* Only supported on kernel virtual addresses. */
- if (base <= VM_MAXUSER_ADDRESS)
- return (EINVAL);
-
- /* 4MB pages and pages that aren't mapped aren't supported. */
- for (tmpva = base; tmpva < (base + size); tmpva += PAGE_SIZE) {
- pde = pmap_pde(kernel_pmap, tmpva);
- if (*pde & PG_PS)
- return (EINVAL);
- if ((*pde & PG_V) == 0)
- return (EINVAL);
- pte = vtopte(va);
- if ((*pte & PG_V) == 0)
- return (EINVAL);
- }
-
- changed = FALSE;
-
- /*
- * Ok, all the pages exist and are 4k, so run through them updating
- * their cache mode.
- */
- for (tmpva = base; size > 0; ) {
- pte = vtopte(tmpva);
-
- /*
- * The cache mode bits are all in the low 32-bits of the
- * PTE, so we can just spin on updating the low 32-bits.
- */
- do {
- opte = *(u_int *)pte;
- npte = opte & ~(PG_PTE_PAT | PG_NC_PCD | PG_NC_PWT);
- npte |= pmap_cache_bits(mode, 0);
- PT_SET_VA_MA(pte, npte, TRUE);
- } while (npte != opte && (*pte != npte));
- if (npte != opte)
- changed = TRUE;
- tmpva += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
-
- /*
- * Flush CPU caches to make sure any data isn't cached that
- * shouldn't be, etc.
- */
- if (changed) {
- pmap_invalidate_range(kernel_pmap, base, tmpva);
- pmap_invalidate_cache_range(base, tmpva, FALSE);
- }
- return (0);
-}
-
-/*
- * perform the pmap work for mincore
- */
-int
-pmap_mincore(pmap_t pmap, vm_offset_t addr, vm_paddr_t *locked_pa)
-{
- pt_entry_t *ptep, pte;
- vm_paddr_t pa;
- int val;
-
- PMAP_LOCK(pmap);
-retry:
- ptep = pmap_pte(pmap, addr);
- pte = (ptep != NULL) ? PT_GET(ptep) : 0;
- pmap_pte_release(ptep);
- val = 0;
- if ((pte & PG_V) != 0) {
- val |= MINCORE_INCORE;
- if ((pte & (PG_M | PG_RW)) == (PG_M | PG_RW))
- val |= MINCORE_MODIFIED | MINCORE_MODIFIED_OTHER;
- if ((pte & PG_A) != 0)
- val |= MINCORE_REFERENCED | MINCORE_REFERENCED_OTHER;
- }
- if ((val & (MINCORE_MODIFIED_OTHER | MINCORE_REFERENCED_OTHER)) !=
- (MINCORE_MODIFIED_OTHER | MINCORE_REFERENCED_OTHER) &&
- (pte & (PG_MANAGED | PG_V)) == (PG_MANAGED | PG_V)) {
- pa = pte & PG_FRAME;
- /* Ensure that "PHYS_TO_VM_PAGE(pa)->object" doesn't change. */
- if (vm_page_pa_tryrelock(pmap, pa, locked_pa))
- goto retry;
- } else
- PA_UNLOCK_COND(*locked_pa);
- PMAP_UNLOCK(pmap);
- return (val);
-}
-
-void
-pmap_activate(struct thread *td)
-{
- pmap_t pmap, oldpmap;
- u_int cpuid;
- u_int32_t cr3;
-
- critical_enter();
- pmap = vmspace_pmap(td->td_proc->p_vmspace);
- oldpmap = PCPU_GET(curpmap);
- cpuid = PCPU_GET(cpuid);
-#if defined(SMP)
- CPU_CLR_ATOMIC(cpuid, &oldpmap->pm_active);
- CPU_SET_ATOMIC(cpuid, &pmap->pm_active);
-#else
- CPU_CLR(cpuid, &oldpmap->pm_active);
- CPU_SET(cpuid, &pmap->pm_active);
-#endif
-#ifdef PAE
- cr3 = vtophys(pmap->pm_pdpt);
-#else
- cr3 = vtophys(pmap->pm_pdir);
-#endif
- /*
- * pmap_activate is for the current thread on the current cpu
- */
- td->td_pcb->pcb_cr3 = cr3;
- PT_UPDATES_FLUSH();
- load_cr3(cr3);
- PCPU_SET(curpmap, pmap);
- critical_exit();
-}
-
-void
-pmap_sync_icache(pmap_t pm, vm_offset_t va, vm_size_t sz)
-{
-}
-
-/*
- * Increase the starting virtual address of the given mapping if a
- * different alignment might result in more superpage mappings.
- */
-void
-pmap_align_superpage(vm_object_t object, vm_ooffset_t offset,
- vm_offset_t *addr, vm_size_t size)
-{
- vm_offset_t superpage_offset;
-
- if (size < NBPDR)
- return;
- if (object != NULL && (object->flags & OBJ_COLORED) != 0)
- offset += ptoa(object->pg_color);
- superpage_offset = offset & PDRMASK;
- if (size - ((NBPDR - superpage_offset) & PDRMASK) < NBPDR ||
- (*addr & PDRMASK) == superpage_offset)
- return;
- if ((*addr & PDRMASK) < superpage_offset)
- *addr = (*addr & ~PDRMASK) + superpage_offset;
- else
- *addr = ((*addr + PDRMASK) & ~PDRMASK) + superpage_offset;
-}
-
-void
-pmap_suspend()
-{
- pmap_t pmap;
- int i, pdir, offset;
- vm_paddr_t pdirma;
- mmu_update_t mu[4];
-
- /*
- * We need to remove the recursive mapping structure from all
- * our pmaps so that Xen doesn't get confused when it restores
- * the page tables. The recursive map lives at page directory
- * index PTDPTDI. We assume that the suspend code has stopped
- * the other vcpus (if any).
- */
- LIST_FOREACH(pmap, &allpmaps, pm_list) {
- for (i = 0; i < 4; i++) {
- /*
- * Figure out which page directory (L2) page
- * contains this bit of the recursive map and
- * the offset within that page of the map
- * entry
- */
- pdir = (PTDPTDI + i) / NPDEPG;
- offset = (PTDPTDI + i) % NPDEPG;
- pdirma = pmap->pm_pdpt[pdir] & PG_FRAME;
- mu[i].ptr = pdirma + offset * sizeof(pd_entry_t);
- mu[i].val = 0;
- }
- HYPERVISOR_mmu_update(mu, 4, NULL, DOMID_SELF);
- }
-}
-
-void
-pmap_resume()
-{
- pmap_t pmap;
- int i, pdir, offset;
- vm_paddr_t pdirma;
- mmu_update_t mu[4];
-
- /*
- * Restore the recursive map that we removed on suspend.
- */
- LIST_FOREACH(pmap, &allpmaps, pm_list) {
- for (i = 0; i < 4; i++) {
- /*
- * Figure out which page directory (L2) page
- * contains this bit of the recursive map and
- * the offset within that page of the map
- * entry
- */
- pdir = (PTDPTDI + i) / NPDEPG;
- offset = (PTDPTDI + i) % NPDEPG;
- pdirma = pmap->pm_pdpt[pdir] & PG_FRAME;
- mu[i].ptr = pdirma + offset * sizeof(pd_entry_t);
- mu[i].val = (pmap->pm_pdpt[i] & PG_FRAME) | PG_V;
- }
- HYPERVISOR_mmu_update(mu, 4, NULL, DOMID_SELF);
- }
-}
-
-#if defined(PMAP_DEBUG)
-pmap_pid_dump(int pid)
-{
- pmap_t pmap;
- struct proc *p;
- int npte = 0;
- int index;
-
- sx_slock(&allproc_lock);
- FOREACH_PROC_IN_SYSTEM(p) {
- if (p->p_pid != pid)
- continue;
-
- if (p->p_vmspace) {
- int i,j;
- index = 0;
- pmap = vmspace_pmap(p->p_vmspace);
- for (i = 0; i < NPDEPTD; i++) {
- pd_entry_t *pde;
- pt_entry_t *pte;
- vm_offset_t base = i << PDRSHIFT;
-
- pde = &pmap->pm_pdir[i];
- if (pde && pmap_pde_v(pde)) {
- for (j = 0; j < NPTEPG; j++) {
- vm_offset_t va = base + (j << PAGE_SHIFT);
- if (va >= (vm_offset_t) VM_MIN_KERNEL_ADDRESS) {
- if (index) {
- index = 0;
- printf("\n");
- }
- sx_sunlock(&allproc_lock);
- return (npte);
- }
- pte = pmap_pte(pmap, va);
- if (pte && pmap_pte_v(pte)) {
- pt_entry_t pa;
- vm_page_t m;
- pa = PT_GET(pte);
- m = PHYS_TO_VM_PAGE(pa & PG_FRAME);
- printf("va: 0x%x, pt: 0x%x, h: %d, w: %d, f: 0x%x",
- va, pa, m->hold_count, m->wire_count, m->flags);
- npte++;
- index++;
- if (index >= 2) {
- index = 0;
- printf("\n");
- } else {
- printf(" ");
- }
- }
- }
- }
- }
- }
- }
- sx_sunlock(&allproc_lock);
- return (npte);
-}
-#endif
-
-#if defined(DEBUG)
-
-static void pads(pmap_t pm);
-void pmap_pvdump(vm_paddr_t pa);
-
-/* print address space of pmap*/
-static void
-pads(pmap_t pm)
-{
- int i, j;
- vm_paddr_t va;
- pt_entry_t *ptep;
-
- if (pm == kernel_pmap)
- return;
- for (i = 0; i < NPDEPTD; i++)
- if (pm->pm_pdir[i])
- for (j = 0; j < NPTEPG; j++) {
- va = (i << PDRSHIFT) + (j << PAGE_SHIFT);
- if (pm == kernel_pmap && va < KERNBASE)
- continue;
- if (pm != kernel_pmap && va > UPT_MAX_ADDRESS)
- continue;
- ptep = pmap_pte(pm, va);
- if (pmap_pte_v(ptep))
- printf("%x:%x ", va, *ptep);
- };
-
-}
-
-void
-pmap_pvdump(vm_paddr_t pa)
-{
- pv_entry_t pv;
- pmap_t pmap;
- vm_page_t m;
-
- printf("pa %x", pa);
- m = PHYS_TO_VM_PAGE(pa);
- TAILQ_FOREACH(pv, &m->md.pv_list, pv_next) {
- pmap = PV_PMAP(pv);
- printf(" -> pmap %p, va %x", (void *)pmap, pv->pv_va);
- pads(pmap);
- }
- printf(" ");
-}
-#endif
diff --git a/sys/i386/xen/xen_machdep.c b/sys/i386/xen/xen_machdep.c
deleted file mode 100644
index dbaa7ad7cadb..000000000000
--- a/sys/i386/xen/xen_machdep.c
+++ /dev/null
@@ -1,1236 +0,0 @@
-/*
- *
- * Copyright (c) 2004 Christian Limpach.
- * Copyright (c) 2004-2006,2008 Kip Macy
- * 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 Christian Limpach.
- * 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/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/ktr.h>
-#include <sys/lock.h>
-#include <sys/mount.h>
-#include <sys/malloc.h>
-#include <sys/mutex.h>
-#include <sys/kernel.h>
-#include <sys/proc.h>
-#include <sys/reboot.h>
-#include <sys/rwlock.h>
-#include <sys/sysproto.h>
-#include <sys/boot.h>
-
-#include <xen/xen-os.h>
-
-#include <vm/vm.h>
-#include <vm/pmap.h>
-#include <machine/segments.h>
-#include <machine/pcb.h>
-#include <machine/stdarg.h>
-#include <machine/vmparam.h>
-#include <machine/cpu.h>
-#include <machine/intr_machdep.h>
-#include <machine/md_var.h>
-#include <machine/asmacros.h>
-
-
-
-#include <xen/hypervisor.h>
-#include <xen/xenstore/xenstorevar.h>
-#include <machine/xen/xenvar.h>
-#include <machine/xen/xenfunc.h>
-#include <machine/xen/xenpmap.h>
-#include <machine/xen/xenfunc.h>
-#include <xen/interface/memory.h>
-#include <machine/xen/features.h>
-#ifdef SMP
-#include <machine/privatespace.h>
-#endif
-
-
-#include <vm/vm_page.h>
-
-
-#define IDTVEC(name) __CONCAT(X,name)
-
-extern inthand_t
-IDTVEC(div), IDTVEC(dbg), IDTVEC(nmi), IDTVEC(bpt), IDTVEC(ofl),
- IDTVEC(bnd), IDTVEC(ill), IDTVEC(dna), IDTVEC(fpusegm),
- IDTVEC(tss), IDTVEC(missing), IDTVEC(stk), IDTVEC(prot),
- IDTVEC(page), IDTVEC(mchk), IDTVEC(rsvd), IDTVEC(fpu), IDTVEC(align),
- IDTVEC(xmm), IDTVEC(lcall_syscall), IDTVEC(int0x80_syscall);
-
-
-int xendebug_flags;
-start_info_t *xen_start_info;
-start_info_t *HYPERVISOR_start_info;
-shared_info_t *HYPERVISOR_shared_info;
-xen_pfn_t *xen_machine_phys = machine_to_phys_mapping;
-xen_pfn_t *xen_phys_machine;
-xen_pfn_t *xen_pfn_to_mfn_frame_list[16];
-xen_pfn_t *xen_pfn_to_mfn_frame_list_list;
-int preemptable, init_first;
-extern unsigned int avail_space;
-int xen_vector_callback_enabled = 0;
-enum xen_domain_type xen_domain_type = XEN_PV_DOMAIN;
-
-void ni_cli(void);
-void ni_sti(void);
-
-
-void
-ni_cli(void)
-{
- CTR0(KTR_SPARE2, "ni_cli disabling interrupts");
- __asm__("pushl %edx;"
- "pushl %eax;"
- );
- __cli();
- __asm__("popl %eax;"
- "popl %edx;"
- );
-}
-
-
-void
-ni_sti(void)
-{
- __asm__("pushl %edx;"
- "pushl %esi;"
- "pushl %eax;"
- );
- __sti();
- __asm__("popl %eax;"
- "popl %esi;"
- "popl %edx;"
- );
-}
-
-void
-force_evtchn_callback(void)
-{
- (void)HYPERVISOR_xen_version(0, NULL);
-}
-
-/*
- * Modify the cmd_line by converting ',' to NULLs so that it is in a format
- * suitable for the static env vars.
- */
-char *
-xen_setbootenv(char *cmd_line)
-{
- char *cmd_line_next;
-
- /* Skip leading spaces */
- for (; *cmd_line == ' '; cmd_line++);
-
- xc_printf("xen_setbootenv(): cmd_line='%s'\n", cmd_line);
-
- for (cmd_line_next = cmd_line; strsep(&cmd_line_next, ",") != NULL;);
- return cmd_line;
-}
-
-int
-xen_boothowto(char *envp)
-{
- int i, howto = 0;
-
- /* get equivalents from the environment */
- for (i = 0; howto_names[i].ev != NULL; i++)
- if (kern_getenv(howto_names[i].ev) != NULL)
- howto |= howto_names[i].mask;
- return howto;
-}
-
-
-#define XPQUEUE_SIZE 128
-
-struct mmu_log {
- char *file;
- int line;
-};
-
-#ifdef SMP
-/* per-cpu queues and indices */
-#ifdef INVARIANTS
-static struct mmu_log xpq_queue_log[XEN_LEGACY_MAX_VCPUS][XPQUEUE_SIZE];
-#endif
-
-static int xpq_idx[XEN_LEGACY_MAX_VCPUS];
-static mmu_update_t xpq_queue[XEN_LEGACY_MAX_VCPUS][XPQUEUE_SIZE];
-
-#define XPQ_QUEUE_LOG xpq_queue_log[vcpu]
-#define XPQ_QUEUE xpq_queue[vcpu]
-#define XPQ_IDX xpq_idx[vcpu]
-#define SET_VCPU() int vcpu = smp_processor_id()
-#else
-
-static mmu_update_t xpq_queue[XPQUEUE_SIZE];
-#ifdef INVARIANTS
-static struct mmu_log xpq_queue_log[XPQUEUE_SIZE];
-#endif
-static int xpq_idx = 0;
-
-#define XPQ_QUEUE_LOG xpq_queue_log
-#define XPQ_QUEUE xpq_queue
-#define XPQ_IDX xpq_idx
-#define SET_VCPU()
-#endif /* !SMP */
-
-#define XPQ_IDX_INC atomic_add_int(&XPQ_IDX, 1);
-
-#if 0
-static void
-xen_dump_queue(void)
-{
- int _xpq_idx = XPQ_IDX;
- int i;
-
- if (_xpq_idx <= 1)
- return;
-
- xc_printf("xen_dump_queue(): %u entries\n", _xpq_idx);
- for (i = 0; i < _xpq_idx; i++) {
- xc_printf(" val: %llx ptr: %llx\n", XPQ_QUEUE[i].val,
- XPQ_QUEUE[i].ptr);
- }
-}
-#endif
-
-
-static __inline void
-_xen_flush_queue(void)
-{
- SET_VCPU();
- int _xpq_idx = XPQ_IDX;
- int error, i;
-
-#ifdef INVARIANTS
- if (__predict_true(gdtset))
- CRITICAL_ASSERT(curthread);
-#endif
-
- XPQ_IDX = 0;
- /* Make sure index is cleared first to avoid double updates. */
- error = HYPERVISOR_mmu_update((mmu_update_t *)&XPQ_QUEUE,
- _xpq_idx, NULL, DOMID_SELF);
-
-#if 0
- if (__predict_true(gdtset))
- for (i = _xpq_idx; i > 0;) {
- if (i >= 3) {
- CTR6(KTR_PMAP, "mmu:val: %lx ptr: %lx val: %lx "
- "ptr: %lx val: %lx ptr: %lx",
- (XPQ_QUEUE[i-1].val & 0xffffffff),
- (XPQ_QUEUE[i-1].ptr & 0xffffffff),
- (XPQ_QUEUE[i-2].val & 0xffffffff),
- (XPQ_QUEUE[i-2].ptr & 0xffffffff),
- (XPQ_QUEUE[i-3].val & 0xffffffff),
- (XPQ_QUEUE[i-3].ptr & 0xffffffff));
- i -= 3;
- } else if (i == 2) {
- CTR4(KTR_PMAP, "mmu: val: %lx ptr: %lx val: %lx ptr: %lx",
- (XPQ_QUEUE[i-1].val & 0xffffffff),
- (XPQ_QUEUE[i-1].ptr & 0xffffffff),
- (XPQ_QUEUE[i-2].val & 0xffffffff),
- (XPQ_QUEUE[i-2].ptr & 0xffffffff));
- i = 0;
- } else {
- CTR2(KTR_PMAP, "mmu: val: %lx ptr: %lx",
- (XPQ_QUEUE[i-1].val & 0xffffffff),
- (XPQ_QUEUE[i-1].ptr & 0xffffffff));
- i = 0;
- }
- }
-#endif
- if (__predict_false(error < 0)) {
- for (i = 0; i < _xpq_idx; i++)
- printf("val: %llx ptr: %llx\n",
- XPQ_QUEUE[i].val, XPQ_QUEUE[i].ptr);
- panic("Failed to execute MMU updates: %d", error);
- }
-
-}
-
-void
-xen_flush_queue(void)
-{
- SET_VCPU();
-
- if (__predict_true(gdtset))
- critical_enter();
- if (XPQ_IDX != 0) _xen_flush_queue();
- if (__predict_true(gdtset))
- critical_exit();
-}
-
-static __inline void
-xen_increment_idx(void)
-{
- SET_VCPU();
-
- XPQ_IDX++;
- if (__predict_false(XPQ_IDX == XPQUEUE_SIZE))
- xen_flush_queue();
-}
-
-void
-xen_check_queue(void)
-{
-#ifdef INVARIANTS
- SET_VCPU();
-
- KASSERT(XPQ_IDX == 0, ("pending operations XPQ_IDX=%d", XPQ_IDX));
-#endif
-}
-
-void
-xen_invlpg(vm_offset_t va)
-{
- struct mmuext_op op;
- op.cmd = MMUEXT_INVLPG_ALL;
- op.arg1.linear_addr = va & ~PAGE_MASK;
- PANIC_IF(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
-}
-
-void
-xen_load_cr3(u_int val)
-{
- struct mmuext_op op;
-#ifdef INVARIANTS
- SET_VCPU();
-
- KASSERT(XPQ_IDX == 0, ("pending operations XPQ_IDX=%d", XPQ_IDX));
-#endif
- op.cmd = MMUEXT_NEW_BASEPTR;
- op.arg1.mfn = xpmap_ptom(val) >> PAGE_SHIFT;
- PANIC_IF(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
-}
-
-#ifdef KTR
-static __inline u_int
-rebp(void)
-{
- u_int data;
-
- __asm __volatile("movl 4(%%ebp),%0" : "=r" (data));
- return (data);
-}
-#endif
-
-u_int
-read_eflags(void)
-{
- vcpu_info_t *_vcpu;
- u_int eflags;
-
- eflags = _read_eflags();
- _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()];
- if (_vcpu->evtchn_upcall_mask)
- eflags &= ~PSL_I;
-
- return (eflags);
-}
-
-void
-write_eflags(u_int eflags)
-{
- u_int intr;
-
- CTR2(KTR_SPARE2, "%x xen_restore_flags eflags %x", rebp(), eflags);
- intr = ((eflags & PSL_I) == 0);
- __restore_flags(intr);
- _write_eflags(eflags);
-}
-
-void
-xen_cli(void)
-{
- CTR1(KTR_SPARE2, "%x xen_cli disabling interrupts", rebp());
- __cli();
-}
-
-void
-xen_sti(void)
-{
- CTR1(KTR_SPARE2, "%x xen_sti enabling interrupts", rebp());
- __sti();
-}
-
-u_int
-xen_rcr2(void)
-{
-
- return (HYPERVISOR_shared_info->vcpu_info[curcpu].arch.cr2);
-}
-
-void
-_xen_machphys_update(vm_paddr_t mfn, vm_paddr_t pfn, char *file, int line)
-{
- SET_VCPU();
-
- if (__predict_true(gdtset))
- critical_enter();
- XPQ_QUEUE[XPQ_IDX].ptr = (mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE;
- XPQ_QUEUE[XPQ_IDX].val = pfn;
-#ifdef INVARIANTS
- XPQ_QUEUE_LOG[XPQ_IDX].file = file;
- XPQ_QUEUE_LOG[XPQ_IDX].line = line;
-#endif
- xen_increment_idx();
- if (__predict_true(gdtset))
- critical_exit();
-}
-
-extern struct rwlock pvh_global_lock;
-
-void
-_xen_queue_pt_update(vm_paddr_t ptr, vm_paddr_t val, char *file, int line)
-{
- SET_VCPU();
-
- if (__predict_true(gdtset))
- rw_assert(&pvh_global_lock, RA_WLOCKED);
-
- KASSERT((ptr & 7) == 0, ("misaligned update"));
-
- if (__predict_true(gdtset))
- critical_enter();
-
- XPQ_QUEUE[XPQ_IDX].ptr = ((uint64_t)ptr) | MMU_NORMAL_PT_UPDATE;
- XPQ_QUEUE[XPQ_IDX].val = (uint64_t)val;
-#ifdef INVARIANTS
- XPQ_QUEUE_LOG[XPQ_IDX].file = file;
- XPQ_QUEUE_LOG[XPQ_IDX].line = line;
-#endif
- xen_increment_idx();
- if (__predict_true(gdtset))
- critical_exit();
-}
-
-void
-xen_pgdpt_pin(vm_paddr_t ma)
-{
- struct mmuext_op op;
- op.cmd = MMUEXT_PIN_L3_TABLE;
- op.arg1.mfn = ma >> PAGE_SHIFT;
- xen_flush_queue();
- PANIC_IF(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
-}
-
-void
-xen_pgd_pin(vm_paddr_t ma)
-{
- struct mmuext_op op;
- op.cmd = MMUEXT_PIN_L2_TABLE;
- op.arg1.mfn = ma >> PAGE_SHIFT;
- xen_flush_queue();
- PANIC_IF(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
-}
-
-void
-xen_pgd_unpin(vm_paddr_t ma)
-{
- struct mmuext_op op;
- op.cmd = MMUEXT_UNPIN_TABLE;
- op.arg1.mfn = ma >> PAGE_SHIFT;
- xen_flush_queue();
- PANIC_IF(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
-}
-
-void
-xen_pt_pin(vm_paddr_t ma)
-{
- struct mmuext_op op;
- op.cmd = MMUEXT_PIN_L1_TABLE;
- op.arg1.mfn = ma >> PAGE_SHIFT;
- xen_flush_queue();
- PANIC_IF(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
-}
-
-void
-xen_pt_unpin(vm_paddr_t ma)
-{
- struct mmuext_op op;
- op.cmd = MMUEXT_UNPIN_TABLE;
- op.arg1.mfn = ma >> PAGE_SHIFT;
- xen_flush_queue();
- PANIC_IF(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
-}
-
-void
-xen_set_ldt(vm_paddr_t ptr, unsigned long len)
-{
- struct mmuext_op op;
- op.cmd = MMUEXT_SET_LDT;
- op.arg1.linear_addr = ptr;
- op.arg2.nr_ents = len;
- xen_flush_queue();
- PANIC_IF(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
-}
-
-void xen_tlb_flush(void)
-{
- struct mmuext_op op;
- op.cmd = MMUEXT_TLB_FLUSH_LOCAL;
- xen_flush_queue();
- PANIC_IF(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
-}
-
-void
-xen_update_descriptor(union descriptor *table, union descriptor *entry)
-{
- vm_paddr_t pa;
- pt_entry_t *ptp;
-
- ptp = vtopte((vm_offset_t)table);
- pa = (*ptp & PG_FRAME) | ((vm_offset_t)table & PAGE_MASK);
- if (HYPERVISOR_update_descriptor(pa, *(uint64_t *)entry))
- panic("HYPERVISOR_update_descriptor failed\n");
-}
-
-
-#if 0
-/*
- * Bitmap is indexed by page number. If bit is set, the page is part of a
- * xen_create_contiguous_region() area of memory.
- */
-unsigned long *contiguous_bitmap;
-
-static void
-contiguous_bitmap_set(unsigned long first_page, unsigned long nr_pages)
-{
- unsigned long start_off, end_off, curr_idx, end_idx;
-
- curr_idx = first_page / BITS_PER_LONG;
- start_off = first_page & (BITS_PER_LONG-1);
- end_idx = (first_page + nr_pages) / BITS_PER_LONG;
- end_off = (first_page + nr_pages) & (BITS_PER_LONG-1);
-
- if (curr_idx == end_idx) {
- contiguous_bitmap[curr_idx] |=
- ((1UL<<end_off)-1) & -(1UL<<start_off);
- } else {
- contiguous_bitmap[curr_idx] |= -(1UL<<start_off);
- while ( ++curr_idx < end_idx )
- contiguous_bitmap[curr_idx] = ~0UL;
- contiguous_bitmap[curr_idx] |= (1UL<<end_off)-1;
- }
-}
-
-static void
-contiguous_bitmap_clear(unsigned long first_page, unsigned long nr_pages)
-{
- unsigned long start_off, end_off, curr_idx, end_idx;
-
- curr_idx = first_page / BITS_PER_LONG;
- start_off = first_page & (BITS_PER_LONG-1);
- end_idx = (first_page + nr_pages) / BITS_PER_LONG;
- end_off = (first_page + nr_pages) & (BITS_PER_LONG-1);
-
- if (curr_idx == end_idx) {
- contiguous_bitmap[curr_idx] &=
- -(1UL<<end_off) | ((1UL<<start_off)-1);
- } else {
- contiguous_bitmap[curr_idx] &= (1UL<<start_off)-1;
- while ( ++curr_idx != end_idx )
- contiguous_bitmap[curr_idx] = 0;
- contiguous_bitmap[curr_idx] &= -(1UL<<end_off);
- }
-}
-#endif
-
-/* Ensure multi-page extents are contiguous in machine memory. */
-int
-xen_create_contiguous_region(vm_page_t pages, int npages)
-{
- unsigned long mfn, i, flags;
- int order;
- struct xen_memory_reservation reservation = {
- .nr_extents = 1,
- .extent_order = 0,
- .domid = DOMID_SELF
- };
- set_xen_guest_handle(reservation.extent_start, &mfn);
-
- balloon_lock(flags);
-
- /* can currently only handle power of two allocation */
- PANIC_IF(ffs(npages) != fls(npages));
-
- /* 0. determine order */
- order = (ffs(npages) == fls(npages)) ? fls(npages) - 1 : fls(npages);
-
- /* 1. give away machine pages. */
- for (i = 0; i < (1 << order); i++) {
- int pfn;
- pfn = VM_PAGE_TO_PHYS(&pages[i]) >> PAGE_SHIFT;
- mfn = PFNTOMFN(pfn);
- PFNTOMFN(pfn) = INVALID_P2M_ENTRY;
- PANIC_IF(HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation) != 1);
- }
-
-
- /* 2. Get a new contiguous memory extent. */
- reservation.extent_order = order;
- /* xenlinux hardcodes this because of aacraid - maybe set to 0 if we're not
- * running with a broxen driver XXXEN
- */
- reservation.address_bits = 31;
- if (HYPERVISOR_memory_op(XENMEM_increase_reservation, &reservation) != 1)
- goto fail;
-
- /* 3. Map the new extent in place of old pages. */
- for (i = 0; i < (1 << order); i++) {
- int pfn;
- pfn = VM_PAGE_TO_PHYS(&pages[i]) >> PAGE_SHIFT;
- xen_machphys_update(mfn+i, pfn);
- PFNTOMFN(pfn) = mfn+i;
- }
-
- xen_tlb_flush();
-
-#if 0
- contiguous_bitmap_set(VM_PAGE_TO_PHYS(&pages[0]) >> PAGE_SHIFT, 1UL << order);
-#endif
-
- balloon_unlock(flags);
-
- return 0;
-
- fail:
- reservation.extent_order = 0;
- reservation.address_bits = 0;
-
- for (i = 0; i < (1 << order); i++) {
- int pfn;
- pfn = VM_PAGE_TO_PHYS(&pages[i]) >> PAGE_SHIFT;
- PANIC_IF(HYPERVISOR_memory_op(
- XENMEM_increase_reservation, &reservation) != 1);
- xen_machphys_update(mfn, pfn);
- PFNTOMFN(pfn) = mfn;
- }
-
- xen_tlb_flush();
-
- balloon_unlock(flags);
-
- return ENOMEM;
-}
-
-void
-xen_destroy_contiguous_region(void *addr, int npages)
-{
- unsigned long mfn, i, flags, order, pfn0;
- struct xen_memory_reservation reservation = {
- .nr_extents = 1,
- .extent_order = 0,
- .domid = DOMID_SELF
- };
- set_xen_guest_handle(reservation.extent_start, &mfn);
-
- pfn0 = vtophys(addr) >> PAGE_SHIFT;
-#if 0
- scrub_pages(vstart, 1 << order);
-#endif
- /* can currently only handle power of two allocation */
- PANIC_IF(ffs(npages) != fls(npages));
-
- /* 0. determine order */
- order = (ffs(npages) == fls(npages)) ? fls(npages) - 1 : fls(npages);
-
- balloon_lock(flags);
-
-#if 0
- contiguous_bitmap_clear(vtophys(addr) >> PAGE_SHIFT, 1UL << order);
-#endif
-
- /* 1. Zap current PTEs, giving away the underlying pages. */
- for (i = 0; i < (1 << order); i++) {
- int pfn;
- uint64_t new_val = 0;
- pfn = vtomach((char *)addr + i*PAGE_SIZE) >> PAGE_SHIFT;
-
- PANIC_IF(HYPERVISOR_update_va_mapping((vm_offset_t)((char *)addr + (i * PAGE_SIZE)), new_val, 0));
- PFNTOMFN(pfn) = INVALID_P2M_ENTRY;
- PANIC_IF(HYPERVISOR_memory_op(
- XENMEM_decrease_reservation, &reservation) != 1);
- }
-
- /* 2. Map new pages in place of old pages. */
- for (i = 0; i < (1 << order); i++) {
- int pfn;
- uint64_t new_val;
- pfn = pfn0 + i;
- PANIC_IF(HYPERVISOR_memory_op(XENMEM_increase_reservation, &reservation) != 1);
-
- new_val = mfn << PAGE_SHIFT;
- PANIC_IF(HYPERVISOR_update_va_mapping((vm_offset_t)addr + (i * PAGE_SIZE),
- new_val, PG_KERNEL));
- xen_machphys_update(mfn, pfn);
- PFNTOMFN(pfn) = mfn;
- }
-
- xen_tlb_flush();
-
- balloon_unlock(flags);
-}
-
-extern vm_offset_t proc0kstack;
-extern int vm86paddr, vm86phystk;
-char *bootmem_start, *bootmem_current, *bootmem_end;
-
-pteinfo_t *pteinfo_list;
-void initvalues(start_info_t *startinfo);
-
-void *
-bootmem_alloc(unsigned int size)
-{
- char *retptr;
-
- retptr = bootmem_current;
- PANIC_IF(retptr + size > bootmem_end);
- bootmem_current += size;
-
- return retptr;
-}
-
-void
-bootmem_free(void *ptr, unsigned int size)
-{
- char *tptr;
-
- tptr = ptr;
- PANIC_IF(tptr != bootmem_current - size ||
- bootmem_current - size < bootmem_start);
-
- bootmem_current -= size;
-}
-
-#if 0
-static vm_paddr_t
-xpmap_mtop2(vm_paddr_t mpa)
-{
- return ((machine_to_phys_mapping[mpa >> PAGE_SHIFT] << PAGE_SHIFT)
- ) | (mpa & ~PG_FRAME);
-}
-
-static pd_entry_t
-xpmap_get_bootpde(vm_paddr_t va)
-{
-
- return ((pd_entry_t *)xen_start_info->pt_base)[va >> 22];
-}
-
-static pd_entry_t
-xpmap_get_vbootpde(vm_paddr_t va)
-{
- pd_entry_t pde;
-
- pde = xpmap_get_bootpde(va);
- if ((pde & PG_V) == 0)
- return (pde & ~PG_FRAME);
- return (pde & ~PG_FRAME) |
- (xpmap_mtop2(pde & PG_FRAME) + KERNBASE);
-}
-
-static pt_entry_t 8*
-xpmap_get_bootptep(vm_paddr_t va)
-{
- pd_entry_t pde;
-
- pde = xpmap_get_vbootpde(va);
- if ((pde & PG_V) == 0)
- return (void *)-1;
-#define PT_MASK 0x003ff000 /* page table address bits */
- return &(((pt_entry_t *)(pde & PG_FRAME))[(va & PT_MASK) >> PAGE_SHIFT]);
-}
-
-static pt_entry_t
-xpmap_get_bootpte(vm_paddr_t va)
-{
-
- return xpmap_get_bootptep(va)[0];
-}
-#endif
-
-
-#ifdef ADD_ISA_HOLE
-static void
-shift_phys_machine(unsigned long *phys_machine, int nr_pages)
-{
-
- unsigned long *tmp_page, *current_page, *next_page;
- int i;
-
- tmp_page = bootmem_alloc(PAGE_SIZE);
- current_page = phys_machine + nr_pages - (PAGE_SIZE/sizeof(unsigned long));
- next_page = current_page - (PAGE_SIZE/sizeof(unsigned long));
- bcopy(phys_machine, tmp_page, PAGE_SIZE);
-
- while (current_page > phys_machine) {
- /* save next page */
- bcopy(next_page, tmp_page, PAGE_SIZE);
- /* shift down page */
- bcopy(current_page, next_page, PAGE_SIZE);
- /* finish swap */
- bcopy(tmp_page, current_page, PAGE_SIZE);
-
- current_page -= (PAGE_SIZE/sizeof(unsigned long));
- next_page -= (PAGE_SIZE/sizeof(unsigned long));
- }
- bootmem_free(tmp_page, PAGE_SIZE);
-
- for (i = 0; i < nr_pages; i++) {
- xen_machphys_update(phys_machine[i], i);
- }
- memset(phys_machine, INVALID_P2M_ENTRY, PAGE_SIZE);
-
-}
-#endif /* ADD_ISA_HOLE */
-
-/*
- * Build a directory of the pages that make up our Physical to Machine
- * mapping table. The Xen suspend/restore code uses this to find our
- * mapping table.
- */
-static void
-init_frame_list_list(void *arg)
-{
- unsigned long nr_pages = xen_start_info->nr_pages;
-#define FPP (PAGE_SIZE/sizeof(xen_pfn_t))
- int i, j, k;
-
- xen_pfn_to_mfn_frame_list_list = malloc(PAGE_SIZE, M_DEVBUF, M_WAITOK);
- for (i = 0, j = 0, k = -1; i < nr_pages;
- i += FPP, j++) {
- if ((j & (FPP - 1)) == 0) {
- k++;
- xen_pfn_to_mfn_frame_list[k] =
- malloc(PAGE_SIZE, M_DEVBUF, M_WAITOK);
- xen_pfn_to_mfn_frame_list_list[k] =
- VTOMFN(xen_pfn_to_mfn_frame_list[k]);
- j = 0;
- }
- xen_pfn_to_mfn_frame_list[k][j] =
- VTOMFN(&xen_phys_machine[i]);
- }
-
- HYPERVISOR_shared_info->arch.max_pfn = nr_pages;
- HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list
- = VTOMFN(xen_pfn_to_mfn_frame_list_list);
-}
-SYSINIT(init_fll, SI_SUB_DEVFS, SI_ORDER_ANY, init_frame_list_list, NULL);
-
-extern unsigned long physfree;
-
-int pdir, curoffset;
-extern int nkpt;
-
-extern uint32_t kernbase;
-
-void
-initvalues(start_info_t *startinfo)
-{
- vm_offset_t cur_space, cur_space_pt;
- struct physdev_set_iopl set_iopl;
-
- int l3_pages, l2_pages, l1_pages, offset;
- vm_paddr_t console_page_ma, xen_store_ma;
- vm_offset_t tmpva;
- vm_paddr_t shinfo;
-#ifdef PAE
- vm_paddr_t IdlePDPTma, IdlePDPTnewma;
- vm_paddr_t IdlePTDnewma[4];
- pd_entry_t *IdlePDPTnew, *IdlePTDnew;
- vm_paddr_t IdlePTDma[4];
-#else
- vm_paddr_t IdlePTDma[1];
-#endif
- unsigned long i;
- int ncpus = MAXCPU;
-
- nkpt = min(
- min(
- max((startinfo->nr_pages >> NPGPTD_SHIFT), nkpt),
- NPGPTD*NPDEPG - KPTDI),
- (HYPERVISOR_VIRT_START - KERNBASE) >> PDRSHIFT);
-
- HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments);
-#ifdef notyet
- /*
- * need to install handler
- */
- HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments_notify);
-#endif
- xen_start_info = startinfo;
- HYPERVISOR_start_info = startinfo;
- xen_phys_machine = (xen_pfn_t *)startinfo->mfn_list;
-
- IdlePTD = (pd_entry_t *)((uint8_t *)startinfo->pt_base + PAGE_SIZE);
- l1_pages = 0;
-
-#ifdef PAE
- l3_pages = 1;
- l2_pages = 0;
- IdlePDPT = (pd_entry_t *)startinfo->pt_base;
- IdlePDPTma = VTOM(startinfo->pt_base);
- for (i = (KERNBASE >> 30);
- (i < 4) && (IdlePDPT[i] != 0); i++)
- l2_pages++;
- /*
- * Note that only one page directory has been allocated at this point.
- * Thus, if KERNBASE
- */
- for (i = 0; i < l2_pages; i++)
- IdlePTDma[i] = VTOM(IdlePTD + i*PAGE_SIZE);
-
- l2_pages = (l2_pages == 0) ? 1 : l2_pages;
-#else
- l3_pages = 0;
- l2_pages = 1;
-#endif
- for (i = (((KERNBASE>>18) & PAGE_MASK)>>PAGE_SHIFT);
- (i<l2_pages*NPDEPG) && (i<(VM_MAX_KERNEL_ADDRESS>>PDRSHIFT)); i++) {
-
- if (IdlePTD[i] == 0)
- break;
- l1_pages++;
- }
-
- /* number of pages allocated after the pts + 1*/;
- cur_space = xen_start_info->pt_base +
- (l3_pages + l2_pages + l1_pages + 1)*PAGE_SIZE;
-
- xc_printf("initvalues(): wooh - availmem=%x,%x\n", avail_space,
- cur_space);
-
- xc_printf("KERNBASE=%x,pt_base=%lx, VTOPFN(base)=%x, nr_pt_frames=%lx\n",
- KERNBASE,xen_start_info->pt_base, VTOPFN(xen_start_info->pt_base),
- xen_start_info->nr_pt_frames);
- xendebug_flags = 0; /* 0xffffffff; */
-
-#ifdef ADD_ISA_HOLE
- shift_phys_machine(xen_phys_machine, xen_start_info->nr_pages);
-#endif
- XENPRINTF("IdlePTD %p\n", IdlePTD);
- XENPRINTF("nr_pages: %ld shared_info: 0x%lx flags: 0x%x pt_base: 0x%lx "
- "mod_start: 0x%lx mod_len: 0x%lx\n",
- xen_start_info->nr_pages, xen_start_info->shared_info,
- xen_start_info->flags, xen_start_info->pt_base,
- xen_start_info->mod_start, xen_start_info->mod_len);
-
-#ifdef PAE
- IdlePDPTnew = (pd_entry_t *)cur_space; cur_space += PAGE_SIZE;
- bzero(IdlePDPTnew, PAGE_SIZE);
-
- IdlePDPTnewma = VTOM(IdlePDPTnew);
- IdlePTDnew = (pd_entry_t *)cur_space; cur_space += 4*PAGE_SIZE;
- bzero(IdlePTDnew, 4*PAGE_SIZE);
-
- for (i = 0; i < 4; i++)
- IdlePTDnewma[i] = VTOM((uint8_t *)IdlePTDnew + i*PAGE_SIZE);
- /*
- * L3
- *
- * Copy the 4 machine addresses of the new PTDs in to the PDPT
- *
- */
- for (i = 0; i < 4; i++)
- IdlePDPTnew[i] = IdlePTDnewma[i] | PG_V;
-
- __asm__("nop;");
- /*
- *
- * re-map the new PDPT read-only
- */
- PT_SET_MA(IdlePDPTnew, IdlePDPTnewma | PG_V);
- /*
- *
- * Unpin the current PDPT
- */
- xen_pt_unpin(IdlePDPTma);
-
-#endif /* PAE */
-
- /* Map proc0's KSTACK */
- proc0kstack = cur_space; cur_space += (KSTACK_PAGES * PAGE_SIZE);
- xc_printf("proc0kstack=%u\n", proc0kstack);
-
- /* vm86/bios stack */
- cur_space += PAGE_SIZE;
-
- /* Map space for the vm86 region */
- vm86paddr = (vm_offset_t)cur_space;
- cur_space += (PAGE_SIZE * 3);
-
- /* allocate 4 pages for bootmem allocator */
- bootmem_start = bootmem_current = (char *)cur_space;
- cur_space += (4 * PAGE_SIZE);
- bootmem_end = (char *)cur_space;
-
- /* allocate pages for gdt */
- gdt = (union descriptor *)cur_space;
- cur_space += PAGE_SIZE*ncpus;
-
- /* allocate page for ldt */
- ldt = (union descriptor *)cur_space; cur_space += PAGE_SIZE;
- cur_space += PAGE_SIZE;
-
- /* unmap remaining pages from initial chunk
- *
- */
- for (tmpva = cur_space; tmpva < (((uint32_t)&kernbase) + (l1_pages<<PDRSHIFT));
- tmpva += PAGE_SIZE) {
- bzero((char *)tmpva, PAGE_SIZE);
- PT_SET_MA(tmpva, (vm_paddr_t)0);
- }
-
- PT_UPDATES_FLUSH();
-
- memcpy(((uint8_t *)IdlePTDnew) + ((unsigned int)(KERNBASE >> 18)),
- ((uint8_t *)IdlePTD) + ((KERNBASE >> 18) & PAGE_MASK),
- l1_pages*sizeof(pt_entry_t));
-
- for (i = 0; i < 4; i++) {
- PT_SET_MA((uint8_t *)IdlePTDnew + i*PAGE_SIZE,
- IdlePTDnewma[i] | PG_V);
- }
- xen_load_cr3(VTOP(IdlePDPTnew));
- xen_pgdpt_pin(VTOM(IdlePDPTnew));
-
- /* allocate remainder of nkpt pages */
- cur_space_pt = cur_space;
- for (offset = (KERNBASE >> PDRSHIFT), i = l1_pages; i < nkpt;
- i++, cur_space += PAGE_SIZE) {
- pdir = (offset + i) / NPDEPG;
- curoffset = ((offset + i) % NPDEPG);
- if (((offset + i) << PDRSHIFT) == VM_MAX_KERNEL_ADDRESS)
- break;
-
- /*
- * make sure that all the initial page table pages
- * have been zeroed
- */
- PT_SET_MA(cur_space, VTOM(cur_space) | PG_V | PG_RW);
- bzero((char *)cur_space, PAGE_SIZE);
- PT_SET_MA(cur_space, (vm_paddr_t)0);
- xen_pt_pin(VTOM(cur_space));
- xen_queue_pt_update((vm_paddr_t)(IdlePTDnewma[pdir] +
- curoffset*sizeof(vm_paddr_t)),
- VTOM(cur_space) | PG_KERNEL);
- PT_UPDATES_FLUSH();
- }
-
- for (i = 0; i < 4; i++) {
- pdir = (PTDPTDI + i) / NPDEPG;
- curoffset = (PTDPTDI + i) % NPDEPG;
-
- xen_queue_pt_update((vm_paddr_t)(IdlePTDnewma[pdir] +
- curoffset*sizeof(vm_paddr_t)),
- IdlePTDnewma[i] | PG_V);
- }
-
- PT_UPDATES_FLUSH();
-
- IdlePTD = IdlePTDnew;
- IdlePDPT = IdlePDPTnew;
- IdlePDPTma = IdlePDPTnewma;
-
- HYPERVISOR_shared_info = (shared_info_t *)cur_space;
- cur_space += PAGE_SIZE;
-
- xen_store = (struct xenstore_domain_interface *)cur_space;
- cur_space += PAGE_SIZE;
-
- console_page = (char *)cur_space;
- cur_space += PAGE_SIZE;
-
- /*
- * shared_info is an unsigned long so this will randomly break if
- * it is allocated above 4GB - I guess people are used to that
- * sort of thing with Xen ... sigh
- */
- shinfo = xen_start_info->shared_info;
- PT_SET_MA(HYPERVISOR_shared_info, shinfo | PG_KERNEL);
-
- xc_printf("#4\n");
-
- xen_store_ma = (((vm_paddr_t)xen_start_info->store_mfn) << PAGE_SHIFT);
- PT_SET_MA(xen_store, xen_store_ma | PG_KERNEL);
- console_page_ma = (((vm_paddr_t)xen_start_info->console.domU.mfn) << PAGE_SHIFT);
- PT_SET_MA(console_page, console_page_ma | PG_KERNEL);
-
- xc_printf("#5\n");
-
- set_iopl.iopl = 1;
- PANIC_IF(HYPERVISOR_physdev_op(PHYSDEVOP_SET_IOPL, &set_iopl));
- xc_printf("#6\n");
-#if 0
- /* add page table for KERNBASE */
- xen_queue_pt_update(IdlePTDma + KPTDI*sizeof(vm_paddr_t),
- VTOM(cur_space) | PG_KERNEL);
- xen_flush_queue();
-#ifdef PAE
- xen_queue_pt_update(pdir_shadow_ma[3] + KPTDI*sizeof(vm_paddr_t),
- VTOM(cur_space) | PG_V | PG_A);
-#else
- xen_queue_pt_update(pdir_shadow_ma + KPTDI*sizeof(vm_paddr_t),
- VTOM(cur_space) | PG_V | PG_A);
-#endif
- xen_flush_queue();
- cur_space += PAGE_SIZE;
- xc_printf("#6\n");
-#endif /* 0 */
-#ifdef notyet
- if (xen_start_info->flags & SIF_INITDOMAIN) {
- /* Map first megabyte */
- for (i = 0; i < (256 << PAGE_SHIFT); i += PAGE_SIZE)
- PT_SET_MA(KERNBASE + i, i | PG_KERNEL | PG_NC_PCD);
- xen_flush_queue();
- }
-#endif
- /*
- * re-map kernel text read-only
- *
- */
- for (i = (((vm_offset_t)&btext) & ~PAGE_MASK);
- i < (((vm_offset_t)&etext) & ~PAGE_MASK); i += PAGE_SIZE)
- PT_SET_MA(i, VTOM(i) | PG_V | PG_A);
-
- xc_printf("#7\n");
- physfree = VTOP(cur_space);
- init_first = physfree >> PAGE_SHIFT;
- IdlePTD = (pd_entry_t *)VTOP(IdlePTD);
- IdlePDPT = (pd_entry_t *)VTOP(IdlePDPT);
- setup_xen_features();
- xc_printf("#8, proc0kstack=%u\n", proc0kstack);
-}
-
-
-trap_info_t trap_table[] = {
- { 0, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(div)},
- { 1, 0|4, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(dbg)},
- { 3, 3|4, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(bpt)},
- { 4, 3, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(ofl)},
- /* This is UPL on Linux and KPL on BSD */
- { 5, 3, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(bnd)},
- { 6, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(ill)},
- { 7, 0|4, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(dna)},
- /*
- * { 8, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(XXX)},
- * no handler for double fault
- */
- { 9, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(fpusegm)},
- {10, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(tss)},
- {11, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(missing)},
- {12, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(stk)},
- {13, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(prot)},
- {14, 0|4, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(page)},
- {15, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(rsvd)},
- {16, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(fpu)},
- {17, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(align)},
- {18, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(mchk)},
- {19, 0, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(xmm)},
- {0x80, 3, GSEL(GCODE_SEL, SEL_KPL), (unsigned long) &IDTVEC(int0x80_syscall)},
- { 0, 0, 0, 0 }
-};
-
-/* Perform a multicall and check that individual calls succeeded. */
-int
-HYPERVISOR_multicall(struct multicall_entry * call_list, int nr_calls)
-{
- int ret = 0;
- int i;
-
- /* Perform the multicall. */
- PANIC_IF(_HYPERVISOR_multicall(call_list, nr_calls));
-
- /* Check the results of individual hypercalls. */
- for (i = 0; i < nr_calls; i++)
- if (__predict_false(call_list[i].result < 0))
- ret++;
- if (__predict_false(ret > 0))
- panic("%d multicall(s) failed: cpu %d\n",
- ret, smp_processor_id());
-
- /* If we didn't panic already, everything succeeded. */
- return (0);
-}
-
-/********** CODE WORTH KEEPING ABOVE HERE *****************/
-
-void xen_failsafe_handler(void);
-
-void
-xen_failsafe_handler(void)
-{
-
- panic("xen_failsafe_handler called!\n");
-}
-
-void xen_handle_thread_switch(struct pcb *pcb);
-
-/* This is called by cpu_switch() when switching threads. */
-/* The pcb arg refers to the process control block of the */
-/* next thread which is to run */
-void
-xen_handle_thread_switch(struct pcb *pcb)
-{
- uint32_t *a = (uint32_t *)&PCPU_GET(fsgs_gdt)[0];
- uint32_t *b = (uint32_t *)&pcb->pcb_fsd;
- multicall_entry_t mcl[3];
- int i = 0;
-
- /* Notify Xen of task switch */
- mcl[i].op = __HYPERVISOR_stack_switch;
- mcl[i].args[0] = GSEL(GDATA_SEL, SEL_KPL);
- mcl[i++].args[1] = (unsigned long)pcb;
-
- /* Check for update of fsd */
- if (*a != *b || *(a+1) != *(b+1)) {
- mcl[i].op = __HYPERVISOR_update_descriptor;
- *(uint64_t *)&mcl[i].args[0] = vtomach((vm_offset_t)a);
- *(uint64_t *)&mcl[i++].args[2] = *(uint64_t *)b;
- }
-
- a += 2;
- b += 2;
-
- /* Check for update of gsd */
- if (*a != *b || *(a+1) != *(b+1)) {
- mcl[i].op = __HYPERVISOR_update_descriptor;
- *(uint64_t *)&mcl[i].args[0] = vtomach((vm_offset_t)a);
- *(uint64_t *)&mcl[i++].args[2] = *(uint64_t *)b;
- }
-
- (void)HYPERVISOR_multicall(mcl, i);
-}
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index 39e4df3156d2..3ff3440f2dba 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -1238,12 +1238,14 @@ __elfN(coredump)(struct thread *td, struct vnode *vp, off_t limit, int flags)
coresize = round_page(hdrsize + notesz) + seginfo.size;
#ifdef RACCT
- PROC_LOCK(td->td_proc);
- error = racct_add(td->td_proc, RACCT_CORE, coresize);
- PROC_UNLOCK(td->td_proc);
- if (error != 0) {
- error = EFAULT;
- goto done;
+ if (racct_enable) {
+ PROC_LOCK(td->td_proc);
+ error = racct_add(td->td_proc, RACCT_CORE, coresize);
+ PROC_UNLOCK(td->td_proc);
+ if (error != 0) {
+ error = EFAULT;
+ goto done;
+ }
}
#endif
if (coresize >= limit) {
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 52909571a061..329f418a1dae 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -857,13 +857,15 @@ do_dup(struct thread *td, int flags, int old, int new)
* the limit on the size of the file descriptor table.
*/
#ifdef RACCT
- PROC_LOCK(p);
- error = racct_set(p, RACCT_NOFILE, new + 1);
- PROC_UNLOCK(p);
- if (error != 0) {
- FILEDESC_XUNLOCK(fdp);
- fdrop(fp, td);
- return (EMFILE);
+ if (racct_enable) {
+ PROC_LOCK(p);
+ error = racct_set(p, RACCT_NOFILE, new + 1);
+ PROC_UNLOCK(p);
+ if (error != 0) {
+ FILEDESC_XUNLOCK(fdp);
+ fdrop(fp, td);
+ return (EMFILE);
+ }
}
#endif
fdgrowtable_exp(fdp, new + 1);
@@ -1609,7 +1611,7 @@ fdalloc(struct thread *td, int minfd, int *result)
{
struct proc *p = td->td_proc;
struct filedesc *fdp = p->p_fd;
- int fd = -1, maxfd, allocfd;
+ int fd, maxfd, allocfd;
#ifdef RACCT
int error;
#endif
@@ -1631,11 +1633,13 @@ fdalloc(struct thread *td, int minfd, int *result)
if (fd >= fdp->fd_nfiles) {
allocfd = min(fd * 2, maxfd);
#ifdef RACCT
- PROC_LOCK(p);
- error = racct_set(p, RACCT_NOFILE, allocfd);
- PROC_UNLOCK(p);
- if (error != 0)
- return (EMFILE);
+ if (racct_enable) {
+ PROC_LOCK(p);
+ error = racct_set(p, RACCT_NOFILE, allocfd);
+ PROC_UNLOCK(p);
+ if (error != 0)
+ return (EMFILE);
+ }
#endif
/*
* fd is already equal to first free descriptor >= minfd, so
@@ -2042,9 +2046,11 @@ fdescfree(struct thread *td)
MPASS(fdp != NULL);
#ifdef RACCT
- PROC_LOCK(td->td_proc);
- racct_set(td->td_proc, RACCT_NOFILE, 0);
- PROC_UNLOCK(td->td_proc);
+ if (racct_enable) {
+ PROC_LOCK(td->td_proc);
+ racct_set(td->td_proc, RACCT_NOFILE, 0);
+ PROC_UNLOCK(td->td_proc);
+ }
#endif
if (td->td_proc->p_fdtol != NULL)
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index ecc2651da32d..9d893f8e445f 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -1060,7 +1060,7 @@ exec_new_vmspace(imgp, sv)
/* Allocate a new stack */
if (imgp->stack_sz != 0) {
- ssiz = imgp->stack_sz;
+ ssiz = trunc_page(imgp->stack_sz);
PROC_LOCK(p);
lim_rlimit(p, RLIMIT_STACK, &rlim_stack);
PROC_UNLOCK(p);
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 4d23fc074bbe..0a601a1b5d21 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -907,9 +907,11 @@ proc_reap(struct thread *td, struct proc *p, int *status, int options)
* Destroy resource accounting information associated with the process.
*/
#ifdef RACCT
- PROC_LOCK(p);
- racct_sub(p, RACCT_NPROC, 1);
- PROC_UNLOCK(p);
+ if (racct_enable) {
+ PROC_LOCK(p);
+ racct_sub(p, RACCT_NPROC, 1);
+ PROC_UNLOCK(p);
+ }
#endif
racct_proc_exit(p);
diff --git a/sys/kern/kern_gzio.c b/sys/kern/kern_gzio.c
index a4974a729c3f..cee21f0655b1 100644
--- a/sys/kern/kern_gzio.c
+++ b/sys/kern/kern_gzio.c
@@ -32,8 +32,7 @@ __FBSDID("$FreeBSD$");
#include <sys/gzio.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
-
-#include <net/zutil.h>
+#include <sys/zutil.h>
#define KERN_GZ_HDRLEN 10 /* gzip header length */
#define KERN_GZ_TRAILERLEN 8 /* gzip trailer length */
diff --git a/sys/kern/kern_intr.c b/sys/kern/kern_intr.c
index 7a5d93659913..a84019ad8241 100644
--- a/sys/kern/kern_intr.c
+++ b/sys/kern/kern_intr.c
@@ -1455,12 +1455,7 @@ intr_event_handle(struct intr_event *ie, struct trapframe *frame)
/* Schedule the ithread if needed. */
if (thread) {
error = intr_event_schedule_thread(ie);
-#ifndef XEN
KASSERT(error == 0, ("bad stray interrupt"));
-#else
- if (error != 0)
- log(LOG_WARNING, "bad stray interrupt");
-#endif
}
critical_exit();
td->td_intr_nesting_level--;
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index 5b231291bc5a..c87c4e2f01b8 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -1778,7 +1778,7 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags)
mtx_unlock(&pr->pr_mtx);
#ifdef RACCT
- if (created)
+ if (racct_enable && created)
prison_racct_attach(pr);
#endif
@@ -1862,7 +1862,7 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags)
}
#ifdef RACCT
- if (!created) {
+ if (racct_enable && !created) {
if (!(flags & JAIL_ATTACH))
sx_sunlock(&allprison_lock);
prison_racct_modify(pr);
@@ -2652,7 +2652,8 @@ prison_deref(struct prison *pr, int flags)
cpuset_rel(pr->pr_cpuset);
osd_jail_exit(pr);
#ifdef RACCT
- prison_racct_detach(pr);
+ if (racct_enable)
+ prison_racct_detach(pr);
#endif
free(pr, M_PRISON);
@@ -4460,12 +4461,15 @@ SYSCTL_JAIL_PARAM(_allow_mount, tmpfs, CTLTYPE_INT | CTLFLAG_RW,
SYSCTL_JAIL_PARAM(_allow_mount, zfs, CTLTYPE_INT | CTLFLAG_RW,
"B", "Jail may mount the zfs file system");
+#ifdef RACCT
void
prison_racct_foreach(void (*callback)(struct racct *racct,
void *arg2, void *arg3), void *arg2, void *arg3)
{
struct prison_racct *prr;
+ ASSERT_RACCT_ENABLED();
+
sx_slock(&allprison_lock);
LIST_FOREACH(prr, &allprison_racct, prr_next)
(callback)(prr->prr_racct, arg2, arg3);
@@ -4477,6 +4481,7 @@ prison_racct_find_locked(const char *name)
{
struct prison_racct *prr;
+ ASSERT_RACCT_ENABLED();
sx_assert(&allprison_lock, SA_XLOCKED);
if (name[0] == '\0' || strlen(name) >= MAXHOSTNAMELEN)
@@ -4507,6 +4512,8 @@ prison_racct_find(const char *name)
{
struct prison_racct *prr;
+ ASSERT_RACCT_ENABLED();
+
sx_xlock(&allprison_lock);
prr = prison_racct_find_locked(name);
sx_xunlock(&allprison_lock);
@@ -4517,6 +4524,8 @@ void
prison_racct_hold(struct prison_racct *prr)
{
+ ASSERT_RACCT_ENABLED();
+
refcount_acquire(&prr->prr_refcount);
}
@@ -4524,6 +4533,7 @@ static void
prison_racct_free_locked(struct prison_racct *prr)
{
+ ASSERT_RACCT_ENABLED();
sx_assert(&allprison_lock, SA_XLOCKED);
if (refcount_release(&prr->prr_refcount)) {
@@ -4538,6 +4548,7 @@ prison_racct_free(struct prison_racct *prr)
{
int old;
+ ASSERT_RACCT_ENABLED();
sx_assert(&allprison_lock, SA_UNLOCKED);
old = prr->prr_refcount;
@@ -4549,12 +4560,12 @@ prison_racct_free(struct prison_racct *prr)
sx_xunlock(&allprison_lock);
}
-#ifdef RACCT
static void
prison_racct_attach(struct prison *pr)
{
struct prison_racct *prr;
+ ASSERT_RACCT_ENABLED();
sx_assert(&allprison_lock, SA_XLOCKED);
prr = prison_racct_find_locked(pr->pr_name);
@@ -4574,6 +4585,8 @@ prison_racct_modify(struct prison *pr)
struct ucred *cred;
struct prison_racct *oldprr;
+ ASSERT_RACCT_ENABLED();
+
sx_slock(&allproc_lock);
sx_xlock(&allprison_lock);
@@ -4613,6 +4626,7 @@ static void
prison_racct_detach(struct prison *pr)
{
+ ASSERT_RACCT_ENABLED();
sx_assert(&allprison_lock, SA_UNLOCKED);
if (pr->pr_prison_racct == NULL)
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index 505521d1fa94..6618c0849373 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -2822,7 +2822,7 @@ static SYSCTL_NODE(_kern_proc, KERN_PROC_PROC, proc, CTLFLAG_RD | CTLFLAG_MPSAFE
sysctl_kern_proc, "Return process table, no threads");
static SYSCTL_NODE(_kern_proc, KERN_PROC_ARGS, args,
- CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_MPSAFE,
+ CTLFLAG_RW | CTLFLAG_CAPWR | CTLFLAG_ANYBODY | CTLFLAG_MPSAFE,
sysctl_kern_proc_args, "Process argument list");
static SYSCTL_NODE(_kern_proc, KERN_PROC_ENV, env, CTLFLAG_RD | CTLFLAG_MPSAFE,
diff --git a/sys/kern/kern_racct.c b/sys/kern/kern_racct.c
index 05becea995d2..5cee140cc1e0 100644
--- a/sys/kern/kern_racct.c
+++ b/sys/kern/kern_racct.c
@@ -70,8 +70,15 @@ FEATURE(racct, "Resource Accounting");
* Do not block processes that have their %cpu usage <= pcpu_threshold.
*/
static int pcpu_threshold = 1;
+#ifdef RACCT_DISABLED
+int racct_enable = 0;
+#else
+int racct_enable = 1;
+#endif
SYSCTL_NODE(_kern, OID_AUTO, racct, CTLFLAG_RW, 0, "Resource Accounting");
+SYSCTL_UINT(_kern_racct, OID_AUTO, enable, CTLFLAG_RDTUN, &racct_enable,
+ 0, "Enable RACCT/RCTL");
SYSCTL_UINT(_kern_racct, OID_AUTO, pcpu_threshold, CTLFLAG_RW, &pcpu_threshold,
0, "Processes with higher %cpu usage than this value can be throttled.");
@@ -313,6 +320,8 @@ racct_getpcpu(struct proc *p, u_int pcpu)
fixpt_t p_pctcpu;
struct thread *td;
+ ASSERT_RACCT_ENABLED();
+
/*
* If the process is swapped out, we count its %cpu usage as zero.
* This behaviour is consistent with the userland ps(1) tool.
@@ -377,6 +386,7 @@ racct_add_racct(struct racct *dest, const struct racct *src)
{
int i;
+ ASSERT_RACCT_ENABLED();
mtx_assert(&racct_lock, MA_OWNED);
/*
@@ -398,6 +408,7 @@ racct_sub_racct(struct racct *dest, const struct racct *src)
{
int i;
+ ASSERT_RACCT_ENABLED();
mtx_assert(&racct_lock, MA_OWNED);
/*
@@ -431,6 +442,9 @@ void
racct_create(struct racct **racctp)
{
+ if (!racct_enable)
+ return;
+
SDT_PROBE(racct, kernel, racct, create, racctp, 0, 0, 0, 0);
KASSERT(*racctp == NULL, ("racct already allocated"));
@@ -444,6 +458,8 @@ racct_destroy_locked(struct racct **racctp)
int i;
struct racct *racct;
+ ASSERT_RACCT_ENABLED();
+
SDT_PROBE(racct, kernel, racct, destroy, racctp, 0, 0, 0, 0);
mtx_assert(&racct_lock, MA_OWNED);
@@ -470,6 +486,9 @@ void
racct_destroy(struct racct **racct)
{
+ if (!racct_enable)
+ return;
+
mtx_lock(&racct_lock);
racct_destroy_locked(racct);
mtx_unlock(&racct_lock);
@@ -485,6 +504,7 @@ racct_alloc_resource(struct racct *racct, int resource,
uint64_t amount)
{
+ ASSERT_RACCT_ENABLED();
mtx_assert(&racct_lock, MA_OWNED);
KASSERT(racct != NULL, ("NULL racct"));
@@ -516,6 +536,8 @@ racct_add_locked(struct proc *p, int resource, uint64_t amount)
int error;
#endif
+ ASSERT_RACCT_ENABLED();
+
SDT_PROBE(racct, kernel, rusage, add, p, resource, amount, 0, 0);
/*
@@ -546,6 +568,9 @@ racct_add(struct proc *p, int resource, uint64_t amount)
{
int error;
+ if (!racct_enable)
+ return (0);
+
mtx_lock(&racct_lock);
error = racct_add_locked(p, resource, amount);
mtx_unlock(&racct_lock);
@@ -557,6 +582,8 @@ racct_add_cred_locked(struct ucred *cred, int resource, uint64_t amount)
{
struct prison *pr;
+ ASSERT_RACCT_ENABLED();
+
SDT_PROBE(racct, kernel, rusage, add__cred, cred, resource, amount,
0, 0);
@@ -577,6 +604,9 @@ void
racct_add_cred(struct ucred *cred, int resource, uint64_t amount)
{
+ if (!racct_enable)
+ return;
+
mtx_lock(&racct_lock);
racct_add_cred_locked(cred, resource, amount);
mtx_unlock(&racct_lock);
@@ -590,6 +620,9 @@ void
racct_add_force(struct proc *p, int resource, uint64_t amount)
{
+ if (!racct_enable)
+ return;
+
SDT_PROBE(racct, kernel, rusage, add__force, p, resource, amount, 0, 0);
/*
@@ -612,6 +645,8 @@ racct_set_locked(struct proc *p, int resource, uint64_t amount)
int error;
#endif
+ ASSERT_RACCT_ENABLED();
+
SDT_PROBE(racct, kernel, rusage, set, p, resource, amount, 0, 0);
/*
@@ -671,6 +706,9 @@ racct_set(struct proc *p, int resource, uint64_t amount)
{
int error;
+ if (!racct_enable)
+ return (0);
+
mtx_lock(&racct_lock);
error = racct_set_locked(p, resource, amount);
mtx_unlock(&racct_lock);
@@ -683,6 +721,8 @@ racct_set_force_locked(struct proc *p, int resource, uint64_t amount)
int64_t old_amount, decayed_amount;
int64_t diff_proc, diff_cred;
+ ASSERT_RACCT_ENABLED();
+
SDT_PROBE(racct, kernel, rusage, set, p, resource, amount, 0, 0);
/*
@@ -717,6 +757,10 @@ racct_set_force_locked(struct proc *p, int resource, uint64_t amount)
void
racct_set_force(struct proc *p, int resource, uint64_t amount)
{
+
+ if (!racct_enable)
+ return;
+
mtx_lock(&racct_lock);
racct_set_force_locked(p, resource, amount);
mtx_unlock(&racct_lock);
@@ -732,6 +776,9 @@ uint64_t
racct_get_limit(struct proc *p, int resource)
{
+ if (!racct_enable)
+ return (UINT64_MAX);
+
#ifdef RCTL
return (rctl_get_limit(p, resource));
#else
@@ -749,6 +796,9 @@ uint64_t
racct_get_available(struct proc *p, int resource)
{
+ if (!racct_enable)
+ return (UINT64_MAX);
+
#ifdef RCTL
return (rctl_get_available(p, resource));
#else
@@ -765,6 +815,8 @@ static int64_t
racct_pcpu_available(struct proc *p)
{
+ ASSERT_RACCT_ENABLED();
+
#ifdef RCTL
return (rctl_pcpu_available(p));
#else
@@ -779,6 +831,9 @@ void
racct_sub(struct proc *p, int resource, uint64_t amount)
{
+ if (!racct_enable)
+ return;
+
SDT_PROBE(racct, kernel, rusage, sub, p, resource, amount, 0, 0);
/*
@@ -804,6 +859,8 @@ racct_sub_cred_locked(struct ucred *cred, int resource, uint64_t amount)
{
struct prison *pr;
+ ASSERT_RACCT_ENABLED();
+
SDT_PROBE(racct, kernel, rusage, sub__cred, cred, resource, amount,
0, 0);
@@ -827,6 +884,9 @@ void
racct_sub_cred(struct ucred *cred, int resource, uint64_t amount)
{
+ if (!racct_enable)
+ return;
+
mtx_lock(&racct_lock);
racct_sub_cred_locked(cred, resource, amount);
mtx_unlock(&racct_lock);
@@ -840,6 +900,9 @@ racct_proc_fork(struct proc *parent, struct proc *child)
{
int i, error = 0;
+ if (!racct_enable)
+ return (0);
+
/*
* Create racct for the child process.
*/
@@ -896,6 +959,9 @@ racct_proc_fork_done(struct proc *child)
{
#ifdef RCTL
+ if (!racct_enable)
+ return;
+
PROC_LOCK(child);
mtx_lock(&racct_lock);
rctl_enforce(child, RACCT_NPROC, 0);
@@ -913,6 +979,9 @@ racct_proc_exit(struct proc *p)
struct timeval wallclock;
uint64_t pct_estimate, pct;
+ if (!racct_enable)
+ return;
+
PROC_LOCK(p);
/*
* We don't need to calculate rux, proc_reap() has already done this.
@@ -967,6 +1036,9 @@ racct_proc_ucred_changed(struct proc *p, struct ucred *oldcred,
struct loginclass *oldlc, *newlc;
struct prison *oldpr, *newpr, *pr;
+ if (!racct_enable)
+ return;
+
PROC_LOCK_ASSERT(p, MA_NOTOWNED);
newuip = newcred->cr_ruidinfo;
@@ -1004,6 +1076,8 @@ void
racct_move(struct racct *dest, struct racct *src)
{
+ ASSERT_RACCT_ENABLED();
+
mtx_lock(&racct_lock);
racct_add_racct(dest, src);
@@ -1020,6 +1094,7 @@ racct_proc_throttle(struct proc *p)
int cpuid;
#endif
+ ASSERT_RACCT_ENABLED();
PROC_LOCK_ASSERT(p, MA_OWNED);
/*
@@ -1065,6 +1140,9 @@ racct_proc_throttle(struct proc *p)
static void
racct_proc_wakeup(struct proc *p)
{
+
+ ASSERT_RACCT_ENABLED();
+
PROC_LOCK_ASSERT(p, MA_OWNED);
if (p->p_throttled) {
@@ -1079,6 +1157,8 @@ racct_decay_resource(struct racct *racct, void * res, void* dummy)
int resource;
int64_t r_old, r_new;
+ ASSERT_RACCT_ENABLED();
+
resource = *(int *)res;
r_old = racct->r_resources[resource];
@@ -1095,6 +1175,9 @@ racct_decay_resource(struct racct *racct, void * res, void* dummy)
static void
racct_decay(int resource)
{
+
+ ASSERT_RACCT_ENABLED();
+
ui_racct_foreach(racct_decay_resource, &resource, NULL);
loginclass_racct_foreach(racct_decay_resource, &resource, NULL);
prison_racct_foreach(racct_decay_resource, &resource, NULL);
@@ -1109,6 +1192,8 @@ racctd(void)
uint64_t runtime;
uint64_t pct, pct_estimate;
+ ASSERT_RACCT_ENABLED();
+
for (;;) {
racct_decay(RACCT_PCTCPU);
@@ -1188,11 +1273,22 @@ static struct kproc_desc racctd_kp = {
racctd,
NULL
};
-SYSINIT(racctd, SI_SUB_RACCTD, SI_ORDER_FIRST, kproc_start, &racctd_kp);
+
+static void
+racctd_init(void)
+{
+ if (!racct_enable)
+ return;
+
+ kproc_start(&racctd_kp);
+}
+SYSINIT(racctd, SI_SUB_RACCTD, SI_ORDER_FIRST, racctd_init, NULL);
static void
racct_init(void)
{
+ if (!racct_enable)
+ return;
racct_zone = uma_zcreate("racct", sizeof(struct racct),
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
diff --git a/sys/kern/kern_rctl.c b/sys/kern/kern_rctl.c
index 934327a41d82..c43b83df433a 100644
--- a/sys/kern/kern_rctl.c
+++ b/sys/kern/kern_rctl.c
@@ -225,6 +225,7 @@ rctl_available_resource(const struct proc *p, const struct rctl_rule *rule)
int64_t available = INT64_MAX;
struct ucred *cred = p->p_ucred;
+ ASSERT_RACCT_ENABLED();
rw_assert(&rctl_lock, RA_LOCKED);
resource = rule->rr_resource;
@@ -264,6 +265,8 @@ rctl_would_exceed(const struct proc *p, const struct rctl_rule *rule,
{
int64_t available;
+ ASSERT_RACCT_ENABLED();
+
rw_assert(&rctl_lock, RA_LOCKED);
available = rctl_available_resource(p, rule);
@@ -283,6 +286,8 @@ rctl_pcpu_available(const struct proc *p) {
struct rctl_rule_link *link;
int64_t available, minavailable, limit;
+ ASSERT_RACCT_ENABLED();
+
minavailable = INT64_MAX;
limit = 0;
@@ -334,6 +339,8 @@ rctl_enforce(struct proc *p, int resource, uint64_t amount)
static int curtime = 0;
static struct timeval lasttime;
+ ASSERT_RACCT_ENABLED();
+
rw_rlock(&rctl_lock);
/*
@@ -457,6 +464,8 @@ rctl_get_limit(struct proc *p, int resource)
struct rctl_rule_link *link;
uint64_t amount = UINT64_MAX;
+ ASSERT_RACCT_ENABLED();
+
rw_rlock(&rctl_lock);
/*
@@ -487,6 +496,8 @@ rctl_get_available(struct proc *p, int resource)
minavailable = INT64_MAX;
+ ASSERT_RACCT_ENABLED();
+
rw_rlock(&rctl_lock);
/*
@@ -521,6 +532,8 @@ static int
rctl_rule_matches(const struct rctl_rule *rule, const struct rctl_rule *filter)
{
+ ASSERT_RACCT_ENABLED();
+
if (filter->rr_subject_type != RCTL_SUBJECT_TYPE_UNDEFINED) {
if (rule->rr_subject_type != filter->rr_subject_type)
return (0);
@@ -635,6 +648,7 @@ rctl_racct_add_rule(struct racct *racct, struct rctl_rule *rule)
{
struct rctl_rule_link *link;
+ ASSERT_RACCT_ENABLED();
KASSERT(rctl_rule_fully_specified(rule), ("rule not fully specified"));
rctl_rule_acquire(rule);
@@ -652,6 +666,7 @@ rctl_racct_add_rule_locked(struct racct *racct, struct rctl_rule *rule)
{
struct rctl_rule_link *link;
+ ASSERT_RACCT_ENABLED();
KASSERT(rctl_rule_fully_specified(rule), ("rule not fully specified"));
rw_assert(&rctl_lock, RA_WLOCKED);
@@ -678,6 +693,7 @@ rctl_racct_remove_rules(struct racct *racct,
int removed = 0;
struct rctl_rule_link *link, *linktmp;
+ ASSERT_RACCT_ENABLED();
rw_assert(&rctl_lock, RA_WLOCKED);
LIST_FOREACH_SAFE(link, &racct->r_rule_links, rrl_next, linktmp) {
@@ -696,6 +712,8 @@ static void
rctl_rule_acquire_subject(struct rctl_rule *rule)
{
+ ASSERT_RACCT_ENABLED();
+
switch (rule->rr_subject_type) {
case RCTL_SUBJECT_TYPE_UNDEFINED:
case RCTL_SUBJECT_TYPE_PROCESS:
@@ -722,6 +740,8 @@ static void
rctl_rule_release_subject(struct rctl_rule *rule)
{
+ ASSERT_RACCT_ENABLED();
+
switch (rule->rr_subject_type) {
case RCTL_SUBJECT_TYPE_UNDEFINED:
case RCTL_SUBJECT_TYPE_PROCESS:
@@ -749,6 +769,8 @@ rctl_rule_alloc(int flags)
{
struct rctl_rule *rule;
+ ASSERT_RACCT_ENABLED();
+
rule = uma_zalloc(rctl_rule_zone, flags);
if (rule == NULL)
return (NULL);
@@ -771,6 +793,8 @@ rctl_rule_duplicate(const struct rctl_rule *rule, int flags)
{
struct rctl_rule *copy;
+ ASSERT_RACCT_ENABLED();
+
copy = uma_zalloc(rctl_rule_zone, flags);
if (copy == NULL)
return (NULL);
@@ -793,6 +817,7 @@ void
rctl_rule_acquire(struct rctl_rule *rule)
{
+ ASSERT_RACCT_ENABLED();
KASSERT(rule->rr_refcount > 0, ("rule->rr_refcount <= 0"));
refcount_acquire(&rule->rr_refcount);
@@ -805,6 +830,7 @@ rctl_rule_free(void *context, int pending)
rule = (struct rctl_rule *)context;
+ ASSERT_RACCT_ENABLED();
KASSERT(rule->rr_refcount == 0, ("rule->rr_refcount != 0"));
/*
@@ -819,6 +845,7 @@ void
rctl_rule_release(struct rctl_rule *rule)
{
+ ASSERT_RACCT_ENABLED();
KASSERT(rule->rr_refcount > 0, ("rule->rr_refcount <= 0"));
if (refcount_release(&rule->rr_refcount)) {
@@ -838,6 +865,8 @@ static int
rctl_rule_fully_specified(const struct rctl_rule *rule)
{
+ ASSERT_RACCT_ENABLED();
+
switch (rule->rr_subject_type) {
case RCTL_SUBJECT_TYPE_UNDEFINED:
return (0);
@@ -882,6 +911,8 @@ rctl_string_to_rule(char *rulestr, struct rctl_rule **rulep)
struct rctl_rule *rule;
id_t id;
+ ASSERT_RACCT_ENABLED();
+
rule = rctl_rule_alloc(M_WAITOK);
subjectstr = strsep(&rulestr, ":");
@@ -1008,6 +1039,7 @@ rctl_rule_add(struct rctl_rule *rule)
struct rctl_rule *rule2;
int match;
+ ASSERT_RACCT_ENABLED();
KASSERT(rctl_rule_fully_specified(rule), ("rule not fully specified"));
/*
@@ -1118,6 +1150,8 @@ rctl_rule_remove_callback(struct racct *racct, void *arg2, void *arg3)
struct rctl_rule *filter = (struct rctl_rule *)arg2;
int found = 0;
+ ASSERT_RACCT_ENABLED();
+
rw_wlock(&rctl_lock);
found += rctl_racct_remove_rules(racct, filter);
rw_wunlock(&rctl_lock);
@@ -1134,6 +1168,8 @@ rctl_rule_remove(struct rctl_rule *filter)
int found = 0;
struct proc *p;
+ ASSERT_RACCT_ENABLED();
+
if (filter->rr_subject_type == RCTL_SUBJECT_TYPE_PROCESS &&
filter->rr_subject.rs_proc != NULL) {
p = filter->rr_subject.rs_proc;
@@ -1172,6 +1208,8 @@ rctl_rule_to_sbuf(struct sbuf *sb, const struct rctl_rule *rule)
{
int64_t amount;
+ ASSERT_RACCT_ENABLED();
+
sbuf_printf(sb, "%s:", rctl_subject_type_name(rule->rr_subject_type));
switch (rule->rr_subject_type) {
@@ -1231,6 +1269,8 @@ rctl_read_inbuf(char **inputstr, const char *inbufp, size_t inbuflen)
int error;
char *str;
+ ASSERT_RACCT_ENABLED();
+
if (inbuflen <= 0)
return (EINVAL);
if (inbuflen > RCTL_MAX_INBUFLEN)
@@ -1256,6 +1296,8 @@ rctl_write_outbuf(struct sbuf *outputsbuf, char *outbufp, size_t outbuflen)
{
int error;
+ ASSERT_RACCT_ENABLED();
+
if (outputsbuf == NULL)
return (0);
@@ -1277,6 +1319,8 @@ rctl_racct_to_sbuf(struct racct *racct, int sloppy)
int64_t amount;
struct sbuf *sb;
+ ASSERT_RACCT_ENABLED();
+
sb = sbuf_new_auto();
for (i = 0; i <= RACCT_MAX; i++) {
if (sloppy == 0 && RACCT_IS_SLOPPY(i))
@@ -1302,6 +1346,9 @@ sys_rctl_get_racct(struct thread *td, struct rctl_get_racct_args *uap)
struct loginclass *lc;
struct prison_racct *prr;
+ if (!racct_enable)
+ return (ENOSYS);
+
error = priv_check(td, PRIV_RCTL_GET_RACCT);
if (error != 0)
return (error);
@@ -1372,6 +1419,8 @@ rctl_get_rules_callback(struct racct *racct, void *arg2, void *arg3)
struct rctl_rule_link *link;
struct sbuf *sb = (struct sbuf *)arg3;
+ ASSERT_RACCT_ENABLED();
+
rw_rlock(&rctl_lock);
LIST_FOREACH(link, &racct->r_rule_links, rrl_next) {
if (!rctl_rule_matches(link->rrl_rule, filter))
@@ -1393,6 +1442,9 @@ sys_rctl_get_rules(struct thread *td, struct rctl_get_rules_args *uap)
struct rctl_rule_link *link;
struct proc *p;
+ if (!racct_enable)
+ return (ENOSYS);
+
error = priv_check(td, PRIV_RCTL_GET_RULES);
if (error != 0)
return (error);
@@ -1467,6 +1519,9 @@ sys_rctl_get_limits(struct thread *td, struct rctl_get_limits_args *uap)
struct rctl_rule *filter;
struct rctl_rule_link *link;
+ if (!racct_enable)
+ return (ENOSYS);
+
error = priv_check(td, PRIV_RCTL_GET_LIMITS);
if (error != 0)
return (error);
@@ -1538,6 +1593,9 @@ sys_rctl_add_rule(struct thread *td, struct rctl_add_rule_args *uap)
struct rctl_rule *rule;
char *inputstr;
+ if (!racct_enable)
+ return (ENOSYS);
+
error = priv_check(td, PRIV_RCTL_ADD_RULE);
if (error != 0)
return (error);
@@ -1580,6 +1638,9 @@ sys_rctl_remove_rule(struct thread *td, struct rctl_remove_rule_args *uap)
struct rctl_rule *filter;
char *inputstr;
+ if (!racct_enable)
+ return (ENOSYS);
+
error = priv_check(td, PRIV_RCTL_REMOVE_RULE);
if (error != 0)
return (error);
@@ -1616,6 +1677,8 @@ rctl_proc_ucred_changed(struct proc *p, struct ucred *newcred)
struct prison_racct *newprr;
LIST_HEAD(, rctl_rule_link) newrules;
+ ASSERT_RACCT_ENABLED();
+
newuip = newcred->cr_ruidinfo;
newlc = newcred->cr_loginclass;
newprr = newcred->cr_prison->pr_prison_racct;
@@ -1756,6 +1819,7 @@ rctl_proc_fork(struct proc *parent, struct proc *child)
LIST_INIT(&child->p_racct->r_rule_links);
+ ASSERT_RACCT_ENABLED();
KASSERT(parent->p_racct != NULL, ("process without racct; p = %p", parent));
rw_wlock(&rctl_lock);
@@ -1809,6 +1873,8 @@ rctl_racct_release(struct racct *racct)
{
struct rctl_rule_link *link;
+ ASSERT_RACCT_ENABLED();
+
rw_wlock(&rctl_lock);
while (!LIST_EMPTY(&racct->r_rule_links)) {
link = LIST_FIRST(&racct->r_rule_links);
@@ -1823,6 +1889,9 @@ static void
rctl_init(void)
{
+ if (!racct_enable)
+ return;
+
rctl_rule_link_zone = uma_zcreate("rctl_rule_link",
sizeof(struct rctl_rule_link), NULL, NULL, NULL, NULL,
UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c
index e547c5f7ff53..998ee150aebb 100644
--- a/sys/kern/kern_shutdown.c
+++ b/sys/kern/kern_shutdown.c
@@ -154,7 +154,6 @@ static void poweroff_wait(void *, int);
static void shutdown_halt(void *junk, int howto);
static void shutdown_panic(void *junk, int howto);
static void shutdown_reset(void *junk, int howto);
-static void vpanic(const char *fmt, va_list ap) __dead2;
/* register various local shutdown events */
static void
@@ -676,7 +675,7 @@ panic(const char *fmt, ...)
vpanic(fmt, ap);
}
-static void
+void
vpanic(const char *fmt, va_list ap)
{
#ifdef SMP
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index ad10dc786371..a238a0944fbc 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -66,12 +66,6 @@ __FBSDID("$FreeBSD$");
#include <machine/cpu.h>
-#ifdef XEN
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/pmap.h>
-#endif
-
#define KTDSTATE(td) \
(((td)->td_inhibitors & TDI_SLEEPING) != 0 ? "sleep" : \
((td)->td_inhibitors & TDI_SUSPENDED) != 0 ? "suspended" : \
@@ -475,9 +469,6 @@ mi_switch(int flags, struct thread *newtd)
"lockname:\"%s\"", td->td_lockname);
#endif
SDT_PROBE0(sched, , , preempt);
-#ifdef XEN
- PT_UPDATES_FLUSH();
-#endif
sched_switch(td, newtd, flags);
KTR_STATE1(KTR_SCHED, "thread", sched_tdname(td), "running",
"prio:%d", td->td_priority);
diff --git a/sys/kern/kern_thr.c b/sys/kern/kern_thr.c
index 280bc0ba9d6d..6911bb97b3df 100644
--- a/sys/kern/kern_thr.c
+++ b/sys/kern/kern_thr.c
@@ -187,11 +187,13 @@ create_thread(struct thread *td, mcontext_t *ctx,
}
#ifdef RACCT
- PROC_LOCK(td->td_proc);
- error = racct_add(p, RACCT_NTHR, 1);
- PROC_UNLOCK(td->td_proc);
- if (error != 0)
- return (EPROCLIM);
+ if (racct_enable) {
+ PROC_LOCK(p);
+ error = racct_add(p, RACCT_NTHR, 1);
+ PROC_UNLOCK(p);
+ if (error != 0)
+ return (EPROCLIM);
+ }
#endif
/* Initialize our td */
@@ -250,9 +252,9 @@ create_thread(struct thread *td, mcontext_t *ctx,
}
}
- PROC_LOCK(td->td_proc);
- td->td_proc->p_flag |= P_HADTHREADS;
- thread_link(newtd, p);
+ PROC_LOCK(p);
+ p->p_flag |= P_HADTHREADS;
+ thread_link(newtd, p);
bcopy(p->p_comm, newtd->td_name, sizeof(newtd->td_name));
thread_lock(td);
/* let the scheduler know about these things. */
@@ -280,9 +282,11 @@ create_thread(struct thread *td, mcontext_t *ctx,
fail:
#ifdef RACCT
- PROC_LOCK(p);
- racct_sub(p, RACCT_NTHR, 1);
- PROC_UNLOCK(p);
+ if (racct_enable) {
+ PROC_LOCK(p);
+ racct_sub(p, RACCT_NTHR, 1);
+ PROC_UNLOCK(p);
+ }
#endif
return (error);
}
diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c
index 65c8276a950b..26be03504e79 100644
--- a/sys/kern/link_elf.c
+++ b/sys/kern/link_elf.c
@@ -66,7 +66,7 @@ __FBSDID("$FreeBSD$");
#include <sys/link_elf.h>
#ifdef DDB_CTF
-#include <net/zlib.h>
+#include <sys/zlib.h>
#endif
#include "linker_if.h"
diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c
index 5c107fee44ba..021381db78d7 100644
--- a/sys/kern/link_elf_obj.c
+++ b/sys/kern/link_elf_obj.c
@@ -60,7 +60,7 @@ __FBSDID("$FreeBSD$");
#include <sys/link_elf.h>
#ifdef DDB_CTF
-#include <net/zlib.h>
+#include <sys/zlib.h>
#endif
#include "linker_if.h"
diff --git a/sys/kern/sched_4bsd.c b/sys/kern/sched_4bsd.c
index 3e39d558dcda..59bd38737118 100644
--- a/sys/kern/sched_4bsd.c
+++ b/sys/kern/sched_4bsd.c
@@ -1585,7 +1585,7 @@ sched_pctcpu(struct thread *td)
return (ts->ts_pctcpu);
}
-#ifdef RACCT
+#ifdef RACCT
/*
* Calculates the contribution to the thread cpu usage for the latest
* (unfinished) second.
diff --git a/sys/kern/subr_dnvlist.c b/sys/kern/subr_dnvlist.c
index fe176845054e..9058520fbda9 100644
--- a/sys/kern/subr_dnvlist.c
+++ b/sys/kern/subr_dnvlist.c
@@ -89,89 +89,6 @@ dnvlist_get_binary(const nvlist_t *nvl, const char *name, size_t *sizep,
return (value);
}
-#ifndef _KERNEL
-#define DNVLIST_GETF(ftype, type) \
-ftype \
-dnvlist_getf_##type(const nvlist_t *nvl, ftype defval, \
- const char *namefmt, ...) \
-{ \
- va_list nameap; \
- ftype value; \
- \
- va_start(nameap, namefmt); \
- value = dnvlist_getv_##type(nvl, defval, namefmt, nameap); \
- va_end(nameap); \
- \
- return (value); \
-}
-
-DNVLIST_GETF(bool, bool)
-DNVLIST_GETF(uint64_t, number)
-DNVLIST_GETF(const char *, string)
-DNVLIST_GETF(const nvlist_t *, nvlist)
-DNVLIST_GETF(int, descriptor)
-
-#undef DNVLIST_GETF
-
-const void *
-dnvlist_getf_binary(const nvlist_t *nvl, size_t *sizep, const void *defval,
- size_t defsize, const char *namefmt, ...)
-{
- va_list nameap;
- const void *value;
-
- va_start(nameap, namefmt);
- value = dnvlist_getv_binary(nvl, sizep, defval, defsize, namefmt,
- nameap);
- va_end(nameap);
-
- return (value);
-}
-
-#define DNVLIST_GETV(ftype, type) \
-ftype \
-dnvlist_getv_##type(const nvlist_t *nvl, ftype defval, \
- const char *namefmt, va_list nameap) \
-{ \
- char *name; \
- ftype value; \
- \
- vasprintf(&name, namefmt, nameap); \
- if (name == NULL) \
- return (defval); \
- value = dnvlist_get_##type(nvl, name, defval); \
- free(name); \
- return (value); \
-}
-
-DNVLIST_GETV(bool, bool)
-DNVLIST_GETV(uint64_t, number)
-DNVLIST_GETV(const char *, string)
-DNVLIST_GETV(const nvlist_t *, nvlist)
-DNVLIST_GETV(int, descriptor)
-
-#undef DNVLIST_GETV
-
-const void *
-dnvlist_getv_binary(const nvlist_t *nvl, size_t *sizep, const void *defval,
- size_t defsize, const char *namefmt, va_list nameap)
-{
- char *name;
- const void *value;
-
- nv_vasprintf(&name, namefmt, nameap);
- if (name != NULL) {
- value = dnvlist_get_binary(nvl, name, sizep, defval, defsize);
- nv_free(name);
- } else {
- if (sizep != NULL)
- *sizep = defsize;
- value = defval;
- }
- return (value);
-}
-#endif
-
#define DNVLIST_TAKE(ftype, type) \
ftype \
dnvlist_take_##type(nvlist_t *nvl, const char *name, ftype defval) \
@@ -209,86 +126,3 @@ dnvlist_take_binary(nvlist_t *nvl, const char *name, size_t *sizep,
return (value);
}
-#ifndef _KERNEL
-#define DNVLIST_TAKEF(ftype, type) \
-ftype \
-dnvlist_takef_##type(nvlist_t *nvl, ftype defval, \
- const char *namefmt, ...) \
-{ \
- va_list nameap; \
- ftype value; \
- \
- va_start(nameap, namefmt); \
- value = dnvlist_takev_##type(nvl, defval, namefmt, nameap); \
- va_end(nameap); \
- \
- return (value); \
-}
-
-DNVLIST_TAKEF(bool, bool)
-DNVLIST_TAKEF(uint64_t, number)
-DNVLIST_TAKEF(char *, string)
-DNVLIST_TAKEF(nvlist_t *, nvlist)
-DNVLIST_TAKEF(int, descriptor)
-
-#undef DNVLIST_TAKEF
-
-void *
-dnvlist_takef_binary(nvlist_t *nvl, size_t *sizep, void *defval,
- size_t defsize, const char *namefmt, ...)
-{
- va_list nameap;
- void *value;
-
- va_start(nameap, namefmt);
- value = dnvlist_takev_binary(nvl, sizep, defval, defsize, namefmt,
- nameap);
- va_end(nameap);
-
- return (value);
-}
-
-#define DNVLIST_TAKEV(ftype, type) \
-ftype \
-dnvlist_takev_##type(nvlist_t *nvl, ftype defval, const char *namefmt, \
- va_list nameap) \
-{ \
- char *name; \
- ftype value; \
- \
- vasprintf(&name, namefmt, nameap); \
- if (name == NULL) \
- return (defval); \
- value = dnvlist_take_##type(nvl, name, defval); \
- free(name); \
- return (value); \
-}
-
-DNVLIST_TAKEV(bool, bool)
-DNVLIST_TAKEV(uint64_t, number)
-DNVLIST_TAKEV(char *, string)
-DNVLIST_TAKEV(nvlist_t *, nvlist)
-DNVLIST_TAKEV(int, descriptor)
-
-#undef DNVLIST_TAKEV
-
-void *
-dnvlist_takev_binary(nvlist_t *nvl, size_t *sizep, void *defval,
- size_t defsize, const char *namefmt, va_list nameap)
-{
- char *name;
- void *value;
-
- nv_vasprintf(&name, namefmt, nameap);
- if (name != NULL) {
- value = dnvlist_take_binary(nvl, name, sizep, defval, defsize);
- nv_free(name);
- } else {
- if (sizep != NULL)
- *sizep = defsize;
- value = defval;
- }
-
- return (value);
-}
-#endif
diff --git a/sys/kern/subr_nvlist.c b/sys/kern/subr_nvlist.c
index f352c6248305..f96b8905d869 100644
--- a/sys/kern/subr_nvlist.c
+++ b/sys/kern/subr_nvlist.c
@@ -142,12 +142,11 @@ void
nvlist_destroy(nvlist_t *nvl)
{
nvpair_t *nvp;
- int serrno;
if (nvl == NULL)
return;
- SAVE_ERRNO(serrno);
+ ERRNO_SAVE();
NVLIST_ASSERT(nvl);
@@ -158,7 +157,7 @@ nvlist_destroy(nvlist_t *nvl)
nvl->nvl_magic = 0;
nv_free(nvl);
- RESTORE_ERRNO(serrno);
+ ERRNO_RESTORE();
}
void
@@ -231,6 +230,17 @@ nvlist_empty(const nvlist_t *nvl)
return (nvlist_first_nvpair(nvl) == NULL);
}
+int
+nvlist_flags(const nvlist_t *nvl)
+{
+
+ NVLIST_ASSERT(nvl);
+ PJDLOG_ASSERT(nvl->nvl_error == 0);
+ PJDLOG_ASSERT((nvl->nvl_flags & ~(NV_FLAG_PUBLIC_MASK)) == 0);
+
+ return (nvl->nvl_flags);
+}
+
static void
nvlist_report_missing(int type, const char *name)
{
@@ -264,7 +274,7 @@ nvlist_find(const nvlist_t *nvl, int type, const char *name)
}
if (nvp == NULL)
- RESTORE_ERRNO(ENOENT);
+ ERRNO_SET(ENOENT);
return (nvp);
}
@@ -281,37 +291,6 @@ nvlist_exists_type(const nvlist_t *nvl, const char *name, int type)
return (nvlist_find(nvl, type, name) != NULL);
}
-#ifndef _KERNEL
-bool
-nvlist_existsf_type(const nvlist_t *nvl, int type, const char *namefmt, ...)
-{
- va_list nameap;
- bool ret;
-
- va_start(nameap, namefmt);
- ret = nvlist_existsv_type(nvl, type, namefmt, nameap);
- va_end(nameap);
-
- return (ret);
-}
-
-bool
-nvlist_existsv_type(const nvlist_t *nvl, int type, const char *namefmt,
- va_list nameap)
-{
- char *name;
- bool exists;
-
- nv_vasprintf(&name, namefmt, nameap);
- if (name == NULL)
- return (false);
-
- exists = nvlist_exists_type(nvl, name, type);
- nv_free(name);
- return (exists);
-}
-#endif
-
void
nvlist_free_type(nvlist_t *nvl, const char *name, int type)
{
@@ -329,30 +308,6 @@ nvlist_free_type(nvlist_t *nvl, const char *name, int type)
nvlist_report_missing(type, name);
}
-#ifndef _KERNEL
-void
-nvlist_freef_type(nvlist_t *nvl, int type, const char *namefmt, ...)
-{
- va_list nameap;
-
- va_start(nameap, namefmt);
- nvlist_freev_type(nvl, type, namefmt, nameap);
- va_end(nameap);
-}
-
-void
-nvlist_freev_type(nvlist_t *nvl, int type, const char *namefmt, va_list nameap)
-{
- char *name;
-
- nv_vasprintf(&name, namefmt, nameap);
- if (name == NULL)
- nvlist_report_missing(type, "<unknown>");
- nvlist_free_type(nvl, name, type);
- nv_free(name);
-}
-#endif
-
nvlist_t *
nvlist_clone(const nvlist_t *nvl)
{
@@ -362,7 +317,7 @@ nvlist_clone(const nvlist_t *nvl)
NVLIST_ASSERT(nvl);
if (nvl->nvl_error != 0) {
- RESTORE_ERRNO(nvl->nvl_error);
+ ERRNO_SET(nvl->nvl_error);
return (NULL);
}
@@ -533,27 +488,30 @@ out:
#ifndef _KERNEL
static int *
-nvlist_xdescriptors(const nvlist_t *nvl, int *descs, int level)
+nvlist_xdescriptors(const nvlist_t *nvl, int *descs)
{
- const nvpair_t *nvp;
+ nvpair_t *nvp;
+ const char *name;
+ int type;
NVLIST_ASSERT(nvl);
PJDLOG_ASSERT(nvl->nvl_error == 0);
- PJDLOG_ASSERT(level < 3);
- for (nvp = nvlist_first_nvpair(nvl); nvp != NULL;
- nvp = nvlist_next_nvpair(nvl, nvp)) {
- switch (nvpair_type(nvp)) {
- case NV_TYPE_DESCRIPTOR:
- *descs = nvpair_get_descriptor(nvp);
- descs++;
- break;
- case NV_TYPE_NVLIST:
- descs = nvlist_xdescriptors(nvpair_get_nvlist(nvp),
- descs, level + 1);
- break;
+ nvp = NULL;
+ do {
+ while ((name = nvlist_next(nvl, &type, (void**)&nvp)) != NULL) {
+ switch (type) {
+ case NV_TYPE_DESCRIPTOR:
+ *descs = nvpair_get_descriptor(nvp);
+ descs++;
+ break;
+ case NV_TYPE_NVLIST:
+ nvl = nvpair_get_nvlist(nvp);
+ nvp = NULL;
+ break;
+ }
}
- }
+ } while ((nvl = nvlist_get_parent(nvl, (void**)&nvp)) != NULL);
return (descs);
}
@@ -571,7 +529,7 @@ nvlist_descriptors(const nvlist_t *nvl, size_t *nitemsp)
if (fds == NULL)
return (NULL);
if (nitems > 0)
- nvlist_xdescriptors(nvl, fds, 0);
+ nvlist_xdescriptors(nvl, fds);
fds[nitems] = -1;
if (nitemsp != NULL)
*nitemsp = nitems;
@@ -579,30 +537,33 @@ nvlist_descriptors(const nvlist_t *nvl, size_t *nitemsp)
}
#endif
-static size_t
-nvlist_xndescriptors(const nvlist_t *nvl, int level)
+size_t
+nvlist_ndescriptors(const nvlist_t *nvl)
{
#ifndef _KERNEL
- const nvpair_t *nvp;
+ nvpair_t *nvp;
+ const char *name;
size_t ndescs;
+ int type;
NVLIST_ASSERT(nvl);
PJDLOG_ASSERT(nvl->nvl_error == 0);
- PJDLOG_ASSERT(level < 3);
ndescs = 0;
- for (nvp = nvlist_first_nvpair(nvl); nvp != NULL;
- nvp = nvlist_next_nvpair(nvl, nvp)) {
- switch (nvpair_type(nvp)) {
- case NV_TYPE_DESCRIPTOR:
- ndescs++;
- break;
- case NV_TYPE_NVLIST:
- ndescs += nvlist_xndescriptors(nvpair_get_nvlist(nvp),
- level + 1);
- break;
+ nvp = NULL;
+ do {
+ while ((name = nvlist_next(nvl, &type, (void**)&nvp)) != NULL) {
+ switch (type) {
+ case NV_TYPE_DESCRIPTOR:
+ ndescs++;
+ break;
+ case NV_TYPE_NVLIST:
+ nvl = nvpair_get_nvlist(nvp);
+ nvp = NULL;
+ break;
+ }
}
- }
+ } while ((nvl = nvlist_get_parent(nvl, (void**)&nvp)) != NULL);
return (ndescs);
#else
@@ -610,13 +571,6 @@ nvlist_xndescriptors(const nvlist_t *nvl, int level)
#endif
}
-size_t
-nvlist_ndescriptors(const nvlist_t *nvl)
-{
-
- return (nvlist_xndescriptors(nvl, 0));
-}
-
static unsigned char *
nvlist_pack_header(const nvlist_t *nvl, unsigned char *ptr, size_t *leftp)
{
@@ -640,7 +594,7 @@ nvlist_pack_header(const nvlist_t *nvl, unsigned char *ptr, size_t *leftp)
return (ptr);
}
-void *
+static void *
nvlist_xpack(const nvlist_t *nvl, int64_t *fdidxp, size_t *sizep)
{
unsigned char *buf, *ptr;
@@ -652,7 +606,7 @@ nvlist_xpack(const nvlist_t *nvl, int64_t *fdidxp, size_t *sizep)
NVLIST_ASSERT(nvl);
if (nvl->nvl_error != 0) {
- RESTORE_ERRNO(nvl->nvl_error);
+ ERRNO_SET(nvl->nvl_error);
return (NULL);
}
@@ -742,12 +696,12 @@ nvlist_pack(const nvlist_t *nvl, size_t *sizep)
NVLIST_ASSERT(nvl);
if (nvl->nvl_error != 0) {
- RESTORE_ERRNO(nvl->nvl_error);
+ ERRNO_SET(nvl->nvl_error);
return (NULL);
}
if (nvlist_ndescriptors(nvl) > 0) {
- RESTORE_ERRNO(EOPNOTSUPP);
+ ERRNO_SET(EOPNOTSUPP);
return (NULL);
}
@@ -759,11 +713,11 @@ nvlist_check_header(struct nvlist_header *nvlhdrp)
{
if (nvlhdrp->nvlh_magic != NVLIST_HEADER_MAGIC) {
- RESTORE_ERRNO(EINVAL);
+ ERRNO_SET(EINVAL);
return (false);
}
if ((nvlhdrp->nvlh_flags & ~NV_FLAG_ALL_MASK) != 0) {
- RESTORE_ERRNO(EINVAL);
+ ERRNO_SET(EINVAL);
return (false);
}
#if BYTE_ORDER == BIG_ENDIAN
@@ -815,11 +769,11 @@ nvlist_unpack_header(nvlist_t *nvl, const unsigned char *ptr, size_t nfds,
return (ptr);
failed:
- RESTORE_ERRNO(EINVAL);
+ ERRNO_SET(EINVAL);
return (NULL);
}
-nvlist_t *
+static nvlist_t *
nvlist_xunpack(const void *buf, size_t size, const int *fds, size_t nfds)
{
const unsigned char *ptr;
@@ -909,10 +863,10 @@ nvlist_send(int sock, const nvlist_t *nvl)
int *fds;
void *data;
int64_t fdidx;
- int serrno, ret;
+ int ret;
if (nvlist_error(nvl) != 0) {
- errno = nvlist_error(nvl);
+ ERRNO_SET(nvlist_error(nvl));
return (-1);
}
@@ -938,10 +892,10 @@ nvlist_send(int sock, const nvlist_t *nvl)
ret = 0;
out:
- serrno = errno;
+ ERRNO_SAVE();
free(fds);
free(data);
- errno = serrno;
+ ERRNO_RESTORE();
return (ret);
}
@@ -952,7 +906,7 @@ nvlist_recv(int sock)
nvlist_t *nvl, *ret;
unsigned char *buf;
size_t nfds, size, i;
- int serrno, *fds;
+ int *fds;
if (buf_recv(sock, &nvlhdr, sizeof(nvlhdr)) == -1)
return (NULL);
@@ -963,7 +917,7 @@ nvlist_recv(int sock)
nfds = (size_t)nvlhdr.nvlh_descriptors;
size = sizeof(nvlhdr) + (size_t)nvlhdr.nvlh_size;
- buf = malloc(size);
+ buf = nv_malloc(size);
if (buf == NULL)
return (NULL);
@@ -976,7 +930,7 @@ nvlist_recv(int sock)
goto out;
if (nfds > 0) {
- fds = malloc(nfds * sizeof(fds[0]));
+ fds = nv_malloc(nfds * sizeof(fds[0]));
if (fds == NULL)
goto out;
if (fd_recv(sock, fds, nfds) == -1)
@@ -985,17 +939,19 @@ nvlist_recv(int sock)
nvl = nvlist_xunpack(buf, size, fds, nfds);
if (nvl == NULL) {
+ ERRNO_SAVE();
for (i = 0; i < nfds; i++)
close(fds[i]);
+ ERRNO_RESTORE();
goto out;
}
ret = nvl;
out:
- serrno = errno;
+ ERRNO_SAVE();
free(buf);
free(fds);
- errno = serrno;
+ ERRNO_RESTORE();
return (ret);
}
@@ -1100,86 +1056,6 @@ NVLIST_EXISTS(binary, BINARY)
#undef NVLIST_EXISTS
-#ifndef _KERNEL
-bool
-nvlist_existsf(const nvlist_t *nvl, const char *namefmt, ...)
-{
- va_list nameap;
- bool ret;
-
- va_start(nameap, namefmt);
- ret = nvlist_existsv(nvl, namefmt, nameap);
- va_end(nameap);
- return (ret);
-}
-
-#define NVLIST_EXISTSF(type) \
-bool \
-nvlist_existsf_##type(const nvlist_t *nvl, const char *namefmt, ...) \
-{ \
- va_list nameap; \
- bool ret; \
- \
- va_start(nameap, namefmt); \
- ret = nvlist_existsv_##type(nvl, namefmt, nameap); \
- va_end(nameap); \
- return (ret); \
-}
-
-NVLIST_EXISTSF(null)
-NVLIST_EXISTSF(bool)
-NVLIST_EXISTSF(number)
-NVLIST_EXISTSF(string)
-NVLIST_EXISTSF(nvlist)
-#ifndef _KERNEL
-NVLIST_EXISTSF(descriptor)
-#endif
-NVLIST_EXISTSF(binary)
-
-#undef NVLIST_EXISTSF
-
-bool
-nvlist_existsv(const nvlist_t *nvl, const char *namefmt, va_list nameap)
-{
- char *name;
- bool exists;
-
- nv_vasprintf(&name, namefmt, nameap);
- if (name == NULL)
- return (false);
-
- exists = nvlist_exists(nvl, name);
- nv_free(name);
- return (exists);
-}
-
-#define NVLIST_EXISTSV(type) \
-bool \
-nvlist_existsv_##type(const nvlist_t *nvl, const char *namefmt, \
- va_list nameap) \
-{ \
- char *name; \
- bool exists; \
- \
- vasprintf(&name, namefmt, nameap); \
- if (name == NULL) \
- return (false); \
- exists = nvlist_exists_##type(nvl, name); \
- free(name); \
- return (exists); \
-}
-
-NVLIST_EXISTSV(null)
-NVLIST_EXISTSV(bool)
-NVLIST_EXISTSV(number)
-NVLIST_EXISTSV(string)
-NVLIST_EXISTSV(nvlist)
-NVLIST_EXISTSV(descriptor)
-NVLIST_EXISTSV(binary)
-
-#undef NVLIST_EXISTSV
-#endif
-
void
nvlist_add_nvpair(nvlist_t *nvl, const nvpair_t *nvp)
{
@@ -1188,19 +1064,19 @@ nvlist_add_nvpair(nvlist_t *nvl, const nvpair_t *nvp)
NVPAIR_ASSERT(nvp);
if (nvlist_error(nvl) != 0) {
- RESTORE_ERRNO(nvlist_error(nvl));
+ ERRNO_SET(nvlist_error(nvl));
return;
}
if (nvlist_exists(nvl, nvpair_name(nvp))) {
nvl->nvl_error = EEXIST;
- RESTORE_ERRNO(nvlist_error(nvl));
+ ERRNO_SET(nvlist_error(nvl));
return;
}
newnvp = nvpair_clone(nvp);
if (newnvp == NULL) {
nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
- RESTORE_ERRNO(nvlist_error(nvl));
+ ERRNO_SET(nvlist_error(nvl));
return;
}
@@ -1208,34 +1084,6 @@ nvlist_add_nvpair(nvlist_t *nvl, const nvpair_t *nvp)
}
void
-nvlist_add_null(nvlist_t *nvl, const char *name)
-{
-
- nvlist_addf_null(nvl, "%s", name);
-}
-
-void
-nvlist_add_bool(nvlist_t *nvl, const char *name, bool value)
-{
-
- nvlist_addf_bool(nvl, value, "%s", name);
-}
-
-void
-nvlist_add_number(nvlist_t *nvl, const char *name, uint64_t value)
-{
-
- nvlist_addf_number(nvl, value, "%s", name);
-}
-
-void
-nvlist_add_string(nvlist_t *nvl, const char *name, const char *value)
-{
-
- nvlist_addf_string(nvl, value, "%s", name);
-}
-
-void
nvlist_add_stringf(nvlist_t *nvl, const char *name, const char *valuefmt, ...)
{
va_list valueap;
@@ -1252,213 +1100,117 @@ nvlist_add_stringv(nvlist_t *nvl, const char *name, const char *valuefmt,
nvpair_t *nvp;
if (nvlist_error(nvl) != 0) {
- RESTORE_ERRNO(nvlist_error(nvl));
+ ERRNO_SET(nvlist_error(nvl));
return;
}
nvp = nvpair_create_stringv(name, valuefmt, valueap);
if (nvp == NULL) {
nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
- RESTORE_ERRNO(nvl->nvl_error);
- } else
+ ERRNO_SET(nvl->nvl_error);
+ } else {
nvlist_move_nvpair(nvl, nvp);
+ }
}
void
-nvlist_add_nvlist(nvlist_t *nvl, const char *name, const nvlist_t *value)
-{
-
- nvlist_addf_nvlist(nvl, value, "%s", name);
-}
-
-#ifndef _KERNEL
-void
-nvlist_add_descriptor(nvlist_t *nvl, const char *name, int value)
-{
-
- nvlist_addf_descriptor(nvl, value, "%s", name);
-}
-#endif
-
-void
-nvlist_add_binary(nvlist_t *nvl, const char *name, const void *value,
- size_t size)
-{
-
- nvlist_addf_binary(nvl, value, size, "%s", name);
-}
-
-void
-nvlist_addf_null(nvlist_t *nvl, const char *namefmt, ...)
-{
- va_list nameap;
-
- va_start(nameap, namefmt);
- nvlist_addv_null(nvl, namefmt, nameap);
- va_end(nameap);
-}
-
-void
-nvlist_addf_bool(nvlist_t *nvl, bool value, const char *namefmt, ...)
-{
- va_list nameap;
-
- va_start(nameap, namefmt);
- nvlist_addv_bool(nvl, value, namefmt, nameap);
- va_end(nameap);
-}
-
-void
-nvlist_addf_number(nvlist_t *nvl, uint64_t value, const char *namefmt, ...)
-{
- va_list nameap;
-
- va_start(nameap, namefmt);
- nvlist_addv_number(nvl, value, namefmt, nameap);
- va_end(nameap);
-}
-
-void
-nvlist_addf_string(nvlist_t *nvl, const char *value, const char *namefmt, ...)
-{
- va_list nameap;
-
- va_start(nameap, namefmt);
- nvlist_addv_string(nvl, value, namefmt, nameap);
- va_end(nameap);
-}
-
-void
-nvlist_addf_nvlist(nvlist_t *nvl, const nvlist_t *value, const char *namefmt,
- ...)
-{
- va_list nameap;
-
- va_start(nameap, namefmt);
- nvlist_addv_nvlist(nvl, value, namefmt, nameap);
- va_end(nameap);
-}
-
-#ifndef _KERNEL
-void
-nvlist_addf_descriptor(nvlist_t *nvl, int value, const char *namefmt, ...)
-{
- va_list nameap;
-
- va_start(nameap, namefmt);
- nvlist_addv_descriptor(nvl, value, namefmt, nameap);
- va_end(nameap);
-}
-#endif
-
-void
-nvlist_addf_binary(nvlist_t *nvl, const void *value, size_t size,
- const char *namefmt, ...)
-{
- va_list nameap;
-
- va_start(nameap, namefmt);
- nvlist_addv_binary(nvl, value, size, namefmt, nameap);
- va_end(nameap);
-}
-
-void
-nvlist_addv_null(nvlist_t *nvl, const char *namefmt, va_list nameap)
+nvlist_add_null(nvlist_t *nvl, const char *name)
{
nvpair_t *nvp;
if (nvlist_error(nvl) != 0) {
- RESTORE_ERRNO(nvlist_error(nvl));
+ ERRNO_SET(nvlist_error(nvl));
return;
}
- nvp = nvpair_createv_null(namefmt, nameap);
+ nvp = nvpair_create_null(name);
if (nvp == NULL) {
nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
- RESTORE_ERRNO(nvl->nvl_error);
- } else
+ ERRNO_SET(nvl->nvl_error);
+ } else {
nvlist_move_nvpair(nvl, nvp);
+ }
}
void
-nvlist_addv_bool(nvlist_t *nvl, bool value, const char *namefmt, va_list nameap)
+nvlist_add_bool(nvlist_t *nvl, const char *name, bool value)
{
nvpair_t *nvp;
if (nvlist_error(nvl) != 0) {
- RESTORE_ERRNO(nvlist_error(nvl));
+ ERRNO_SET(nvlist_error(nvl));
return;
}
- nvp = nvpair_createv_bool(value, namefmt, nameap);
+ nvp = nvpair_create_bool(name, value);
if (nvp == NULL) {
nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
- RESTORE_ERRNO(nvl->nvl_error);
- } else
+ ERRNO_SET(nvl->nvl_error);
+ } else {
nvlist_move_nvpair(nvl, nvp);
+ }
}
void
-nvlist_addv_number(nvlist_t *nvl, uint64_t value, const char *namefmt,
- va_list nameap)
+nvlist_add_number(nvlist_t *nvl, const char *name, uint64_t value)
{
nvpair_t *nvp;
if (nvlist_error(nvl) != 0) {
- RESTORE_ERRNO(nvlist_error(nvl));
+ ERRNO_SET(nvlist_error(nvl));
return;
}
- nvp = nvpair_createv_number(value, namefmt, nameap);
+ nvp = nvpair_create_number(name, value);
if (nvp == NULL) {
nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
- RESTORE_ERRNO(nvl->nvl_error);
- } else
+ ERRNO_SET(nvl->nvl_error);
+ } else {
nvlist_move_nvpair(nvl, nvp);
+ }
}
void
-nvlist_addv_string(nvlist_t *nvl, const char *value, const char *namefmt,
- va_list nameap)
+nvlist_add_string(nvlist_t *nvl, const char *name, const char *value)
{
nvpair_t *nvp;
if (nvlist_error(nvl) != 0) {
- RESTORE_ERRNO(nvlist_error(nvl));
+ ERRNO_SET(nvlist_error(nvl));
return;
}
- nvp = nvpair_createv_string(value, namefmt, nameap);
+ nvp = nvpair_create_string(name, value);
if (nvp == NULL) {
nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
- RESTORE_ERRNO(nvl->nvl_error);
- } else
+ ERRNO_SET(nvl->nvl_error);
+ } else {
nvlist_move_nvpair(nvl, nvp);
+ }
}
void
-nvlist_addv_nvlist(nvlist_t *nvl, const nvlist_t *value, const char *namefmt,
- va_list nameap)
+nvlist_add_nvlist(nvlist_t *nvl, const char *name, const nvlist_t *value)
{
nvpair_t *nvp;
if (nvlist_error(nvl) != 0) {
- RESTORE_ERRNO(nvlist_error(nvl));
+ ERRNO_SET(nvlist_error(nvl));
return;
}
- nvp = nvpair_createv_nvlist(value, namefmt, nameap);
+ nvp = nvpair_create_nvlist(name, value);
if (nvp == NULL) {
nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
- RESTORE_ERRNO(nvl->nvl_error);
- } else
+ ERRNO_SET(nvl->nvl_error);
+ } else {
nvlist_move_nvpair(nvl, nvp);
+ }
}
#ifndef _KERNEL
void
-nvlist_addv_descriptor(nvlist_t *nvl, int value, const char *namefmt,
- va_list nameap)
+nvlist_add_descriptor(nvlist_t *nvl, const char *name, int value)
{
nvpair_t *nvp;
@@ -1467,7 +1219,7 @@ nvlist_addv_descriptor(nvlist_t *nvl, int value, const char *namefmt,
return;
}
- nvp = nvpair_createv_descriptor(value, namefmt, nameap);
+ nvp = nvpair_create_descriptor(name, value);
if (nvp == NULL)
nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM);
else
@@ -1476,22 +1228,23 @@ nvlist_addv_descriptor(nvlist_t *nvl, int value, const char *namefmt,
#endif
void
-nvlist_addv_binary(nvlist_t *nvl, const void *value, size_t size,
- const char *namefmt, va_list nameap)
+nvlist_add_binary(nvlist_t *nvl, const char *name, const void *value,
+ size_t size)
{
nvpair_t *nvp;
if (nvlist_error(nvl) != 0) {
- RESTORE_ERRNO(nvlist_error(nvl));
+ ERRNO_SET(nvlist_error(nvl));
return;
}
- nvp = nvpair_createv_binary(value, size, namefmt, nameap);
+ nvp = nvpair_create_binary(name, value, size);
if (nvp == NULL) {
nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
- RESTORE_ERRNO(nvl->nvl_error);
- } else
+ ERRNO_SET(nvl->nvl_error);
+ } else {
nvlist_move_nvpair(nvl, nvp);
+ }
}
void
@@ -1503,153 +1256,100 @@ nvlist_move_nvpair(nvlist_t *nvl, nvpair_t *nvp)
if (nvlist_error(nvl) != 0) {
nvpair_free(nvp);
- RESTORE_ERRNO(nvlist_error(nvl));
+ ERRNO_SET(nvlist_error(nvl));
return;
}
if (nvlist_exists(nvl, nvpair_name(nvp))) {
nvpair_free(nvp);
nvl->nvl_error = EEXIST;
- RESTORE_ERRNO(nvl->nvl_error);
+ ERRNO_SET(nvl->nvl_error);
return;
}
nvpair_insert(&nvl->nvl_head, nvp, nvl);
}
-#define NVLIST_MOVE(vtype, type) \
-void \
-nvlist_move_##type(nvlist_t *nvl, const char *name, vtype value) \
-{ \
- \
- nvlist_movef_##type(nvl, value, "%s", name); \
-}
-
-NVLIST_MOVE(char *, string)
-NVLIST_MOVE(nvlist_t *, nvlist)
-#ifndef _KERNEL
-NVLIST_MOVE(int, descriptor)
-#endif
-
-#undef NVLIST_MOVE
-
-void
-nvlist_move_binary(nvlist_t *nvl, const char *name, void *value, size_t size)
-{
-
- nvlist_movef_binary(nvl, value, size, "%s", name);
-}
-
-#define NVLIST_MOVEF(vtype, type) \
-void \
-nvlist_movef_##type(nvlist_t *nvl, vtype value, const char *namefmt, \
- ...) \
-{ \
- va_list nameap; \
- \
- va_start(nameap, namefmt); \
- nvlist_movev_##type(nvl, value, namefmt, nameap); \
- va_end(nameap); \
-}
-
-NVLIST_MOVEF(char *, string)
-NVLIST_MOVEF(nvlist_t *, nvlist)
-#ifndef _KERNEL
-NVLIST_MOVEF(int, descriptor)
-#endif
-
-#undef NVLIST_MOVEF
-
-void
-nvlist_movef_binary(nvlist_t *nvl, void *value, size_t size,
- const char *namefmt, ...)
-{
- va_list nameap;
-
- va_start(nameap, namefmt);
- nvlist_movev_binary(nvl, value, size, namefmt, nameap);
- va_end(nameap);
-}
-
void
-nvlist_movev_string(nvlist_t *nvl, char *value, const char *namefmt,
- va_list nameap)
+nvlist_move_string(nvlist_t *nvl, const char *name, char *value)
{
nvpair_t *nvp;
if (nvlist_error(nvl) != 0) {
nv_free(value);
- RESTORE_ERRNO(nvlist_error(nvl));
+ ERRNO_SET(nvlist_error(nvl));
return;
}
- nvp = nvpair_movev_string(value, namefmt, nameap);
+ nvp = nvpair_move_string(name, value);
if (nvp == NULL) {
nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
- RESTORE_ERRNO(nvl->nvl_error);
- } else
+ ERRNO_SET(nvl->nvl_error);
+ } else {
nvlist_move_nvpair(nvl, nvp);
+ }
}
void
-nvlist_movev_nvlist(nvlist_t *nvl, nvlist_t *value, const char *namefmt,
- va_list nameap)
+nvlist_move_nvlist(nvlist_t *nvl, const char *name, nvlist_t *value)
{
nvpair_t *nvp;
if (nvlist_error(nvl) != 0) {
if (value != NULL && nvlist_get_nvpair_parent(value) != NULL)
nvlist_destroy(value);
- RESTORE_ERRNO(nvlist_error(nvl));
+ ERRNO_SET(nvlist_error(nvl));
return;
}
- nvp = nvpair_movev_nvlist(value, namefmt, nameap);
+ nvp = nvpair_move_nvlist(name, value);
if (nvp == NULL) {
nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
- RESTORE_ERRNO(nvl->nvl_error);
- } else
+ ERRNO_SET(nvl->nvl_error);
+ } else {
nvlist_move_nvpair(nvl, nvp);
+ }
}
#ifndef _KERNEL
void
-nvlist_movev_descriptor(nvlist_t *nvl, int value, const char *namefmt,
- va_list nameap)
+nvlist_move_descriptor(nvlist_t *nvl, const char *name, int value)
{
nvpair_t *nvp;
if (nvlist_error(nvl) != 0) {
close(value);
- errno = nvlist_error(nvl);
+ ERRNO_SET(nvlist_error(nvl));
return;
}
- nvp = nvpair_movev_descriptor(value, namefmt, nameap);
- if (nvp == NULL)
- nvl->nvl_error = errno = (errno != 0 ? errno : ENOMEM);
- else
+ nvp = nvpair_move_descriptor(name, value);
+ if (nvp == NULL) {
+ nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
+ ERRNO_SET(nvl->nvl_error);
+ } else {
nvlist_move_nvpair(nvl, nvp);
+ }
}
#endif
void
-nvlist_movev_binary(nvlist_t *nvl, void *value, size_t size,
- const char *namefmt, va_list nameap)
+nvlist_move_binary(nvlist_t *nvl, const char *name, void *value, size_t size)
{
nvpair_t *nvp;
if (nvlist_error(nvl) != 0) {
nv_free(value);
- RESTORE_ERRNO(nvlist_error(nvl));
+ ERRNO_SET(nvlist_error(nvl));
return;
}
- nvp = nvpair_movev_binary(value, size, namefmt, nameap);
+ nvp = nvpair_move_binary(name, value, size);
if (nvp == NULL) {
nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
- RESTORE_ERRNO(nvl->nvl_error);
- } else
+ ERRNO_SET(nvl->nvl_error);
+ } else {
nvlist_move_nvpair(nvl, nvp);
+ }
}
const nvpair_t *
@@ -1693,84 +1393,6 @@ nvlist_get_binary(const nvlist_t *nvl, const char *name, size_t *sizep)
return (nvpair_get_binary(nvp, sizep));
}
-#define NVLIST_GETF(ftype, type) \
-ftype \
-nvlist_getf_##type(const nvlist_t *nvl, const char *namefmt, ...) \
-{ \
- va_list nameap; \
- ftype value; \
- \
- va_start(nameap, namefmt); \
- value = nvlist_getv_##type(nvl, namefmt, nameap); \
- va_end(nameap); \
- \
- return (value); \
-}
-
-#ifndef _KERNEL
-NVLIST_GETF(bool, bool)
-NVLIST_GETF(uint64_t, number)
-NVLIST_GETF(const char *, string)
-NVLIST_GETF(const nvlist_t *, nvlist)
-NVLIST_GETF(int, descriptor)
-
-#undef NVLIST_GETF
-
-const void *
-nvlist_getf_binary(const nvlist_t *nvl, size_t *sizep, const char *namefmt, ...)
-{
- va_list nameap;
- const void *value;
-
- va_start(nameap, namefmt);
- value = nvlist_getv_binary(nvl, sizep, namefmt, nameap);
- va_end(nameap);
-
- return (value);
-}
-
-#define NVLIST_GETV(ftype, type, TYPE) \
-ftype \
-nvlist_getv_##type(const nvlist_t *nvl, const char *namefmt, \
- va_list nameap) \
-{ \
- char *name; \
- ftype value; \
- \
- vasprintf(&name, namefmt, nameap); \
- if (name == NULL) \
- nvlist_report_missing(NV_TYPE_##TYPE, "<unknown>"); \
- value = nvlist_get_##type(nvl, name); \
- free(name); \
- \
- return (value); \
-}
-
-NVLIST_GETV(bool, bool, BOOL)
-NVLIST_GETV(uint64_t, number, NUMBER)
-NVLIST_GETV(const char *, string, STRING)
-NVLIST_GETV(const nvlist_t *, nvlist, NVLIST)
-NVLIST_GETV(int, descriptor, DESCRIPTOR)
-
-#undef NVLIST_GETV
-
-const void *
-nvlist_getv_binary(const nvlist_t *nvl, size_t *sizep, const char *namefmt,
- va_list nameap)
-{
- char *name;
- const void *binary;
-
- nv_vasprintf(&name, namefmt, nameap);
- if (name == NULL)
- nvlist_report_missing(NV_TYPE_BINARY, "<unknown>");
-
- binary = nvlist_get_binary(nvl, name, sizep);
- nv_free(name);
- return (binary);
-}
-#endif
-
#define NVLIST_TAKE(ftype, type, TYPE) \
ftype \
nvlist_take_##type(nvlist_t *nvl, const char *name) \
@@ -1813,82 +1435,6 @@ nvlist_take_binary(nvlist_t *nvl, const char *name, size_t *sizep)
return (value);
}
-#define NVLIST_TAKEF(ftype, type) \
-ftype \
-nvlist_takef_##type(nvlist_t *nvl, const char *namefmt, ...) \
-{ \
- va_list nameap; \
- ftype value; \
- \
- va_start(nameap, namefmt); \
- value = nvlist_takev_##type(nvl, namefmt, nameap); \
- va_end(nameap); \
- \
- return (value); \
-}
-
-#ifndef _KERNEL
-NVLIST_TAKEF(bool, bool)
-NVLIST_TAKEF(uint64_t, number)
-NVLIST_TAKEF(char *, string)
-NVLIST_TAKEF(nvlist_t *, nvlist)
-NVLIST_TAKEF(int, descriptor)
-
-#undef NVLIST_TAKEF
-
-void *
-nvlist_takef_binary(nvlist_t *nvl, size_t *sizep, const char *namefmt, ...)
-{
- va_list nameap;
- void *value;
-
- va_start(nameap, namefmt);
- value = nvlist_takev_binary(nvl, sizep, namefmt, nameap);
- va_end(nameap);
-
- return (value);
-}
-
-#define NVLIST_TAKEV(ftype, type, TYPE) \
-ftype \
-nvlist_takev_##type(nvlist_t *nvl, const char *namefmt, va_list nameap) \
-{ \
- char *name; \
- ftype value; \
- \
- vasprintf(&name, namefmt, nameap); \
- if (name == NULL) \
- nvlist_report_missing(NV_TYPE_##TYPE, "<unknown>"); \
- value = nvlist_take_##type(nvl, name); \
- free(name); \
- return (value); \
-}
-
-NVLIST_TAKEV(bool, bool, BOOL)
-NVLIST_TAKEV(uint64_t, number, NUMBER)
-NVLIST_TAKEV(char *, string, STRING)
-NVLIST_TAKEV(nvlist_t *, nvlist, NVLIST)
-NVLIST_TAKEV(int, descriptor, DESCRIPTOR)
-
-#undef NVLIST_TAKEV
-
-void *
-nvlist_takev_binary(nvlist_t *nvl, size_t *sizep, const char *namefmt,
- va_list nameap)
-{
- char *name;
- void *binary;
-
- nv_vasprintf(&name, namefmt, nameap);
- if (name == NULL)
- nvlist_report_missing(NV_TYPE_BINARY, "<unknown>");
-
- binary = nvlist_take_binary(nvl, name, sizep);
- nv_free(name);
- return (binary);
-}
-#endif
-
void
nvlist_remove_nvpair(nvlist_t *nvl, nvpair_t *nvp)
{
@@ -1927,68 +1473,6 @@ NVLIST_FREE(binary, BINARY)
#undef NVLIST_FREE
-#ifndef _KERNEL
-void
-nvlist_freef(nvlist_t *nvl, const char *namefmt, ...)
-{
- va_list nameap;
-
- va_start(nameap, namefmt);
- nvlist_freev(nvl, namefmt, nameap);
- va_end(nameap);
-}
-
-#define NVLIST_FREEF(type) \
-void \
-nvlist_freef_##type(nvlist_t *nvl, const char *namefmt, ...) \
-{ \
- va_list nameap; \
- \
- va_start(nameap, namefmt); \
- nvlist_freev_##type(nvl, namefmt, nameap); \
- va_end(nameap); \
-}
-
-NVLIST_FREEF(null)
-NVLIST_FREEF(bool)
-NVLIST_FREEF(number)
-NVLIST_FREEF(string)
-NVLIST_FREEF(nvlist)
-NVLIST_FREEF(descriptor)
-NVLIST_FREEF(binary)
-
-#undef NVLIST_FREEF
-
-void
-nvlist_freev(nvlist_t *nvl, const char *namefmt, va_list nameap)
-{
-
- nvlist_freev_type(nvl, NV_TYPE_NONE, namefmt, nameap);
-}
-
-#define NVLIST_FREEV(type, TYPE) \
-void \
-nvlist_freev_##type(nvlist_t *nvl, const char *namefmt, va_list nameap) \
-{ \
- char *name; \
- \
- vasprintf(&name, namefmt, nameap); \
- if (name == NULL) \
- nvlist_report_missing(NV_TYPE_##TYPE, "<unknown>"); \
- nvlist_free_##type(nvl, name); \
- free(name); \
-}
-
-NVLIST_FREEV(null, NULL)
-NVLIST_FREEV(bool, BOOL)
-NVLIST_FREEV(number, NUMBER)
-NVLIST_FREEV(string, STRING)
-NVLIST_FREEV(nvlist, NVLIST)
-NVLIST_FREEV(descriptor, DESCRIPTOR)
-NVLIST_FREEV(binary, BINARY)
-#undef NVLIST_FREEV
-#endif
-
void
nvlist_free_nvpair(nvlist_t *nvl, nvpair_t *nvp)
{
@@ -2000,3 +1484,4 @@ nvlist_free_nvpair(nvlist_t *nvl, nvpair_t *nvp)
nvlist_remove_nvpair(nvl, nvp);
nvpair_free(nvp);
}
+
diff --git a/sys/kern/subr_nvpair.c b/sys/kern/subr_nvpair.c
index 7b88e424eae5..b0fc322190f3 100644
--- a/sys/kern/subr_nvpair.c
+++ b/sys/kern/subr_nvpair.c
@@ -468,7 +468,7 @@ nvpair_unpack_header(bool isbe, nvpair_t *nvp, const unsigned char *ptr,
return (ptr);
failed:
- RESTORE_ERRNO(EINVAL);
+ ERRNO_SET(EINVAL);
return (NULL);
}
@@ -480,7 +480,7 @@ nvpair_unpack_null(bool isbe __unused, nvpair_t *nvp, const unsigned char *ptr,
PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_NULL);
if (nvp->nvp_datasize != 0) {
- RESTORE_ERRNO(EINVAL);
+ ERRNO_SET(EINVAL);
return (NULL);
}
@@ -496,11 +496,11 @@ nvpair_unpack_bool(bool isbe __unused, nvpair_t *nvp, const unsigned char *ptr,
PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_BOOL);
if (nvp->nvp_datasize != sizeof(value)) {
- RESTORE_ERRNO(EINVAL);
+ ERRNO_SET(EINVAL);
return (NULL);
}
if (*leftp < sizeof(value)) {
- RESTORE_ERRNO(EINVAL);
+ ERRNO_SET(EINVAL);
return (NULL);
}
@@ -509,7 +509,7 @@ nvpair_unpack_bool(bool isbe __unused, nvpair_t *nvp, const unsigned char *ptr,
*leftp -= sizeof(value);
if (value != 0 && value != 1) {
- RESTORE_ERRNO(EINVAL);
+ ERRNO_SET(EINVAL);
return (NULL);
}
@@ -526,11 +526,11 @@ nvpair_unpack_number(bool isbe, nvpair_t *nvp, const unsigned char *ptr,
PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_NUMBER);
if (nvp->nvp_datasize != sizeof(uint64_t)) {
- RESTORE_ERRNO(EINVAL);
+ ERRNO_SET(EINVAL);
return (NULL);
}
if (*leftp < sizeof(uint64_t)) {
- RESTORE_ERRNO(EINVAL);
+ ERRNO_SET(EINVAL);
return (NULL);
}
@@ -552,13 +552,13 @@ nvpair_unpack_string(bool isbe __unused, nvpair_t *nvp,
PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_STRING);
if (*leftp < nvp->nvp_datasize || nvp->nvp_datasize == 0) {
- RESTORE_ERRNO(EINVAL);
+ ERRNO_SET(EINVAL);
return (NULL);
}
if (strnlen((const char *)ptr, nvp->nvp_datasize) !=
nvp->nvp_datasize - 1) {
- RESTORE_ERRNO(EINVAL);
+ ERRNO_SET(EINVAL);
return (NULL);
}
@@ -581,7 +581,7 @@ nvpair_unpack_nvlist(bool isbe __unused, nvpair_t *nvp,
PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_NVLIST);
if (*leftp < nvp->nvp_datasize || nvp->nvp_datasize == 0) {
- RESTORE_ERRNO(EINVAL);
+ ERRNO_SET(EINVAL);
return (NULL);
}
@@ -609,11 +609,11 @@ nvpair_unpack_descriptor(bool isbe, nvpair_t *nvp, const unsigned char *ptr,
PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_DESCRIPTOR);
if (nvp->nvp_datasize != sizeof(idx)) {
- errno = EINVAL;
+ ERRNO_SET(EINVAL);
return (NULL);
}
if (*leftp < sizeof(idx)) {
- errno = EINVAL;
+ ERRNO_SET(EINVAL);
return (NULL);
}
@@ -623,12 +623,12 @@ nvpair_unpack_descriptor(bool isbe, nvpair_t *nvp, const unsigned char *ptr,
idx = le64dec(ptr);
if (idx < 0) {
- errno = EINVAL;
+ ERRNO_SET(EINVAL);
return (NULL);
}
if ((size_t)idx >= nfds) {
- errno = EINVAL;
+ ERRNO_SET(EINVAL);
return (NULL);
}
@@ -650,7 +650,7 @@ nvpair_unpack_binary(bool isbe __unused, nvpair_t *nvp,
PJDLOG_ASSERT(nvp->nvp_type == NV_TYPE_BINARY);
if (*leftp < nvp->nvp_datasize || nvp->nvp_datasize == 0) {
- RESTORE_ERRNO(EINVAL);
+ ERRNO_SET(EINVAL);
return (NULL);
}
@@ -716,69 +716,34 @@ nvpair_name(const nvpair_t *nvp)
}
static nvpair_t *
-nvpair_allocv(int type, uint64_t data, size_t datasize, const char *namefmt,
- va_list nameap)
+nvpair_allocv(const char *name, int type, uint64_t data, size_t datasize)
{
nvpair_t *nvp;
- char *name;
- int namelen;
+ size_t namelen;
PJDLOG_ASSERT(type >= NV_TYPE_FIRST && type <= NV_TYPE_LAST);
- namelen = nv_vasprintf(&name, namefmt, nameap);
- if (namelen < 0)
- return (NULL);
-
- PJDLOG_ASSERT(namelen > 0);
+ namelen = strlen(name);
if (namelen >= NV_NAME_MAX) {
- nv_free(name);
- RESTORE_ERRNO(ENAMETOOLONG);
+ ERRNO_SET(ENAMETOOLONG);
return (NULL);
}
nvp = nv_calloc(1, sizeof(*nvp) + namelen + 1);
if (nvp != NULL) {
nvp->nvp_name = (char *)(nvp + 1);
- memcpy(nvp->nvp_name, name, namelen + 1);
+ memcpy(nvp->nvp_name, name, namelen);
+ nvp->nvp_name[namelen + 1] = '\0';
nvp->nvp_type = type;
nvp->nvp_data = data;
nvp->nvp_datasize = datasize;
nvp->nvp_magic = NVPAIR_MAGIC;
}
- nv_free(name);
return (nvp);
};
nvpair_t *
-nvpair_create_null(const char *name)
-{
-
- return (nvpair_createf_null("%s", name));
-}
-
-nvpair_t *
-nvpair_create_bool(const char *name, bool value)
-{
-
- return (nvpair_createf_bool(value, "%s", name));
-}
-
-nvpair_t *
-nvpair_create_number(const char *name, uint64_t value)
-{
-
- return (nvpair_createf_number(value, "%s", name));
-}
-
-nvpair_t *
-nvpair_create_string(const char *name, const char *value)
-{
-
- return (nvpair_createf_string(value, "%s", name));
-}
-
-nvpair_t *
nvpair_create_stringf(const char *name, const char *valuefmt, ...)
{
va_list valueap;
@@ -808,153 +773,36 @@ nvpair_create_stringv(const char *name, const char *valuefmt, va_list valueap)
}
nvpair_t *
-nvpair_create_nvlist(const char *name, const nvlist_t *value)
-{
-
- return (nvpair_createf_nvlist(value, "%s", name));
-}
-
-#ifndef _KERNEL
-nvpair_t *
-nvpair_create_descriptor(const char *name, int value)
-{
-
- return (nvpair_createf_descriptor(value, "%s", name));
-}
-#endif
-
-nvpair_t *
-nvpair_create_binary(const char *name, const void *value, size_t size)
-{
-
- return (nvpair_createf_binary(value, size, "%s", name));
-}
-
-nvpair_t *
-nvpair_createf_null(const char *namefmt, ...)
-{
- va_list nameap;
- nvpair_t *nvp;
-
- va_start(nameap, namefmt);
- nvp = nvpair_createv_null(namefmt, nameap);
- va_end(nameap);
-
- return (nvp);
-}
-
-nvpair_t *
-nvpair_createf_bool(bool value, const char *namefmt, ...)
-{
- va_list nameap;
- nvpair_t *nvp;
-
- va_start(nameap, namefmt);
- nvp = nvpair_createv_bool(value, namefmt, nameap);
- va_end(nameap);
-
- return (nvp);
-}
-
-nvpair_t *
-nvpair_createf_number(uint64_t value, const char *namefmt, ...)
-{
- va_list nameap;
- nvpair_t *nvp;
-
- va_start(nameap, namefmt);
- nvp = nvpair_createv_number(value, namefmt, nameap);
- va_end(nameap);
-
- return (nvp);
-}
-
-nvpair_t *
-nvpair_createf_string(const char *value, const char *namefmt, ...)
-{
- va_list nameap;
- nvpair_t *nvp;
-
- va_start(nameap, namefmt);
- nvp = nvpair_createv_string(value, namefmt, nameap);
- va_end(nameap);
-
- return (nvp);
-}
-
-nvpair_t *
-nvpair_createf_nvlist(const nvlist_t *value, const char *namefmt, ...)
-{
- va_list nameap;
- nvpair_t *nvp;
-
- va_start(nameap, namefmt);
- nvp = nvpair_createv_nvlist(value, namefmt, nameap);
- va_end(nameap);
-
- return (nvp);
-}
-
-#ifndef _KERNEL
-nvpair_t *
-nvpair_createf_descriptor(int value, const char *namefmt, ...)
-{
- va_list nameap;
- nvpair_t *nvp;
-
- va_start(nameap, namefmt);
- nvp = nvpair_createv_descriptor(value, namefmt, nameap);
- va_end(nameap);
-
- return (nvp);
-}
-#endif
-
-nvpair_t *
-nvpair_createf_binary(const void *value, size_t size, const char *namefmt, ...)
-{
- va_list nameap;
- nvpair_t *nvp;
-
- va_start(nameap, namefmt);
- nvp = nvpair_createv_binary(value, size, namefmt, nameap);
- va_end(nameap);
-
- return (nvp);
-}
-
-nvpair_t *
-nvpair_createv_null(const char *namefmt, va_list nameap)
+nvpair_create_null(const char *name)
{
- return (nvpair_allocv(NV_TYPE_NULL, 0, 0, namefmt, nameap));
+ return (nvpair_allocv(name, NV_TYPE_NULL, 0, 0));
}
nvpair_t *
-nvpair_createv_bool(bool value, const char *namefmt, va_list nameap)
+nvpair_create_bool(const char *name, bool value)
{
- return (nvpair_allocv(NV_TYPE_BOOL, value ? 1 : 0, sizeof(uint8_t),
- namefmt, nameap));
+ return (nvpair_allocv(name, NV_TYPE_BOOL, value ? 1 : 0,
+ sizeof(uint8_t)));
}
nvpair_t *
-nvpair_createv_number(uint64_t value, const char *namefmt, va_list nameap)
+nvpair_create_number(const char *name, uint64_t value)
{
- return (nvpair_allocv(NV_TYPE_NUMBER, value, sizeof(value), namefmt,
- nameap));
+ return (nvpair_allocv(name, NV_TYPE_NUMBER, value, sizeof(value)));
}
nvpair_t *
-nvpair_createv_string(const char *value, const char *namefmt, va_list nameap)
+nvpair_create_string(const char *name, const char *value)
{
nvpair_t *nvp;
size_t size;
char *data;
if (value == NULL) {
- RESTORE_ERRNO(EINVAL);
+ ERRNO_SET(EINVAL);
return (NULL);
}
@@ -963,8 +811,8 @@ nvpair_createv_string(const char *value, const char *namefmt, va_list nameap)
return (NULL);
size = strlen(value) + 1;
- nvp = nvpair_allocv(NV_TYPE_STRING, (uint64_t)(uintptr_t)data, size,
- namefmt, nameap);
+ nvp = nvpair_allocv(name, NV_TYPE_STRING, (uint64_t)(uintptr_t)data,
+ size);
if (nvp == NULL)
nv_free(data);
@@ -972,14 +820,13 @@ nvpair_createv_string(const char *value, const char *namefmt, va_list nameap)
}
nvpair_t *
-nvpair_createv_nvlist(const nvlist_t *value, const char *namefmt,
- va_list nameap)
+nvpair_create_nvlist(const char *name, const nvlist_t *value)
{
nvlist_t *nvl;
nvpair_t *nvp;
if (value == NULL) {
- RESTORE_ERRNO(EINVAL);
+ ERRNO_SET(EINVAL);
return (NULL);
}
@@ -987,8 +834,7 @@ nvpair_createv_nvlist(const nvlist_t *value, const char *namefmt,
if (nvl == NULL)
return (NULL);
- nvp = nvpair_allocv(NV_TYPE_NVLIST, (uint64_t)(uintptr_t)nvl, 0,
- namefmt, nameap);
+ nvp = nvpair_allocv(name, NV_TYPE_NVLIST, (uint64_t)(uintptr_t)nvl, 0);
if (nvp == NULL)
nvlist_destroy(nvl);
else
@@ -999,12 +845,12 @@ nvpair_createv_nvlist(const nvlist_t *value, const char *namefmt,
#ifndef _KERNEL
nvpair_t *
-nvpair_createv_descriptor(int value, const char *namefmt, va_list nameap)
+nvpair_create_descriptor(const char *name, int value)
{
nvpair_t *nvp;
if (value < 0 || !fd_is_valid(value)) {
- errno = EBADF;
+ ERRNO_SET(EBADF);
return (NULL);
}
@@ -1012,24 +858,26 @@ nvpair_createv_descriptor(int value, const char *namefmt, va_list nameap)
if (value < 0)
return (NULL);
- nvp = nvpair_allocv(NV_TYPE_DESCRIPTOR, (uint64_t)value,
- sizeof(int64_t), namefmt, nameap);
- if (nvp == NULL)
+ nvp = nvpair_allocv(name, NV_TYPE_DESCRIPTOR, (uint64_t)value,
+ sizeof(int64_t));
+ if (nvp == NULL) {
+ ERRNO_SAVE();
close(value);
+ ERRNO_RESTORE();
+ }
return (nvp);
}
#endif
nvpair_t *
-nvpair_createv_binary(const void *value, size_t size, const char *namefmt,
- va_list nameap)
+nvpair_create_binary(const char *name, const void *value, size_t size)
{
nvpair_t *nvp;
void *data;
if (value == NULL || size == 0) {
- RESTORE_ERRNO(EINVAL);
+ ERRNO_SET(EINVAL);
return (NULL);
}
@@ -1038,8 +886,8 @@ nvpair_createv_binary(const void *value, size_t size, const char *namefmt,
return (NULL);
memcpy(data, value, size);
- nvp = nvpair_allocv(NV_TYPE_BINARY, (uint64_t)(uintptr_t)data, size,
- namefmt, nameap);
+ nvp = nvpair_allocv(name, NV_TYPE_BINARY, (uint64_t)(uintptr_t)data,
+ size);
if (nvp == NULL)
nv_free(data);
@@ -1049,127 +897,42 @@ nvpair_createv_binary(const void *value, size_t size, const char *namefmt,
nvpair_t *
nvpair_move_string(const char *name, char *value)
{
-
- return (nvpair_movef_string(value, "%s", name));
-}
-
-nvpair_t *
-nvpair_move_nvlist(const char *name, nvlist_t *value)
-{
-
- return (nvpair_movef_nvlist(value, "%s", name));
-}
-
-#ifndef _KERNEL
-nvpair_t *
-nvpair_move_descriptor(const char *name, int value)
-{
-
- return (nvpair_movef_descriptor(value, "%s", name));
-}
-#endif
-
-nvpair_t *
-nvpair_move_binary(const char *name, void *value, size_t size)
-{
-
- return (nvpair_movef_binary(value, size, "%s", name));
-}
-
-nvpair_t *
-nvpair_movef_string(char *value, const char *namefmt, ...)
-{
- va_list nameap;
- nvpair_t *nvp;
-
- va_start(nameap, namefmt);
- nvp = nvpair_movev_string(value, namefmt, nameap);
- va_end(nameap);
-
- return (nvp);
-}
-
-nvpair_t *
-nvpair_movef_nvlist(nvlist_t *value, const char *namefmt, ...)
-{
- va_list nameap;
- nvpair_t *nvp;
-
- va_start(nameap, namefmt);
- nvp = nvpair_movev_nvlist(value, namefmt, nameap);
- va_end(nameap);
-
- return (nvp);
-}
-
-#ifndef _KERNEL
-nvpair_t *
-nvpair_movef_descriptor(int value, const char *namefmt, ...)
-{
- va_list nameap;
- nvpair_t *nvp;
-
- va_start(nameap, namefmt);
- nvp = nvpair_movev_descriptor(value, namefmt, nameap);
- va_end(nameap);
-
- return (nvp);
-}
-#endif
-
-nvpair_t *
-nvpair_movef_binary(void *value, size_t size, const char *namefmt, ...)
-{
- va_list nameap;
- nvpair_t *nvp;
-
- va_start(nameap, namefmt);
- nvp = nvpair_movev_binary(value, size, namefmt, nameap);
- va_end(nameap);
-
- return (nvp);
-}
-
-nvpair_t *
-nvpair_movev_string(char *value, const char *namefmt, va_list nameap)
-{
nvpair_t *nvp;
- int serrno;
if (value == NULL) {
- RESTORE_ERRNO(EINVAL);
+ ERRNO_SET(EINVAL);
return (NULL);
}
- nvp = nvpair_allocv(NV_TYPE_STRING, (uint64_t)(uintptr_t)value,
- strlen(value) + 1, namefmt, nameap);
+ nvp = nvpair_allocv(name, NV_TYPE_STRING, (uint64_t)(uintptr_t)value,
+ strlen(value) + 1);
if (nvp == NULL) {
- SAVE_ERRNO(serrno);
+ ERRNO_SAVE();
nv_free(value);
- RESTORE_ERRNO(serrno);
+ ERRNO_RESTORE();
}
return (nvp);
}
nvpair_t *
-nvpair_movev_nvlist(nvlist_t *value, const char *namefmt, va_list nameap)
+nvpair_move_nvlist(const char *name, nvlist_t *value)
{
nvpair_t *nvp;
if (value == NULL || nvlist_get_nvpair_parent(value) != NULL) {
- RESTORE_ERRNO(EINVAL);
+ ERRNO_SET(EINVAL);
return (NULL);
}
if (nvlist_error(value) != 0) {
- RESTORE_ERRNO(nvlist_error(value));
+ ERRNO_SET(nvlist_error(value));
nvlist_destroy(value);
return (NULL);
}
- nvp = nvpair_allocv(NV_TYPE_NVLIST, (uint64_t)(uintptr_t)value, 0,
- namefmt, nameap);
+ nvp = nvpair_allocv(name, NV_TYPE_NVLIST, (uint64_t)(uintptr_t)value,
+ 0);
if (nvp == NULL)
nvlist_destroy(value);
else
@@ -1180,22 +943,21 @@ nvpair_movev_nvlist(nvlist_t *value, const char *namefmt, va_list nameap)
#ifndef _KERNEL
nvpair_t *
-nvpair_movev_descriptor(int value, const char *namefmt, va_list nameap)
+nvpair_move_descriptor(const char *name, int value)
{
nvpair_t *nvp;
- int serrno;
if (value < 0 || !fd_is_valid(value)) {
- errno = EBADF;
+ ERRNO_SET(EBADF);
return (NULL);
}
- nvp = nvpair_allocv(NV_TYPE_DESCRIPTOR, (uint64_t)value,
- sizeof(int64_t), namefmt, nameap);
+ nvp = nvpair_allocv(name, NV_TYPE_DESCRIPTOR, (uint64_t)value,
+ sizeof(int64_t));
if (nvp == NULL) {
- serrno = errno;
+ ERRNO_SAVE();
close(value);
- errno = serrno;
+ ERRNO_RESTORE();
}
return (nvp);
@@ -1203,23 +965,21 @@ nvpair_movev_descriptor(int value, const char *namefmt, va_list nameap)
#endif
nvpair_t *
-nvpair_movev_binary(void *value, size_t size, const char *namefmt,
- va_list nameap)
+nvpair_move_binary(const char *name, void *value, size_t size)
{
nvpair_t *nvp;
- int serrno;
if (value == NULL || size == 0) {
- RESTORE_ERRNO(EINVAL);
+ ERRNO_SET(EINVAL);
return (NULL);
}
- nvp = nvpair_allocv(NV_TYPE_BINARY, (uint64_t)(uintptr_t)value, size,
- namefmt, nameap);
+ nvp = nvpair_allocv(name, NV_TYPE_BINARY, (uint64_t)(uintptr_t)value,
+ size);
if (nvp == NULL) {
- SAVE_ERRNO(serrno);
+ ERRNO_SAVE();
nv_free(value);
- RESTORE_ERRNO(serrno);
+ ERRNO_RESTORE();
}
return (nvp);
@@ -1348,3 +1108,4 @@ nvpair_type_string(int type)
return ("<UNKNOWN>");
}
}
+
diff --git a/sys/kern/subr_param.c b/sys/kern/subr_param.c
index f662ec268077..cba656aa1884 100644
--- a/sys/kern/subr_param.c
+++ b/sys/kern/subr_param.c
@@ -99,11 +99,7 @@ pid_t pid_max = PID_MAX;
long maxswzone; /* max swmeta KVA storage */
long maxbcache; /* max buffer cache KVA storage */
long maxpipekva; /* Limit on pipe KVA */
-#ifdef XEN
-int vm_guest = VM_GUEST_XEN;
-#else
int vm_guest = VM_GUEST_NO; /* Running as virtual machine guest? */
-#endif
u_long maxtsiz; /* max text size */
u_long dfldsiz; /* initial data size limit */
u_long maxdsiz; /* max data size */
diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c
index cfc3ed70f6df..93f7557aef63 100644
--- a/sys/kern/subr_trap.c
+++ b/sys/kern/subr_trap.c
@@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$");
#include <sys/ktr.h>
#include <sys/pioctl.h>
#include <sys/ptrace.h>
+#include <sys/racct.h>
#include <sys/resourcevar.h>
#include <sys/sched.h>
#include <sys/signalvar.h>
@@ -79,12 +80,6 @@ __FBSDID("$FreeBSD$");
#include <net/vnet.h>
#endif
-#ifdef XEN
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/pmap.h>
-#endif
-
#ifdef HWPMC_HOOKS
#include <sys/pmckern.h>
#endif
@@ -135,9 +130,6 @@ userret(struct thread *td, struct trapframe *frame)
* Let the scheduler adjust our priority etc.
*/
sched_userret(td);
-#ifdef XEN
- PT_UPDATES_FLUSH();
-#endif
/*
* Check for misbehavior.
@@ -172,11 +164,13 @@ userret(struct thread *td, struct trapframe *frame)
__func__, td, p->p_pid, td->td_name, curvnet,
(td->td_vnet_lpush != NULL) ? td->td_vnet_lpush : "N/A"));
#endif
-#ifdef RACCT
- PROC_LOCK(p);
- while (p->p_throttled == 1)
- msleep(p->p_racct, &p->p_mtx, 0, "racct", 0);
- PROC_UNLOCK(p);
+#ifdef RACCT
+ if (racct_enable) {
+ PROC_LOCK(p);
+ while (p->p_throttled == 1)
+ msleep(p->p_racct, &p->p_mtx, 0, "racct", 0);
+ PROC_UNLOCK(p);
+ }
#endif
}
diff --git a/sys/kern/sysv_msg.c b/sys/kern/sysv_msg.c
index acc44710a78a..59357c492240 100644
--- a/sys/kern/sysv_msg.c
+++ b/sys/kern/sysv_msg.c
@@ -617,12 +617,14 @@ sys_msgget(td, uap)
goto done2;
}
#ifdef RACCT
- PROC_LOCK(td->td_proc);
- error = racct_add(td->td_proc, RACCT_NMSGQ, 1);
- PROC_UNLOCK(td->td_proc);
- if (error != 0) {
- error = ENOSPC;
- goto done2;
+ if (racct_enable) {
+ PROC_LOCK(td->td_proc);
+ error = racct_add(td->td_proc, RACCT_NMSGQ, 1);
+ PROC_UNLOCK(td->td_proc);
+ if (error != 0) {
+ error = ENOSPC;
+ goto done2;
+ }
}
#endif
DPRINTF(("msqid %d is available\n", msqid));
@@ -724,20 +726,22 @@ kern_msgsnd(td, msqid, msgp, msgsz, msgflg, mtype)
#endif
#ifdef RACCT
- PROC_LOCK(td->td_proc);
- if (racct_add(td->td_proc, RACCT_MSGQQUEUED, 1)) {
- PROC_UNLOCK(td->td_proc);
- error = EAGAIN;
- goto done2;
- }
- saved_msgsz = msgsz;
- if (racct_add(td->td_proc, RACCT_MSGQSIZE, msgsz)) {
- racct_sub(td->td_proc, RACCT_MSGQQUEUED, 1);
+ if (racct_enable) {
+ PROC_LOCK(td->td_proc);
+ if (racct_add(td->td_proc, RACCT_MSGQQUEUED, 1)) {
+ PROC_UNLOCK(td->td_proc);
+ error = EAGAIN;
+ goto done2;
+ }
+ saved_msgsz = msgsz;
+ if (racct_add(td->td_proc, RACCT_MSGQSIZE, msgsz)) {
+ racct_sub(td->td_proc, RACCT_MSGQQUEUED, 1);
+ PROC_UNLOCK(td->td_proc);
+ error = EAGAIN;
+ goto done2;
+ }
PROC_UNLOCK(td->td_proc);
- error = EAGAIN;
- goto done2;
}
- PROC_UNLOCK(td->td_proc);
#endif
segs_needed = (msgsz + msginfo.msgssz - 1) / msginfo.msgssz;
@@ -994,7 +998,7 @@ kern_msgsnd(td, msqid, msgp, msgsz, msgflg, mtype)
td->td_retval[0] = 0;
done3:
#ifdef RACCT
- if (error != 0) {
+ if (racct_enable && error != 0) {
PROC_LOCK(td->td_proc);
racct_sub(td->td_proc, RACCT_MSGQQUEUED, 1);
racct_sub(td->td_proc, RACCT_MSGQSIZE, saved_msgsz);
diff --git a/sys/kern/sysv_sem.c b/sys/kern/sysv_sem.c
index 6ff578926a51..d9324f46d0df 100644
--- a/sys/kern/sysv_sem.c
+++ b/sys/kern/sysv_sem.c
@@ -915,12 +915,14 @@ sys_semget(struct thread *td, struct semget_args *uap)
goto done2;
}
#ifdef RACCT
- PROC_LOCK(td->td_proc);
- error = racct_add(td->td_proc, RACCT_NSEM, nsems);
- PROC_UNLOCK(td->td_proc);
- if (error != 0) {
- error = ENOSPC;
- goto done2;
+ if (racct_enable) {
+ PROC_LOCK(td->td_proc);
+ error = racct_add(td->td_proc, RACCT_NSEM, nsems);
+ PROC_UNLOCK(td->td_proc);
+ if (error != 0) {
+ error = ENOSPC;
+ goto done2;
+ }
}
#endif
DPRINTF(("semid %d is available\n", semid));
@@ -1009,12 +1011,15 @@ sys_semop(struct thread *td, struct semop_args *uap)
return (E2BIG);
} else {
#ifdef RACCT
- PROC_LOCK(td->td_proc);
- if (nsops > racct_get_available(td->td_proc, RACCT_NSEMOP)) {
+ if (racct_enable) {
+ PROC_LOCK(td->td_proc);
+ if (nsops >
+ racct_get_available(td->td_proc, RACCT_NSEMOP)) {
+ PROC_UNLOCK(td->td_proc);
+ return (E2BIG);
+ }
PROC_UNLOCK(td->td_proc);
- return (E2BIG);
}
- PROC_UNLOCK(td->td_proc);
#endif
sops = malloc(nsops * sizeof(*sops), M_TEMP, M_WAITOK);
diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c
index 274deda3c82d..3240a5fe7ddd 100644
--- a/sys/kern/sysv_shm.c
+++ b/sys/kern/sysv_shm.c
@@ -651,17 +651,19 @@ shmget_allocate_segment(struct thread *td, struct shmget_args *uap, int mode)
("segnum %d shmalloced %d", segnum, shmalloced));
shmseg = &shmsegs[segnum];
#ifdef RACCT
- PROC_LOCK(td->td_proc);
- if (racct_add(td->td_proc, RACCT_NSHM, 1)) {
- PROC_UNLOCK(td->td_proc);
- return (ENOSPC);
- }
- if (racct_add(td->td_proc, RACCT_SHMSIZE, size)) {
- racct_sub(td->td_proc, RACCT_NSHM, 1);
+ if (racct_enable) {
+ PROC_LOCK(td->td_proc);
+ if (racct_add(td->td_proc, RACCT_NSHM, 1)) {
+ PROC_UNLOCK(td->td_proc);
+ return (ENOSPC);
+ }
+ if (racct_add(td->td_proc, RACCT_SHMSIZE, size)) {
+ racct_sub(td->td_proc, RACCT_NSHM, 1);
+ PROC_UNLOCK(td->td_proc);
+ return (ENOMEM);
+ }
PROC_UNLOCK(td->td_proc);
- return (ENOMEM);
}
- PROC_UNLOCK(td->td_proc);
#endif
/*
@@ -672,10 +674,12 @@ shmget_allocate_segment(struct thread *td, struct shmget_args *uap, int mode)
0, size, VM_PROT_DEFAULT, 0, cred);
if (shm_object == NULL) {
#ifdef RACCT
- PROC_LOCK(td->td_proc);
- racct_sub(td->td_proc, RACCT_NSHM, 1);
- racct_sub(td->td_proc, RACCT_SHMSIZE, size);
- PROC_UNLOCK(td->td_proc);
+ if (racct_enable) {
+ PROC_LOCK(td->td_proc);
+ racct_sub(td->td_proc, RACCT_NSHM, 1);
+ racct_sub(td->td_proc, RACCT_SHMSIZE, size);
+ PROC_UNLOCK(td->td_proc);
+ }
#endif
return (ENOMEM);
}
@@ -961,39 +965,39 @@ oshmctl(struct thread *td, struct oshmctl_args *uap)
if (!prison_allow(td->td_ucred, PR_ALLOW_SYSVIPC))
return (ENOSYS);
+ if (uap->cmd != IPC_STAT) {
+ return (freebsd7_shmctl(td,
+ (struct freebsd7_shmctl_args *)uap));
+ }
SYSVSHM_LOCK();
shmseg = shm_find_segment(uap->shmid, true);
if (shmseg == NULL) {
SYSVSHM_UNLOCK();
return (EINVAL);
}
- switch (uap->cmd) {
- case IPC_STAT:
- error = ipcperm(td, &shmseg->u.shm_perm, IPC_R);
- if (error != 0)
- break;
+ error = ipcperm(td, &shmseg->u.shm_perm, IPC_R);
+ if (error != 0) {
+ SYSVSHM_UNLOCK();
+ return (error);
+ }
#ifdef MAC
- error = mac_sysvshm_check_shmctl(td->td_ucred, shmseg,
- uap->cmd);
- if (error != 0)
- break;
-#endif
- ipcperm_new2old(&shmseg->u.shm_perm, &outbuf.shm_perm);
- outbuf.shm_segsz = shmseg->u.shm_segsz;
- outbuf.shm_cpid = shmseg->u.shm_cpid;
- outbuf.shm_lpid = shmseg->u.shm_lpid;
- outbuf.shm_nattch = shmseg->u.shm_nattch;
- outbuf.shm_atime = shmseg->u.shm_atime;
- outbuf.shm_dtime = shmseg->u.shm_dtime;
- outbuf.shm_ctime = shmseg->u.shm_ctime;
- outbuf.shm_handle = shmseg->object;
- error = copyout(&outbuf, uap->ubuf, sizeof(outbuf));
- break;
- default:
- error = freebsd7_shmctl(td, (struct freebsd7_shmctl_args *)uap);
- break;
+ error = mac_sysvshm_check_shmctl(td->td_ucred, shmseg, uap->cmd);
+ if (error != 0) {
+ SYSVSHM_UNLOCK();
+ return (error);
}
+#endif
+ ipcperm_new2old(&shmseg->u.shm_perm, &outbuf.shm_perm);
+ outbuf.shm_segsz = shmseg->u.shm_segsz;
+ outbuf.shm_cpid = shmseg->u.shm_cpid;
+ outbuf.shm_lpid = shmseg->u.shm_lpid;
+ outbuf.shm_nattch = shmseg->u.shm_nattch;
+ outbuf.shm_atime = shmseg->u.shm_atime;
+ outbuf.shm_dtime = shmseg->u.shm_dtime;
+ outbuf.shm_ctime = shmseg->u.shm_ctime;
+ outbuf.shm_handle = shmseg->object;
SYSVSHM_UNLOCK();
+ error = copyout(&outbuf, uap->ubuf, sizeof(outbuf));
return (error);
#else
return (EINVAL);
@@ -1025,9 +1029,7 @@ sys_shmsys(struct thread *td, struct shmsys_args *uap)
return (ENOSYS);
if (uap->which < 0 || uap->which >= nitems(shmcalls))
return (EINVAL);
- SYSVSHM_LOCK();
error = (*shmcalls[uap->which])(td, &uap->a2);
- SYSVSHM_UNLOCK();
return (error);
}
diff --git a/sys/kern/uipc_shm.c b/sys/kern/uipc_shm.c
index 8410ed9b894a..93c7ed1cdcce 100644
--- a/sys/kern/uipc_shm.c
+++ b/sys/kern/uipc_shm.c
@@ -170,7 +170,7 @@ uiomove_object_page(vm_object_t obj, size_t len, struct uio *uio)
if (uio->uio_rw == UIO_READ && vm_page_lookup(obj, idx) == NULL &&
!vm_pager_has_page(obj, idx, NULL, NULL)) {
VM_OBJECT_WUNLOCK(obj);
- return (uiomove(__DECONST(void *, zero_region), len, uio));
+ return (uiomove(__DECONST(void *, zero_region), tlen, uio));
}
/*
diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c
index c7e602e2eb86..0bfcf2d09578 100644
--- a/sys/kern/vfs_aio.c
+++ b/sys/kern/vfs_aio.c
@@ -59,10 +59,12 @@ __FBSDID("$FreeBSD$");
#include <sys/conf.h>
#include <sys/event.h>
#include <sys/mount.h>
+#include <geom/geom.h>
#include <machine/atomic.h>
#include <vm/vm.h>
+#include <vm/vm_page.h>
#include <vm/vm_extern.h>
#include <vm/pmap.h>
#include <vm/vm_map.h>
@@ -232,9 +234,10 @@ struct aiocblist {
int jobstate; /* (b) job state */
int inputcharge; /* (*) input blockes */
int outputcharge; /* (*) output blockes */
- struct buf *bp; /* (*) private to BIO backend,
- * buffer pointer
- */
+ struct bio *bp; /* (*) BIO backend BIO pointer */
+ struct buf *pbuf; /* (*) BIO backend buffer pointer */
+ struct vm_page *pages[btoc(MAXPHYS)+1]; /* BIO backend pages */
+ int npages; /* BIO backend number of pages */
struct proc *userproc; /* (*) user process */
struct ucred *cred; /* (*) active credential when created */
struct file *fd_file; /* (*) pointer to file structure */
@@ -243,7 +246,6 @@ struct aiocblist {
struct knlist klist; /* (a) list of knotes */
struct aiocb uaiocb; /* (*) kernel I/O control block */
ksiginfo_t ksi; /* (a) realtime signal info */
- struct task biotask; /* (*) private to BIO backend */
uint64_t seqno; /* (*) job number */
int pending; /* (a) number of pending I/O, aio_fsync only */
};
@@ -344,11 +346,10 @@ static void aio_process_mlock(struct aiocblist *aiocbe);
static int aio_newproc(int *);
int aio_aqueue(struct thread *td, struct aiocb *job,
struct aioliojob *lio, int type, struct aiocb_ops *ops);
-static void aio_physwakeup(struct buf *bp);
+static void aio_physwakeup(struct bio *bp);
static void aio_proc_rundown(void *arg, struct proc *p);
static void aio_proc_rundown_exec(void *arg, struct proc *p, struct image_params *imgp);
static int aio_qphysio(struct proc *p, struct aiocblist *iocb);
-static void biohelper(void *, int);
static void aio_daemon(void *param);
static void aio_swake_cb(struct socket *, struct sockbuf *);
static int aio_unload(void);
@@ -1294,13 +1295,15 @@ aio_qphysio(struct proc *p, struct aiocblist *aiocbe)
{
struct aiocb *cb;
struct file *fp;
- struct buf *bp;
+ struct bio *bp;
+ struct buf *pbuf;
struct vnode *vp;
struct cdevsw *csw;
struct cdev *dev;
struct kaioinfo *ki;
struct aioliojob *lj;
- int error, ref;
+ int error, ref, unmap, poff;
+ vm_prot_t prot;
cb = &aiocbe->uaiocb;
fp = aiocbe->fd_file;
@@ -1309,107 +1312,121 @@ aio_qphysio(struct proc *p, struct aiocblist *aiocbe)
return (-1);
vp = fp->f_vnode;
-
- /*
- * If its not a disk, we don't want to return a positive error.
- * It causes the aio code to not fall through to try the thread
- * way when you're talking to a regular file.
- */
- if (!vn_isdisk(vp, &error)) {
- if (error == ENOTBLK)
- return (-1);
- else
- return (error);
- }
-
- if (vp->v_bufobj.bo_bsize == 0)
- return (-1);
-
- if (cb->aio_nbytes % vp->v_bufobj.bo_bsize)
+ if (vp->v_type != VCHR)
return (-1);
-
- if (cb->aio_nbytes >
- MAXPHYS - (((vm_offset_t) cb->aio_buf) & PAGE_MASK))
+ if (vp->v_bufobj.bo_bsize == 0)
return (-1);
-
- ki = p->p_aioinfo;
- if (ki->kaio_buffer_count >= ki->kaio_ballowed_count)
+ if (cb->aio_nbytes % vp->v_bufobj.bo_bsize)
return (-1);
ref = 0;
csw = devvn_refthread(vp, &dev, &ref);
if (csw == NULL)
return (ENXIO);
+
+ if ((csw->d_flags & D_DISK) == 0) {
+ error = -1;
+ goto unref;
+ }
if (cb->aio_nbytes > dev->si_iosize_max) {
error = -1;
goto unref;
}
- /* Create and build a buffer header for a transfer. */
- bp = (struct buf *)getpbuf(NULL);
- BUF_KERNPROC(bp);
+ ki = p->p_aioinfo;
+ poff = (vm_offset_t)cb->aio_buf & PAGE_MASK;
+ unmap = ((dev->si_flags & SI_UNMAPPED) && unmapped_buf_allowed);
+ if (unmap) {
+ if (cb->aio_nbytes > MAXPHYS) {
+ error = -1;
+ goto unref;
+ }
+ } else {
+ if (cb->aio_nbytes > MAXPHYS - poff) {
+ error = -1;
+ goto unref;
+ }
+ if (ki->kaio_buffer_count >= ki->kaio_ballowed_count) {
+ error = -1;
+ goto unref;
+ }
+ }
+ aiocbe->bp = bp = g_alloc_bio();
+ if (!unmap) {
+ aiocbe->pbuf = pbuf = (struct buf *)getpbuf(NULL);
+ BUF_KERNPROC(pbuf);
+ }
AIO_LOCK(ki);
ki->kaio_count++;
- ki->kaio_buffer_count++;
+ if (!unmap)
+ ki->kaio_buffer_count++;
lj = aiocbe->lio;
if (lj)
lj->lioj_count++;
- AIO_UNLOCK(ki);
-
- /*
- * Get a copy of the kva from the physical buffer.
- */
- error = 0;
-
- bp->b_bcount = cb->aio_nbytes;
- bp->b_bufsize = cb->aio_nbytes;
- bp->b_iodone = aio_physwakeup;
- bp->b_saveaddr = bp->b_data;
- bp->b_data = (void *)(uintptr_t)cb->aio_buf;
- bp->b_offset = cb->aio_offset;
- bp->b_iooffset = cb->aio_offset;
- bp->b_blkno = btodb(cb->aio_offset);
- bp->b_iocmd = cb->aio_lio_opcode == LIO_WRITE ? BIO_WRITE : BIO_READ;
-
- /*
- * Bring buffer into kernel space.
- */
- if (vmapbuf(bp, (dev->si_flags & SI_UNMAPPED) == 0) < 0) {
- error = EFAULT;
- goto doerror;
- }
-
- AIO_LOCK(ki);
- aiocbe->bp = bp;
- bp->b_caller1 = (void *)aiocbe;
TAILQ_INSERT_TAIL(&ki->kaio_bufqueue, aiocbe, plist);
TAILQ_INSERT_TAIL(&ki->kaio_all, aiocbe, allist);
aiocbe->jobstate = JOBST_JOBQBUF;
cb->_aiocb_private.status = cb->aio_nbytes;
AIO_UNLOCK(ki);
- atomic_add_int(&num_queue_count, 1);
- atomic_add_int(&num_buf_aio, 1);
-
- bp->b_error = 0;
+ bp->bio_length = cb->aio_nbytes;
+ bp->bio_bcount = cb->aio_nbytes;
+ bp->bio_done = aio_physwakeup;
+ bp->bio_data = (void *)(uintptr_t)cb->aio_buf;
+ bp->bio_offset = cb->aio_offset;
+ bp->bio_cmd = cb->aio_lio_opcode == LIO_WRITE ? BIO_WRITE : BIO_READ;
+ bp->bio_dev = dev;
+ bp->bio_caller1 = (void *)aiocbe;
+
+ prot = VM_PROT_READ;
+ if (cb->aio_lio_opcode == LIO_READ)
+ prot |= VM_PROT_WRITE; /* Less backwards than it looks */
+ if ((aiocbe->npages = vm_fault_quick_hold_pages(
+ &curproc->p_vmspace->vm_map,
+ (vm_offset_t)bp->bio_data, bp->bio_length, prot, aiocbe->pages,
+ sizeof(aiocbe->pages)/sizeof(aiocbe->pages[0]))) < 0) {
+ error = EFAULT;
+ goto doerror;
+ }
+ if (!unmap) {
+ pmap_qenter((vm_offset_t)pbuf->b_data,
+ aiocbe->pages, aiocbe->npages);
+ bp->bio_data = pbuf->b_data + poff;
+ } else {
+ bp->bio_ma = aiocbe->pages;
+ bp->bio_ma_n = aiocbe->npages;
+ bp->bio_ma_offset = poff;
+ bp->bio_data = unmapped_buf;
+ bp->bio_flags |= BIO_UNMAPPED;
+ }
- TASK_INIT(&aiocbe->biotask, 0, biohelper, aiocbe);
+ atomic_add_int(&num_queue_count, 1);
+ if (!unmap)
+ atomic_add_int(&num_buf_aio, 1);
/* Perform transfer. */
- dev_strategy_csw(dev, csw, bp);
+ csw->d_strategy(bp);
dev_relthread(dev, ref);
return (0);
doerror:
AIO_LOCK(ki);
+ aiocbe->jobstate = JOBST_NULL;
+ TAILQ_REMOVE(&ki->kaio_bufqueue, aiocbe, plist);
+ TAILQ_REMOVE(&ki->kaio_all, aiocbe, allist);
ki->kaio_count--;
- ki->kaio_buffer_count--;
+ if (!unmap)
+ ki->kaio_buffer_count--;
if (lj)
lj->lioj_count--;
- aiocbe->bp = NULL;
AIO_UNLOCK(ki);
- relpbuf(bp, NULL);
+ if (pbuf) {
+ relpbuf(pbuf, NULL);
+ aiocbe->pbuf = NULL;
+ }
+ g_destroy_bio(bp);
+ aiocbe->bp = NULL;
unref:
dev_relthread(dev, ref);
return (error);
@@ -1787,8 +1804,6 @@ no_kqueue:
}
#endif
queueit:
- /* No buffer for daemon I/O. */
- aiocbe->bp = NULL;
atomic_add_int(&num_queue_count, 1);
AIO_LOCK(ki);
@@ -2425,54 +2440,43 @@ sys_lio_listio(struct thread *td, struct lio_listio_args *uap)
return (error);
}
-/*
- * Called from interrupt thread for physio, we should return as fast
- * as possible, so we schedule a biohelper task.
- */
static void
-aio_physwakeup(struct buf *bp)
+aio_physwakeup(struct bio *bp)
{
- struct aiocblist *aiocbe;
-
- aiocbe = (struct aiocblist *)bp->b_caller1;
- taskqueue_enqueue(taskqueue_aiod_bio, &aiocbe->biotask);
-}
-
-/*
- * Task routine to perform heavy tasks, process wakeup, and signals.
- */
-static void
-biohelper(void *context, int pending)
-{
- struct aiocblist *aiocbe = context;
- struct buf *bp;
+ struct aiocblist *aiocbe = (struct aiocblist *)bp->bio_caller1;
struct proc *userp;
struct kaioinfo *ki;
int nblks;
+ /* Release mapping into kernel space. */
+ if (aiocbe->pbuf) {
+ pmap_qremove((vm_offset_t)aiocbe->pbuf->b_data, aiocbe->npages);
+ relpbuf(aiocbe->pbuf, NULL);
+ aiocbe->pbuf = NULL;
+ atomic_subtract_int(&num_buf_aio, 1);
+ }
+ vm_page_unhold_pages(aiocbe->pages, aiocbe->npages);
+
bp = aiocbe->bp;
+ aiocbe->bp = NULL;
userp = aiocbe->userproc;
ki = userp->p_aioinfo;
AIO_LOCK(ki);
- aiocbe->uaiocb._aiocb_private.status -= bp->b_resid;
+ aiocbe->uaiocb._aiocb_private.status -= bp->bio_resid;
aiocbe->uaiocb._aiocb_private.error = 0;
- if (bp->b_ioflags & BIO_ERROR)
- aiocbe->uaiocb._aiocb_private.error = bp->b_error;
+ if (bp->bio_flags & BIO_ERROR)
+ aiocbe->uaiocb._aiocb_private.error = bp->bio_error;
nblks = btodb(aiocbe->uaiocb.aio_nbytes);
if (aiocbe->uaiocb.aio_lio_opcode == LIO_WRITE)
aiocbe->outputcharge += nblks;
else
aiocbe->inputcharge += nblks;
- aiocbe->bp = NULL;
TAILQ_REMOVE(&userp->p_aioinfo->kaio_bufqueue, aiocbe, plist);
ki->kaio_buffer_count--;
aio_bio_done_notify(userp, aiocbe, DONE_BUF);
AIO_UNLOCK(ki);
- /* Release mapping into kernel space. */
- vunmapbuf(bp);
- relpbuf(bp, NULL);
- atomic_subtract_int(&num_buf_aio, 1);
+ g_destroy_bio(bp);
}
/* syscall - wait for the next completion of an aio request */
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index dfe2997bb400..5ac04acfb0d9 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -113,8 +113,8 @@ static void vfs_setdirty_locked_object(struct buf *bp);
static void vfs_vmio_release(struct buf *bp);
static int vfs_bio_clcheck(struct vnode *vp, int size,
daddr_t lblkno, daddr_t blkno);
-static int buf_flush(int);
-static int flushbufqueues(int, int);
+static int buf_flush(struct vnode *vp, int);
+static int flushbufqueues(struct vnode *, int, int);
static void buf_daemon(void);
static void bremfreel(struct buf *bp);
static __inline void bd_wakeup(void);
@@ -805,6 +805,7 @@ bufinit(void)
struct buf *bp;
int i;
+ CTASSERT(MAXBCACHEBUF >= MAXBSIZE);
mtx_init(&bqclean, "bufq clean lock", NULL, MTX_DEF);
mtx_init(&bqdirty, "bufq dirty lock", NULL, MTX_DEF);
mtx_init(&rbreqlock, "runningbufspace lock", NULL, MTX_DEF);
@@ -846,8 +847,8 @@ bufinit(void)
* by the system.
*/
maxbufspace = (long)nbuf * BKVASIZE;
- hibufspace = lmax(3 * maxbufspace / 4, maxbufspace - MAXBSIZE * 10);
- lobufspace = hibufspace - MAXBSIZE;
+ hibufspace = lmax(3 * maxbufspace / 4, maxbufspace - MAXBCACHEBUF * 10);
+ lobufspace = hibufspace - MAXBCACHEBUF;
/*
* Note: The 16 MiB upper limit for hirunningspace was chosen
@@ -857,9 +858,9 @@ bufinit(void)
* The lower 1 MiB limit is the historical upper limit for
* hirunningspace.
*/
- hirunningspace = lmax(lmin(roundup(hibufspace / 64, MAXBSIZE),
+ hirunningspace = lmax(lmin(roundup(hibufspace / 64, MAXBCACHEBUF),
16 * 1024 * 1024), 1024 * 1024);
- lorunningspace = roundup((hirunningspace * 2) / 3, MAXBSIZE);
+ lorunningspace = roundup((hirunningspace * 2) / 3, MAXBCACHEBUF);
/*
* Limit the amount of malloc memory since it is wired permanently into
@@ -2096,7 +2097,7 @@ getnewbuf_bufd_help(struct vnode *vp, int gbflags, int slpflag, int slptimeo,
{
struct thread *td;
char *waitmsg;
- int cnt, error, flags, norunbuf, wait;
+ int error, fl, flags, norunbuf;
mtx_assert(&bqclean, MA_OWNED);
@@ -2118,8 +2119,6 @@ getnewbuf_bufd_help(struct vnode *vp, int gbflags, int slpflag, int slptimeo,
return;
td = curthread;
- cnt = 0;
- wait = MNT_NOWAIT;
rw_wlock(&nblock);
while ((needsbuffer & flags) != 0) {
if (vp != NULL && vp->v_type != VCHR &&
@@ -2133,20 +2132,23 @@ getnewbuf_bufd_help(struct vnode *vp, int gbflags, int slpflag, int slptimeo,
* cannot be achieved by the buf_daemon, that
* cannot lock the vnode.
*/
- if (cnt++ > 2)
- wait = MNT_WAIT;
- ASSERT_VOP_LOCKED(vp, "bufd_helper");
- error = VOP_ISLOCKED(vp) == LK_EXCLUSIVE ? 0 :
- vn_lock(vp, LK_TRYUPGRADE);
- if (error == 0) {
- /* play bufdaemon */
- norunbuf = curthread_pflags_set(TDP_BUFNEED |
- TDP_NORUNNINGBUF);
- VOP_FSYNC(vp, wait, td);
- atomic_add_long(&notbufdflushes, 1);
- curthread_pflags_restore(norunbuf);
- }
+ norunbuf = ~(TDP_BUFNEED | TDP_NORUNNINGBUF) |
+ (td->td_pflags & TDP_NORUNNINGBUF);
+
+ /*
+ * Play bufdaemon. The getnewbuf() function
+ * may be called while the thread owns lock
+ * for another dirty buffer for the same
+ * vnode, which makes it impossible to use
+ * VOP_FSYNC() there, due to the buffer lock
+ * recursion.
+ */
+ td->td_pflags |= TDP_BUFNEED | TDP_NORUNNINGBUF;
+ fl = buf_flush(vp, flushbufqtarget);
+ td->td_pflags &= norunbuf;
rw_wlock(&nblock);
+ if (fl != 0)
+ continue;
if ((needsbuffer & flags) == 0)
break;
}
@@ -2565,18 +2567,20 @@ static struct kproc_desc buf_kp = {
SYSINIT(bufdaemon, SI_SUB_KTHREAD_BUF, SI_ORDER_FIRST, kproc_start, &buf_kp);
static int
-buf_flush(int target)
+buf_flush(struct vnode *vp, int target)
{
int flushed;
- flushed = flushbufqueues(target, 0);
+ flushed = flushbufqueues(vp, target, 0);
if (flushed == 0) {
/*
* Could not find any buffers without rollback
* dependencies, so just write the first one
* in the hopes of eventually making progress.
*/
- flushed = flushbufqueues(target, 1);
+ if (vp != NULL && target > 2)
+ target /= 2;
+ flushbufqueues(vp, target, 1);
}
return (flushed);
}
@@ -2613,7 +2617,7 @@ buf_daemon()
* the I/O system.
*/
while (numdirtybuffers > lodirty) {
- if (buf_flush(numdirtybuffers - lodirty) == 0)
+ if (buf_flush(NULL, numdirtybuffers - lodirty) == 0)
break;
kern_yield(PRI_USER);
}
@@ -2668,7 +2672,7 @@ SYSCTL_INT(_vfs, OID_AUTO, flushwithdeps, CTLFLAG_RW, &flushwithdeps,
0, "Number of buffers flushed with dependecies that require rollbacks");
static int
-flushbufqueues(int target, int flushdeps)
+flushbufqueues(struct vnode *lvp, int target, int flushdeps)
{
struct buf *sentinel;
struct vnode *vp;
@@ -2678,6 +2682,7 @@ flushbufqueues(int target, int flushdeps)
int flushed;
int queue;
int error;
+ bool unlock;
flushed = 0;
queue = QUEUE_DIRTY;
@@ -2699,8 +2704,18 @@ flushbufqueues(int target, int flushdeps)
mtx_unlock(&bqdirty);
break;
}
- KASSERT(bp->b_qindex != QUEUE_SENTINEL,
- ("parallel calls to flushbufqueues() bp %p", bp));
+ /*
+ * Skip sentinels inserted by other invocations of the
+ * flushbufqueues(), taking care to not reorder them.
+ *
+ * Only flush the buffers that belong to the
+ * vnode locked by the curthread.
+ */
+ if (bp->b_qindex == QUEUE_SENTINEL || (lvp != NULL &&
+ bp->b_vp != lvp)) {
+ mtx_unlock(&bqdirty);
+ continue;
+ }
error = BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL);
mtx_unlock(&bqdirty);
if (error != 0)
@@ -2748,16 +2763,37 @@ flushbufqueues(int target, int flushdeps)
BUF_UNLOCK(bp);
continue;
}
- error = vn_lock(vp, LK_EXCLUSIVE | LK_NOWAIT);
+ if (lvp == NULL) {
+ unlock = true;
+ error = vn_lock(vp, LK_EXCLUSIVE | LK_NOWAIT);
+ } else {
+ ASSERT_VOP_LOCKED(vp, "getbuf");
+ unlock = false;
+ error = VOP_ISLOCKED(vp) == LK_EXCLUSIVE ? 0 :
+ vn_lock(vp, LK_TRYUPGRADE);
+ }
if (error == 0) {
CTR3(KTR_BUF, "flushbufqueue(%p) vp %p flags %X",
bp, bp->b_vp, bp->b_flags);
- vfs_bio_awrite(bp);
+ if (curproc == bufdaemonproc) {
+ vfs_bio_awrite(bp);
+ } else {
+ bremfree(bp);
+ bwrite(bp);
+ notbufdflushes++;
+ }
vn_finished_write(mp);
- VOP_UNLOCK(vp, 0);
+ if (unlock)
+ VOP_UNLOCK(vp, 0);
flushwithdeps += hasdeps;
flushed++;
- if (runningbufspace > hirunningspace)
+
+ /*
+ * Sleeping on runningbufspace while holding
+ * vnode lock leads to deadlock.
+ */
+ if (curproc == bufdaemonproc &&
+ runningbufspace > hirunningspace)
waitrunningbufspace();
continue;
}
@@ -3073,8 +3109,9 @@ getblk(struct vnode *vp, daddr_t blkno, int size, int slpflag, int slptimeo,
KASSERT((flags & (GB_UNMAPPED | GB_KVAALLOC)) != GB_KVAALLOC,
("GB_KVAALLOC only makes sense with GB_UNMAPPED"));
ASSERT_VOP_LOCKED(vp, "getblk");
- if (size > MAXBSIZE)
- panic("getblk: size(%d) > MAXBSIZE(%d)\n", size, MAXBSIZE);
+ if (size > MAXBCACHEBUF)
+ panic("getblk: size(%d) > MAXBCACHEBUF(%d)\n", size,
+ MAXBCACHEBUF);
if (!unmapped_buf_allowed)
flags &= ~(GB_UNMAPPED | GB_KVAALLOC);
diff --git a/sys/net/zlib.c b/sys/libkern/zlib.c
index b3482483d334..f5c3854800e3 100644
--- a/sys/net/zlib.c
+++ b/sys/libkern/zlib.c
@@ -54,7 +54,7 @@
#define _Z_UTIL_H
#ifdef _KERNEL
-#include <net/zlib.h>
+#include <sys/zlib.h>
#else
#include "zlib.h"
#endif
diff --git a/sys/mips/mips/busdma_machdep.c b/sys/mips/mips/busdma_machdep.c
index 083e8f534290..90ec3994c285 100644
--- a/sys/mips/mips/busdma_machdep.c
+++ b/sys/mips/mips/busdma_machdep.c
@@ -1359,8 +1359,8 @@ add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr,
if (dmat->flags & BUS_DMA_KEEP_PG_OFFSET) {
/* Page offset needs to be preserved. */
- bpage->vaddr |= vaddr & PAGE_MASK;
- bpage->busaddr |= vaddr & PAGE_MASK;
+ bpage->vaddr |= addr & PAGE_MASK;
+ bpage->busaddr |= addr & PAGE_MASK;
}
bpage->datavaddr = vaddr;
bpage->dataaddr = addr;
diff --git a/sys/modules/ix/Makefile b/sys/modules/ix/Makefile
index 5a5485d4036c..1f30cb0795df 100644
--- a/sys/modules/ix/Makefile
+++ b/sys/modules/ix/Makefile
@@ -9,7 +9,7 @@ SRCS += if_ix.c ix_txrx.c
# Shared source
SRCS += ixgbe_common.c ixgbe_api.c ixgbe_phy.c ixgbe_mbx.c ixgbe_vf.c
SRCS += ixgbe_dcb.c ixgbe_dcb_82598.c ixgbe_dcb_82599.c
-SRCS += ixgbe_82599.c ixgbe_82598.c ixgbe_x540.c
+SRCS += ixgbe_82598.c ixgbe_82599.c ixgbe_x540.c ixgbe_x550.c
CFLAGS+= -I${.CURDIR}/../../dev/ixgbe -DSMP
.include <bsd.kmod.mk>
diff --git a/sys/modules/ixv/Makefile b/sys/modules/ixv/Makefile
index 20ecaf14f79e..f8ce347d3128 100644
--- a/sys/modules/ixv/Makefile
+++ b/sys/modules/ixv/Makefile
@@ -9,7 +9,7 @@ SRCS += if_ixv.c ix_txrx.c
# Shared source
SRCS += ixgbe_common.c ixgbe_api.c ixgbe_phy.c ixgbe_mbx.c ixgbe_vf.c
SRCS += ixgbe_dcb.c ixgbe_dcb_82598.c ixgbe_dcb_82599.c
-SRCS += ixgbe_82599.c ixgbe_82598.c ixgbe_x540.c
+SRCS += ixgbe_82598.c ixgbe_82599.c ixgbe_x540.c ixgbe_x550.c
CFLAGS+= -I${.CURDIR}/../../dev/ixgbe -DSMP
.include <bsd.kmod.mk>
diff --git a/sys/modules/oce/Makefile b/sys/modules/oce/Makefile
index 4821533f01c5..95e828d5318e 100644
--- a/sys/modules/oce/Makefile
+++ b/sys/modules/oce/Makefile
@@ -3,7 +3,7 @@
#
.PATH: ${.CURDIR}/../../dev/oce
-KMOD = oce
+KMOD = if_oce
SRCS = oce_if.c oce_hw.c oce_mbox.c oce_util.c oce_queue.c oce_sysctl.c
SRCS += bus_if.h device_if.h pci_if.h opt_inet.h opt_inet6.h
diff --git a/sys/modules/zlib/Makefile b/sys/modules/zlib/Makefile
index 0a475b55fce3..235d1c7c3cb2 100644
--- a/sys/modules/zlib/Makefile
+++ b/sys/modules/zlib/Makefile
@@ -1,6 +1,6 @@
# $FreeBSD$
-.PATH: ${.CURDIR}/../../net
+.PATH: ${.CURDIR}/../../libkern
KMOD= zlib
SRCS= zlib.c
diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c
index 0753e0abab7a..462c9078fbc1 100644
--- a/sys/net/if_vlan.c
+++ b/sys/net/if_vlan.c
@@ -1705,27 +1705,6 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
}
break;
- case SIOCSIFCAP:
- VLAN_LOCK();
- if (TRUNK(ifv) != NULL) {
- p = PARENT(ifv);
- VLAN_UNLOCK();
- if ((p->if_type != IFT_ETHER) &&
- (ifr->ifr_reqcap & IFCAP_VLAN_HWTAGGING) == 0) {
- error = EINVAL;
- break;
- }
- error = (*p->if_ioctl)(p, cmd, data);
- if (error)
- break;
- /* Propogate vlan interface capabilities */
- vlan_trunk_capabilities(p);
- } else {
- VLAN_UNLOCK();
- error = EINVAL;
- }
- break;
-
default:
error = EINVAL;
break;
diff --git a/sys/net/netisr.c b/sys/net/netisr.c
index 178c3cbd1479..4b3576ded2ae 100644
--- a/sys/net/netisr.c
+++ b/sys/net/netisr.c
@@ -156,10 +156,13 @@ SYSCTL_PROC(_net_isr, OID_AUTO, dispatch, CTLTYPE_STRING | CTLFLAG_RWTUN,
/*
* Allow the administrator to limit the number of threads (CPUs) to use for
* netisr. We don't check netisr_maxthreads before creating the thread for
- * CPU 0, so in practice we ignore values <= 1. This must be set at boot.
- * We will create at most one thread per CPU.
+ * CPU 0. This must be set at boot. We will create at most one thread per CPU.
+ * By default we initialize this to 1 which would assign just 1 cpu (cpu0) and
+ * therefore only 1 workstream. If set to -1, netisr would use all cpus
+ * (mp_ncpus) and therefore would have those many workstreams. One workstream
+ * per thread (CPU).
*/
-static int netisr_maxthreads = -1; /* Max number of threads. */
+static int netisr_maxthreads = 1; /* Max number of threads. */
SYSCTL_INT(_net_isr, OID_AUTO, maxthreads, CTLFLAG_RDTUN,
&netisr_maxthreads, 0,
"Use at most this many CPUs for netisr processing");
@@ -1120,8 +1123,10 @@ netisr_init(void *arg)
KASSERT(curcpu == 0, ("%s: not on CPU 0", __func__));
NETISR_LOCK_INIT();
- if (netisr_maxthreads < 1)
- netisr_maxthreads = 1;
+ if (netisr_maxthreads == 0 || netisr_maxthreads < -1 )
+ netisr_maxthreads = 1; /* default behavior */
+ else if (netisr_maxthreads == -1)
+ netisr_maxthreads = mp_ncpus; /* use max cpus */
if (netisr_maxthreads > mp_ncpus) {
printf("netisr_init: forcing maxthreads from %d to %d\n",
netisr_maxthreads, mp_ncpus);
diff --git a/sys/netgraph/ng_deflate.c b/sys/netgraph/ng_deflate.c
index da68e49d24a8..be5294236150 100644
--- a/sys/netgraph/ng_deflate.c
+++ b/sys/netgraph/ng_deflate.c
@@ -39,8 +39,7 @@
#include <sys/endian.h>
#include <sys/errno.h>
#include <sys/syslog.h>
-
-#include <net/zlib.h>
+#include <sys/zlib.h>
#include <netgraph/ng_message.h>
#include <netgraph/netgraph.h>
diff --git a/sys/netinet/in_kdtrace.c b/sys/netinet/in_kdtrace.c
index d37e3c09ce28..edcc85383a45 100644
--- a/sys/netinet/in_kdtrace.c
+++ b/sys/netinet/in_kdtrace.c
@@ -102,6 +102,9 @@ SDT_PROBE_DEFINE5_XLATE(tcp, , , send,
"struct tcpcb *", "tcpsinfo_t *" ,
"struct tcphdr *", "tcpinfo_t *");
+SDT_PROBE_DEFINE1_XLATE(tcp, , , siftr,
+ "struct pkt_node *", "siftrinfo_t *");
+
SDT_PROBE_DEFINE6_XLATE(tcp, , , state__change,
"void *", "void *",
"struct tcpcb *", "csinfo_t *",
diff --git a/sys/netinet/in_kdtrace.h b/sys/netinet/in_kdtrace.h
index 07b3e3a4ca70..c0511d084b77 100644
--- a/sys/netinet/in_kdtrace.h
+++ b/sys/netinet/in_kdtrace.h
@@ -32,6 +32,8 @@
SDT_PROBE6(ip, , , probe, arg0, arg1, arg2, arg3, arg4, arg5)
#define UDP_PROBE(probe, arg0, arg1, arg2, arg3, arg4) \
SDT_PROBE5(udp, , , probe, arg0, arg1, arg2, arg3, arg4)
+#define TCP_PROBE1(probe, arg0) \
+ SDT_PROBE1(tcp, , , probe, arg0)
#define TCP_PROBE5(probe, arg0, arg1, arg2, arg3, arg4) \
SDT_PROBE5(tcp, , , probe, arg0, arg1, arg2, arg3, arg4)
#define TCP_PROBE6(probe, arg0, arg1, arg2, arg3, arg4, arg5) \
@@ -51,6 +53,7 @@ SDT_PROBE_DECLARE(tcp, , , connect__refused);
SDT_PROBE_DECLARE(tcp, , , connect__request);
SDT_PROBE_DECLARE(tcp, , , receive);
SDT_PROBE_DECLARE(tcp, , , send);
+SDT_PROBE_DECLARE(tcp, , , siftr);
SDT_PROBE_DECLARE(tcp, , , state__change);
SDT_PROBE_DECLARE(udp, , , receive);
diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h
index 9c53793126f3..d1764bbf5f1a 100644
--- a/sys/netinet/ip_fw.h
+++ b/sys/netinet/ip_fw.h
@@ -40,10 +40,12 @@
#define IPFW_MAX_SETS 32 /* Number of sets supported by ipfw*/
/*
- * Default number of ipfw tables.
+ * Compat values for old clients
*/
+#ifndef _KERNEL
#define IPFW_TABLES_MAX 65535
#define IPFW_TABLES_DEFAULT 128
+#endif
/*
* Most commands (queue, pipe, tag, untag, limit...) can have a 16-bit
@@ -963,7 +965,6 @@ typedef struct _ipfw_ta_info {
uint64_t spare1;
} ipfw_ta_info;
-#define IPFW_OBJTYPE_TABLE 1
typedef struct _ipfw_obj_header {
ip_fw3_opheader opheader; /* IP_FW3 opcode */
uint32_t spare;
diff --git a/sys/netinet/ip_ipsec.c b/sys/netinet/ip_ipsec.c
index 1a643fb73bfd..47f683ddd71c 100644
--- a/sys/netinet/ip_ipsec.c
+++ b/sys/netinet/ip_ipsec.c
@@ -199,6 +199,9 @@ ip_ipsec_output(struct mbuf **m, struct inpcb *inp, int *error)
/* NB: callee frees mbuf */
*error = ipsec4_process_packet(*m, sp->req);
+ /* Release SP if an error occured */
+ if (*error != 0)
+ KEY_FREESP(&sp);
if (*error == EJUSTRETURN) {
/*
* We had a SP with a level of 'use' and no SA. We
@@ -234,13 +237,9 @@ ip_ipsec_output(struct mbuf **m, struct inpcb *inp, int *error)
/* No IPsec processing for this packet. */
}
done:
- if (sp != NULL)
- KEY_FREESP(&sp);
- return 0;
+ return (0);
reinjected:
- if (sp != NULL)
- KEY_FREESP(&sp);
- return -1;
+ return (-1);
bad:
if (sp != NULL)
KEY_FREESP(&sp);
diff --git a/sys/netinet/libalias/libalias.3 b/sys/netinet/libalias/libalias.3
index 45e7fa4c4ced..543420b87db0 100644
--- a/sys/netinet/libalias/libalias.3
+++ b/sys/netinet/libalias/libalias.3
@@ -173,10 +173,12 @@ Mainly useful for debugging when the log file is viewed continuously with
.It Dv PKT_ALIAS_DENY_INCOMING
If this mode bit is set, all incoming packets associated with new TCP
connections or new UDP transactions will be marked for being ignored
-.Fn ( LibAliasIn
+.Po
+.Fn LibAliasIn
returns
.Dv PKT_ALIAS_IGNORED
-code)
+code
+.Pc
by the calling program.
Response packets to connections or transactions initiated from the packet
aliasing host or local network will be unaffected.
@@ -1001,7 +1003,7 @@ If this results in a conflict, then port numbers are randomly chosen until
a unique aliasing link can be established.
In an alternate operating mode, the first choice of an aliasing port is also
random and unrelated to the local port number.
-.Sh MODULAR ARCHITECTURE (AND Xr ipfw 4 Sh SUPPORT)
+.Sh MODULAR ARCHITECTURE Po AND Xr ipfw 4 SUPPORT Pc
One of the latest improvements to
.Nm
was to make its support
diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c
index ea3d3e7894db..d3b485560305 100644
--- a/sys/netinet/sctp_indata.c
+++ b/sys/netinet/sctp_indata.c
@@ -3614,24 +3614,17 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
send_s = asoc->sending_seq;
}
if (SCTP_TSN_GE(cumack, send_s)) {
-#ifndef INVARIANTS
struct mbuf *op_err;
char msg[SCTP_DIAG_INFO_LEN];
-#endif
-#ifdef INVARIANTS
- panic("Impossible sack 1");
-#else
-
*abort_now = 1;
/* XXX */
- snprintf(msg, sizeof(msg), "Cum ack %8.8x greater or equal then TSN %8.8x",
+ snprintf(msg, sizeof(msg), "Cum ack %8.8x greater or equal than TSN %8.8x",
cumack, send_s);
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_25;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
return;
-#endif
}
}
asoc->this_sack_highest_gap = cumack;
@@ -4195,7 +4188,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
hopeless_peer:
*abort_now = 1;
/* XXX */
- snprintf(msg, sizeof(msg), "Cum ack %8.8x greater or equal then TSN %8.8x",
+ snprintf(msg, sizeof(msg), "Cum ack %8.8x greater or equal than TSN %8.8x",
cum_ack, send_s);
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_25;
diff --git a/sys/netinet/siftr.c b/sys/netinet/siftr.c
index 2cd58ad09b48..6b31d7b6a8e5 100644
--- a/sys/netinet/siftr.c
+++ b/sys/netinet/siftr.c
@@ -75,6 +75,7 @@ __FBSDID("$FreeBSD$");
#include <sys/pcpu.h>
#include <sys/proc.h>
#include <sys/sbuf.h>
+#include <sys/sdt.h>
#include <sys/smp.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
@@ -86,6 +87,7 @@ __FBSDID("$FreeBSD$");
#include <net/pfil.h>
#include <netinet/in.h>
+#include <netinet/in_kdtrace.h>
#include <netinet/in_pcb.h>
#include <netinet/in_systm.h>
#include <netinet/in_var.h>
@@ -811,6 +813,8 @@ siftr_siftdata(struct pkt_node *pn, struct inpcb *inp, struct tcpcb *tp,
* maximum pps throughput processing when SIFTR is loaded and enabled.
*/
microtime(&pn->tval);
+ TCP_PROBE1(siftr, &pn);
+
}
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index d7da6c6ecd1d..d75221c40735 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -2159,6 +2159,7 @@ tcp_signature_do_compute(struct mbuf *m, int len, int optlen,
break;
#endif
default:
+ KEY_FREESAV(&sav);
return (-1);
/* NOTREACHED */
break;
diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c
index da4861521755..1ba74d86ae68 100644
--- a/sys/netinet/tcp_timewait.c
+++ b/sys/netinet/tcp_timewait.c
@@ -251,6 +251,13 @@ tcp_twstart(struct tcpcb *tp)
}
}
+
+ /*
+ * For use only by DTrace. We do not reference the state
+ * after this point so modifying it in place is not a problem.
+ */
+ tcp_state_change(tp, TCPS_TIME_WAIT);
+
tw = uma_zalloc(V_tcptw_zone, M_NOWAIT);
if (tw == NULL) {
/*
diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c
index 08234d5d6863..83e58c14d70d 100644
--- a/sys/netinet6/ip6_forward.c
+++ b/sys/netinet6/ip6_forward.c
@@ -248,8 +248,7 @@ ip6_forward(struct mbuf *m, int srcrt)
/*
* when the kernel forwards a packet, it is not proper to apply
- * IPsec transport mode to the packet is not proper. this check
- * avoid from this.
+ * IPsec transport mode to the packet. This check avoid from this.
* at present, if there is even a transport mode SA request in the
* security policy, the kernel does not apply IPsec to the packet.
* this check is not enough because the following case is valid.
@@ -283,9 +282,9 @@ ip6_forward(struct mbuf *m, int srcrt)
* ipsec6_proces_packet will send the packet using ip6_output
*/
error = ipsec6_process_packet(m, sp->req);
-
- KEY_FREESP(&sp);
-
+ /* Release SP if an error occured */
+ if (error != 0)
+ KEY_FREESP(&sp);
if (error == EJUSTRETURN) {
/*
* We had a SP with a level of 'use' and no SA. We
diff --git a/sys/netinet6/ip6_ipsec.c b/sys/netinet6/ip6_ipsec.c
index 0a416cdd049b..e6e16eda2d95 100644
--- a/sys/netinet6/ip6_ipsec.c
+++ b/sys/netinet6/ip6_ipsec.c
@@ -213,7 +213,9 @@ ip6_ipsec_output(struct mbuf **m, struct inpcb *inp, int *error)
/* NB: callee frees mbuf */
*error = ipsec6_process_packet(*m, sp->req);
-
+ /* Release SP if an error occured */
+ if (*error != 0)
+ KEY_FREESP(&sp);
if (*error == EJUSTRETURN) {
/*
* We had a SP with a level of 'use' and no SA. We
@@ -249,13 +251,9 @@ ip6_ipsec_output(struct mbuf **m, struct inpcb *inp, int *error)
/* No IPsec processing for this packet. */
}
done:
- if (sp != NULL)
- KEY_FREESP(&sp);
- return 0;
+ return (0);
reinjected:
- if (sp != NULL)
- KEY_FREESP(&sp);
- return -1;
+ return (-1);
bad:
if (sp != NULL)
KEY_FREESP(&sp);
diff --git a/sys/netipsec/ipsec.c b/sys/netipsec/ipsec.c
index abad3d2048ab..266f6d00d5a0 100644
--- a/sys/netipsec/ipsec.c
+++ b/sys/netipsec/ipsec.c
@@ -238,6 +238,7 @@ SYSCTL_VNET_PCPUSTAT(_net_inet6_ipsec6, IPSECCTL_STATS, ipsecstats,
struct ipsecstat, ipsec6stat, "IPsec IPv6 statistics.");
#endif /* INET6 */
+static int ipsec_in_reject(struct secpolicy *, struct mbuf *);
static int ipsec_setspidx_inpcb(struct mbuf *, struct inpcb *);
static int ipsec_setspidx(struct mbuf *, struct secpolicyindex *, int);
static void ipsec4_get_ulp(struct mbuf *m, struct secpolicyindex *, int);
@@ -1191,7 +1192,7 @@ ipsec_get_reqlevel(struct ipsecrequest *isr)
* 0: valid
* 1: invalid
*/
-int
+static int
ipsec_in_reject(struct secpolicy *sp, struct mbuf *m)
{
struct ipsecrequest *isr;
diff --git a/sys/netipsec/ipsec.h b/sys/netipsec/ipsec.h
index 7f4c25ede16f..442387aefe44 100644
--- a/sys/netipsec/ipsec.h
+++ b/sys/netipsec/ipsec.h
@@ -309,7 +309,6 @@ struct inpcb;
extern int ipsec_init_policy(struct socket *so, struct inpcbpolicy **);
extern int ipsec_copy_policy(struct inpcbpolicy *, struct inpcbpolicy *);
extern u_int ipsec_get_reqlevel(struct ipsecrequest *);
-extern int ipsec_in_reject(struct secpolicy *, struct mbuf *);
extern int ipsec_set_policy(struct inpcb *inp, int optname,
caddr_t request, size_t len, struct ucred *cred);
diff --git a/sys/netipsec/ipsec_input.c b/sys/netipsec/ipsec_input.c
index 6c5278185bf0..583769952ff7 100644
--- a/sys/netipsec/ipsec_input.c
+++ b/sys/netipsec/ipsec_input.c
@@ -391,6 +391,7 @@ ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip,
ipsec_bpf(m, sav, AF_INET, ENC_IN|ENC_BEFORE);
if ((error = ipsec_filter(&m, PFIL_IN, ENC_IN|ENC_BEFORE)) != 0)
return (error);
+ ip = mtod(m, struct ip *);
#endif /* DEV_ENC */
/* IP-in-IP encapsulation */
diff --git a/sys/netipsec/ipsec_output.c b/sys/netipsec/ipsec_output.c
index 583f4b0cffe5..ae360700b629 100644
--- a/sys/netipsec/ipsec_output.c
+++ b/sys/netipsec/ipsec_output.c
@@ -104,6 +104,7 @@ ipsec_process_done(struct mbuf *m, struct ipsecrequest *isr)
IPSEC_ASSERT(m != NULL, ("null mbuf"));
IPSEC_ASSERT(isr != NULL, ("null ISR"));
+ IPSEC_ASSERT(isr->sp != NULL, ("NULL isr->sp"));
sav = isr->sav;
IPSEC_ASSERT(sav != NULL, ("null SA"));
IPSEC_ASSERT(sav->sah != NULL, ("null SAH"));
@@ -163,6 +164,10 @@ ipsec_process_done(struct mbuf *m, struct ipsecrequest *isr)
* If this is a problem we'll need to introduce a queue
* to set the packet on so we can unwind the stack before
* doing further processing.
+ *
+ * If ipsec[46]_process_packet() will successfully queue
+ * the request, we need to take additional reference to SP,
+ * because xform callback will release reference.
*/
if (isr->next) {
/* XXX-BZ currently only support same AF bundles. */
@@ -170,7 +175,11 @@ ipsec_process_done(struct mbuf *m, struct ipsecrequest *isr)
#ifdef INET
case AF_INET:
IPSECSTAT_INC(ips_out_bundlesa);
- return ipsec4_process_packet(m, isr->next);
+ key_addref(isr->sp);
+ error = ipsec4_process_packet(m, isr->next);
+ if (error != 0)
+ KEY_FREESP(&isr->sp);
+ return (error);
/* NOTREACHED */
#endif
#ifdef notyet
@@ -178,7 +187,11 @@ ipsec_process_done(struct mbuf *m, struct ipsecrequest *isr)
case AF_INET6:
/* XXX */
IPSEC6STAT_INC(ips_out_bundlesa);
- return ipsec6_process_packet(m, isr->next);
+ key_addref(isr->sp);
+ error = ipsec6_process_packet(m, isr->next);
+ if (error != 0)
+ KEY_FREESP(&isr->sp);
+ return (error);
/* NOTREACHED */
#endif /* INET6 */
#endif
@@ -193,8 +206,7 @@ ipsec_process_done(struct mbuf *m, struct ipsecrequest *isr)
/*
* We're done with IPsec processing, transmit the packet using the
- * appropriate network protocol (IP or IPv6). SPD lookup will be
- * performed again there.
+ * appropriate network protocol (IP or IPv6).
*/
switch (saidx->dst.sa.sa_family) {
#ifdef INET
@@ -565,6 +577,7 @@ ipsec4_process_packet(struct mbuf *m, struct ipsecrequest *isr)
/* pass the mbuf to enc0 for packet filtering */
if ((error = ipsec_filter(&m, PFIL_OUT, ENC_OUT|ENC_BEFORE)) != 0)
goto bad;
+ ip = mtod(m, struct ip *);
#endif
/* Do the appropriate encapsulation, if necessary */
if (isr->saidx.mode == IPSEC_MODE_TUNNEL || /* Tunnel requ'd */
@@ -686,6 +699,7 @@ ipsec6_process_packet(struct mbuf *m, struct ipsecrequest *isr)
/* pass the mbuf to enc0 for packet filtering */
if ((error = ipsec_filter(&m, PFIL_OUT, ENC_OUT|ENC_BEFORE)) != 0)
goto bad;
+ ip6 = mtod(m, struct ip6_hdr *);
#endif /* DEV_ENC */
/* Do the appropriate encapsulation, if necessary */
diff --git a/sys/netipsec/xform_ah.c b/sys/netipsec/xform_ah.c
index cb257a5800d9..8f791dbde0c9 100644
--- a/sys/netipsec/xform_ah.c
+++ b/sys/netipsec/xform_ah.c
@@ -1091,6 +1091,7 @@ ah_output_cb(struct cryptop *crp)
m = (struct mbuf *) crp->crp_buf;
isr = tc->tc_isr;
+ IPSEC_ASSERT(isr->sp != NULL, ("NULL isr->sp"));
IPSECREQUEST_LOCK(isr);
sav = tc->tc_sav;
/* With the isr lock released SA pointer can be updated. */
@@ -1154,16 +1155,18 @@ ah_output_cb(struct cryptop *crp)
error = ipsec_process_done(m, isr);
KEY_FREESAV(&sav);
IPSECREQUEST_UNLOCK(isr);
- return error;
+ KEY_FREESP(&isr->sp);
+ return (error);
bad:
if (sav)
KEY_FREESAV(&sav);
IPSECREQUEST_UNLOCK(isr);
+ KEY_FREESP(&isr->sp);
if (m)
m_freem(m);
free(tc, M_XDATA);
crypto_freereq(crp);
- return error;
+ return (error);
}
static struct xformsw ah_xformsw = {
diff --git a/sys/netipsec/xform_esp.c b/sys/netipsec/xform_esp.c
index 2fbdb816b878..003c5149ddfa 100644
--- a/sys/netipsec/xform_esp.c
+++ b/sys/netipsec/xform_esp.c
@@ -888,6 +888,7 @@ esp_output_cb(struct cryptop *crp)
m = (struct mbuf *) crp->crp_buf;
isr = tc->tc_isr;
+ IPSEC_ASSERT(isr->sp != NULL, ("NULL isr->sp"));
IPSECREQUEST_LOCK(isr);
sav = tc->tc_sav;
/* With the isr lock released SA pointer can be updated. */
@@ -966,16 +967,18 @@ esp_output_cb(struct cryptop *crp)
error = ipsec_process_done(m, isr);
KEY_FREESAV(&sav);
IPSECREQUEST_UNLOCK(isr);
- return error;
+ KEY_FREESP(&isr->sp);
+ return (error);
bad:
if (sav)
KEY_FREESAV(&sav);
IPSECREQUEST_UNLOCK(isr);
+ KEY_FREESP(&isr->sp);
if (m)
m_freem(m);
free(tc, M_XDATA);
crypto_freereq(crp);
- return error;
+ return (error);
}
static struct xformsw esp_xformsw = {
diff --git a/sys/netipsec/xform_ipcomp.c b/sys/netipsec/xform_ipcomp.c
index 5f3afd93832a..ef460cdc90dc 100644
--- a/sys/netipsec/xform_ipcomp.c
+++ b/sys/netipsec/xform_ipcomp.c
@@ -492,6 +492,7 @@ ipcomp_output_cb(struct cryptop *crp)
skip = tc->tc_skip;
isr = tc->tc_isr;
+ IPSEC_ASSERT(isr->sp != NULL, ("NULL isr->sp"));
IPSECREQUEST_LOCK(isr);
sav = tc->tc_sav;
/* With the isr lock released SA pointer can be updated. */
@@ -606,16 +607,18 @@ ipcomp_output_cb(struct cryptop *crp)
error = ipsec_process_done(m, isr);
KEY_FREESAV(&sav);
IPSECREQUEST_UNLOCK(isr);
- return error;
+ KEY_FREESP(&isr->sp);
+ return (error);
bad:
if (sav)
KEY_FREESAV(&sav);
IPSECREQUEST_UNLOCK(isr);
+ KEY_FREESP(&isr->sp);
if (m)
m_freem(m);
free(tc, M_XDATA);
crypto_freereq(crp);
- return error;
+ return (error);
}
static struct xformsw ipcomp_xformsw = {
diff --git a/sys/netpfil/ipfw/ip_fw2.c b/sys/netpfil/ipfw/ip_fw2.c
index a30f6bf9fef0..4da0ee015663 100644
--- a/sys/netpfil/ipfw/ip_fw2.c
+++ b/sys/netpfil/ipfw/ip_fw2.c
@@ -2762,6 +2762,10 @@ vnet_ipfw_init(const void *unused)
LIST_INIT(&chain->nat);
#endif
+ /* Init shared services hash table */
+ ipfw_init_srv(chain);
+
+ ipfw_init_obj_rewriter();
ipfw_init_counters();
/* insert the default rule and create the initial map */
chain->n_rules = 1;
@@ -2860,9 +2864,11 @@ vnet_ipfw_uninit(const void *unused)
if (reap != NULL)
ipfw_reap_rules(reap);
vnet_ipfw_iface_destroy(chain);
+ ipfw_destroy_srv(chain);
IPFW_LOCK_DESTROY(chain);
ipfw_dyn_uninit(1); /* free the remaining parts */
ipfw_destroy_counters();
+ ipfw_destroy_obj_rewriter();
return (0);
}
diff --git a/sys/netpfil/ipfw/ip_fw_nat.c b/sys/netpfil/ipfw/ip_fw_nat.c
index 201be2f1e052..df403982086b 100644
--- a/sys/netpfil/ipfw/ip_fw_nat.c
+++ b/sys/netpfil/ipfw/ip_fw_nat.c
@@ -242,6 +242,8 @@ add_redir_spool_cfg(char *buf, struct cfg_nat *ptr)
}
if (r->alink[0] == NULL) {
printf("LibAliasRedirect* returned NULL\n");
+ free(r->alink, M_IPFW);
+ free(r, M_IPFW);
return (EINVAL);
}
/* LSNAT handling. */
@@ -263,6 +265,16 @@ add_redir_spool_cfg(char *buf, struct cfg_nat *ptr)
return (0);
}
+static void
+free_nat_instance(struct cfg_nat *ptr)
+{
+
+ del_redir_spool_cfg(ptr, &ptr->redir_chain);
+ LibAliasUninit(ptr->lib);
+ free(ptr, M_IPFW);
+}
+
+
/*
* ipfw_nat - perform mbuf header translation.
*
@@ -536,7 +548,7 @@ nat44_config(struct ip_fw_chain *chain, struct nat44_cfg_nat *ucfg)
IPFW_UH_WUNLOCK(chain);
if (tcfg != NULL)
- free(tcfg, M_IPFW);
+ free_nat_instance(ptr);
}
/*
@@ -626,9 +638,7 @@ nat44_destroy(struct ip_fw_chain *chain, ip_fw3_opheader *op3,
IPFW_WUNLOCK(chain);
IPFW_UH_WUNLOCK(chain);
- del_redir_spool_cfg(ptr, &ptr->redir_chain);
- LibAliasUninit(ptr->lib);
- free(ptr, M_IPFW);
+ free_nat_instance(ptr);
return (0);
}
@@ -994,9 +1004,7 @@ ipfw_nat_del(struct sockopt *sopt)
flush_nat_ptrs(chain, i);
IPFW_WUNLOCK(chain);
IPFW_UH_WUNLOCK(chain);
- del_redir_spool_cfg(ptr, &ptr->redir_chain);
- LibAliasUninit(ptr->lib);
- free(ptr, M_IPFW);
+ free_nat_instance(ptr);
return (0);
}
@@ -1139,9 +1147,7 @@ vnet_ipfw_nat_uninit(const void *arg __unused)
IPFW_WLOCK(chain);
LIST_FOREACH_SAFE(ptr, &chain->nat, _next, ptr_temp) {
LIST_REMOVE(ptr, _next);
- del_redir_spool_cfg(ptr, &ptr->redir_chain);
- LibAliasUninit(ptr->lib);
- free(ptr, M_IPFW);
+ free_nat_instance(ptr);
}
flush_nat_ptrs(chain, -1 /* flush all */);
V_ipfw_nat_ready = 0;
diff --git a/sys/netpfil/ipfw/ip_fw_private.h b/sys/netpfil/ipfw/ip_fw_private.h
index bb5b3bab5ce3..504093bce6d1 100644
--- a/sys/netpfil/ipfw/ip_fw_private.h
+++ b/sys/netpfil/ipfw/ip_fw_private.h
@@ -264,10 +264,10 @@ struct ip_fw_chain {
struct ip_fw **map; /* array of rule ptrs to ease lookup */
uint32_t id; /* ruleset id */
int n_rules; /* number of static rules */
- LIST_HEAD(nat_list, cfg_nat) nat; /* list of nat entries */
void *tablestate; /* runtime table info */
void *valuestate; /* runtime table value info */
int *idxmap; /* skipto array of rules */
+ void **srvstate; /* runtime service mappings */
#if defined( __linux__ ) || defined( _WIN32 )
spinlock_t rwmtx;
#else
@@ -275,10 +275,12 @@ struct ip_fw_chain {
#endif
int static_len; /* total len of static rules (v0) */
uint32_t gencnt; /* NAT generation count */
+ LIST_HEAD(nat_list, cfg_nat) nat; /* list of nat entries */
struct ip_fw *default_rule;
struct tables_config *tblcfg; /* tables module data */
void *ifcfg; /* interface module data */
int *idxmap_back; /* standby skipto array of rules */
+ struct namedobj_instance *srvmap; /* cfg name->number mappings */
#if defined( __linux__ ) || defined( _WIN32 )
spinlock_t uh_lock;
#else
@@ -306,16 +308,15 @@ struct table_value {
uint64_t refcnt; /* Number of references */
};
-struct namedobj_instance;
struct named_object {
TAILQ_ENTRY(named_object) nn_next; /* namehash */
TAILQ_ENTRY(named_object) nv_next; /* valuehash */
char *name; /* object name */
- uint8_t type; /* object type */
- uint8_t compat; /* Object name is number */
+ uint8_t subtype; /* object subtype within class */
+ uint8_t etlv; /* Export TLV id */
+ uint16_t spare[2];
uint16_t kidx; /* object kernel index */
- uint16_t uidx; /* userland idx for compat records */
uint32_t set; /* set object belongs to */
uint32_t refcnt; /* number of references */
};
@@ -450,7 +451,7 @@ struct obj_idx {
struct rule_check_info {
uint16_t flags; /* rule-specific check flags */
- uint16_t table_opcodes; /* count of opcodes referencing table */
+ uint16_t object_opcodes; /* num of opcodes referencing objects */
uint16_t urule_numoff; /* offset of rulenum in bytes */
uint8_t version; /* rule version */
uint8_t spare;
@@ -507,6 +508,84 @@ struct ip_fw_bcounter0 {
(r)->cmd_len * 4 - 4, 8))
#define RULEKSIZE1(r) roundup2((sizeof(struct ip_fw) + (r)->cmd_len*4 - 4), 8)
+/*
+ * Tables/Objects index rewriting code
+ */
+
+/* Default and maximum number of ipfw tables/objects. */
+#define IPFW_TABLES_MAX 65536
+#define IPFW_TABLES_DEFAULT 128
+#define IPFW_OBJECTS_MAX 65536
+#define IPFW_OBJECTS_DEFAULT 128
+
+#define CHAIN_TO_SRV(ch) ((ch)->srvmap)
+
+struct tid_info {
+ uint32_t set; /* table set */
+ uint16_t uidx; /* table index */
+ uint8_t type; /* table type */
+ uint8_t atype;
+ uint8_t spare;
+ int tlen; /* Total TLV size block */
+ void *tlvs; /* Pointer to first TLV */
+};
+
+/*
+ * Classifier callback. Checks if @cmd opcode contains kernel object reference.
+ * If true, returns its index and type.
+ * Returns 0 if match is found, 1 overwise.
+ */
+typedef int (ipfw_obj_rw_cl)(ipfw_insn *cmd, uint16_t *puidx, uint8_t *ptype);
+/*
+ * Updater callback. Sets kernel object reference index to @puidx
+ */
+typedef void (ipfw_obj_rw_upd)(ipfw_insn *cmd, uint16_t puidx);
+/*
+ * Finder callback. Tries to find named object by name (specified via @ti).
+ * Stores found named object pointer in @pno.
+ * If object was not found, NULL is stored.
+ *
+ * Return 0 if input data was valid.
+ */
+typedef int (ipfw_obj_fname_cb)(struct ip_fw_chain *ch,
+ struct tid_info *ti, struct named_object **pno);
+/*
+ * Another finder callback. Tries to findex named object by kernel index.
+ *
+ * Returns pointer to named object or NULL.
+ */
+typedef struct named_object *(ipfw_obj_fidx_cb)(struct ip_fw_chain *ch,
+ uint16_t kidx);
+/*
+ * Object creator callback. Tries to create object specified by @ti.
+ * Stores newly-allocated object index in @pkidx.
+ *
+ * Returns 0 on success.
+ */
+typedef int (ipfw_obj_create_cb)(struct ip_fw_chain *ch, struct tid_info *ti,
+ uint16_t *pkidx);
+
+
+struct opcode_obj_rewrite {
+ uint32_t opcode; /* Opcode to act upon */
+ uint32_t etlv; /* Relevant export TLV id */
+ ipfw_obj_rw_cl *classifier; /* Check if rewrite is needed */
+ ipfw_obj_rw_upd *update; /* update cmd with new value */
+ ipfw_obj_fname_cb *find_byname; /* Find named object by name */
+ ipfw_obj_fidx_cb *find_bykidx; /* Find named object by kidx */
+ ipfw_obj_create_cb *create_object; /* Create named object */
+};
+
+#define IPFW_ADD_OBJ_REWRITER(f, c) do { \
+ if ((f) != 0) \
+ ipfw_add_obj_rewriter(c, \
+ sizeof(c) / sizeof(c[0])); \
+ } while(0)
+#define IPFW_DEL_OBJ_REWRITER(l, c) do { \
+ if ((l) != 0) \
+ ipfw_del_obj_rewriter(c, \
+ sizeof(c) / sizeof(c[0])); \
+ } while(0)
/* In ip_fw_iface.c */
int ipfw_iface_init(void);
@@ -562,6 +641,7 @@ caddr_t ipfw_get_sopt_header(struct sockopt_data *sd, size_t needed);
sizeof(c) / sizeof(c[0])); \
} while(0)
+struct namedobj_instance;
typedef void (objhash_cb_t)(struct namedobj_instance *ni, struct named_object *,
void *arg);
typedef uint32_t (objhash_hash_f)(struct namedobj_instance *ni, void *key,
@@ -578,6 +658,8 @@ void ipfw_objhash_bitmap_free(void *idx, int blocks);
void ipfw_objhash_set_hashf(struct namedobj_instance *ni, objhash_hash_f *f);
struct named_object *ipfw_objhash_lookup_name(struct namedobj_instance *ni,
uint32_t set, char *name);
+struct named_object *ipfw_objhash_lookup_name_type(struct namedobj_instance *ni,
+ uint32_t set, uint32_t type, char *name);
struct named_object *ipfw_objhash_lookup_kidx(struct namedobj_instance *ni,
uint16_t idx);
int ipfw_objhash_same_name(struct namedobj_instance *ni, struct named_object *a,
@@ -591,6 +673,25 @@ int ipfw_objhash_free_idx(struct namedobj_instance *ni, uint16_t idx);
int ipfw_objhash_alloc_idx(void *n, uint16_t *pidx);
void ipfw_objhash_set_funcs(struct namedobj_instance *ni,
objhash_hash_f *hash_f, objhash_cmp_f *cmp_f);
+void ipfw_init_obj_rewriter(void);
+void ipfw_destroy_obj_rewriter(void);
+void ipfw_add_obj_rewriter(struct opcode_obj_rewrite *rw, size_t count);
+int ipfw_del_obj_rewriter(struct opcode_obj_rewrite *rw, size_t count);
+
+int ipfw_rewrite_rule_uidx(struct ip_fw_chain *chain,
+ struct rule_check_info *ci);
+int ipfw_mark_object_kidx(struct ip_fw_chain *chain, struct ip_fw *rule,
+ uint32_t *bmask);
+int ref_opcode_object(struct ip_fw_chain *ch, ipfw_insn *cmd, struct tid_info *ti,
+ struct obj_idx *pidx, int *found, int *unresolved);
+void unref_oib_objects(struct ip_fw_chain *ch, ipfw_insn *cmd,
+ struct obj_idx *oib, struct obj_idx *end);
+int create_objects_compat(struct ip_fw_chain *ch, ipfw_insn *cmd,
+ struct obj_idx *oib, struct obj_idx *pidx, struct tid_info *ti);
+void update_opcode_kidx(ipfw_insn *cmd, uint16_t idx);
+int classify_opcode_kidx(ipfw_insn *cmd, uint16_t *puidx);
+void ipfw_init_srv(struct ip_fw_chain *ch);
+void ipfw_destroy_srv(struct ip_fw_chain *ch);
/* In ip_fw_table.c */
struct table_info;
diff --git a/sys/netpfil/ipfw/ip_fw_sockopt.c b/sys/netpfil/ipfw/ip_fw_sockopt.c
index ef1ff6cfb051..d618a6c615b3 100644
--- a/sys/netpfil/ipfw/ip_fw_sockopt.c
+++ b/sys/netpfil/ipfw/ip_fw_sockopt.c
@@ -148,6 +148,21 @@ static struct ipfw_sopt_handler scodes[] = {
{ IP_FW_DUMP_SOPTCODES, 0, HDIR_GET, dump_soptcodes },
};
+static int
+set_legacy_obj_kidx(struct ip_fw_chain *ch, struct ip_fw_rule0 *rule);
+struct opcode_obj_rewrite *ipfw_find_op_rw(uint16_t opcode);
+static int mark_object_kidx(struct ip_fw_chain *ch, struct ip_fw *rule,
+ uint32_t *bmask);
+static void unref_rule_objects(struct ip_fw_chain *chain, struct ip_fw *rule);
+static int export_objhash_ntlv(struct namedobj_instance *ni, uint16_t kidx,
+ struct sockopt_data *sd);
+
+/*
+ * Opcode object rewriter variables
+ */
+struct opcode_obj_rewrite *ctl3_rewriters;
+static size_t ctl3_rsize;
+
/*
* static variables followed by global ones
*/
@@ -646,17 +661,18 @@ commit_rules(struct ip_fw_chain *chain, struct rule_check_info *rci, int count)
struct ip_fw *krule;
struct ip_fw **map; /* the new array of pointers */
- /* Check if we need to do table remap */
+ /* Check if we need to do table/obj index remap */
tcount = 0;
for (ci = rci, i = 0; i < count; ci++, i++) {
- if (ci->table_opcodes == 0)
+ if (ci->object_opcodes == 0)
continue;
/*
- * Rule has some table opcodes.
- * Reference & allocate needed tables/
+ * Rule has some object opcodes.
+ * We need to find (and create non-existing)
+ * kernel objects, and reference existing ones.
*/
- error = ipfw_rewrite_table_uidx(chain, ci);
+ error = ipfw_rewrite_rule_uidx(chain, ci);
if (error != 0) {
/*
@@ -674,9 +690,9 @@ commit_rules(struct ip_fw_chain *chain, struct rule_check_info *rci, int count)
IPFW_UH_WLOCK(chain);
while (ci != rci) {
ci--;
- if (ci->table_opcodes == 0)
+ if (ci->object_opcodes == 0)
continue;
- ipfw_unref_rule_tables(chain,ci->krule);
+ unref_rule_objects(chain,ci->krule);
}
IPFW_UH_WUNLOCK(chain);
@@ -696,10 +712,10 @@ commit_rules(struct ip_fw_chain *chain, struct rule_check_info *rci, int count)
/* Unbind tables */
IPFW_UH_WLOCK(chain);
for (ci = rci, i = 0; i < count; ci++, i++) {
- if (ci->table_opcodes == 0)
+ if (ci->object_opcodes == 0)
continue;
- ipfw_unref_rule_tables(chain, ci->krule);
+ unref_rule_objects(chain, ci->krule);
}
IPFW_UH_WUNLOCK(chain);
}
@@ -759,7 +775,7 @@ ipfw_reap_add(struct ip_fw_chain *chain, struct ip_fw **head,
IPFW_UH_WLOCK_ASSERT(chain);
/* Unlink rule from everywhere */
- ipfw_unref_rule_tables(chain, rule);
+ unref_rule_objects(chain, rule);
*((struct ip_fw **)rule) = *head;
*head = rule;
@@ -1542,7 +1558,7 @@ check_ipfw_rule_body(ipfw_insn *cmd, int cmd_len, struct rule_check_info *ci)
cmdlen != F_INSN_SIZE(ipfw_insn_u32) + 1 &&
cmdlen != F_INSN_SIZE(ipfw_insn_u32))
goto bad_size;
- ci->table_opcodes++;
+ ci->object_opcodes++;
break;
case O_IP_FLOW_LOOKUP:
if (cmd->arg1 >= V_fw_tables_max) {
@@ -1553,7 +1569,7 @@ check_ipfw_rule_body(ipfw_insn *cmd, int cmd_len, struct rule_check_info *ci)
if (cmdlen != F_INSN_SIZE(ipfw_insn) &&
cmdlen != F_INSN_SIZE(ipfw_insn_u32))
goto bad_size;
- ci->table_opcodes++;
+ ci->object_opcodes++;
break;
case O_MACADDR2:
if (cmdlen != F_INSN_SIZE(ipfw_insn_mac))
@@ -1587,7 +1603,7 @@ check_ipfw_rule_body(ipfw_insn *cmd, int cmd_len, struct rule_check_info *ci)
case O_XMIT:
case O_VIA:
if (((ipfw_insn_if *)cmd)->name[0] == '\1')
- ci->table_opcodes++;
+ ci->object_opcodes++;
if (cmdlen != F_INSN_SIZE(ipfw_insn_if))
goto bad_size;
break;
@@ -1788,7 +1804,7 @@ ipfw_getrules(struct ip_fw_chain *chain, void *buf, size_t space)
l = RULESIZE7(rule);
if (bp + l + sizeof(uint32_t) <= ep) {
bcopy(rule, bp, l + sizeof(uint32_t));
- error = ipfw_rewrite_table_kidx(chain,
+ error = set_legacy_obj_kidx(chain,
(struct ip_fw_rule0 *)bp);
if (error != 0)
return (0);
@@ -1817,7 +1833,7 @@ ipfw_getrules(struct ip_fw_chain *chain, void *buf, size_t space)
}
dst = (struct ip_fw_rule0 *)bp;
export_rule0(rule, dst, l);
- error = ipfw_rewrite_table_kidx(chain, dst);
+ error = set_legacy_obj_kidx(chain, dst);
/*
* XXX HACK. Store the disable mask in the "next"
@@ -1861,6 +1877,34 @@ struct dump_args {
};
/*
+ * Export named object info in instance @ni, identified by @kidx
+ * to ipfw_obj_ntlv. TLV is allocated from @sd space.
+ *
+ * Returns 0 on success.
+ */
+static int
+export_objhash_ntlv(struct namedobj_instance *ni, uint16_t kidx,
+ struct sockopt_data *sd)
+{
+ struct named_object *no;
+ ipfw_obj_ntlv *ntlv;
+
+ no = ipfw_objhash_lookup_kidx(ni, kidx);
+ KASSERT(no != NULL, ("invalid object kernel index passed"));
+
+ ntlv = (ipfw_obj_ntlv *)ipfw_get_sopt_space(sd, sizeof(*ntlv));
+ if (ntlv == NULL)
+ return (ENOMEM);
+
+ ntlv->head.type = no->etlv;
+ ntlv->head.length = sizeof(*ntlv);
+ ntlv->idx = no->kidx;
+ strlcpy(ntlv->name, no->name, sizeof(ntlv->name));
+
+ return (0);
+}
+
+/*
* Dumps static rules with table TLVs in buffer @sd.
*
* Returns 0 on success.
@@ -1874,6 +1918,7 @@ dump_static_rules(struct ip_fw_chain *chain, struct dump_args *da,
uint32_t tcount;
ipfw_obj_ctlv *ctlv;
struct ip_fw *krule;
+ struct namedobj_instance *ni;
caddr_t dst;
/* Dump table names first (if any) */
@@ -1891,13 +1936,21 @@ dump_static_rules(struct ip_fw_chain *chain, struct dump_args *da,
i = 0;
tcount = da->tcount;
+ ni = ipfw_get_table_objhash(chain);
while (tcount > 0) {
if ((bmask[i / 32] & (1 << (i % 32))) == 0) {
i++;
continue;
}
- if ((error = ipfw_export_table_ntlv(chain, i, sd)) != 0)
+ /* Jump to shared named object bitmask */
+ if (i >= IPFW_TABLES_MAX) {
+ ni = CHAIN_TO_SRV(chain);
+ i -= IPFW_TABLES_MAX;
+ bmask += IPFW_TABLES_MAX / 32;
+ }
+
+ if ((error = export_objhash_ntlv(ni, i, sd)) != 0)
return (error);
i++;
@@ -1929,6 +1982,52 @@ dump_static_rules(struct ip_fw_chain *chain, struct dump_args *da,
}
/*
+ * Marks every object index used in @rule with bit in @bmask.
+ * Used to generate bitmask of referenced tables/objects for given ruleset
+ * or its part.
+ *
+ * Returns number of newly-referenced objects.
+ */
+static int
+mark_object_kidx(struct ip_fw_chain *ch, struct ip_fw *rule,
+ uint32_t *bmask)
+{
+ int cmdlen, l, count;
+ ipfw_insn *cmd;
+ uint16_t kidx;
+ struct opcode_obj_rewrite *rw;
+ int bidx;
+ uint8_t subtype;
+
+ l = rule->cmd_len;
+ cmd = rule->cmd;
+ cmdlen = 0;
+ count = 0;
+ for ( ; l > 0 ; l -= cmdlen, cmd += cmdlen) {
+ cmdlen = F_LEN(cmd);
+
+ rw = ipfw_find_op_rw(cmd->opcode);
+ if (rw == NULL)
+ continue;
+
+ if (rw->classifier(cmd, &kidx, &subtype) != 0)
+ continue;
+
+ bidx = kidx / 32;
+ /* Maintain separate bitmasks for table and non-table objects */
+ if (rw->etlv != IPFW_TLV_TBL_NAME)
+ bidx += IPFW_TABLES_MAX / 32;
+
+ if ((bmask[bidx] & (1 << (kidx % 32))) == 0)
+ count++;
+
+ bmask[bidx] |= 1 << (kidx % 32);
+ }
+
+ return (count);
+}
+
+/*
* Dumps requested objects data
* Data layout (version 0)(current):
* Request: [ ipfw_cfg_lheader ] + IPFW_CFG_GET_* flags
@@ -1963,9 +2062,9 @@ dump_config(struct ip_fw_chain *chain, ip_fw3_opheader *op3,
error = 0;
bmask = NULL;
- /* Allocate needed state */
+ /* Allocate needed state. Note we allocate 2xspace mask, for table&srv */
if (hdr->flags & IPFW_CFG_GET_STATIC)
- bmask = malloc(IPFW_TABLES_MAX / 8, M_TEMP, M_WAITOK | M_ZERO);
+ bmask = malloc(IPFW_TABLES_MAX / 4, M_TEMP, M_WAITOK | M_ZERO);
IPFW_UH_RLOCK(chain);
@@ -1994,7 +2093,8 @@ dump_config(struct ip_fw_chain *chain, ip_fw3_opheader *op3,
rule = chain->map[i];
da.rsize += RULEUSIZE1(rule) + sizeof(ipfw_obj_tlv);
da.rcount++;
- da.tcount += ipfw_mark_table_kidx(chain, rule, bmask);
+ /* Update bitmask of used objects for given range */
+ da.tcount += mark_object_kidx(chain, rule, bmask);
}
/* Add counters if requested */
if (hdr->flags & IPFW_CFG_GET_COUNTERS) {
@@ -2064,6 +2164,241 @@ check_object_name(ipfw_obj_ntlv *ntlv)
}
/*
+ * Creates non-existent objects referenced by rule.
+ *
+ * Return 0 on success.
+ */
+int
+create_objects_compat(struct ip_fw_chain *ch, ipfw_insn *cmd,
+ struct obj_idx *oib, struct obj_idx *pidx, struct tid_info *ti)
+{
+ struct opcode_obj_rewrite *rw;
+ struct obj_idx *p;
+ uint16_t kidx;
+ int error;
+
+ /*
+ * Compatibility stuff: do actual creation for non-existing,
+ * but referenced objects.
+ */
+ for (p = oib; p < pidx; p++) {
+ if (p->kidx != 0)
+ continue;
+
+ ti->uidx = p->uidx;
+ ti->type = p->type;
+ ti->atype = 0;
+
+ rw = ipfw_find_op_rw((cmd + p->off)->opcode);
+ KASSERT(rw != NULL, ("Unable to find handler for op %d",
+ (cmd + p->off)->opcode));
+
+ error = rw->create_object(ch, ti, &kidx);
+ if (error == 0) {
+ p->kidx = kidx;
+ continue;
+ }
+
+ /*
+ * Error happened. We have to rollback everything.
+ * Drop all already acquired references.
+ */
+ IPFW_UH_WLOCK(ch);
+ unref_oib_objects(ch, cmd, oib, pidx);
+ IPFW_UH_WUNLOCK(ch);
+
+ return (error);
+ }
+
+ return (0);
+}
+
+/*
+ * Compatibility function for old ipfw(8) binaries.
+ * Rewrites table/nat kernel indices with userland ones.
+ * Convert tables matching '/^\d+$/' to their atoi() value.
+ * Use number 65535 for other tables.
+ *
+ * Returns 0 on success.
+ */
+static int
+set_legacy_obj_kidx(struct ip_fw_chain *ch, struct ip_fw_rule0 *rule)
+{
+ int cmdlen, error, l;
+ ipfw_insn *cmd;
+ uint16_t kidx, uidx;
+ struct named_object *no;
+ struct opcode_obj_rewrite *rw;
+ uint8_t subtype;
+ char *end;
+ long val;
+
+ error = 0;
+
+ l = rule->cmd_len;
+ cmd = rule->cmd;
+ cmdlen = 0;
+ for ( ; l > 0 ; l -= cmdlen, cmd += cmdlen) {
+ cmdlen = F_LEN(cmd);
+
+ rw = ipfw_find_op_rw(cmd->opcode);
+ if (rw == NULL)
+ continue;
+
+ /* Check if is index in given opcode */
+ if (rw->classifier(cmd, &kidx, &subtype) != 0)
+ continue;
+
+ /* Try to find referenced kernel object */
+ no = rw->find_bykidx(ch, kidx);
+ if (no == NULL)
+ continue;
+
+ val = strtol(no->name, &end, 10);
+ if (*end == '\0' && val < 65535) {
+ uidx = val;
+ } else {
+
+ /*
+ * We are called via legacy opcode.
+ * Save error and show table as fake number
+ * not to make ipfw(8) hang.
+ */
+ uidx = 65535;
+ error = 2;
+ }
+
+ rw->update(cmd, uidx);
+ }
+
+ return (error);
+}
+
+
+/*
+ * Unreferences all already-referenced objects in given @cmd rule,
+ * using information in @oib.
+ *
+ * Used to rollback partially converted rule on error.
+ */
+void
+unref_oib_objects(struct ip_fw_chain *ch, ipfw_insn *cmd, struct obj_idx *oib,
+ struct obj_idx *end)
+{
+ struct opcode_obj_rewrite *rw;
+ struct named_object *no;
+ struct obj_idx *p;
+
+ IPFW_UH_WLOCK_ASSERT(ch);
+
+ for (p = oib; p < end; p++) {
+ if (p->kidx == 0)
+ continue;
+
+ rw = ipfw_find_op_rw((cmd + p->off)->opcode);
+ KASSERT(rw != NULL, ("Unable to find handler for op %d",
+ (cmd + p->off)->opcode));
+
+ /* Find & unref by existing idx */
+ no = rw->find_bykidx(ch, p->kidx);
+ KASSERT(no != NULL, ("Ref'd object %d disappeared", p->kidx));
+ no->refcnt--;
+ }
+}
+
+/*
+ * Remove references from every object used in @rule.
+ * Used at rule removal code.
+ */
+static void
+unref_rule_objects(struct ip_fw_chain *ch, struct ip_fw *rule)
+{
+ int cmdlen, l;
+ ipfw_insn *cmd;
+ struct named_object *no;
+ uint16_t kidx;
+ struct opcode_obj_rewrite *rw;
+ uint8_t subtype;
+
+ IPFW_UH_WLOCK_ASSERT(ch);
+
+ l = rule->cmd_len;
+ cmd = rule->cmd;
+ cmdlen = 0;
+ for ( ; l > 0 ; l -= cmdlen, cmd += cmdlen) {
+ cmdlen = F_LEN(cmd);
+
+ rw = ipfw_find_op_rw(cmd->opcode);
+ if (rw == NULL)
+ continue;
+ if (rw->classifier(cmd, &kidx, &subtype) != 0)
+ continue;
+
+ no = rw->find_bykidx(ch, kidx);
+
+ KASSERT(no != NULL, ("table id %d not found", kidx));
+ KASSERT(no->subtype == subtype,
+ ("wrong type %d (%d) for table id %d",
+ no->subtype, subtype, kidx));
+ KASSERT(no->refcnt > 0, ("refcount for table %d is %d",
+ kidx, no->refcnt));
+
+ no->refcnt--;
+ }
+}
+
+
+/*
+ * Find and reference object (if any) stored in instruction @cmd.
+ *
+ * Saves object info in @pidx, sets
+ * - @found to 1 if object was found and references
+ * - @unresolved to 1 if object should exists but not found
+ *
+ * Returns non-zero value in case of error.
+ */
+int
+ref_opcode_object(struct ip_fw_chain *ch, ipfw_insn *cmd, struct tid_info *ti,
+ struct obj_idx *pidx, int *found, int *unresolved)
+{
+ struct named_object *no;
+ struct opcode_obj_rewrite *rw;
+ int error;
+
+ *found = 0;
+ *unresolved = 0;
+
+ /* Check if this opcode is candidate for rewrite */
+ rw = ipfw_find_op_rw(cmd->opcode);
+ if (rw == NULL)
+ return (0);
+
+ /* Check if we need to rewrite this opcode */
+ if (rw->classifier(cmd, &ti->uidx, &ti->type) != 0)
+ return (0);
+
+ /* Need to rewrite. Save necessary fields */
+ pidx->uidx = ti->uidx;
+ pidx->type = ti->type;
+
+ /* Try to find referenced kernel object */
+ error = rw->find_byname(ch, ti, &no);
+ if (error != 0)
+ return (error);
+ if (no == NULL) {
+ *unresolved = 1;
+ return (0);
+ }
+
+ /* Found. bump refcount */
+ *found = 1;
+ no->refcnt++;
+ pidx->kidx = no->kidx;
+
+ return (0);
+}
+
+/*
* Adds one or more rules to ipfw @chain.
* Data layout (version 0)(current):
* Request:
@@ -2315,6 +2650,160 @@ dump_soptcodes(struct ip_fw_chain *chain, ip_fw3_opheader *op3,
}
/*
+ * Compares two opcodes.
+ * Used both in qsort() and bsearch().
+ *
+ * Returns 0 if match is found.
+ */
+static int
+compare_opcodes(const void *_a, const void *_b)
+{
+ const struct opcode_obj_rewrite *a, *b;
+
+ a = (const struct opcode_obj_rewrite *)_a;
+ b = (const struct opcode_obj_rewrite *)_b;
+
+ if (a->opcode < b->opcode)
+ return (-1);
+ else if (a->opcode > b->opcode)
+ return (1);
+
+ return (0);
+}
+
+/*
+ * Finds opcode object rewriter based on @code.
+ *
+ * Returns pointer to handler or NULL.
+ */
+struct opcode_obj_rewrite *
+ipfw_find_op_rw(uint16_t opcode)
+{
+ struct opcode_obj_rewrite *rw, h;
+
+ memset(&h, 0, sizeof(h));
+ h.opcode = opcode;
+
+ rw = (struct opcode_obj_rewrite *)bsearch(&h, ctl3_rewriters,
+ ctl3_rsize, sizeof(h), compare_opcodes);
+
+ return (rw);
+}
+
+int
+classify_opcode_kidx(ipfw_insn *cmd, uint16_t *puidx)
+{
+ struct opcode_obj_rewrite *rw;
+ uint8_t subtype;
+
+ rw = ipfw_find_op_rw(cmd->opcode);
+ if (rw == NULL)
+ return (1);
+
+ return (rw->classifier(cmd, puidx, &subtype));
+}
+
+void
+update_opcode_kidx(ipfw_insn *cmd, uint16_t idx)
+{
+ struct opcode_obj_rewrite *rw;
+
+ rw = ipfw_find_op_rw(cmd->opcode);
+ KASSERT(rw != NULL, ("No handler to update opcode %d", cmd->opcode));
+ rw->update(cmd, idx);
+}
+
+void
+ipfw_init_obj_rewriter()
+{
+
+ ctl3_rewriters = NULL;
+ ctl3_rsize = 0;
+}
+
+void
+ipfw_destroy_obj_rewriter()
+{
+
+ if (ctl3_rewriters != NULL)
+ free(ctl3_rewriters, M_IPFW);
+ ctl3_rewriters = NULL;
+ ctl3_rsize = 0;
+}
+
+/*
+ * Adds one or more opcode object rewrite handlers to the global array.
+ * Function may sleep.
+ */
+void
+ipfw_add_obj_rewriter(struct opcode_obj_rewrite *rw, size_t count)
+{
+ size_t sz;
+ struct opcode_obj_rewrite *tmp;
+
+ CTL3_LOCK();
+
+ for (;;) {
+ sz = ctl3_rsize + count;
+ CTL3_UNLOCK();
+ tmp = malloc(sizeof(*rw) * sz, M_IPFW, M_WAITOK | M_ZERO);
+ CTL3_LOCK();
+ if (ctl3_rsize + count <= sz)
+ break;
+
+ /* Retry */
+ free(tmp, M_IPFW);
+ }
+
+ /* Merge old & new arrays */
+ sz = ctl3_rsize + count;
+ memcpy(tmp, ctl3_rewriters, ctl3_rsize * sizeof(*rw));
+ memcpy(&tmp[ctl3_rsize], rw, count * sizeof(*rw));
+ qsort(tmp, sz, sizeof(*rw), compare_opcodes);
+ /* Switch new and free old */
+ if (ctl3_rewriters != NULL)
+ free(ctl3_rewriters, M_IPFW);
+ ctl3_rewriters = tmp;
+ ctl3_rsize = sz;
+
+ CTL3_UNLOCK();
+}
+
+/*
+ * Removes one or more object rewrite handlers from the global array.
+ */
+int
+ipfw_del_obj_rewriter(struct opcode_obj_rewrite *rw, size_t count)
+{
+ size_t sz;
+ struct opcode_obj_rewrite *tmp, *h;
+ int i;
+
+ CTL3_LOCK();
+
+ for (i = 0; i < count; i++) {
+ tmp = &rw[i];
+ h = ipfw_find_op_rw(tmp->opcode);
+ if (h == NULL)
+ continue;
+
+ sz = (ctl3_rewriters + ctl3_rsize - (h + 1)) * sizeof(*h);
+ memmove(h, h + 1, sz);
+ ctl3_rsize--;
+ }
+
+ if (ctl3_rsize == 0) {
+ if (ctl3_rewriters != NULL)
+ free(ctl3_rewriters, M_IPFW);
+ ctl3_rewriters = NULL;
+ }
+
+ CTL3_UNLOCK();
+
+ return (0);
+}
+
+/*
* Compares two sopt handlers (code, version and handler ptr).
* Used both as qsort() and bsearch().
* Does not compare handler for latter case.
@@ -3150,6 +3639,23 @@ convert_rule_to_8(struct ip_fw_rule0 *rule)
*
*/
+void
+ipfw_init_srv(struct ip_fw_chain *ch)
+{
+
+ ch->srvmap = ipfw_objhash_create(IPFW_OBJECTS_DEFAULT);
+ ch->srvstate = malloc(sizeof(void *) * IPFW_OBJECTS_DEFAULT,
+ M_IPFW, M_WAITOK | M_ZERO);
+}
+
+void
+ipfw_destroy_srv(struct ip_fw_chain *ch)
+{
+
+ free(ch->srvstate, M_IPFW);
+ ipfw_objhash_destroy(ch->srvmap);
+}
+
/*
* Allocate new bitmask which can be used to enlarge/shrink
* named instance index.
@@ -3323,6 +3829,26 @@ ipfw_objhash_lookup_name(struct namedobj_instance *ni, uint32_t set, char *name)
return (NULL);
}
+/*
+ * Find named object by name, considering also its TLV type.
+ */
+struct named_object *
+ipfw_objhash_lookup_name_type(struct namedobj_instance *ni, uint32_t set,
+ uint32_t type, char *name)
+{
+ struct named_object *no;
+ uint32_t hash;
+
+ hash = ni->hash_f(ni, name, set) % ni->nn_size;
+
+ TAILQ_FOREACH(no, &ni->names[hash], nn_next) {
+ if (ni->cmp_f(no, name, set) == 0 && no->etlv == type)
+ return (no);
+ }
+
+ return (NULL);
+}
+
struct named_object *
ipfw_objhash_lookup_kidx(struct namedobj_instance *ni, uint16_t kidx)
{
diff --git a/sys/netpfil/ipfw/ip_fw_table.c b/sys/netpfil/ipfw/ip_fw_table.c
index 4498ace88d40..ca4e0e4c3ea9 100644
--- a/sys/netpfil/ipfw/ip_fw_table.c
+++ b/sys/netpfil/ipfw/ip_fw_table.c
@@ -89,6 +89,8 @@ struct table_config {
struct namedobj_instance *vi;
};
+static int find_table_err(struct namedobj_instance *ni, struct tid_info *ti,
+ struct table_config **tc);
static struct table_config *find_table(struct namedobj_instance *ni,
struct tid_info *ti);
static struct table_config *alloc_table_config(struct ip_fw_chain *ch,
@@ -122,7 +124,6 @@ static struct table_algo *find_table_algo(struct tables_config *tableconf,
static void objheader_to_ti(struct _ipfw_obj_header *oh, struct tid_info *ti);
static void ntlv_to_ti(struct _ipfw_obj_ntlv *ntlv, struct tid_info *ti);
-static int classify_table_opcode(ipfw_insn *cmd, uint16_t *puidx, uint8_t *ptype);
#define CHAIN_TO_NI(chain) (CHAIN_TO_TCFG(chain)->namehash)
#define KIDX_TO_TI(ch, k) (&(((struct table_info *)(ch)->tablestate)[k]))
@@ -297,7 +298,7 @@ find_ref_table(struct ip_fw_chain *ch, struct tid_info *ti,
tc = NULL;
if ((tc = find_table(ni, ti)) != NULL) {
/* check table type */
- if (tc->no.type != ti->type)
+ if (tc->no.subtype != ti->type)
return (EINVAL);
if (tc->locked != 0)
@@ -1116,7 +1117,7 @@ find_table_entry(struct ip_fw_chain *ch, ip_fw3_opheader *op3,
}
/* check table type */
- if (tc->no.type != ti.type) {
+ if (tc->no.subtype != ti.type) {
IPFW_UH_RUNLOCK(ch);
return (EINVAL);
}
@@ -1399,7 +1400,7 @@ swap_tables(struct ip_fw_chain *ch, struct tid_info *a,
}
/* Check type and value are the same */
- if (tc_a->no.type != tc_b->no.type || tc_a->tflags != tc_b->tflags) {
+ if (tc_a->no.subtype!=tc_b->no.subtype || tc_a->tflags!=tc_b->tflags) {
IPFW_UH_WUNLOCK(ch);
return (EINVAL);
}
@@ -1613,7 +1614,6 @@ ipfw_switch_tables_namespace(struct ip_fw_chain *ch, unsigned int sets)
ipfw_insn *cmd;
int cmdlen, i, l;
uint16_t kidx;
- uint8_t type;
IPFW_UH_WLOCK(ch);
@@ -1636,7 +1636,7 @@ ipfw_switch_tables_namespace(struct ip_fw_chain *ch, unsigned int sets)
for ( ; l > 0 ; l -= cmdlen, cmd += cmdlen) {
cmdlen = F_LEN(cmd);
- if (classify_table_opcode(cmd, &kidx, &type) != 0)
+ if (classify_opcode_kidx(cmd, &kidx) != 0)
continue;
no = ipfw_objhash_lookup_kidx(ni, kidx);
@@ -1920,7 +1920,7 @@ create_table_internal(struct ip_fw_chain *ch, struct tid_info *ti,
* requesting to create existing table
* which has the same type
*/
- if (compat == 0 || tc_new->no.type != tc->no.type) {
+ if (compat == 0 || tc_new->no.subtype != tc->no.subtype) {
IPFW_UH_WUNLOCK(ch);
free_table_config(ni, tc);
return (EEXIST);
@@ -1940,6 +1940,7 @@ create_table_internal(struct ip_fw_chain *ch, struct tid_info *ti,
return (EBUSY);
}
tc->no.kidx = kidx;
+ tc->no.etlv = IPFW_TLV_TBL_NAME;
IPFW_WLOCK(ch);
link_table(ch, tc);
@@ -1977,6 +1978,13 @@ objheader_to_ti(struct _ipfw_obj_header *oh, struct tid_info *ti)
ntlv_to_ti(&oh->ntlv, ti);
}
+struct namedobj_instance *
+ipfw_get_table_objhash(struct ip_fw_chain *ch)
+{
+
+ return (CHAIN_TO_NI(ch));
+}
+
/*
* Exports basic table info as name TLV.
* Used inside dump_static_rules() to provide info
@@ -2009,40 +2017,6 @@ ipfw_export_table_ntlv(struct ip_fw_chain *ch, uint16_t kidx,
return (0);
}
-/*
- * Marks every table kidx used in @rule with bit in @bmask.
- * Used to generate bitmask of referenced tables for given ruleset.
- *
- * Returns number of newly-referenced tables.
- */
-int
-ipfw_mark_table_kidx(struct ip_fw_chain *chain, struct ip_fw *rule,
- uint32_t *bmask)
-{
- int cmdlen, l, count;
- ipfw_insn *cmd;
- uint16_t kidx;
- uint8_t type;
-
- l = rule->cmd_len;
- cmd = rule->cmd;
- cmdlen = 0;
- count = 0;
- for ( ; l > 0 ; l -= cmdlen, cmd += cmdlen) {
- cmdlen = F_LEN(cmd);
-
- if (classify_table_opcode(cmd, &kidx, &type) != 0)
- continue;
-
- if ((bmask[kidx / 32] & (1 << (kidx % 32))) == 0)
- count++;
-
- bmask[kidx / 32] |= 1 << (kidx % 32);
- }
-
- return (count);
-}
-
struct dump_args {
struct ip_fw_chain *ch;
struct table_info *ti;
@@ -2111,7 +2085,7 @@ export_table_info(struct ip_fw_chain *ch, struct table_config *tc,
struct table_info *ti;
struct table_algo *ta;
- i->type = tc->no.type;
+ i->type = tc->no.subtype;
i->tflags = tc->tflags;
i->vmask = tc->vmask;
i->set = tc->no.set;
@@ -2296,7 +2270,7 @@ dump_table_v0(struct ip_fw_chain *ch, ip_fw3_opheader *op3,
xtbl->cnt = count;
xtbl->size = sz;
- xtbl->type = tc->no.type;
+ xtbl->type = tc->no.subtype;
xtbl->tbl = ti.uidx;
if (sd->valsize < sz) {
@@ -2440,7 +2414,7 @@ ipfw_dump_table_legacy(struct ip_fw_chain *ch, struct tid_info *ti,
ta = tc->ta;
/* This dump format supports IPv4 only */
- if (tc->no.type != IPFW_TABLE_ADDR)
+ if (tc->no.subtype != IPFW_TABLE_ADDR)
return (0);
memset(&da, 0, sizeof(da));
@@ -2531,7 +2505,7 @@ dump_table_xentry(void *e, void *arg)
pval = get_table_value(da->ch, da->tc, da->tent.v.kidx);
xent->value = ipfw_export_table_value_legacy(pval);
/* Apply some hacks */
- if (tc->no.type == IPFW_TABLE_ADDR && tent->subtype == AF_INET) {
+ if (tc->no.subtype == IPFW_TABLE_ADDR && tent->subtype == AF_INET) {
xent->k.addr6.s6_addr32[3] = tent->k.addr.s_addr;
xent->flags = IPFW_TCF_INET;
} else
@@ -2781,114 +2755,157 @@ list_table_algo(struct ip_fw_chain *ch, ip_fw3_opheader *op3,
return (0);
}
-/*
- * Tables rewriting code
- */
-
-/*
- * Determine table number and lookup type for @cmd.
- * Fill @tbl and @type with appropriate values.
- * Returns 0 for relevant opcodes, 1 otherwise.
- */
static int
-classify_table_opcode(ipfw_insn *cmd, uint16_t *puidx, uint8_t *ptype)
+classify_srcdst(ipfw_insn *cmd, uint16_t *puidx, uint8_t *ptype)
{
- ipfw_insn_if *cmdif;
- int skip;
- uint16_t v;
-
- skip = 1;
-
- switch (cmd->opcode) {
- case O_IP_SRC_LOOKUP:
- case O_IP_DST_LOOKUP:
- /* Basic IPv4/IPv6 or u32 lookups */
- *puidx = cmd->arg1;
- /* Assume ADDR by default */
- *ptype = IPFW_TABLE_ADDR;
- skip = 0;
+ /* Basic IPv4/IPv6 or u32 lookups */
+ *puidx = cmd->arg1;
+ /* Assume ADDR by default */
+ *ptype = IPFW_TABLE_ADDR;
+ int v;
- if (F_LEN(cmd) > F_INSN_SIZE(ipfw_insn_u32)) {
- /*
- * generic lookup. The key must be
- * in 32bit big-endian format.
- */
- v = ((ipfw_insn_u32 *)cmd)->d[1];
- switch (v) {
- case 0:
- case 1:
- /* IPv4 src/dst */
- break;
- case 2:
- case 3:
- /* src/dst port */
- *ptype = IPFW_TABLE_NUMBER;
- break;
- case 4:
- /* uid/gid */
- *ptype = IPFW_TABLE_NUMBER;
- break;
- case 5:
- /* jid */
- *ptype = IPFW_TABLE_NUMBER;
- break;
- case 6:
- /* dscp */
- *ptype = IPFW_TABLE_NUMBER;
- break;
- }
- }
- break;
- case O_XMIT:
- case O_RECV:
- case O_VIA:
- /* Interface table, possibly */
- cmdif = (ipfw_insn_if *)cmd;
- if (cmdif->name[0] != '\1')
+ if (F_LEN(cmd) > F_INSN_SIZE(ipfw_insn_u32)) {
+ /*
+ * generic lookup. The key must be
+ * in 32bit big-endian format.
+ */
+ v = ((ipfw_insn_u32 *)cmd)->d[1];
+ switch (v) {
+ case 0:
+ case 1:
+ /* IPv4 src/dst */
break;
-
- *ptype = IPFW_TABLE_INTERFACE;
- *puidx = cmdif->p.kidx;
- skip = 0;
- break;
- case O_IP_FLOW_LOOKUP:
- *puidx = cmd->arg1;
- *ptype = IPFW_TABLE_FLOW;
- skip = 0;
- break;
+ case 2:
+ case 3:
+ /* src/dst port */
+ *ptype = IPFW_TABLE_NUMBER;
+ break;
+ case 4:
+ /* uid/gid */
+ *ptype = IPFW_TABLE_NUMBER;
+ break;
+ case 5:
+ /* jid */
+ *ptype = IPFW_TABLE_NUMBER;
+ break;
+ case 6:
+ /* dscp */
+ *ptype = IPFW_TABLE_NUMBER;
+ break;
+ }
}
- return (skip);
+ return (0);
+}
+
+static int
+classify_via(ipfw_insn *cmd, uint16_t *puidx, uint8_t *ptype)
+{
+ ipfw_insn_if *cmdif;
+
+ /* Interface table, possibly */
+ cmdif = (ipfw_insn_if *)cmd;
+ if (cmdif->name[0] != '\1')
+ return (1);
+
+ *ptype = IPFW_TABLE_INTERFACE;
+ *puidx = cmdif->p.kidx;
+
+ return (0);
+}
+
+static int
+classify_flow(ipfw_insn *cmd, uint16_t *puidx, uint8_t *ptype)
+{
+
+ *puidx = cmd->arg1;
+ *ptype = IPFW_TABLE_FLOW;
+
+ return (0);
+}
+
+static void
+update_arg1(ipfw_insn *cmd, uint16_t idx)
+{
+
+ cmd->arg1 = idx;
}
-/*
- * Sets new table value for given opcode.
- * Assume the same opcodes as classify_table_opcode()
- */
static void
-update_table_opcode(ipfw_insn *cmd, uint16_t idx)
+update_via(ipfw_insn *cmd, uint16_t idx)
{
ipfw_insn_if *cmdif;
- switch (cmd->opcode) {
- case O_IP_SRC_LOOKUP:
- case O_IP_DST_LOOKUP:
- /* Basic IPv4/IPv6 or u32 lookups */
- cmd->arg1 = idx;
- break;
- case O_XMIT:
- case O_RECV:
- case O_VIA:
- /* Interface table, possibly */
- cmdif = (ipfw_insn_if *)cmd;
- cmdif->p.kidx = idx;
- break;
- case O_IP_FLOW_LOOKUP:
- cmd->arg1 = idx;
- break;
- }
+ cmdif = (ipfw_insn_if *)cmd;
+ cmdif->p.kidx = idx;
}
+static int
+table_findbyname(struct ip_fw_chain *ch, struct tid_info *ti,
+ struct named_object **pno)
+{
+ struct table_config *tc;
+ int error;
+
+ IPFW_UH_WLOCK_ASSERT(ch);
+
+ error = find_table_err(CHAIN_TO_NI(ch), ti, &tc);
+ if (error != 0)
+ return (error);
+
+ *pno = &tc->no;
+ return (0);
+}
+
+/* XXX: sets-sets! */
+static struct named_object *
+table_findbykidx(struct ip_fw_chain *ch, uint16_t idx)
+{
+ struct namedobj_instance *ni;
+ struct table_config *tc;
+
+ IPFW_UH_WLOCK_ASSERT(ch);
+ ni = CHAIN_TO_NI(ch);
+ tc = (struct table_config *)ipfw_objhash_lookup_kidx(ni, idx);
+ KASSERT(tc != NULL, ("Table with index %d not found", idx));
+
+ return (&tc->no);
+}
+
+static struct opcode_obj_rewrite opcodes[] = {
+ {
+ O_IP_SRC_LOOKUP, IPFW_TLV_TBL_NAME,
+ classify_srcdst, update_arg1,
+ table_findbyname, table_findbykidx, create_table_compat
+ },
+ {
+ O_IP_DST_LOOKUP, IPFW_TLV_TBL_NAME,
+ classify_srcdst, update_arg1,
+ table_findbyname, table_findbykidx, create_table_compat
+ },
+ {
+ O_IP_FLOW_LOOKUP, IPFW_TLV_TBL_NAME,
+ classify_flow, update_arg1,
+ table_findbyname, table_findbykidx, create_table_compat
+ },
+ {
+ O_XMIT, IPFW_TLV_TBL_NAME,
+ classify_via, update_via,
+ table_findbyname, table_findbykidx, create_table_compat
+ },
+ {
+ O_RECV, IPFW_TLV_TBL_NAME,
+ classify_via, update_via,
+ table_findbyname, table_findbykidx, create_table_compat
+ },
+ {
+ O_VIA, IPFW_TLV_TBL_NAME,
+ classify_via, update_via,
+ table_findbyname, table_findbykidx, create_table_compat
+ },
+};
+
+
/*
* Checks table name for validity.
* Enforce basic length checks, the rest
@@ -2960,10 +2977,11 @@ find_name_tlv(void *tlvs, int len, uint16_t uidx)
* or name in ntlv.
* Note @ti structure contains unchecked data from userland.
*
- * Returns pointer to table_config or NULL.
+ * Returns 0 in success and fills in @tc with found config
*/
-static struct table_config *
-find_table(struct namedobj_instance *ni, struct tid_info *ti)
+static int
+find_table_err(struct namedobj_instance *ni, struct tid_info *ti,
+ struct table_config **tc)
{
char *name, bname[16];
struct named_object *no;
@@ -2973,7 +2991,7 @@ find_table(struct namedobj_instance *ni, struct tid_info *ti)
if (ti->tlvs != NULL) {
ntlv = find_name_tlv(ti->tlvs, ti->tlen, ti->uidx);
if (ntlv == NULL)
- return (NULL);
+ return (EINVAL);
name = ntlv->name;
/*
@@ -2989,8 +3007,27 @@ find_table(struct namedobj_instance *ni, struct tid_info *ti)
}
no = ipfw_objhash_lookup_name(ni, set, name);
+ *tc = (struct table_config *)no;
+
+ return (0);
+}
+
+/*
+ * Finds table config based on either legacy index
+ * or name in ntlv.
+ * Note @ti structure contains unchecked data from userland.
+ *
+ * Returns pointer to table_config or NULL.
+ */
+static struct table_config *
+find_table(struct namedobj_instance *ni, struct tid_info *ti)
+{
+ struct table_config *tc;
+
+ if (find_table_err(ni, ti, &tc) != 0)
+ return (NULL);
- return ((struct table_config *)no);
+ return (tc);
}
/*
@@ -3016,6 +3053,7 @@ alloc_table_config(struct ip_fw_chain *ch, struct tid_info *ti,
name = ntlv->name;
set = ntlv->set;
} else {
+ /* Compat part: convert number to string representation */
snprintf(bname, sizeof(bname), "%d", ti->uidx);
name = bname;
set = 0;
@@ -3023,7 +3061,7 @@ alloc_table_config(struct ip_fw_chain *ch, struct tid_info *ti,
tc = malloc(sizeof(struct table_config), M_IPFW, M_WAITOK | M_ZERO);
tc->no.name = tc->tablename;
- tc->no.type = ta->type;
+ tc->no.subtype = ta->type;
tc->no.set = set;
tc->tflags = tflags;
tc->ta = ta;
@@ -3031,11 +3069,6 @@ alloc_table_config(struct ip_fw_chain *ch, struct tid_info *ti,
/* Set "shared" value type by default */
tc->vshared = 1;
- if (ti->tlvs == NULL) {
- tc->no.compat = 1;
- tc->no.uidx = ti->uidx;
- }
-
/* Preallocate data structures for new tables */
error = ta->init(ch, &tc->astate, &tc->ti_copy, aname, tflags);
if (error != 0) {
@@ -3211,7 +3244,6 @@ ipfw_move_tables_sets(struct ip_fw_chain *ch, ipfw_range_tlv *rt,
struct namedobj_instance *ni;
int bad, i, l, cmdlen;
uint16_t kidx;
- uint8_t type;
ipfw_insn *cmd;
IPFW_UH_WLOCK_ASSERT(ch);
@@ -3229,7 +3261,7 @@ ipfw_move_tables_sets(struct ip_fw_chain *ch, ipfw_range_tlv *rt,
cmdlen = 0;
for ( ; l > 0 ; l -= cmdlen, cmd += cmdlen) {
cmdlen = F_LEN(cmd);
- if (classify_table_opcode(cmd, &kidx, &type) != 0)
+ if (classify_opcode_kidx(cmd, &kidx) != 0)
continue;
no = ipfw_objhash_lookup_kidx(ni, kidx);
KASSERT(no != NULL,
@@ -3252,7 +3284,7 @@ ipfw_move_tables_sets(struct ip_fw_chain *ch, ipfw_range_tlv *rt,
cmdlen = 0;
for ( ; l > 0 ; l -= cmdlen, cmd += cmdlen) {
cmdlen = F_LEN(cmd);
- if (classify_table_opcode(cmd, &kidx, &type) != 0)
+ if (classify_opcode_kidx(cmd, &kidx) != 0)
continue;
no = ipfw_objhash_lookup_kidx(ni, kidx);
KASSERT(no != NULL,
@@ -3291,7 +3323,7 @@ ipfw_move_tables_sets(struct ip_fw_chain *ch, ipfw_range_tlv *rt,
cmdlen = 0;
for ( ; l > 0 ; l -= cmdlen, cmd += cmdlen) {
cmdlen = F_LEN(cmd);
- if (classify_table_opcode(cmd, &kidx, &type) != 0)
+ if (classify_opcode_kidx(cmd, &kidx) != 0)
continue;
no = ipfw_objhash_lookup_kidx(ni, kidx);
KASSERT(no != NULL,
@@ -3313,215 +3345,68 @@ ipfw_move_tables_sets(struct ip_fw_chain *ch, ipfw_range_tlv *rt,
}
/*
- * Finds and bumps refcount for tables referenced by given @rule.
+ * Finds and bumps refcount for objects referenced by given @rule.
* Auto-creates non-existing tables.
* Fills in @oib array with userland/kernel indexes.
- * First free oidx pointer is saved back in @oib.
*
* Returns 0 on success.
*/
static int
-find_ref_rule_tables(struct ip_fw_chain *ch, struct ip_fw *rule,
- struct rule_check_info *ci, struct obj_idx **oib, struct tid_info *ti)
+ref_rule_objects(struct ip_fw_chain *ch, struct ip_fw *rule,
+ struct rule_check_info *ci, struct obj_idx *oib, struct tid_info *ti)
{
- struct table_config *tc;
- struct namedobj_instance *ni;
- struct named_object *no;
int cmdlen, error, l, numnew;
- uint16_t kidx;
ipfw_insn *cmd;
- struct obj_idx *pidx, *pidx_first, *p;
+ struct obj_idx *pidx;
+ int found, unresolved;
- pidx_first = *oib;
- pidx = pidx_first;
+ pidx = oib;
l = rule->cmd_len;
cmd = rule->cmd;
cmdlen = 0;
error = 0;
numnew = 0;
+ found = 0;
+ unresolved = 0;
IPFW_UH_WLOCK(ch);
- ni = CHAIN_TO_NI(ch);
/* Increase refcount on each existing referenced table. */
for ( ; l > 0 ; l -= cmdlen, cmd += cmdlen) {
cmdlen = F_LEN(cmd);
- if (classify_table_opcode(cmd, &ti->uidx, &ti->type) != 0)
- continue;
-
- pidx->uidx = ti->uidx;
- pidx->type = ti->type;
-
- if ((tc = find_table(ni, ti)) != NULL) {
- if (tc->no.type != ti->type) {
- /* Incompatible types */
- error = EINVAL;
- break;
- }
-
- /* Reference found table and save kidx */
- tc->no.refcnt++;
- pidx->kidx = tc->no.kidx;
+ error = ref_opcode_object(ch, cmd, ti, pidx, &found, &unresolved);
+ if (error != 0)
+ break;
+ if (found || unresolved) {
+ pidx->off = rule->cmd_len - l;
pidx++;
- continue;
}
-
/*
* Compability stuff for old clients:
- * prepare to manually create non-existing tables.
+ * prepare to manually create non-existing objects.
*/
- pidx++;
- numnew++;
+ if (unresolved)
+ numnew++;
}
if (error != 0) {
/* Unref everything we have already done */
- for (p = *oib; p < pidx; p++) {
- if (p->kidx == 0)
- continue;
-
- /* Find & unref by existing idx */
- no = ipfw_objhash_lookup_kidx(ni, p->kidx);
- KASSERT(no != NULL, ("Ref'd table %d disappeared",
- p->kidx));
-
- no->refcnt--;
- }
- }
-
- IPFW_UH_WUNLOCK(ch);
-
- if (numnew == 0) {
- *oib = pidx;
- return (error);
- }
-
- /*
- * Compatibility stuff: do actual creation for non-existing,
- * but referenced tables.
- */
- for (p = pidx_first; p < pidx; p++) {
- if (p->kidx != 0)
- continue;
-
- ti->uidx = p->uidx;
- ti->type = p->type;
- ti->atype = 0;
-
- error = create_table_compat(ch, ti, &kidx);
- if (error == 0) {
- p->kidx = kidx;
- continue;
- }
-
- /* Error. We have to drop references */
- IPFW_UH_WLOCK(ch);
- for (p = pidx_first; p < pidx; p++) {
- if (p->kidx == 0)
- continue;
-
- /* Find & unref by existing idx */
- no = ipfw_objhash_lookup_kidx(ni, p->kidx);
- KASSERT(no != NULL, ("Ref'd table %d disappeared",
- p->kidx));
-
- no->refcnt--;
- }
+ unref_oib_objects(ch, rule->cmd, oib, pidx);
IPFW_UH_WUNLOCK(ch);
-
return (error);
}
- *oib = pidx;
-
- return (error);
-}
-
-/*
- * Remove references from every table used in @rule.
- */
-void
-ipfw_unref_rule_tables(struct ip_fw_chain *chain, struct ip_fw *rule)
-{
- int cmdlen, l;
- ipfw_insn *cmd;
- struct namedobj_instance *ni;
- struct named_object *no;
- uint16_t kidx;
- uint8_t type;
-
- IPFW_UH_WLOCK_ASSERT(chain);
- ni = CHAIN_TO_NI(chain);
-
- l = rule->cmd_len;
- cmd = rule->cmd;
- cmdlen = 0;
- for ( ; l > 0 ; l -= cmdlen, cmd += cmdlen) {
- cmdlen = F_LEN(cmd);
-
- if (classify_table_opcode(cmd, &kidx, &type) != 0)
- continue;
-
- no = ipfw_objhash_lookup_kidx(ni, kidx);
-
- KASSERT(no != NULL, ("table id %d not found", kidx));
- KASSERT(no->type == type, ("wrong type %d (%d) for table id %d",
- no->type, type, kidx));
- KASSERT(no->refcnt > 0, ("refcount for table %d is %d",
- kidx, no->refcnt));
-
- no->refcnt--;
- }
-}
-
-/*
- * Compatibility function for old ipfw(8) binaries.
- * Rewrites table kernel indices with userland ones.
- * Convert tables matching '/^\d+$/' to their atoi() value.
- * Use number 65535 for other tables.
- *
- * Returns 0 on success.
- */
-int
-ipfw_rewrite_table_kidx(struct ip_fw_chain *chain, struct ip_fw_rule0 *rule)
-{
- int cmdlen, error, l;
- ipfw_insn *cmd;
- uint16_t kidx, uidx;
- uint8_t type;
- struct named_object *no;
- struct namedobj_instance *ni;
-
- ni = CHAIN_TO_NI(chain);
- error = 0;
-
- l = rule->cmd_len;
- cmd = rule->cmd;
- cmdlen = 0;
- for ( ; l > 0 ; l -= cmdlen, cmd += cmdlen) {
- cmdlen = F_LEN(cmd);
-
- if (classify_table_opcode(cmd, &kidx, &type) != 0)
- continue;
+ IPFW_UH_WUNLOCK(ch);
- if ((no = ipfw_objhash_lookup_kidx(ni, kidx)) == NULL)
- return (1);
+ found = pidx - oib;
+ KASSERT(found == ci->object_opcodes,
+ ("refcount inconsistency: found: %d total: %d",
+ found, ci->object_opcodes));
- uidx = no->uidx;
- if (no->compat == 0) {
-
- /*
- * We are called via legacy opcode.
- * Save error and show table as fake number
- * not to make ipfw(8) hang.
- */
- uidx = 65535;
- error = 2;
- }
-
- update_table_opcode(cmd, uidx);
- }
+ /* Perform auto-creation for non-existing objects */
+ if (numnew != 0)
+ error = create_objects_compat(ch, rule->cmd, oib, pidx, ti);
return (error);
}
@@ -3534,31 +3419,27 @@ ipfw_rewrite_table_kidx(struct ip_fw_chain *chain, struct ip_fw_rule0 *rule)
* Returns 0 on success and appropriate error code otherwise.
*/
int
-ipfw_rewrite_table_uidx(struct ip_fw_chain *chain,
+ipfw_rewrite_rule_uidx(struct ip_fw_chain *chain,
struct rule_check_info *ci)
{
- int cmdlen, error, l;
+ int error;
ipfw_insn *cmd;
- uint16_t uidx;
uint8_t type;
- struct namedobj_instance *ni;
struct obj_idx *p, *pidx_first, *pidx_last;
struct tid_info ti;
- ni = CHAIN_TO_NI(chain);
-
/*
* Prepare an array for storing opcode indices.
* Use stack allocation by default.
*/
- if (ci->table_opcodes <= (sizeof(ci->obuf)/sizeof(ci->obuf[0]))) {
+ if (ci->object_opcodes <= (sizeof(ci->obuf)/sizeof(ci->obuf[0]))) {
/* Stack */
pidx_first = ci->obuf;
} else
- pidx_first = malloc(ci->table_opcodes * sizeof(struct obj_idx),
+ pidx_first = malloc(ci->object_opcodes * sizeof(struct obj_idx),
M_IPFW, M_WAITOK | M_ZERO);
- pidx_last = pidx_first;
+ pidx_last = pidx_first + ci->object_opcodes;
error = 0;
type = 0;
memset(&ti, 0, sizeof(ti));
@@ -3573,28 +3454,18 @@ ipfw_rewrite_table_uidx(struct ip_fw_chain *chain,
ti.tlen = ci->ctlv->head.length - sizeof(ipfw_obj_ctlv);
}
- /* Reference all used tables */
- error = find_ref_rule_tables(chain, ci->krule, ci, &pidx_last, &ti);
+ /* Reference all used tables and other objects */
+ error = ref_rule_objects(chain, ci->krule, ci, pidx_first, &ti);
if (error != 0)
goto free;
- IPFW_UH_WLOCK(chain);
-
/* Perform rule rewrite */
- l = ci->krule->cmd_len;
- cmd = ci->krule->cmd;
- cmdlen = 0;
p = pidx_first;
- for ( ; l > 0 ; l -= cmdlen, cmd += cmdlen) {
- cmdlen = F_LEN(cmd);
- if (classify_table_opcode(cmd, &uidx, &type) != 0)
- continue;
- update_table_opcode(cmd, p->kidx);
- p++;
+ for (p = pidx_first; p < pidx_last; p++) {
+ cmd = ci->krule->cmd + p->off;
+ update_opcode_kidx(cmd, p->kidx);
}
- IPFW_UH_WUNLOCK(chain);
-
free:
if (pidx_first != ci->obuf)
free(pidx_first, M_IPFW);
@@ -3641,6 +3512,7 @@ ipfw_destroy_tables(struct ip_fw_chain *ch, int last)
{
IPFW_DEL_SOPT_HANDLER(last, scodes);
+ IPFW_DEL_OBJ_REWRITER(last, opcodes);
/* Remove all tables from working set */
IPFW_UH_WLOCK(ch);
@@ -3678,6 +3550,7 @@ ipfw_init_tables(struct ip_fw_chain *ch, int first)
ipfw_table_value_init(ch, first);
ipfw_table_algo_init(ch);
+ IPFW_ADD_OBJ_REWRITER(first, opcodes);
IPFW_ADD_SOPT_HANDLER(first, scodes);
return (0);
}
diff --git a/sys/netpfil/ipfw/ip_fw_table.h b/sys/netpfil/ipfw/ip_fw_table.h
index 028e4502ab45..ca49fd47b69e 100644
--- a/sys/netpfil/ipfw/ip_fw_table.h
+++ b/sys/netpfil/ipfw/ip_fw_table.h
@@ -53,16 +53,6 @@ struct table_info {
u_long data; /* Hints for given func */
};
-/* Internal structures for handling sockopt data */
-struct tid_info {
- uint32_t set; /* table set */
- uint16_t uidx; /* table index */
- uint8_t type; /* table type */
- uint8_t atype;
- void *tlvs; /* Pointer to first TLV */
- int tlen; /* Total TLV size block */
-};
-
struct table_value;
struct tentry_info {
void *paddr;
@@ -189,13 +179,12 @@ void rollback_table_values(struct tableop_state *ts);
int ipfw_rewrite_table_uidx(struct ip_fw_chain *chain,
struct rule_check_info *ci);
-int ipfw_rewrite_table_kidx(struct ip_fw_chain *chain,
- struct ip_fw_rule0 *rule);
int ipfw_mark_table_kidx(struct ip_fw_chain *chain, struct ip_fw *rule,
uint32_t *bmask);
int ipfw_export_table_ntlv(struct ip_fw_chain *ch, uint16_t kidx,
struct sockopt_data *sd);
void ipfw_unref_rule_tables(struct ip_fw_chain *chain, struct ip_fw *rule);
+struct namedobj_instance *ipfw_get_table_objhash(struct ip_fw_chain *ch);
/* utility functions */
int ipfw_check_table_name(char *name);
diff --git a/sys/opencrypto/cryptodeflate.c b/sys/opencrypto/cryptodeflate.c
index 0ad86e3303e3..c55210dcbb78 100644
--- a/sys/opencrypto/cryptodeflate.c
+++ b/sys/opencrypto/cryptodeflate.c
@@ -29,7 +29,7 @@
/*
* This file contains a wrapper around the deflate algo compression
- * functions using the zlib library (see net/zlib.{c,h})
+ * functions using the zlib library (see libkern/zlib.c and sys/zlib.h})
*/
#include <sys/cdefs.h>
@@ -42,7 +42,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/sdt.h>
#include <sys/systm.h>
-#include <net/zlib.h>
+#include <sys/zlib.h>
#include <opencrypto/cryptodev.h>
#include <opencrypto/deflate.h>
diff --git a/sys/opencrypto/deflate.h b/sys/opencrypto/deflate.h
index dcf7a8441350..d31a3bf27e5b 100644
--- a/sys/opencrypto/deflate.h
+++ b/sys/opencrypto/deflate.h
@@ -36,7 +36,7 @@
#ifndef _CRYPTO_DEFLATE_H_
#define _CRYPTO_DEFLATE_H_
-#include <net/zlib.h>
+#include <sys/zlib.h>
#define Z_METHOD 8
#define Z_MEMLEVEL 8
diff --git a/sys/powerpc/aim/machdep.c b/sys/powerpc/aim/aim_machdep.c
index 1c2222048276..ab09ab6b5ad7 100644
--- a/sys/powerpc/aim/machdep.c
+++ b/sys/powerpc/aim/aim_machdep.c
@@ -129,106 +129,14 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/openfirm.h>
-int cold = 1;
#ifdef __powerpc64__
extern int n_slbs;
-int cacheline_size = 128;
-#else
-int cacheline_size = 32;
#endif
-int hw_direct_map = 1;
-
-extern void *ap_pcpu;
-
-struct pcpu __pcpu[MAXCPU];
-
-static struct trapframe frame0;
-
-char machine[] = "powerpc";
-SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, "");
-
-static void cpu_startup(void *);
-SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL);
-
-SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size,
- CTLFLAG_RD, &cacheline_size, 0, "");
-
-uintptr_t powerpc_init(vm_offset_t, vm_offset_t, vm_offset_t, void *);
-
-long Maxmem = 0;
-long realmem = 0;
#ifndef __powerpc64__
struct bat battable[16];
#endif
-struct kva_md_info kmi;
-
-static void
-cpu_startup(void *dummy)
-{
-
- /*
- * Initialise the decrementer-based clock.
- */
- decr_init();
-
- /*
- * Good {morning,afternoon,evening,night}.
- */
- cpu_setup(PCPU_GET(cpuid));
-
-#ifdef PERFMON
- perfmon_init();
-#endif
- printf("real memory = %ld (%ld MB)\n", ptoa(physmem),
- ptoa(physmem) / 1048576);
- realmem = physmem;
-
- if (bootverbose)
- printf("available KVA = %zd (%zd MB)\n",
- virtual_end - virtual_avail,
- (virtual_end - virtual_avail) / 1048576);
-
- /*
- * Display any holes after the first chunk of extended memory.
- */
- if (bootverbose) {
- int indx;
-
- printf("Physical memory chunk(s):\n");
- for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) {
- vm_offset_t size1 =
- phys_avail[indx + 1] - phys_avail[indx];
-
- #ifdef __powerpc64__
- printf("0x%016lx - 0x%016lx, %ld bytes (%ld pages)\n",
- #else
- printf("0x%08x - 0x%08x, %d bytes (%ld pages)\n",
- #endif
- phys_avail[indx], phys_avail[indx + 1] - 1, size1,
- size1 / PAGE_SIZE);
- }
- }
-
- vm_ksubmap_init(&kmi);
-
- printf("avail memory = %ld (%ld MB)\n", ptoa(vm_cnt.v_free_count),
- ptoa(vm_cnt.v_free_count) / 1048576);
-
- /*
- * Set up buffers, so they can be used to read disk labels.
- */
- bufinit();
- vm_pager_bufferinit();
-}
-
-extern vm_offset_t __startkernel, __endkernel;
-extern unsigned char __bss_start[];
-extern unsigned char __sbss_start[];
-extern unsigned char __sbss_end[];
-extern unsigned char _end[];
-
#ifndef __powerpc64__
/* Bits for running on 64-bit systems in 32-bit mode. */
extern void *testppc64, *testppc64size;
@@ -252,121 +160,25 @@ extern void *imisstrap, *imisssize;
extern void *dlmisstrap, *dlmisssize;
extern void *dsmisstrap, *dsmisssize;
-uintptr_t
-powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp)
+extern void *ap_pcpu;
+
+void aim_cpu_init(vm_offset_t toc);
+
+void
+aim_cpu_init(vm_offset_t toc)
{
- struct pcpu *pc;
- vm_offset_t startkernel, endkernel;
size_t trap_offset, trapsize;
vm_offset_t trap;
- void *kmdp;
- char *env;
register_t msr, scratch;
uint8_t *cache_check;
int cacheline_warn;
#ifndef __powerpc64__
int ppc64;
#endif
-#ifdef DDB
- vm_offset_t ksym_start;
- vm_offset_t ksym_end;
-#endif
- kmdp = NULL;
trap_offset = 0;
cacheline_warn = 0;
- /* First guess at start/end kernel positions */
- startkernel = __startkernel;
- endkernel = __endkernel;
-
- /* Check for ePAPR loader, which puts a magic value into r6 */
- if (mdp == (void *)0x65504150)
- mdp = NULL;
-
- /*
- * Parse metadata if present and fetch parameters. Must be done
- * before console is inited so cninit gets the right value of
- * boothowto.
- */
- if (mdp != NULL) {
- preload_metadata = mdp;
- kmdp = preload_search_by_type("elf kernel");
- if (kmdp != NULL) {
- boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
- kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *);
- endkernel = ulmax(endkernel, MD_FETCH(kmdp,
- MODINFOMD_KERNEND, vm_offset_t));
-#ifdef DDB
- ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t);
- ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t);
- db_fetch_ksymtab(ksym_start, ksym_end);
-#endif
- }
- } else {
- bzero(__sbss_start, __sbss_end - __sbss_start);
- bzero(__bss_start, _end - __bss_start);
- }
-
- /* Store boot environment state */
- OF_initial_setup((void *)fdt, NULL, (int (*)(void *))ofentry);
-
- /*
- * Init params/tunables that can be overridden by the loader
- */
- init_param1();
-
- /*
- * Start initializing proc0 and thread0.
- */
- proc_linkup0(&proc0, &thread0);
- thread0.td_frame = &frame0;
-
- /*
- * Set up per-cpu data.
- */
- pc = __pcpu;
- pcpu_init(pc, 0, sizeof(struct pcpu));
- pc->pc_curthread = &thread0;
-#ifdef __powerpc64__
- __asm __volatile("mr 13,%0" :: "r"(pc->pc_curthread));
-#else
- __asm __volatile("mr 2,%0" :: "r"(pc->pc_curthread));
-#endif
- pc->pc_cpuid = 0;
-
- __asm __volatile("mtsprg 0, %0" :: "r"(pc));
-
- /*
- * Init mutexes, which we use heavily in PMAP
- */
-
- mutex_init();
-
- /*
- * Install the OF client interface
- */
-
- OF_bootstrap();
-
- /*
- * Initialize the console before printing anything.
- */
- cninit();
-
- /*
- * Complain if there is no metadata.
- */
- if (mdp == NULL || kmdp == NULL) {
- printf("powerpc_init: no loader metadata.\n");
- }
-
- /*
- * Init KDB
- */
-
- kdb_init();
-
/* Various very early CPU fix ups */
switch (mfpvr() >> 16) {
/*
@@ -431,9 +243,6 @@ powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp)
cacheline_size = 32;
}
- /* Make sure the kernel icache is valid before we go too much further */
- __syncicache((caddr_t)startkernel, endkernel - startkernel);
-
#ifndef __powerpc64__
/*
* Figure out whether we need to use the 64 bit PMAP. This works by
@@ -552,12 +361,6 @@ powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp)
}
/*
- * Choose a platform module so we can get the physical memory map.
- */
-
- platform_probe_and_attach();
-
- /*
* Initialise virtual memory. Use BUS_PROBE_GENERIC priority
* in case the platform module had a better idea of what we
* should do.
@@ -566,96 +369,6 @@ powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp)
pmap_mmu_install(MMU_TYPE_G5, BUS_PROBE_GENERIC);
else
pmap_mmu_install(MMU_TYPE_OEA, BUS_PROBE_GENERIC);
-
- pmap_bootstrap(startkernel, endkernel);
- mtmsr(PSL_KERNSET & ~PSL_EE);
-
- /*
- * Initialize params/tunables that are derived from memsize
- */
- init_param2(physmem);
-
- /*
- * Grab booted kernel's name
- */
- env = kern_getenv("kernelname");
- if (env != NULL) {
- strlcpy(kernelname, env, sizeof(kernelname));
- freeenv(env);
- }
-
- /*
- * Finish setting up thread0.
- */
- thread0.td_pcb = (struct pcb *)
- ((thread0.td_kstack + thread0.td_kstack_pages * PAGE_SIZE -
- sizeof(struct pcb)) & ~15UL);
- bzero((void *)thread0.td_pcb, sizeof(struct pcb));
- pc->pc_curpcb = thread0.td_pcb;
-
- /* Initialise the message buffer. */
- msgbufinit(msgbufp, msgbufsize);
-
-#ifdef KDB
- if (boothowto & RB_KDB)
- kdb_enter(KDB_WHY_BOOTFLAGS,
- "Boot flags requested debugger");
-#endif
-
- return (((uintptr_t)thread0.td_pcb -
- (sizeof(struct callframe) - 3*sizeof(register_t))) & ~15UL);
-}
-
-void
-bzero(void *buf, size_t len)
-{
- caddr_t p;
-
- p = buf;
-
- while (((vm_offset_t) p & (sizeof(u_long) - 1)) && len) {
- *p++ = 0;
- len--;
- }
-
- while (len >= sizeof(u_long) * 8) {
- *(u_long*) p = 0;
- *((u_long*) p + 1) = 0;
- *((u_long*) p + 2) = 0;
- *((u_long*) p + 3) = 0;
- len -= sizeof(u_long) * 8;
- *((u_long*) p + 4) = 0;
- *((u_long*) p + 5) = 0;
- *((u_long*) p + 6) = 0;
- *((u_long*) p + 7) = 0;
- p += sizeof(u_long) * 8;
- }
-
- while (len >= sizeof(u_long)) {
- *(u_long*) p = 0;
- len -= sizeof(u_long);
- p += sizeof(u_long);
- }
-
- while (len) {
- *p++ = 0;
- len--;
- }
-}
-
-void
-cpu_boot(int howto)
-{
-}
-
-/*
- * Flush the D-cache for non-DMA I/O so that the I-cache can
- * be made coherent later.
- */
-void
-cpu_flush_dcache(void *ptr, size_t len)
-{
- /* TBD */
}
/*
@@ -669,17 +382,6 @@ cpu_halt(void)
}
int
-ptrace_set_pc(struct thread *td, unsigned long addr)
-{
- struct trapframe *tf;
-
- tf = td->td_frame;
- tf->srr0 = (register_t)addr;
-
- return (0);
-}
-
-int
ptrace_single_step(struct thread *td)
{
struct trapframe *tf;
@@ -727,41 +429,7 @@ memcpy(pcpu->pc_slb, PCPU_GET(slb), sizeof(pcpu->pc_slb));
#endif
}
-void
-spinlock_enter(void)
-{
- struct thread *td;
- register_t msr;
-
- td = curthread;
- if (td->td_md.md_spinlock_count == 0) {
- __asm __volatile("or 2,2,2"); /* Set high thread priority */
- msr = intr_disable();
- td->td_md.md_spinlock_count = 1;
- td->td_md.md_saved_msr = msr;
- } else
- td->td_md.md_spinlock_count++;
- critical_enter();
-}
-
-void
-spinlock_exit(void)
-{
- struct thread *td;
- register_t msr;
-
- td = curthread;
- critical_exit();
- msr = td->td_md.md_saved_msr;
- td->td_md.md_spinlock_count--;
- if (td->td_md.md_spinlock_count == 0) {
- intr_restore(msr);
- __asm __volatile("or 6,6,6"); /* Set normal thread priority */
- }
-}
-
#ifndef __powerpc64__
-
uint64_t
va_to_vsid(pmap_t pm, vm_offset_t va)
{
@@ -945,3 +613,4 @@ cpu_sleep()
enable_vec(curthread);
powerpc_sync();
}
+
diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c
index 23bd4498977b..c45f941231d2 100644
--- a/sys/powerpc/aim/mmu_oea64.c
+++ b/sys/powerpc/aim/mmu_oea64.c
@@ -137,8 +137,6 @@ struct ofw_map {
extern unsigned char _etext[];
extern unsigned char _end[];
-extern int ofw_real_mode;
-
/*
* Map of physical memory regions.
*/
@@ -852,8 +850,7 @@ moea64_late_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend
*/
chosen = OF_finddevice("/chosen");
- if (!ofw_real_mode && chosen != -1 &&
- OF_getprop(chosen, "mmu", &mmui, 4) != -1) {
+ if (chosen != -1 && OF_getprop(chosen, "mmu", &mmui, 4) != -1) {
mmu = OF_instance_to_package(mmui);
if (mmu == -1 ||
(sz = OF_getproplen(mmu, "translations")) == -1)
diff --git a/sys/powerpc/booke/machdep.c b/sys/powerpc/booke/booke_machdep.c
index 943063cfdb44..2a2777500727 100644
--- a/sys/powerpc/booke/machdep.c
+++ b/sys/powerpc/booke/booke_machdep.c
@@ -163,6 +163,7 @@ extern unsigned char __bss_start[];
extern unsigned char __sbss_start[];
extern unsigned char __sbss_end[];
extern unsigned char _end[];
+extern vm_offset_t __endkernel;
/*
* Bootinfo is passed to us by legacy loaders. Save the address of the
@@ -170,25 +171,6 @@ extern unsigned char _end[];
*/
uint32_t *bootinfo;
-struct kva_md_info kmi;
-struct pcpu __pcpu[MAXCPU];
-struct trapframe frame0;
-int cold = 1;
-long realmem = 0;
-long Maxmem = 0;
-char machine[] = "powerpc";
-SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, "");
-
-int cacheline_size = 32;
-
-SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size,
- CTLFLAG_RD, &cacheline_size, 0, "");
-
-int hw_direct_map = 0;
-
-static void cpu_booke_startup(void *);
-SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_booke_startup, NULL);
-
void print_kernel_section_addr(void);
void print_kenv(void);
u_int booke_init(uint32_t, uint32_t);
@@ -219,6 +201,16 @@ extern void *int_performance_counter;
("Handler " #handler " too far from interrupt vector base")); \
mtspr(ivor, (uintptr_t)(&handler) & 0xffffUL);
+uintptr_t powerpc_init(vm_offset_t fdt, vm_offset_t, vm_offset_t, void *mdp);
+void booke_cpu_init(void);
+
+void
+booke_cpu_init(void)
+{
+
+ pmap_mmu_install(MMU_TYPE_BOOKE, BUS_PROBE_GENERIC);
+}
+
void
ivor_setup(void)
{
@@ -244,90 +236,6 @@ ivor_setup(void)
#endif
}
-static void
-cpu_booke_startup(void *dummy)
-{
- int indx;
- unsigned long size;
-
- /* Initialise the decrementer-based clock. */
- decr_init();
-
- /* Good {morning,afternoon,evening,night}. */
- cpu_setup(PCPU_GET(cpuid));
-
- printf("real memory = %lu (%ld MB)\n", ptoa(physmem),
- ptoa(physmem) / 1048576);
- realmem = physmem;
-
- /* Display any holes after the first chunk of extended memory. */
- if (bootverbose) {
- printf("Physical memory chunk(s):\n");
- for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) {
- size = phys_avail[indx + 1] - phys_avail[indx];
-
- printf("0x%08x - 0x%08x, %lu bytes (%lu pages)\n",
- phys_avail[indx], phys_avail[indx + 1] - 1,
- size, size / PAGE_SIZE);
- }
- }
-
- vm_ksubmap_init(&kmi);
-
- printf("avail memory = %lu (%ld MB)\n", ptoa(vm_cnt.v_free_count),
- ptoa(vm_cnt.v_free_count) / 1048576);
-
- /* Set up buffers, so they can be used to read disk labels. */
- bufinit();
- vm_pager_bufferinit();
-}
-
-static char *
-kenv_next(char *cp)
-{
-
- if (cp != NULL) {
- while (*cp != 0)
- cp++;
- cp++;
- if (*cp == 0)
- cp = NULL;
- }
- return (cp);
-}
-
-void
-print_kenv(void)
-{
- int len;
- char *cp;
-
- debugf("loader passed (static) kenv:\n");
- if (kern_envp == NULL) {
- debugf(" no env, null ptr\n");
- return;
- }
- debugf(" kern_envp = 0x%08x\n", (u_int32_t)kern_envp);
-
- len = 0;
- for (cp = kern_envp; cp != NULL; cp = kenv_next(cp))
- debugf(" %x %s\n", (u_int32_t)cp, cp);
-}
-
-void
-print_kernel_section_addr(void)
-{
-
- debugf("kernel image addresses:\n");
- debugf(" kernel_text = 0x%08x\n", (uint32_t)kernel_text);
- debugf(" _etext (sdata) = 0x%08x\n", (uint32_t)_etext);
- debugf(" _edata = 0x%08x\n", (uint32_t)_edata);
- debugf(" __sbss_start = 0x%08x\n", (uint32_t)__sbss_start);
- debugf(" __sbss_end = 0x%08x\n", (uint32_t)__sbss_end);
- debugf(" __sbss_start = 0x%08x\n", (uint32_t)__bss_start);
- debugf(" _end = 0x%08x\n", (uint32_t)_end);
-}
-
static int
booke_check_for_fdt(uint32_t arg1, vm_offset_t *dtbp)
{
@@ -345,24 +253,20 @@ booke_check_for_fdt(uint32_t arg1, vm_offset_t *dtbp)
return (0);
}
-u_int
+uintptr_t
booke_init(uint32_t arg1, uint32_t arg2)
{
- struct pcpu *pc;
- void *kmdp, *mdp;
+ uintptr_t ret;
+ void *mdp;
vm_offset_t dtbp, end;
-#ifdef DDB
- vm_offset_t ksym_start;
- vm_offset_t ksym_end;
-#endif
-
- kmdp = NULL;
end = (uintptr_t)_end;
dtbp = (vm_offset_t)NULL;
/* Set up TLB initially */
bootinfo = NULL;
+ bzero(__sbss_start, __sbss_end - __sbss_start);
+ bzero(__bss_start, _end - __bss_start);
tlb1_init();
/*
@@ -391,152 +295,22 @@ booke_init(uint32_t arg1, uint32_t arg2)
memmove((void *)end, (void *)dtbp, fdt_totalsize((void *)dtbp));
dtbp = end;
end += fdt_totalsize((void *)dtbp);
+ __endkernel = end;
mdp = NULL;
} else if (arg1 > (uintptr_t)kernel_text) /* FreeBSD loader */
mdp = (void *)arg1;
else /* U-Boot */
mdp = NULL;
- /*
- * Parse metadata and fetch parameters.
- */
- if (mdp != NULL) {
- preload_metadata = mdp;
- kmdp = preload_search_by_type("elf kernel");
- if (kmdp != NULL) {
- boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
- kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *);
- dtbp = MD_FETCH(kmdp, MODINFOMD_DTBP, vm_offset_t);
- end = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t);
-
- bootinfo = (uint32_t *)preload_search_info(kmdp,
- MODINFO_METADATA | MODINFOMD_BOOTINFO);
-
-#ifdef DDB
- ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t);
- ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t);
- db_fetch_ksymtab(ksym_start, ksym_end);
-#endif
- }
- } else {
- bzero(__sbss_start, __sbss_end - __sbss_start);
- bzero(__bss_start, _end - __bss_start);
- }
-
-#if defined(FDT_DTB_STATIC)
- /*
- * In case the device tree blob was not retrieved (from metadata) try
- * to use the statically embedded one.
- */
- if (dtbp == (vm_offset_t)NULL)
- dtbp = (vm_offset_t)&fdt_static_dtb;
-#endif
-
- if (OF_install(OFW_FDT, 0) == FALSE)
- while (1);
-
- if (OF_init((void *)dtbp) != 0)
- while (1);
-
- OF_interpret("perform-fixup", 0);
-
/* Reset TLB1 to get rid of temporary mappings */
tlb1_init();
- /* Reset Time Base */
- mttb(0);
-
- /* Init params/tunables that can be overridden by the loader. */
- init_param1();
-
- /* Start initializing proc0 and thread0. */
- proc_linkup0(&proc0, &thread0);
- thread0.td_frame = &frame0;
-
- /* Set up per-cpu data and store the pointer in SPR general 0. */
- pc = &__pcpu[0];
- pcpu_init(pc, 0, sizeof(struct pcpu));
- pc->pc_curthread = &thread0;
-#ifdef __powerpc64__
- __asm __volatile("mr 13,%0" :: "r"(pc->pc_curthread));
-#else
- __asm __volatile("mr 2,%0" :: "r"(pc->pc_curthread));
-#endif
- __asm __volatile("mtsprg 0, %0" :: "r"(pc));
-
- /* Initialize system mutexes. */
- mutex_init();
-
- /* Initialize the console before printing anything. */
- cninit();
-
- /* Print out some debug info... */
- debugf("%s: console initialized\n", __func__);
- debugf(" arg3 mdp = 0x%08x\n", (u_int32_t)mdp);
- debugf(" end = 0x%08x\n", (u_int32_t)end);
- debugf(" boothowto = 0x%08x\n", boothowto);
-#ifdef MPC85XX
- debugf(" kernel ccsrbar = 0x%08x\n", CCSRBAR_VA);
-#endif
- debugf(" MSR = 0x%08x\n", mfmsr());
-#if defined(BOOKE_E500)
- debugf(" HID0 = 0x%08x\n", mfspr(SPR_HID0));
- debugf(" HID1 = 0x%08x\n", mfspr(SPR_HID1));
- debugf(" BUCSR = 0x%08x\n", mfspr(SPR_BUCSR));
-#endif
-
- debugf(" dtbp = 0x%08x\n", (uint32_t)dtbp);
-
- print_kernel_section_addr();
- print_kenv();
-#if defined(BOOKE_E500)
- //tlb1_print_entries();
- //tlb1_print_tlbentries();
-#endif
-
- kdb_init();
-
-#ifdef KDB
- if (boothowto & RB_KDB)
- kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
-#endif
-
- /* Initialise platform module */
- platform_probe_and_attach();
-
- /* Initialise virtual memory. */
- pmap_mmu_install(MMU_TYPE_BOOKE, 0);
- pmap_bootstrap((uintptr_t)kernel_text, end);
- debugf("MSR = 0x%08x\n", mfmsr());
-#if defined(BOOKE_E500)
- //tlb1_print_entries();
- //tlb1_print_tlbentries();
-#endif
-
- /* Initialize params/tunables that are derived from memsize. */
- init_param2(physmem);
-
- /* Finish setting up thread0. */
- thread0.td_pcb = (struct pcb *)
- ((thread0.td_kstack + thread0.td_kstack_pages * PAGE_SIZE -
- sizeof(struct pcb)) & ~15);
- bzero((void *)thread0.td_pcb, sizeof(struct pcb));
- pc->pc_curpcb = thread0.td_pcb;
-
- /* Initialise the message buffer. */
- msgbufinit(msgbufp, msgbufsize);
-
- /* Enable Machine Check interrupt. */
- mtmsr(mfmsr() | PSL_ME);
- isync();
+ ret = powerpc_init(dtbp, 0, 0, mdp);
/* Enable L1 caches */
booke_enable_l1_cache();
- debugf("%s: SP = 0x%08x\n", __func__,
- ((uintptr_t)thread0.td_pcb - 16) & ~15);
-
- return (((uintptr_t)thread0.td_pcb - 16) & ~15);
+ return (ret);
}
#define RES_GRANULE 32
@@ -560,63 +334,6 @@ cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz)
#endif
}
-/*
- * Flush the D-cache for non-DMA I/O so that the I-cache can
- * be made coherent later.
- */
-void
-cpu_flush_dcache(void *ptr, size_t len)
-{
- register_t addr, off;
-
- /*
- * Align the address to a cacheline and adjust the length
- * accordingly. Then round the length to a multiple of the
- * cacheline for easy looping.
- */
- addr = (uintptr_t)ptr;
- off = addr & (cacheline_size - 1);
- addr -= off;
- len = (len + off + cacheline_size - 1) & ~(cacheline_size - 1);
-
- while (len > 0) {
- __asm __volatile ("dcbf 0,%0" :: "r"(addr));
- __asm __volatile ("sync");
- addr += cacheline_size;
- len -= cacheline_size;
- }
-}
-
-void
-spinlock_enter(void)
-{
- struct thread *td;
- register_t msr;
-
- td = curthread;
- if (td->td_md.md_spinlock_count == 0) {
- msr = intr_disable();
- td->td_md.md_spinlock_count = 1;
- td->td_md.md_saved_msr = msr;
- } else
- td->td_md.md_spinlock_count++;
- critical_enter();
-}
-
-void
-spinlock_exit(void)
-{
- struct thread *td;
- register_t msr;
-
- td = curthread;
- critical_exit();
- msr = td->td_md.md_saved_msr;
- td->td_md.md_spinlock_count--;
- if (td->td_md.md_spinlock_count == 0)
- intr_restore(msr);
-}
-
/* Shutdown the CPU as much as possible. */
void
cpu_halt(void)
@@ -628,17 +345,6 @@ cpu_halt(void)
}
int
-ptrace_set_pc(struct thread *td, unsigned long addr)
-{
- struct trapframe *tf;
-
- tf = td->td_frame;
- tf->srr0 = (register_t)addr;
-
- return (0);
-}
-
-int
ptrace_single_step(struct thread *td)
{
struct trapframe *tf;
@@ -680,40 +386,3 @@ kdb_cpu_set_singlestep(void)
kdb_frame->srr1 |= PSL_DE;
}
-void
-bzero(void *buf, size_t len)
-{
- caddr_t p;
-
- p = buf;
-
- while (((vm_offset_t) p & (sizeof(u_long) - 1)) && len) {
- *p++ = 0;
- len--;
- }
-
- while (len >= sizeof(u_long) * 8) {
- *(u_long*) p = 0;
- *((u_long*) p + 1) = 0;
- *((u_long*) p + 2) = 0;
- *((u_long*) p + 3) = 0;
- len -= sizeof(u_long) * 8;
- *((u_long*) p + 4) = 0;
- *((u_long*) p + 5) = 0;
- *((u_long*) p + 6) = 0;
- *((u_long*) p + 7) = 0;
- p += sizeof(u_long) * 8;
- }
-
- while (len >= sizeof(u_long)) {
- *(u_long*) p = 0;
- len -= sizeof(u_long);
- p += sizeof(u_long);
- }
-
- while (len) {
- *p++ = 0;
- len--;
- }
-}
-
diff --git a/sys/powerpc/booke/pmap.c b/sys/powerpc/booke/pmap.c
index 2c6df639342b..c5e3bf33d0c1 100644
--- a/sys/powerpc/booke/pmap.c
+++ b/sys/powerpc/booke/pmap.c
@@ -1031,13 +1031,8 @@ mmu_booke_bootstrap(mmu_t mmu, vm_offset_t start, vm_offset_t kernelend)
* Align kernel start and end address (kernel image).
* Note that kernel end does not necessarily relate to kernsize.
* kernsize is the size of the kernel that is actually mapped.
- * Also note that "start - 1" is deliberate. With SMP, the
- * entry point is exactly a page from the actual load address.
- * As such, trunc_page() has no effect and we're off by a page.
- * Since we always have the ELF header between the load address
- * and the entry point, we can safely subtract 1 to compensate.
*/
- kernstart = trunc_page(start - 1);
+ kernstart = trunc_page(start);
data_start = round_page(kernelend);
data_end = data_start;
diff --git a/sys/powerpc/conf/GENERIC b/sys/powerpc/conf/GENERIC
index e3939be027a7..b5bf850263c2 100644
--- a/sys/powerpc/conf/GENERIC
+++ b/sys/powerpc/conf/GENERIC
@@ -32,6 +32,7 @@ options PSIM #GDB PSIM ppc simulator
options MAMBO #IBM Mambo Full System Simulator
options PSERIES #PAPR-compliant systems
+options FDT
options SCHED_ULE #ULE scheduler
options PREEMPTION #Enable kernel thread preemption
options INET #InterNETworking
diff --git a/sys/powerpc/ofw/ofw_machdep.c b/sys/powerpc/ofw/ofw_machdep.c
index 05af09436797..31813fb3a0ad 100644
--- a/sys/powerpc/ofw/ofw_machdep.c
+++ b/sys/powerpc/ofw/ofw_machdep.c
@@ -62,11 +62,12 @@ __FBSDID("$FreeBSD$");
#include <machine/ofw_machdep.h>
#include <machine/trap.h>
+static void *fdt;
+int ofw_real_mode;
+
#ifdef AIM
extern register_t ofmsr[5];
extern void *openfirmware_entry;
-static void *fdt;
-int ofw_real_mode;
char save_trap_init[0x2f00]; /* EXC_LAST */
char save_trap_of[0x2f00]; /* EXC_LAST */
@@ -336,10 +337,10 @@ ofw_mem_regions(struct mem_region *memp, int *memsz,
*availsz = asz;
}
-#ifdef AIM
void
OF_initial_setup(void *fdt_ptr, void *junk, int (*openfirm)(void *))
{
+#ifdef AIM
ofmsr[0] = mfmsr();
#ifdef __powerpc64__
ofmsr[0] &= ~PSL_SF;
@@ -348,22 +349,25 @@ OF_initial_setup(void *fdt_ptr, void *junk, int (*openfirm)(void *))
__asm __volatile("mfsprg1 %0" : "=&r"(ofmsr[2]));
__asm __volatile("mfsprg2 %0" : "=&r"(ofmsr[3]));
__asm __volatile("mfsprg3 %0" : "=&r"(ofmsr[4]));
+ openfirmware_entry = openfirm;
if (ofmsr[0] & PSL_DR)
ofw_real_mode = 0;
else
ofw_real_mode = 1;
+ ofw_save_trap_vec(save_trap_init);
+#else
+ ofw_real_mode = 1;
+#endif
+
fdt = fdt_ptr;
- openfirmware_entry = openfirm;
#ifdef FDT_DTB_STATIC
/* Check for a statically included blob */
if (fdt == NULL)
fdt = &fdt_static_dtb;
#endif
-
- ofw_save_trap_vec(save_trap_init);
}
boolean_t
@@ -371,6 +375,7 @@ OF_bootstrap()
{
boolean_t status = FALSE;
+#ifdef AIM
if (openfirmware_entry != NULL) {
if (ofw_real_mode) {
status = OF_install(OFW_STD_REAL, 0);
@@ -386,18 +391,22 @@ OF_bootstrap()
return status;
OF_init(openfirmware);
- } else if (fdt != NULL) {
+ } else
+#endif
+ if (fdt != NULL) {
status = OF_install(OFW_FDT, 0);
if (status != TRUE)
return status;
OF_init(fdt);
+ OF_interpret("perform-fixup", 0);
}
return (status);
}
+#ifdef AIM
void
ofw_quiesce(void)
{
diff --git a/sys/powerpc/powerpc/busdma_machdep.c b/sys/powerpc/powerpc/busdma_machdep.c
index bd226c85951c..9ea51ced1de4 100644
--- a/sys/powerpc/powerpc/busdma_machdep.c
+++ b/sys/powerpc/powerpc/busdma_machdep.c
@@ -1121,8 +1121,8 @@ add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr,
if (dmat->flags & BUS_DMA_KEEP_PG_OFFSET) {
/* Page offset needs to be preserved. */
- bpage->vaddr |= vaddr & PAGE_MASK;
- bpage->busaddr |= vaddr & PAGE_MASK;
+ bpage->vaddr |= addr & PAGE_MASK;
+ bpage->busaddr |= addr & PAGE_MASK;
}
bpage->datavaddr = vaddr;
bpage->dataaddr = addr;
diff --git a/sys/powerpc/powerpc/machdep.c b/sys/powerpc/powerpc/machdep.c
new file mode 100644
index 000000000000..2bc9496ad6d0
--- /dev/null
+++ b/sys/powerpc/powerpc/machdep.c
@@ -0,0 +1,502 @@
+/*-
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 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.
+ */
+/*-
+ * Copyright (C) 2001 Benno Rice
+ * 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 Benno Rice ``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: machdep.c,v 1.74.2.1 2000/11/01 16:13:48 tv Exp $
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_compat.h"
+#include "opt_ddb.h"
+#include "opt_kstack_pages.h"
+#include "opt_platform.h"
+
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/systm.h>
+#include <sys/bio.h>
+#include <sys/buf.h>
+#include <sys/bus.h>
+#include <sys/cons.h>
+#include <sys/cpu.h>
+#include <sys/eventhandler.h>
+#include <sys/exec.h>
+#include <sys/imgact.h>
+#include <sys/kdb.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/linker.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/msgbuf.h>
+#include <sys/mutex.h>
+#include <sys/ptrace.h>
+#include <sys/reboot.h>
+#include <sys/rwlock.h>
+#include <sys/signalvar.h>
+#include <sys/syscallsubr.h>
+#include <sys/sysctl.h>
+#include <sys/sysent.h>
+#include <sys/sysproto.h>
+#include <sys/ucontext.h>
+#include <sys/uio.h>
+#include <sys/vmmeter.h>
+#include <sys/vnode.h>
+
+#include <net/netisr.h>
+
+#include <vm/vm.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 <machine/altivec.h>
+#ifndef __powerpc64__
+#include <machine/bat.h>
+#endif
+#include <machine/cpu.h>
+#include <machine/elf.h>
+#include <machine/fpu.h>
+#include <machine/hid.h>
+#include <machine/kdb.h>
+#include <machine/md_var.h>
+#include <machine/metadata.h>
+#include <machine/mmuvar.h>
+#include <machine/pcb.h>
+#include <machine/reg.h>
+#include <machine/sigframe.h>
+#include <machine/spr.h>
+#include <machine/trap.h>
+#include <machine/vmparam.h>
+#include <machine/ofw_machdep.h>
+
+#include <ddb/ddb.h>
+
+#include <dev/ofw/openfirm.h>
+
+int cold = 1;
+#ifdef __powerpc64__
+int cacheline_size = 128;
+#else
+int cacheline_size = 32;
+#endif
+int hw_direct_map = 1;
+
+extern void *ap_pcpu;
+
+struct pcpu __pcpu[MAXCPU];
+
+static struct trapframe frame0;
+
+char machine[] = "powerpc";
+SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, "");
+
+static void cpu_startup(void *);
+SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL);
+
+SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size,
+ CTLFLAG_RD, &cacheline_size, 0, "");
+
+uintptr_t powerpc_init(vm_offset_t, vm_offset_t, vm_offset_t, void *);
+
+long Maxmem = 0;
+long realmem = 0;
+
+struct kva_md_info kmi;
+
+static void
+cpu_startup(void *dummy)
+{
+
+ /*
+ * Initialise the decrementer-based clock.
+ */
+ decr_init();
+
+ /*
+ * Good {morning,afternoon,evening,night}.
+ */
+ cpu_setup(PCPU_GET(cpuid));
+
+#ifdef PERFMON
+ perfmon_init();
+#endif
+ printf("real memory = %ld (%ld MB)\n", ptoa(physmem),
+ ptoa(physmem) / 1048576);
+ realmem = physmem;
+
+ if (bootverbose)
+ printf("available KVA = %zd (%zd MB)\n",
+ virtual_end - virtual_avail,
+ (virtual_end - virtual_avail) / 1048576);
+
+ /*
+ * Display any holes after the first chunk of extended memory.
+ */
+ if (bootverbose) {
+ int indx;
+
+ printf("Physical memory chunk(s):\n");
+ for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) {
+ vm_offset_t size1 =
+ phys_avail[indx + 1] - phys_avail[indx];
+
+ #ifdef __powerpc64__
+ printf("0x%016lx - 0x%016lx, %ld bytes (%ld pages)\n",
+ #else
+ printf("0x%08x - 0x%08x, %d bytes (%ld pages)\n",
+ #endif
+ phys_avail[indx], phys_avail[indx + 1] - 1, size1,
+ size1 / PAGE_SIZE);
+ }
+ }
+
+ vm_ksubmap_init(&kmi);
+
+ printf("avail memory = %ld (%ld MB)\n", ptoa(vm_cnt.v_free_count),
+ ptoa(vm_cnt.v_free_count) / 1048576);
+
+ /*
+ * Set up buffers, so they can be used to read disk labels.
+ */
+ bufinit();
+ vm_pager_bufferinit();
+}
+
+extern vm_offset_t __startkernel, __endkernel;
+extern unsigned char __bss_start[];
+extern unsigned char __sbss_start[];
+extern unsigned char __sbss_end[];
+extern unsigned char _end[];
+
+void aim_cpu_init(vm_offset_t toc);
+void booke_cpu_init(void);
+
+uintptr_t
+powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp)
+{
+ struct pcpu *pc;
+ vm_offset_t startkernel, endkernel;
+ void *kmdp;
+ char *env;
+#ifdef DDB
+ vm_offset_t ksym_start;
+ vm_offset_t ksym_end;
+#endif
+
+ kmdp = NULL;
+
+ /* First guess at start/end kernel positions */
+ startkernel = __startkernel;
+ endkernel = __endkernel;
+
+ /* Check for ePAPR loader, which puts a magic value into r6 */
+ if (mdp == (void *)0x65504150)
+ mdp = NULL;
+
+ /*
+ * Parse metadata if present and fetch parameters. Must be done
+ * before console is inited so cninit gets the right value of
+ * boothowto.
+ */
+ if (mdp != NULL) {
+ preload_metadata = mdp;
+ kmdp = preload_search_by_type("elf kernel");
+ if (kmdp != NULL) {
+ boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
+ kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *);
+ endkernel = ulmax(endkernel, MD_FETCH(kmdp,
+ MODINFOMD_KERNEND, vm_offset_t));
+#ifdef DDB
+ ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t);
+ ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t);
+ db_fetch_ksymtab(ksym_start, ksym_end);
+#endif
+ }
+ } else {
+ bzero(__sbss_start, __sbss_end - __sbss_start);
+ bzero(__bss_start, _end - __bss_start);
+ }
+#ifdef BOOKE
+ tlb1_init();
+#endif
+
+ /* Store boot environment state */
+ OF_initial_setup((void *)fdt, NULL, (int (*)(void *))ofentry);
+
+ /*
+ * Init params/tunables that can be overridden by the loader
+ */
+ init_param1();
+
+ /*
+ * Start initializing proc0 and thread0.
+ */
+ proc_linkup0(&proc0, &thread0);
+ thread0.td_frame = &frame0;
+
+ /*
+ * Set up per-cpu data.
+ */
+ pc = __pcpu;
+ pcpu_init(pc, 0, sizeof(struct pcpu));
+ pc->pc_curthread = &thread0;
+#ifdef __powerpc64__
+ __asm __volatile("mr 13,%0" :: "r"(pc->pc_curthread));
+#else
+ __asm __volatile("mr 2,%0" :: "r"(pc->pc_curthread));
+#endif
+ pc->pc_cpuid = 0;
+
+ __asm __volatile("mtsprg 0, %0" :: "r"(pc));
+
+ /*
+ * Init mutexes, which we use heavily in PMAP
+ */
+
+ mutex_init();
+
+ /*
+ * Install the OF client interface
+ */
+
+ OF_bootstrap();
+
+ /*
+ * Initialize the console before printing anything.
+ */
+ cninit();
+
+ /*
+ * Complain if there is no metadata.
+ */
+ if (mdp == NULL || kmdp == NULL) {
+ printf("powerpc_init: no loader metadata.\n");
+ }
+
+ /*
+ * Init KDB
+ */
+
+ kdb_init();
+
+#ifdef AIM
+ aim_cpu_init(toc);
+#else /* BOOKE */
+ booke_cpu_init();
+
+ /* Make sure the kernel icache is valid before we go too much further */
+ __syncicache((caddr_t)startkernel, endkernel - startkernel);
+#endif
+
+ /*
+ * Choose a platform module so we can get the physical memory map.
+ */
+
+ platform_probe_and_attach();
+
+ /*
+ * Bring up MMU
+ */
+ pmap_bootstrap(startkernel, endkernel);
+ mtmsr(PSL_KERNSET & ~PSL_EE);
+
+ /*
+ * Initialize params/tunables that are derived from memsize
+ */
+ init_param2(physmem);
+
+ /*
+ * Grab booted kernel's name
+ */
+ env = kern_getenv("kernelname");
+ if (env != NULL) {
+ strlcpy(kernelname, env, sizeof(kernelname));
+ freeenv(env);
+ }
+
+ /*
+ * Finish setting up thread0.
+ */
+ thread0.td_pcb = (struct pcb *)
+ ((thread0.td_kstack + thread0.td_kstack_pages * PAGE_SIZE -
+ sizeof(struct pcb)) & ~15UL);
+ bzero((void *)thread0.td_pcb, sizeof(struct pcb));
+ pc->pc_curpcb = thread0.td_pcb;
+
+ /* Initialise the message buffer. */
+ msgbufinit(msgbufp, msgbufsize);
+
+#ifdef KDB
+ if (boothowto & RB_KDB)
+ kdb_enter(KDB_WHY_BOOTFLAGS,
+ "Boot flags requested debugger");
+#endif
+
+ return (((uintptr_t)thread0.td_pcb -
+ (sizeof(struct callframe) - 3*sizeof(register_t))) & ~15UL);
+}
+
+void
+bzero(void *buf, size_t len)
+{
+ caddr_t p;
+
+ p = buf;
+
+ while (((vm_offset_t) p & (sizeof(u_long) - 1)) && len) {
+ *p++ = 0;
+ len--;
+ }
+
+ while (len >= sizeof(u_long) * 8) {
+ *(u_long*) p = 0;
+ *((u_long*) p + 1) = 0;
+ *((u_long*) p + 2) = 0;
+ *((u_long*) p + 3) = 0;
+ len -= sizeof(u_long) * 8;
+ *((u_long*) p + 4) = 0;
+ *((u_long*) p + 5) = 0;
+ *((u_long*) p + 6) = 0;
+ *((u_long*) p + 7) = 0;
+ p += sizeof(u_long) * 8;
+ }
+
+ while (len >= sizeof(u_long)) {
+ *(u_long*) p = 0;
+ len -= sizeof(u_long);
+ p += sizeof(u_long);
+ }
+
+ while (len) {
+ *p++ = 0;
+ len--;
+ }
+}
+
+/*
+ * Flush the D-cache for non-DMA I/O so that the I-cache can
+ * be made coherent later.
+ */
+void
+cpu_flush_dcache(void *ptr, size_t len)
+{
+ register_t addr, off;
+
+ /*
+ * Align the address to a cacheline and adjust the length
+ * accordingly. Then round the length to a multiple of the
+ * cacheline for easy looping.
+ */
+ addr = (uintptr_t)ptr;
+ off = addr & (cacheline_size - 1);
+ addr -= off;
+ len = (len + off + cacheline_size - 1) & ~(cacheline_size - 1);
+
+ while (len > 0) {
+ __asm __volatile ("dcbf 0,%0" :: "r"(addr));
+ __asm __volatile ("sync");
+ addr += cacheline_size;
+ len -= cacheline_size;
+ }
+}
+
+int
+ptrace_set_pc(struct thread *td, unsigned long addr)
+{
+ struct trapframe *tf;
+
+ tf = td->td_frame;
+ tf->srr0 = (register_t)addr;
+
+ return (0);
+}
+
+void
+spinlock_enter(void)
+{
+ struct thread *td;
+ register_t msr;
+
+ td = curthread;
+ if (td->td_md.md_spinlock_count == 0) {
+ __asm __volatile("or 2,2,2"); /* Set high thread priority */
+ msr = intr_disable();
+ td->td_md.md_spinlock_count = 1;
+ td->td_md.md_saved_msr = msr;
+ } else
+ td->td_md.md_spinlock_count++;
+ critical_enter();
+}
+
+void
+spinlock_exit(void)
+{
+ struct thread *td;
+ register_t msr;
+
+ td = curthread;
+ critical_exit();
+ msr = td->td_md.md_saved_msr;
+ td->td_md.md_spinlock_count--;
+ if (td->td_md.md_spinlock_count == 0) {
+ intr_restore(msr);
+ __asm __volatile("or 6,6,6"); /* Set normal thread priority */
+ }
+}
+
diff --git a/sys/powerpc/aim/uma_machdep.c b/sys/powerpc/powerpc/uma_machdep.c
index 1c27e3e773ed..1c27e3e773ed 100644
--- a/sys/powerpc/aim/uma_machdep.c
+++ b/sys/powerpc/powerpc/uma_machdep.c
diff --git a/sys/sparc64/pci/apb.c b/sys/sparc64/pci/apb.c
index 9b3fa4427265..c0d61728de8f 100644
--- a/sys/sparc64/pci/apb.c
+++ b/sys/sparc64/pci/apb.c
@@ -171,20 +171,14 @@ apb_attach(device_t dev)
* Get current bridge configuration.
*/
sc->sc_bsc.ops_pcib_sc.domain = pci_get_domain(dev);
- sc->sc_bsc.ops_pcib_sc.secstat =
- pci_read_config(dev, PCIR_SECSTAT_1, 2);
- sc->sc_bsc.ops_pcib_sc.command =
- pci_read_config(dev, PCIR_COMMAND, 2);
- sc->sc_bsc.ops_pcib_sc.pribus =
- pci_read_config(dev, PCIR_PRIBUS_1, 1);
+ sc->sc_bsc.ops_pcib_sc.pribus = pci_get_bus(dev);
+ pci_write_config(dev, PCIR_PRIBUS_1, sc->sc_bsc.ops_pcib_sc.pribus, 1);
sc->sc_bsc.ops_pcib_sc.bus.sec =
pci_read_config(dev, PCIR_SECBUS_1, 1);
sc->sc_bsc.ops_pcib_sc.bus.sub =
pci_read_config(dev, PCIR_SUBBUS_1, 1);
sc->sc_bsc.ops_pcib_sc.bridgectl =
pci_read_config(dev, PCIR_BRIDGECTL_1, 2);
- sc->sc_bsc.ops_pcib_sc.seclat =
- pci_read_config(dev, PCIR_SECLAT_1, 1);
sc->sc_iomap = pci_read_config(dev, APBR_IOMAP, 1);
sc->sc_memmap = pci_read_config(dev, APBR_MEMMAP, 1);
diff --git a/sys/sys/cdefs.h b/sys/sys/cdefs.h
index 553a8999648d..ab7d59d2546a 100644
--- a/sys/sys/cdefs.h
+++ b/sys/sys/cdefs.h
@@ -388,6 +388,12 @@
#define __alloc_size(x)
#endif
+#if __has_attribute(alloc_align) || __GNUC_PREREQ__(4, 9)
+#define __alloc_align(x) __attribute__((__alloc_align__(x)))
+#else
+#define __alloc_align(x)
+#endif
+
/* XXX: should use `#if __STDC_VERSION__ < 199901'. */
#if !__GNUC_PREREQ__(2, 7) && !defined(__INTEL_COMPILER)
#define __func__ NULL
@@ -763,6 +769,24 @@
#endif
/*
+ * Type Safety Checking
+ *
+ * Clang provides additional attributes to enable checking type safety
+ * properties that cannot be enforced by the C type system.
+ */
+
+#if __has_attribute(argument_with_type_tag) && \
+ __has_attribute(type_tag_for_datatype) && !defined(lint)
+#define __arg_type_tag(arg_kind, arg_idx, type_tag_idx) \
+ __attribute__((__argument_with_type_tag__(arg_kind, arg_idx, type_tag_idx)))
+#define __datatype_type_tag(kind, type) \
+ __attribute__((__type_tag_for_datatype__(kind, type)))
+#else
+#define __arg_type_tag(arg_kind, arg_idx, type_tag_idx)
+#define __datatype_type_tag(kind, type)
+#endif
+
+/*
* Lock annotations.
*
* Clang provides support for doing basic thread-safety tests at
diff --git a/sys/sys/nv.h b/sys/sys/nv.h
index 0876e575c814..5c342dced820 100644
--- a/sys/sys/nv.h
+++ b/sys/sys/nv.h
@@ -75,6 +75,7 @@ nvlist_t *nvlist_create(int flags);
void nvlist_destroy(nvlist_t *nvl);
int nvlist_error(const nvlist_t *nvl);
bool nvlist_empty(const nvlist_t *nvl);
+int nvlist_flags(const nvlist_t *nvl);
void nvlist_set_error(nvlist_t *nvl, int error);
nvlist_t *nvlist_clone(const nvlist_t *nvl);
@@ -194,129 +195,6 @@ void nvlist_free_descriptor(nvlist_t *nvl, const char *name);
#endif
void nvlist_free_binary(nvlist_t *nvl, const char *name);
-/*
- * Below are the same functions, but which operate on format strings and
- * variable argument lists.
- *
- * Functions that are not inserting a new pair into the nvlist cannot handle
- * a failure to allocate the memory to hold the new name. Therefore these
- * functions are not provided in the kernel.
- */
-
-#ifndef _KERNEL
-bool nvlist_existsf(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
-bool nvlist_existsf_type(const nvlist_t *nvl, int type, const char *namefmt, ...) __printflike(3, 4);
-
-bool nvlist_existsf_null(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
-bool nvlist_existsf_bool(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
-bool nvlist_existsf_number(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
-bool nvlist_existsf_string(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
-bool nvlist_existsf_nvlist(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
-bool nvlist_existsf_descriptor(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
-bool nvlist_existsf_binary(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
-
-bool nvlist_existsv(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
-bool nvlist_existsv_type(const nvlist_t *nvl, int type, const char *namefmt, va_list nameap) __printflike(3, 0);
-
-bool nvlist_existsv_null(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
-bool nvlist_existsv_bool(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
-bool nvlist_existsv_number(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
-bool nvlist_existsv_string(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
-bool nvlist_existsv_nvlist(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
-bool nvlist_existsv_descriptor(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
-bool nvlist_existsv_binary(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
-#endif
-
-void nvlist_addf_null(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
-void nvlist_addf_bool(nvlist_t *nvl, bool value, const char *namefmt, ...) __printflike(3, 4);
-void nvlist_addf_number(nvlist_t *nvl, uint64_t value, const char *namefmt, ...) __printflike(3, 4);
-void nvlist_addf_string(nvlist_t *nvl, const char *value, const char *namefmt, ...) __printflike(3, 4);
-void nvlist_addf_nvlist(nvlist_t *nvl, const nvlist_t *value, const char *namefmt, ...) __printflike(3, 4);
-#ifndef _KERNEL
-void nvlist_addf_descriptor(nvlist_t *nvl, int value, const char *namefmt, ...) __printflike(3, 4);
-#endif
-void nvlist_addf_binary(nvlist_t *nvl, const void *value, size_t size, const char *namefmt, ...) __printflike(4, 5);
-
-#if !defined(_KERNEL) || defined(_VA_LIST_DECLARED)
-void nvlist_addv_null(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
-void nvlist_addv_bool(nvlist_t *nvl, bool value, const char *namefmt, va_list nameap) __printflike(3, 0);
-void nvlist_addv_number(nvlist_t *nvl, uint64_t value, const char *namefmt, va_list nameap) __printflike(3, 0);
-void nvlist_addv_string(nvlist_t *nvl, const char *value, const char *namefmt, va_list nameap) __printflike(3, 0);
-void nvlist_addv_nvlist(nvlist_t *nvl, const nvlist_t *value, const char *namefmt, va_list nameap) __printflike(3, 0);
-#ifndef _KERNEL
-void nvlist_addv_descriptor(nvlist_t *nvl, int value, const char *namefmt, va_list nameap) __printflike(3, 0);
-#endif
-void nvlist_addv_binary(nvlist_t *nvl, const void *value, size_t size, const char *namefmt, va_list nameap) __printflike(4, 0);
-#endif
-
-void nvlist_movef_string(nvlist_t *nvl, char *value, const char *namefmt, ...) __printflike(3, 4);
-void nvlist_movef_nvlist(nvlist_t *nvl, nvlist_t *value, const char *namefmt, ...) __printflike(3, 4);
-#ifndef _KERNEL
-void nvlist_movef_descriptor(nvlist_t *nvl, int value, const char *namefmt, ...) __printflike(3, 4);
-#endif
-void nvlist_movef_binary(nvlist_t *nvl, void *value, size_t size, const char *namefmt, ...) __printflike(4, 5);
-
-#if !defined(_KERNEL) || defined(_VA_LIST_DECLARED)
-void nvlist_movev_string(nvlist_t *nvl, char *value, const char *namefmt, va_list nameap) __printflike(3, 0);
-void nvlist_movev_nvlist(nvlist_t *nvl, nvlist_t *value, const char *namefmt, va_list nameap) __printflike(3, 0);
-#ifndef _KERNEL
-void nvlist_movev_descriptor(nvlist_t *nvl, int value, const char *namefmt, va_list nameap) __printflike(3, 0);
-#endif
-void nvlist_movev_binary(nvlist_t *nvl, void *value, size_t size, const char *namefmt, va_list nameap) __printflike(4, 0);
-#endif
-
-#ifndef _KERNEL
-bool nvlist_getf_bool(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
-uint64_t nvlist_getf_number(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
-const char *nvlist_getf_string(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
-const nvlist_t *nvlist_getf_nvlist(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
-int nvlist_getf_descriptor(const nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
-const void *nvlist_getf_binary(const nvlist_t *nvl, size_t *sizep, const char *namefmt, ...) __printflike(3, 4);
-
-bool nvlist_getv_bool(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
-uint64_t nvlist_getv_number(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
-const char *nvlist_getv_string(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
-const nvlist_t *nvlist_getv_nvlist(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
-int nvlist_getv_descriptor(const nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
-const void *nvlist_getv_binary(const nvlist_t *nvl, size_t *sizep, const char *namefmt, va_list nameap) __printflike(3, 0);
-
-bool nvlist_takef_bool(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
-uint64_t nvlist_takef_number(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
-char *nvlist_takef_string(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
-nvlist_t *nvlist_takef_nvlist(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
-int nvlist_takef_descriptor(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
-void *nvlist_takef_binary(nvlist_t *nvl, size_t *sizep, const char *namefmt, ...) __printflike(3, 4);
-
-bool nvlist_takev_bool(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
-uint64_t nvlist_takev_number(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
-char *nvlist_takev_string(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
-nvlist_t *nvlist_takev_nvlist(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
-int nvlist_takev_descriptor(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
-void *nvlist_takev_binary(nvlist_t *nvl, size_t *sizep, const char *namefmt, va_list nameap) __printflike(3, 0);
-
-void nvlist_freef(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
-void nvlist_freef_type(nvlist_t *nvl, int type, const char *namefmt, ...) __printflike(3, 4);
-
-void nvlist_freef_null(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
-void nvlist_freef_bool(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
-void nvlist_freef_number(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
-void nvlist_freef_string(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
-void nvlist_freef_nvlist(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
-void nvlist_freef_descriptor(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
-void nvlist_freef_binary(nvlist_t *nvl, const char *namefmt, ...) __printflike(2, 3);
-
-void nvlist_freev(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
-void nvlist_freev_type(nvlist_t *nvl, int type, const char *namefmt, va_list nameap) __printflike(3, 0);
-
-void nvlist_freev_null(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
-void nvlist_freev_bool(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
-void nvlist_freev_number(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
-void nvlist_freev_string(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
-void nvlist_freev_nvlist(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
-void nvlist_freev_descriptor(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
-void nvlist_freev_binary(nvlist_t *nvl, const char *namefmt, va_list nameap) __printflike(2, 0);
-#endif /* _KERNEL */
-
__END_DECLS
#endif /* !_NV_H_ */
diff --git a/sys/sys/nv_impl.h b/sys/sys/nv_impl.h
index da90e79a3d3a..c088c3d03bfc 100644
--- a/sys/sys/nv_impl.h
+++ b/sys/sys/nv_impl.h
@@ -41,23 +41,24 @@ typedef struct nvpair nvpair_t;
#define NV_TYPE_NVLIST_UP 255
-#define NV_TYPE_FIRST NV_TYPE_NULL
-#define NV_TYPE_LAST NV_TYPE_BINARY
+#define NV_TYPE_FIRST NV_TYPE_NULL
+#define NV_TYPE_LAST NV_TYPE_BINARY
#define NV_FLAG_BIG_ENDIAN 0x80
#ifdef _KERNEL
-#define nv_malloc(size) malloc((size), M_NVLIST, M_NOWAIT)
+#define nv_malloc(size) malloc((size), M_NVLIST, M_WAITOK)
#define nv_calloc(n, size) malloc((n) * (size), M_NVLIST, \
- M_NOWAIT | M_ZERO)
+ M_WAITOK | M_ZERO)
#define nv_realloc(buf, size) realloc((buf), (size), M_NVLIST, \
- M_NOWAIT)
+ M_WAITOK)
#define nv_free(buf) free((buf), M_NVLIST)
#define nv_strdup(buf) strdup((buf), M_NVLIST)
#define nv_vasprintf(ptr, ...) vasprintf(ptr, M_NVLIST, __VA_ARGS__)
-#define SAVE_ERRNO(var) ((void)(var))
-#define RESTORE_ERRNO(var) ((void)(var))
+#define ERRNO_SET(var) do { } while (0)
+#define ERRNO_SAVE() do { do { } while(0)
+#define ERRNO_RESTORE() } while (0)
#define ERRNO_OR_DEFAULT(default) (default)
@@ -70,8 +71,14 @@ typedef struct nvpair nvpair_t;
#define nv_strdup(buf) strdup((buf))
#define nv_vasprintf(ptr, ...) vasprintf(ptr, __VA_ARGS__)
-#define SAVE_ERRNO(var) (var) = errno
-#define RESTORE_ERRNO(var) errno = (var)
+#define ERRNO_SET(var) do { errno = (var); } while (0)
+#define ERRNO_SAVE() do { \
+ int _serrno; \
+ \
+ _serrno = errno
+
+#define ERRNO_RESTORE() errno = _serrno; \
+ } while (0)
#define ERRNO_OR_DEFAULT(default) (errno == 0 ? (default) : errno)
@@ -128,30 +135,4 @@ const void *nvpair_get_binary(const nvpair_t *nvp, size_t *sizep);
void nvpair_free(nvpair_t *nvp);
-nvpair_t *nvpair_createf_null(const char *namefmt, ...) __printflike(1, 2);
-nvpair_t *nvpair_createf_bool(bool value, const char *namefmt, ...) __printflike(2, 3);
-nvpair_t *nvpair_createf_number(uint64_t value, const char *namefmt, ...) __printflike(2, 3);
-nvpair_t *nvpair_createf_string(const char *value, const char *namefmt, ...) __printflike(2, 3);
-nvpair_t *nvpair_createf_nvlist(const nvlist_t *value, const char *namefmt, ...) __printflike(2, 3);
-nvpair_t *nvpair_createf_descriptor(int value, const char *namefmt, ...) __printflike(2, 3);
-nvpair_t *nvpair_createf_binary(const void *value, size_t size, const char *namefmt, ...) __printflike(3, 4);
-
-nvpair_t *nvpair_createv_null(const char *namefmt, va_list nameap) __printflike(1, 0);
-nvpair_t *nvpair_createv_bool(bool value, const char *namefmt, va_list nameap) __printflike(2, 0);
-nvpair_t *nvpair_createv_number(uint64_t value, const char *namefmt, va_list nameap) __printflike(2, 0);
-nvpair_t *nvpair_createv_string(const char *value, const char *namefmt, va_list nameap) __printflike(2, 0);
-nvpair_t *nvpair_createv_nvlist(const nvlist_t *value, const char *namefmt, va_list nameap) __printflike(2, 0);
-nvpair_t *nvpair_createv_descriptor(int value, const char *namefmt, va_list nameap) __printflike(2, 0);
-nvpair_t *nvpair_createv_binary(const void *value, size_t size, const char *namefmt, va_list nameap) __printflike(3, 0);
-
-nvpair_t *nvpair_movef_string(char *value, const char *namefmt, ...) __printflike(2, 3);
-nvpair_t *nvpair_movef_nvlist(nvlist_t *value, const char *namefmt, ...) __printflike(2, 3);
-nvpair_t *nvpair_movef_descriptor(int value, const char *namefmt, ...) __printflike(2, 3);
-nvpair_t *nvpair_movef_binary(void *value, size_t size, const char *namefmt, ...) __printflike(3, 4);
-
-nvpair_t *nvpair_movev_string(char *value, const char *namefmt, va_list nameap) __printflike(2, 0);
-nvpair_t *nvpair_movev_nvlist(nvlist_t *value, const char *namefmt, va_list nameap) __printflike(2, 0);
-nvpair_t *nvpair_movev_descriptor(int value, const char *namefmt, va_list nameap) __printflike(2, 0);
-nvpair_t *nvpair_movev_binary(void *value, size_t size, const char *namefmt, va_list nameap) __printflike(3, 0);
-
#endif /* !_NV_IMPL_H_ */
diff --git a/sys/sys/nvlist_impl.h b/sys/sys/nvlist_impl.h
index a59a90e34b39..8aeac672a842 100644
--- a/sys/sys/nvlist_impl.h
+++ b/sys/sys/nvlist_impl.h
@@ -38,10 +38,6 @@
#include "nv.h"
-void *nvlist_xpack(const nvlist_t *nvl, int64_t *fdidxp, size_t *sizep);
-nvlist_t *nvlist_xunpack(const void *buf, size_t size, const int *fds,
- size_t nfds);
-
nvpair_t *nvlist_get_nvpair_parent(const nvlist_t *nvl);
const unsigned char *nvlist_unpack_header(nvlist_t *nvl,
const unsigned char *ptr, size_t nfds, bool *isbep, size_t *leftp);
diff --git a/sys/sys/param.h b/sys/sys/param.h
index 33eaa71a6d82..867dbf1b8807 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -58,7 +58,7 @@
* in the range 5 to 9.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 1100070 /* Master, propagated to newvers */
+#define __FreeBSD_version 1100071 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
@@ -233,10 +233,19 @@
* and may be made smaller at the risk of not being able to use
* filesystems which require a block size exceeding MAXBSIZE.
*
+ * MAXBCACHEBUF - Maximum size of a buffer in the buffer cache. This must
+ * be >= MAXBSIZE and can be set differently for different
+ * architectures by defining it in <machine/param.h>.
+ * Making this larger allows NFS to do larger reads/writes.
+ *
* BKVASIZE - Nominal buffer space per buffer, in bytes. BKVASIZE is the
* minimum KVM memory reservation the kernel is willing to make.
* Filesystems can of course request smaller chunks. Actual
* backing memory uses a chunk size of a page (PAGE_SIZE).
+ * The default value here can be overridden on a per-architecture
+ * basis by defining it in <machine/param.h>. This should
+ * probably be done to increase its value, when MAXBCACHEBUF is
+ * defined as a larger value in <machine/param.h>.
*
* If you make BKVASIZE too small you risk seriously fragmenting
* the buffer KVM map which may slow things down a bit. If you
@@ -248,7 +257,12 @@
* normal UFS filesystem.
*/
#define MAXBSIZE 65536 /* must be power of 2 */
+#ifndef MAXBCACHEBUF
+#define MAXBCACHEBUF MAXBSIZE /* must be a power of 2 >= MAXBSIZE */
+#endif
+#ifndef BKVASIZE
#define BKVASIZE 16384 /* must be power of 2 */
+#endif
#define BKVAMASK (BKVASIZE-1)
/*
diff --git a/sys/sys/procctl.h b/sys/sys/procctl.h
index c57eee63d51a..75dbf537cc17 100644
--- a/sys/sys/procctl.h
+++ b/sys/sys/procctl.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2013 Advanced Computing Technologies LLC
+ * Copyright (c) 2013 Hudson River Trading LLC
* Written by: John H. Baldwin <jhb@FreeBSD.org>
* All rights reserved.
*
diff --git a/sys/sys/racct.h b/sys/sys/racct.h
index 966d27a11183..313d5d05de96 100644
--- a/sys/sys/racct.h
+++ b/sys/sys/racct.h
@@ -83,6 +83,10 @@ struct ucred;
#define RACCT_DECAYING 0x20
extern int racct_types[];
+extern int racct_enable;
+
+#define ASSERT_RACCT_ENABLED() KASSERT(racct_enable, \
+ ("%s called with !racct_enable", __func__))
/*
* Amount stored in c_resources[] is 10**6 times bigger than what's
diff --git a/sys/sys/seq.h b/sys/sys/seq.h
index eaab86eb6193..21067cb6ff80 100644
--- a/sys/sys/seq.h
+++ b/sys/sys/seq.h
@@ -79,7 +79,7 @@ typedef uint32_t seq_t;
* on amd64 but still has unnecessary cost.
*/
static __inline int
-atomic_load_rmb_int(volatile u_int *p)
+atomic_load_rmb_int(volatile const u_int *p)
{
volatile u_int v;
@@ -89,7 +89,7 @@ atomic_load_rmb_int(volatile u_int *p)
}
static __inline int
-atomic_rmb_load_int(volatile u_int *p)
+atomic_rmb_load_int(volatile const u_int *p)
{
volatile u_int v = 0;
@@ -122,7 +122,7 @@ seq_write_end(seq_t *seqp)
}
static __inline seq_t
-seq_read(seq_t *seqp)
+seq_read(const seq_t *seqp)
{
seq_t ret;
@@ -139,7 +139,7 @@ seq_read(seq_t *seqp)
}
static __inline seq_t
-seq_consistent(seq_t *seqp, seq_t oldseq)
+seq_consistent(const seq_t *seqp, seq_t oldseq)
{
return (atomic_rmb_load_int(seqp) == oldseq);
diff --git a/sys/sys/systm.h b/sys/sys/systm.h
index 8a358cec21c0..786414fec39b 100644
--- a/sys/sys/systm.h
+++ b/sys/sys/systm.h
@@ -187,6 +187,7 @@ void *phashinit(int count, struct malloc_type *type, u_long *nentries);
void g_waitidle(void);
void panic(const char *, ...) __dead2 __printflike(1, 2);
+void vpanic(const char *, __va_list) __dead2 __printflike(1, 0);
void cpu_boot(int);
void cpu_flush_dcache(void *, size_t);
diff --git a/sys/net/zlib.h b/sys/sys/zlib.h
index 16edae12b6f6..16edae12b6f6 100644
--- a/sys/net/zlib.h
+++ b/sys/sys/zlib.h
diff --git a/sys/net/zutil.h b/sys/sys/zutil.h
index 74f022181e28..1431b6f9e9a3 100644
--- a/sys/net/zutil.h
+++ b/sys/sys/zutil.h
@@ -17,7 +17,7 @@
#define ZEXPORT
#ifdef _KERNEL
-#include <net/zlib.h>
+#include <sys/zlib.h>
#else
#include "zlib.h"
#endif
diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c
index c918cd74f65a..c384064befbb 100644
--- a/sys/ufs/ffs/ffs_alloc.c
+++ b/sys/ufs/ffs/ffs_alloc.c
@@ -112,8 +112,7 @@ static void ffs_blkfree_trim_task(void *ctx, int pending __unused);
#ifdef INVARIANTS
static int ffs_checkblk(struct inode *, ufs2_daddr_t, long);
#endif
-static ufs2_daddr_t ffs_clusteralloc(struct inode *, u_int, ufs2_daddr_t, int,
- int);
+static ufs2_daddr_t ffs_clusteralloc(struct inode *, u_int, ufs2_daddr_t, int);
static ino_t ffs_dirpref(struct inode *);
static ufs2_daddr_t ffs_fragextend(struct inode *, u_int, ufs2_daddr_t,
int, int);
@@ -460,10 +459,16 @@ nospace:
SYSCTL_NODE(_vfs, OID_AUTO, ffs, CTLFLAG_RW, 0, "FFS filesystem");
static int doasyncfree = 1;
-SYSCTL_INT(_vfs_ffs, OID_AUTO, doasyncfree, CTLFLAG_RW, &doasyncfree, 0, "");
+SYSCTL_INT(_vfs_ffs, OID_AUTO, doasyncfree, CTLFLAG_RW, &doasyncfree, 0,
+"do not force synchronous writes when blocks are reallocated");
static int doreallocblks = 1;
-SYSCTL_INT(_vfs_ffs, OID_AUTO, doreallocblks, CTLFLAG_RW, &doreallocblks, 0, "");
+SYSCTL_INT(_vfs_ffs, OID_AUTO, doreallocblks, CTLFLAG_RW, &doreallocblks, 0,
+"enable block reallocation");
+
+static int maxclustersearch = 10;
+SYSCTL_INT(_vfs_ffs, OID_AUTO, maxclustersearch, CTLFLAG_RW, &maxclustersearch,
+0, "max number of cylinder group to search for contigous blocks");
#ifdef DEBUG
static volatile int prtrealloc = 0;
@@ -510,7 +515,7 @@ ffs_reallocblks_ufs1(ap)
ufs1_daddr_t soff, newblk, blkno;
ufs2_daddr_t pref;
struct indir start_ap[NIADDR + 1], end_ap[NIADDR + 1], *idp;
- int i, len, start_lvl, end_lvl, ssize;
+ int i, cg, len, start_lvl, end_lvl, ssize;
vp = ap->a_vp;
ip = VTOI(vp);
@@ -597,18 +602,39 @@ ffs_reallocblks_ufs1(ap)
ebap = (ufs1_daddr_t *)ebp->b_data;
}
/*
- * Find the preferred location for the cluster.
+ * Find the preferred location for the cluster. If we have not
+ * previously failed at this endeavor, then follow our standard
+ * preference calculation. If we have failed at it, then pick up
+ * where we last ended our search.
*/
UFS_LOCK(ump);
- pref = ffs_blkpref_ufs1(ip, start_lbn, soff, sbap);
+ if (ip->i_nextclustercg == -1)
+ pref = ffs_blkpref_ufs1(ip, start_lbn, soff, sbap);
+ else
+ pref = cgdata(fs, ip->i_nextclustercg);
/*
* Search the block map looking for an allocation of the desired size.
+ * To avoid wasting too much time, we limit the number of cylinder
+ * groups that we will search.
+ */
+ cg = dtog(fs, pref);
+ for (i = min(maxclustersearch, fs->fs_ncg); i > 0; i--) {
+ if ((newblk = ffs_clusteralloc(ip, cg, pref, len)) != 0)
+ break;
+ cg += 1;
+ if (cg >= fs->fs_ncg)
+ cg = 0;
+ }
+ /*
+ * If we have failed in our search, record where we gave up for
+ * next time. Otherwise, fall back to our usual search citerion.
*/
- if ((newblk = ffs_hashalloc(ip, dtog(fs, pref), pref,
- len, len, ffs_clusteralloc)) == 0) {
+ if (newblk == 0) {
+ ip->i_nextclustercg = cg;
UFS_UNLOCK(ump);
goto fail;
}
+ ip->i_nextclustercg = -1;
/*
* We have found a new contiguous block.
*
@@ -737,7 +763,7 @@ ffs_reallocblks_ufs2(ap)
ufs_lbn_t start_lbn, end_lbn;
ufs2_daddr_t soff, newblk, blkno, pref;
struct indir start_ap[NIADDR + 1], end_ap[NIADDR + 1], *idp;
- int i, len, start_lvl, end_lvl, ssize;
+ int i, cg, len, start_lvl, end_lvl, ssize;
vp = ap->a_vp;
ip = VTOI(vp);
@@ -824,18 +850,39 @@ ffs_reallocblks_ufs2(ap)
ebap = (ufs2_daddr_t *)ebp->b_data;
}
/*
- * Find the preferred location for the cluster.
+ * Find the preferred location for the cluster. If we have not
+ * previously failed at this endeavor, then follow our standard
+ * preference calculation. If we have failed at it, then pick up
+ * where we last ended our search.
*/
UFS_LOCK(ump);
- pref = ffs_blkpref_ufs2(ip, start_lbn, soff, sbap);
+ if (ip->i_nextclustercg == -1)
+ pref = ffs_blkpref_ufs2(ip, start_lbn, soff, sbap);
+ else
+ pref = cgdata(fs, ip->i_nextclustercg);
/*
* Search the block map looking for an allocation of the desired size.
+ * To avoid wasting too much time, we limit the number of cylinder
+ * groups that we will search.
+ */
+ cg = dtog(fs, pref);
+ for (i = min(maxclustersearch, fs->fs_ncg); i > 0; i--) {
+ if ((newblk = ffs_clusteralloc(ip, cg, pref, len)) != 0)
+ break;
+ cg += 1;
+ if (cg >= fs->fs_ncg)
+ cg = 0;
+ }
+ /*
+ * If we have failed in our search, record where we gave up for
+ * next time. Otherwise, fall back to our usual search citerion.
*/
- if ((newblk = ffs_hashalloc(ip, dtog(fs, pref), pref,
- len, len, ffs_clusteralloc)) == 0) {
+ if (newblk == 0) {
+ ip->i_nextclustercg = cg;
UFS_UNLOCK(ump);
goto fail;
}
+ ip->i_nextclustercg = -1;
/*
* We have found a new contiguous block.
*
@@ -1786,12 +1833,11 @@ gotit:
* take the first one that we find following bpref.
*/
static ufs2_daddr_t
-ffs_clusteralloc(ip, cg, bpref, len, unused)
+ffs_clusteralloc(ip, cg, bpref, len)
struct inode *ip;
u_int cg;
ufs2_daddr_t bpref;
int len;
- int unused;
{
struct fs *fs;
struct cg *cgp;
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index 88f952f0cd4e..2a368bd980fb 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -1688,6 +1688,7 @@ ffs_vgetf(mp, ino, flags, vpp, ffs_flags)
ip->i_dev = dev;
ip->i_number = ino;
ip->i_ea_refs = 0;
+ ip->i_nextclustercg = -1;
#ifdef QUOTA
{
int i;
diff --git a/sys/ufs/ufs/inode.h b/sys/ufs/ufs/inode.h
index 37081d5fd261..cd7c47261534 100644
--- a/sys/ufs/ufs/inode.h
+++ b/sys/ufs/ufs/inode.h
@@ -87,6 +87,8 @@ struct inode {
daddr_t *snapblklist; /* Collect expunged snapshot blocks. */
} i_un;
+ int i_nextclustercg; /* last cg searched for cluster */
+
/*
* Data for extended attribute modification.
*/
diff --git a/sys/vm/sg_pager.c b/sys/vm/sg_pager.c
index 08e8fc7d2060..e35741e49ee4 100644
--- a/sys/vm/sg_pager.c
+++ b/sys/vm/sg_pager.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2009 Advanced Computing Technologies LLC
+ * Copyright (c) 2009 Hudson River Trading LLC
* Written by: John H. Baldwin <jhb@FreeBSD.org>
* All rights reserved.
*
diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index 55e02c456ffd..15e5b245a82c 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -198,11 +198,13 @@ swap_reserve_by_cred(vm_ooffset_t incr, struct ucred *cred)
panic("swap_reserve: & PAGE_MASK");
#ifdef RACCT
- PROC_LOCK(curproc);
- error = racct_add(curproc, RACCT_SWAP, incr);
- PROC_UNLOCK(curproc);
- if (error != 0)
- return (0);
+ if (racct_enable) {
+ PROC_LOCK(curproc);
+ error = racct_add(curproc, RACCT_SWAP, incr);
+ PROC_UNLOCK(curproc);
+ if (error != 0)
+ return (0);
+ }
#endif
res = 0;
diff --git a/sys/vm/uma_int.h b/sys/vm/uma_int.h
index 11ab24f973a7..ad2a4053fc29 100644
--- a/sys/vm/uma_int.h
+++ b/sys/vm/uma_int.h
@@ -311,7 +311,7 @@ struct uma_zone {
* This HAS to be the last item because we adjust the zone size
* based on NCPU and then allocate the space for the zones.
*/
- struct uma_cache uz_cpu[]; /* Per cpu caches */
+ struct uma_cache uz_cpu[1]; /* Per cpu caches */
};
/*
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index 13f46e149907..0c84d44c697e 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -348,6 +348,10 @@ 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;
+ }
fs.entry->eflags |= MAP_ENTRY_NEEDS_WAKEUP;
vm_map_unlock_and_wait(fs.map, 0);
} else
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index b7e668b928b0..bad999451ccb 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -300,11 +300,11 @@ vmspace_alloc(vm_offset_t min, vm_offset_t max, pmap_pinit_t pinit)
return (vm);
}
+#ifdef RACCT
static void
vmspace_container_reset(struct proc *p)
{
-#ifdef RACCT
PROC_LOCK(p);
racct_set(p, RACCT_DATA, 0);
racct_set(p, RACCT_STACK, 0);
@@ -312,8 +312,8 @@ vmspace_container_reset(struct proc *p)
racct_set(p, RACCT_MEMLOCK, 0);
racct_set(p, RACCT_VMEM, 0);
PROC_UNLOCK(p);
-#endif
}
+#endif
static inline void
vmspace_dofree(struct vmspace *vm)
@@ -415,7 +415,10 @@ vmspace_exit(struct thread *td)
pmap_activate(td);
vmspace_dofree(vm);
}
- vmspace_container_reset(p);
+#ifdef RACCT
+ if (racct_enable)
+ vmspace_container_reset(p);
+#endif
}
/* Acquire reference to vmspace owned by another process. */
@@ -3652,14 +3655,16 @@ Retry:
return (KERN_NO_SPACE);
}
#ifdef RACCT
- PROC_LOCK(p);
- if (is_procstack &&
- racct_set(p, RACCT_STACK, ctob(vm->vm_ssize) + grow_amount)) {
+ if (racct_enable) {
+ PROC_LOCK(p);
+ if (is_procstack && racct_set(p, RACCT_STACK,
+ ctob(vm->vm_ssize) + grow_amount)) {
+ PROC_UNLOCK(p);
+ vm_map_unlock_read(map);
+ return (KERN_NO_SPACE);
+ }
PROC_UNLOCK(p);
- vm_map_unlock_read(map);
- return (KERN_NO_SPACE);
}
- PROC_UNLOCK(p);
#endif
/* Round up the grow amount modulo sgrowsiz */
@@ -3685,15 +3690,17 @@ Retry:
goto out;
}
#ifdef RACCT
- PROC_LOCK(p);
- if (racct_set(p, RACCT_MEMLOCK,
- ptoa(pmap_wired_count(map->pmap)) + grow_amount)) {
+ if (racct_enable) {
+ PROC_LOCK(p);
+ if (racct_set(p, RACCT_MEMLOCK,
+ ptoa(pmap_wired_count(map->pmap)) + grow_amount)) {
+ PROC_UNLOCK(p);
+ vm_map_unlock_read(map);
+ rv = KERN_NO_SPACE;
+ goto out;
+ }
PROC_UNLOCK(p);
- vm_map_unlock_read(map);
- rv = KERN_NO_SPACE;
- goto out;
}
- PROC_UNLOCK(p);
#endif
}
/* If we would blow our VMEM resource limit, no go */
@@ -3703,14 +3710,16 @@ Retry:
goto out;
}
#ifdef RACCT
- PROC_LOCK(p);
- if (racct_set(p, RACCT_VMEM, map->size + grow_amount)) {
+ if (racct_enable) {
+ PROC_LOCK(p);
+ if (racct_set(p, RACCT_VMEM, map->size + grow_amount)) {
+ PROC_UNLOCK(p);
+ vm_map_unlock_read(map);
+ rv = KERN_NO_SPACE;
+ goto out;
+ }
PROC_UNLOCK(p);
- vm_map_unlock_read(map);
- rv = KERN_NO_SPACE;
- goto out;
}
- PROC_UNLOCK(p);
#endif
if (vm_map_lock_upgrade(map))
@@ -3809,7 +3818,7 @@ Retry:
out:
#ifdef RACCT
- if (rv != KERN_SUCCESS) {
+ if (racct_enable && rv != KERN_SUCCESS) {
PROC_LOCK(p);
error = racct_set(p, RACCT_VMEM, map->size);
KASSERT(error == 0, ("decreasing RACCT_VMEM failed"));
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
index 02634d6e55f7..1dd24792a85f 100644
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -1122,16 +1122,18 @@ vm_mlock(struct proc *proc, struct ucred *cred, const void *addr0, size_t len)
if (npages + vm_cnt.v_wire_count > vm_page_max_wired)
return (EAGAIN);
#ifdef RACCT
- PROC_LOCK(proc);
- error = racct_set(proc, RACCT_MEMLOCK, nsize);
- PROC_UNLOCK(proc);
- if (error != 0)
- return (ENOMEM);
+ if (racct_enable) {
+ PROC_LOCK(proc);
+ error = racct_set(proc, RACCT_MEMLOCK, nsize);
+ PROC_UNLOCK(proc);
+ if (error != 0)
+ return (ENOMEM);
+ }
#endif
error = vm_map_wire(map, start, end,
VM_MAP_WIRE_USER | VM_MAP_WIRE_NOHOLES);
#ifdef RACCT
- if (error != KERN_SUCCESS) {
+ if (racct_enable && error != KERN_SUCCESS) {
PROC_LOCK(proc);
racct_set(proc, RACCT_MEMLOCK,
ptoa(pmap_wired_count(map->pmap)));
@@ -1179,11 +1181,13 @@ sys_mlockall(td, uap)
PROC_UNLOCK(td->td_proc);
}
#ifdef RACCT
- PROC_LOCK(td->td_proc);
- error = racct_set(td->td_proc, RACCT_MEMLOCK, map->size);
- PROC_UNLOCK(td->td_proc);
- if (error != 0)
- return (ENOMEM);
+ if (racct_enable) {
+ PROC_LOCK(td->td_proc);
+ error = racct_set(td->td_proc, RACCT_MEMLOCK, map->size);
+ PROC_UNLOCK(td->td_proc);
+ if (error != 0)
+ return (ENOMEM);
+ }
#endif
if (uap->how & MCL_FUTURE) {
@@ -1205,7 +1209,7 @@ sys_mlockall(td, uap)
error = (error == KERN_SUCCESS ? 0 : EAGAIN);
}
#ifdef RACCT
- if (error != KERN_SUCCESS) {
+ if (racct_enable && error != KERN_SUCCESS) {
PROC_LOCK(td->td_proc);
racct_set(td->td_proc, RACCT_MEMLOCK,
ptoa(pmap_wired_count(map->pmap)));
@@ -1247,7 +1251,7 @@ sys_munlockall(td, uap)
error = vm_map_unwire(map, vm_map_min(map), vm_map_max(map),
VM_MAP_WIRE_USER|VM_MAP_WIRE_HOLESOK);
#ifdef RACCT
- if (error == KERN_SUCCESS) {
+ if (racct_enable && error == KERN_SUCCESS) {
PROC_LOCK(td->td_proc);
racct_set(td->td_proc, RACCT_MEMLOCK, 0);
PROC_UNLOCK(td->td_proc);
@@ -1291,7 +1295,7 @@ sys_munlock(td, uap)
error = vm_map_unwire(&td->td_proc->p_vmspace->vm_map, start, end,
VM_MAP_WIRE_USER | VM_MAP_WIRE_NOHOLES);
#ifdef RACCT
- if (error == KERN_SUCCESS) {
+ if (racct_enable && error == KERN_SUCCESS) {
PROC_LOCK(td->td_proc);
map = &td->td_proc->p_vmspace->vm_map;
racct_set(td->td_proc, RACCT_MEMLOCK,
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index 64ca13075c65..0aec01f64bc2 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -91,12 +91,14 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/kernel.h>
#include <sys/limits.h>
+#include <sys/linker.h>
#include <sys/malloc.h>
#include <sys/mman.h>
#include <sys/msgbuf.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/rwlock.h>
+#include <sys/sbuf.h>
#include <sys/sysctl.h>
#include <sys/vmmeter.h>
#include <sys/vnode.h>
@@ -142,6 +144,12 @@ static int pa_tryrelock_restart;
SYSCTL_INT(_vm, OID_AUTO, tryrelock_restart, CTLFLAG_RD,
&pa_tryrelock_restart, 0, "Number of tryrelock restarts");
+static TAILQ_HEAD(, vm_page) blacklist_head;
+static int sysctl_vm_page_blacklist(SYSCTL_HANDLER_ARGS);
+SYSCTL_PROC(_vm, OID_AUTO, page_blacklist, CTLTYPE_STRING | CTLFLAG_RD |
+ CTLFLAG_MPSAFE, NULL, 0, sysctl_vm_page_blacklist, "A", "Blacklist pages");
+
+
static uma_zone_t fakepg_zone;
static struct vnode *vm_page_alloc_init(vm_page_t m);
@@ -216,35 +224,153 @@ vm_set_page_size(void)
}
/*
- * vm_page_blacklist_lookup:
+ * vm_page_blacklist_next:
*
- * See if a physical address in this page has been listed
- * in the blacklist tunable. Entries in the tunable are
- * separated by spaces or commas. If an invalid integer is
- * encountered then the rest of the string is skipped.
+ * Find the next entry in the provided string of blacklist
+ * addresses. Entries are separated by space, comma, or newline.
+ * If an invalid integer is encountered then the rest of the
+ * string is skipped. Updates the list pointer to the next
+ * character, or NULL if the string is exhausted or invalid.
*/
-static int
-vm_page_blacklist_lookup(char *list, vm_paddr_t pa)
+static vm_paddr_t
+vm_page_blacklist_next(char **list, char *end)
{
vm_paddr_t bad;
char *cp, *pos;
- for (pos = list; *pos != '\0'; pos = cp) {
+ if (list == NULL || *list == NULL)
+ return (0);
+ if (**list =='\0') {
+ *list = NULL;
+ return (0);
+ }
+
+ /*
+ * If there's no end pointer then the buffer is coming from
+ * the kenv and we know it's null-terminated.
+ */
+ if (end == NULL)
+ end = *list + strlen(*list);
+
+ /* Ensure that strtoq() won't walk off the end */
+ if (*end != '\0') {
+ if (*end == '\n' || *end == ' ' || *end == ',')
+ *end = '\0';
+ else {
+ printf("Blacklist not terminated, skipping\n");
+ *list = NULL;
+ return (0);
+ }
+ }
+
+ for (pos = *list; *pos != '\0'; pos = cp) {
bad = strtoq(pos, &cp, 0);
- if (*cp != '\0') {
- if (*cp == ' ' || *cp == ',') {
- cp++;
- if (cp == pos)
+ if (*cp == '\0' || *cp == ' ' || *cp == ',' || *cp == '\n') {
+ if (bad == 0) {
+ if (++cp < end)
continue;
- } else
- break;
- }
- if (pa == trunc_page(bad))
- return (1);
+ else
+ break;
+ }
+ } else
+ break;
+ if (*cp == '\0' || ++cp >= end)
+ *list = NULL;
+ else
+ *list = cp;
+ return (trunc_page(bad));
}
+ printf("Garbage in RAM blacklist, skipping\n");
+ *list = NULL;
return (0);
}
+/*
+ * vm_page_blacklist_check:
+ *
+ * Iterate through the provided string of blacklist addresses, pulling
+ * each entry out of the physical allocator free list and putting it
+ * onto a list for reporting via the vm.page_blacklist sysctl.
+ */
+static void
+vm_page_blacklist_check(char *list, char *end)
+{
+ vm_paddr_t pa;
+ vm_page_t m;
+ char *next;
+ int ret;
+
+ next = list;
+ while (next != NULL) {
+ if ((pa = vm_page_blacklist_next(&next, end)) == 0)
+ continue;
+ m = vm_phys_paddr_to_vm_page(pa);
+ if (m == NULL)
+ continue;
+ mtx_lock(&vm_page_queue_free_mtx);
+ ret = vm_phys_unfree_page(m);
+ mtx_unlock(&vm_page_queue_free_mtx);
+ if (ret == TRUE) {
+ TAILQ_INSERT_TAIL(&blacklist_head, m, listq);
+ if (bootverbose)
+ printf("Skipping page with pa 0x%jx\n",
+ (uintmax_t)pa);
+ }
+ }
+}
+
+/*
+ * vm_page_blacklist_load:
+ *
+ * Search for a special module named "ram_blacklist". It'll be a
+ * plain text file provided by the user via the loader directive
+ * of the same name.
+ */
+static void
+vm_page_blacklist_load(char **list, char **end)
+{
+ void *mod;
+ u_char *ptr;
+ u_int len;
+
+ mod = NULL;
+ ptr = NULL;
+
+ mod = preload_search_by_type("ram_blacklist");
+ if (mod != NULL) {
+ ptr = preload_fetch_addr(mod);
+ len = preload_fetch_size(mod);
+ }
+ *list = ptr;
+ if (ptr != NULL)
+ *end = ptr + len;
+ else
+ *end = NULL;
+ return;
+}
+
+static int
+sysctl_vm_page_blacklist(SYSCTL_HANDLER_ARGS)
+{
+ vm_page_t m;
+ struct sbuf sbuf;
+ int error, first;
+
+ first = 1;
+ error = sysctl_wire_old_buffer(req, 0);
+ if (error != 0)
+ return (error);
+ sbuf_new_for_sysctl(&sbuf, NULL, 128, req);
+ TAILQ_FOREACH(m, &blacklist_head, listq) {
+ sbuf_printf(&sbuf, "%s%#jx", first ? "" : ",",
+ (uintmax_t)m->phys_addr);
+ first = 0;
+ }
+ error = sbuf_finish(&sbuf);
+ sbuf_delete(&sbuf);
+ return (error);
+}
+
static void
vm_page_domain_init(struct vm_domain *vmd)
{
@@ -290,7 +416,7 @@ vm_page_startup(vm_offset_t vaddr)
int i;
vm_paddr_t pa;
vm_paddr_t last_pa;
- char *list;
+ char *list, *listend;
vm_paddr_t end;
vm_paddr_t biggestsize;
vm_paddr_t low_water, high_water;
@@ -305,14 +431,6 @@ vm_page_startup(vm_offset_t vaddr)
phys_avail[i + 1] = trunc_page(phys_avail[i + 1]);
}
-#ifdef XEN
- /*
- * There is no obvious reason why i386 PV Xen needs vm_page structs
- * created for these pseudo-physical addresses. XXX
- */
- vm_phys_add_seg(0, phys_avail[0]);
-#endif
-
low_water = phys_avail[0];
high_water = phys_avail[1];
@@ -477,20 +595,22 @@ vm_page_startup(vm_offset_t vaddr)
*/
vm_cnt.v_page_count = 0;
vm_cnt.v_free_count = 0;
- list = kern_getenv("vm.blacklist");
for (i = 0; phys_avail[i + 1] != 0; i += 2) {
pa = phys_avail[i];
last_pa = phys_avail[i + 1];
while (pa < last_pa) {
- if (list != NULL &&
- vm_page_blacklist_lookup(list, pa))
- printf("Skipping page with pa 0x%jx\n",
- (uintmax_t)pa);
- else
- vm_phys_add_page(pa);
+ vm_phys_add_page(pa);
pa += PAGE_SIZE;
}
}
+
+ TAILQ_INIT(&blacklist_head);
+ vm_page_blacklist_load(&list, &listend);
+ vm_page_blacklist_check(list, listend);
+
+ list = kern_getenv("vm.blacklist");
+ vm_page_blacklist_check(list, NULL);
+
freeenv(list);
#if VM_NRESERVLEVEL > 0
/*
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c
index 6f50053604c7..872ffd8f6a07 100644
--- a/sys/vm/vm_pageout.c
+++ b/sys/vm/vm_pageout.c
@@ -1787,11 +1787,13 @@ vm_daemon(void)
while (TRUE) {
mtx_lock(&vm_daemon_mtx);
+ msleep(&vm_daemon_needed, &vm_daemon_mtx, PPAUSE, "psleep",
#ifdef RACCT
- msleep(&vm_daemon_needed, &vm_daemon_mtx, PPAUSE, "psleep", hz);
+ racct_enable ? hz : 0
#else
- msleep(&vm_daemon_needed, &vm_daemon_mtx, PPAUSE, "psleep", 0);
+ 0
#endif
+ );
swapout_flags = vm_pageout_req_swapout;
vm_pageout_req_swapout = 0;
mtx_unlock(&vm_daemon_mtx);
@@ -1866,33 +1868,40 @@ again:
&vm->vm_map, limit);
}
#ifdef RACCT
- rsize = IDX_TO_OFF(size);
- PROC_LOCK(p);
- racct_set(p, RACCT_RSS, rsize);
- ravailable = racct_get_available(p, RACCT_RSS);
- PROC_UNLOCK(p);
- if (rsize > ravailable) {
- /*
- * Don't be overly aggressive; this might be
- * an innocent process, and the limit could've
- * been exceeded by some memory hog. Don't
- * try to deactivate more than 1/4th of process'
- * resident set size.
- */
- if (attempts <= 8) {
- if (ravailable < rsize - (rsize / 4))
- ravailable = rsize - (rsize / 4);
- }
- vm_pageout_map_deactivate_pages(
- &vm->vm_map, OFF_TO_IDX(ravailable));
- /* Update RSS usage after paging out. */
- size = vmspace_resident_count(vm);
+ if (racct_enable) {
rsize = IDX_TO_OFF(size);
PROC_LOCK(p);
racct_set(p, RACCT_RSS, rsize);
+ ravailable = racct_get_available(p, RACCT_RSS);
PROC_UNLOCK(p);
- if (rsize > ravailable)
- tryagain = 1;
+ if (rsize > ravailable) {
+ /*
+ * Don't be overly aggressive; this
+ * might be an innocent process,
+ * and the limit could've been exceeded
+ * by some memory hog. Don't try
+ * to deactivate more than 1/4th
+ * of process' resident set size.
+ */
+ if (attempts <= 8) {
+ if (ravailable < rsize -
+ (rsize / 4)) {
+ ravailable = rsize -
+ (rsize / 4);
+ }
+ }
+ vm_pageout_map_deactivate_pages(
+ &vm->vm_map,
+ OFF_TO_IDX(ravailable));
+ /* Update RSS usage after paging out. */
+ size = vmspace_resident_count(vm);
+ rsize = IDX_TO_OFF(size);
+ PROC_LOCK(p);
+ racct_set(p, RACCT_RSS, rsize);
+ PROC_UNLOCK(p);
+ if (rsize > ravailable)
+ tryagain = 1;
+ }
}
#endif
vmspace_free(vm);
diff --git a/sys/vm/vm_unix.c b/sys/vm/vm_unix.c
index de9aa78c134f..cc77ff73b10e 100644
--- a/sys/vm/vm_unix.c
+++ b/sys/vm/vm_unix.c
@@ -130,35 +130,39 @@ sys_obreak(td, uap)
goto done;
}
#ifdef RACCT
- PROC_LOCK(td->td_proc);
- error = racct_set(td->td_proc, RACCT_DATA, new - base);
- if (error != 0) {
- PROC_UNLOCK(td->td_proc);
- error = ENOMEM;
- goto done;
- }
- error = racct_set(td->td_proc, RACCT_VMEM,
- map->size + (new - old));
- if (error != 0) {
- racct_set_force(td->td_proc, RACCT_DATA, old - base);
- PROC_UNLOCK(td->td_proc);
- error = ENOMEM;
- goto done;
- }
- if (!old_mlock && map->flags & MAP_WIREFUTURE) {
- error = racct_set(td->td_proc, RACCT_MEMLOCK,
- ptoa(pmap_wired_count(map->pmap)) + (new - old));
+ if (racct_enable) {
+ PROC_LOCK(td->td_proc);
+ error = racct_set(td->td_proc, RACCT_DATA, new - base);
+ if (error != 0) {
+ PROC_UNLOCK(td->td_proc);
+ error = ENOMEM;
+ goto done;
+ }
+ error = racct_set(td->td_proc, RACCT_VMEM,
+ map->size + (new - old));
if (error != 0) {
racct_set_force(td->td_proc, RACCT_DATA,
old - base);
- racct_set_force(td->td_proc, RACCT_VMEM,
- map->size);
PROC_UNLOCK(td->td_proc);
error = ENOMEM;
goto done;
}
+ if (!old_mlock && map->flags & MAP_WIREFUTURE) {
+ error = racct_set(td->td_proc, RACCT_MEMLOCK,
+ ptoa(pmap_wired_count(map->pmap)) +
+ (new - old));
+ if (error != 0) {
+ racct_set_force(td->td_proc, RACCT_DATA,
+ old - base);
+ racct_set_force(td->td_proc, RACCT_VMEM,
+ map->size);
+ PROC_UNLOCK(td->td_proc);
+ error = ENOMEM;
+ goto done;
+ }
+ }
+ PROC_UNLOCK(td->td_proc);
}
- PROC_UNLOCK(td->td_proc);
#endif
prot = VM_PROT_RW;
#ifdef COMPAT_FREEBSD32
@@ -170,14 +174,19 @@ sys_obreak(td, uap)
rv = vm_map_insert(map, NULL, 0, old, new, prot, VM_PROT_ALL, 0);
if (rv != KERN_SUCCESS) {
#ifdef RACCT
- PROC_LOCK(td->td_proc);
- racct_set_force(td->td_proc, RACCT_DATA, old - base);
- racct_set_force(td->td_proc, RACCT_VMEM, map->size);
- if (!old_mlock && map->flags & MAP_WIREFUTURE) {
- racct_set_force(td->td_proc, RACCT_MEMLOCK,
- ptoa(pmap_wired_count(map->pmap)));
+ if (racct_enable) {
+ PROC_LOCK(td->td_proc);
+ racct_set_force(td->td_proc,
+ RACCT_DATA, old - base);
+ racct_set_force(td->td_proc,
+ RACCT_VMEM, map->size);
+ if (!old_mlock && map->flags & MAP_WIREFUTURE) {
+ racct_set_force(td->td_proc,
+ RACCT_MEMLOCK,
+ ptoa(pmap_wired_count(map->pmap)));
+ }
+ PROC_UNLOCK(td->td_proc);
}
- PROC_UNLOCK(td->td_proc);
#endif
error = ENOMEM;
goto done;
@@ -205,14 +214,16 @@ sys_obreak(td, uap)
}
vm->vm_dsize -= btoc(old - new);
#ifdef RACCT
- PROC_LOCK(td->td_proc);
- racct_set_force(td->td_proc, RACCT_DATA, new - base);
- racct_set_force(td->td_proc, RACCT_VMEM, map->size);
- if (!old_mlock && map->flags & MAP_WIREFUTURE) {
- racct_set_force(td->td_proc, RACCT_MEMLOCK,
- ptoa(pmap_wired_count(map->pmap)));
+ if (racct_enable) {
+ PROC_LOCK(td->td_proc);
+ racct_set_force(td->td_proc, RACCT_DATA, new - base);
+ racct_set_force(td->td_proc, RACCT_VMEM, map->size);
+ if (!old_mlock && map->flags & MAP_WIREFUTURE) {
+ racct_set_force(td->td_proc, RACCT_MEMLOCK,
+ ptoa(pmap_wired_count(map->pmap)));
+ }
+ PROC_UNLOCK(td->td_proc);
}
- PROC_UNLOCK(td->td_proc);
#endif
}
done:
diff --git a/sys/x86/acpica/srat.c b/sys/x86/acpica/srat.c
index 8335a8c0c084..8d2a7417625c 100644
--- a/sys/x86/acpica/srat.c
+++ b/sys/x86/acpica/srat.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2010 Advanced Computing Technologies LLC
+ * Copyright (c) 2010 Hudson River Trading LLC
* Written by: John H. Baldwin <jhb@FreeBSD.org>
* All rights reserved.
*
diff --git a/sys/x86/include/apicvar.h b/sys/x86/include/apicvar.h
index 818a83188566..0bd9fe5ece62 100644
--- a/sys/x86/include/apicvar.h
+++ b/sys/x86/include/apicvar.h
@@ -454,6 +454,7 @@ void lapic_handle_error(void);
void lapic_handle_intr(int vector, struct trapframe *frame);
void lapic_handle_timer(struct trapframe *frame);
void xen_intr_handle_upcall(struct trapframe *frame);
+void hv_vector_handler(struct trapframe *frame);
extern int x2apic_mode;
extern int lapic_eoi_suppression;
diff --git a/sys/x86/include/mca.h b/sys/x86/include/mca.h
index 29728b91df79..6420eb8c1c39 100644
--- a/sys/x86/include/mca.h
+++ b/sys/x86/include/mca.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2009 Advanced Computing Technologies LLC
+ * Copyright (c) 2009 Hudson River Trading LLC
* Written by: John H. Baldwin <jhb@FreeBSD.org>
* All rights reserved.
*
diff --git a/sys/x86/include/segments.h b/sys/x86/include/segments.h
index a5c1ea46b7b4..65b5870d4a82 100644
--- a/sys/x86/include/segments.h
+++ b/sys/x86/include/segments.h
@@ -46,11 +46,7 @@
*/
#define SEL_RPL_MASK 3 /* requester priv level */
#define ISPL(s) ((s)&3) /* priority level of a selector */
-#ifdef XEN
-#define SEL_KPL 1 /* kernel priority level */
-#else
#define SEL_KPL 0 /* kernel priority level */
-#endif
#define SEL_UPL 3 /* user priority level */
#define ISLDT(s) ((s)&SEL_LDT) /* is it local or global */
#define SEL_LDT 4 /* local descriptor table */
@@ -244,11 +240,7 @@ union descriptor {
#define GBIOSUTIL_SEL 16 /* BIOS interface (Utility) */
#define GBIOSARGS_SEL 17 /* BIOS interface (Arguments) */
#define GNDIS_SEL 18 /* For the NDIS layer */
-#ifdef XEN
-#define NGDT 9
-#else
#define NGDT 19
-#endif
/*
* Entries in the Local Descriptor Table (LDT)
diff --git a/sys/x86/pci/qpi.c b/sys/x86/pci/qpi.c
index 2f8889100d94..ae29daa1d349 100644
--- a/sys/x86/pci/qpi.c
+++ b/sys/x86/pci/qpi.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2010 Advanced Computing Technologies LLC
+ * Copyright (c) 2010 Hudson River Trading LLC
* Written by: John H. Baldwin <jhb@FreeBSD.org>
* All rights reserved.
*
diff --git a/sys/x86/x86/busdma_bounce.c b/sys/x86/x86/busdma_bounce.c
index 1438053ccc58..dcdeafa733ca 100644
--- a/sys/x86/x86/busdma_bounce.c
+++ b/sys/x86/x86/busdma_bounce.c
@@ -147,11 +147,6 @@ static void _bus_dmamap_count_phys(bus_dma_tag_t dmat, bus_dmamap_t map,
static int _bus_dmamap_reserve_pages(bus_dma_tag_t dmat, bus_dmamap_t map,
int flags);
-#ifdef XEN
-#undef pmap_kextract
-#define pmap_kextract pmap_kextract_ma
-#endif
-
/*
* Allocate a device specific dma_tag.
*/
@@ -994,8 +989,8 @@ add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr,
if (dmat->common.flags & BUS_DMA_KEEP_PG_OFFSET) {
/* Page offset needs to be preserved. */
- bpage->vaddr |= vaddr & PAGE_MASK;
- bpage->busaddr |= vaddr & PAGE_MASK;
+ bpage->vaddr |= addr & PAGE_MASK;
+ bpage->busaddr |= addr & PAGE_MASK;
}
bpage->datavaddr = vaddr;
bpage->dataaddr = addr;
diff --git a/sys/x86/x86/cpu_machdep.c b/sys/x86/x86/cpu_machdep.c
index 846a1236c3ea..f8d1f083c244 100644
--- a/sys/x86/x86/cpu_machdep.c
+++ b/sys/x86/x86/cpu_machdep.c
@@ -100,15 +100,6 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_pager.h>
#include <vm/vm_param.h>
-#ifdef XEN
-/* XEN includes */
-#include <xen/xen-os.h>
-#include <xen/hypervisor.h>
-#include <machine/xen/xenvar.h>
-#include <machine/xen/xenfunc.h>
-#include <xen/xen_intr.h>
-#endif
-
/*
* Machine dependent boot() routine
*
@@ -193,33 +184,6 @@ cpu_est_clockrate(int cpu_id, uint64_t *rate)
return (0);
}
-#if defined(__i386__) && defined(XEN)
-
-static void
-idle_block(void)
-{
-
- HYPERVISOR_sched_op(SCHEDOP_block, 0);
-}
-
-void
-cpu_halt(void)
-{
- HYPERVISOR_shutdown(SHUTDOWN_poweroff);
-}
-
-int scheduler_running;
-
-static void
-cpu_idle_hlt(sbintime_t sbt)
-{
-
- scheduler_running = 1;
- enable_intr();
- idle_block();
-}
-
-#else
/*
* Shutdown the CPU as much as possible
*/
@@ -230,8 +194,6 @@ cpu_halt(void)
halt();
}
-#endif
-
void (*cpu_idle_hook)(sbintime_t) = NULL; /* ACPI idle hook. */
static int cpu_ident_amdc1e = 0; /* AMD C1E supported. */
static int idle_mwait = 1; /* Use MONITOR/MWAIT for short idle. */
@@ -263,7 +225,6 @@ cpu_idle_acpi(sbintime_t sbt)
}
#endif /* !PC98 */
-#if !defined(__i386__) || !defined(XEN)
static void
cpu_idle_hlt(sbintime_t sbt)
{
@@ -295,7 +256,6 @@ cpu_idle_hlt(sbintime_t sbt)
__asm __volatile("sti; hlt");
*state = STATE_RUNNING;
}
-#endif
static void
cpu_idle_mwait(sbintime_t sbt)
@@ -370,7 +330,7 @@ cpu_probe_amdc1e(void)
}
}
-#if defined(__i386__) && (defined(PC98) || defined(XEN))
+#if defined(__i386__) && defined(PC98)
void (*cpu_idle_fn)(sbintime_t) = cpu_idle_hlt;
#else
void (*cpu_idle_fn)(sbintime_t) = cpu_idle_acpi;
@@ -379,17 +339,15 @@ void (*cpu_idle_fn)(sbintime_t) = cpu_idle_acpi;
void
cpu_idle(int busy)
{
-#if !defined(__i386__) || !defined(XEN)
uint64_t msr;
-#endif
sbintime_t sbt = -1;
CTR2(KTR_SPARE2, "cpu_idle(%d) at %d",
busy, curcpu);
-#if defined(MP_WATCHDOG) && (!defined(__i386__) || !defined(XEN))
+#ifdef MP_WATCHDOG
ap_watchdog(PCPU_GET(cpuid));
#endif
-#if !defined(__i386__) || !defined(XEN)
+
/* If we are busy - try to use fast methods. */
if (busy) {
if ((cpu_feature2 & CPUID2_MON) && idle_mwait) {
@@ -397,7 +355,6 @@ cpu_idle(int busy)
goto out;
}
}
-#endif
/* If we have time - switch timers into idle mode. */
if (!busy) {
@@ -405,14 +362,12 @@ cpu_idle(int busy)
sbt = cpu_idleclock();
}
-#if !defined(__i386__) || !defined(XEN)
/* Apply AMD APIC timer C1E workaround. */
if (cpu_ident_amdc1e && cpu_disable_c3_sleep) {
msr = rdmsr(MSR_AMDK8_IPM);
if (msr & AMDK8_CMPHALT)
wrmsr(MSR_AMDK8_IPM, msr & ~AMDK8_CMPHALT);
}
-#endif
/* Call main idle method. */
cpu_idle_fn(sbt);
@@ -422,9 +377,7 @@ cpu_idle(int busy)
cpu_activeclock();
critical_exit();
}
-#if !defined(__i386__) || !defined(XEN)
out:
-#endif
CTR2(KTR_SPARE2, "cpu_idle(%d) at %d done",
busy, curcpu);
}
diff --git a/sys/x86/x86/identcpu.c b/sys/x86/x86/identcpu.c
index ca2b5ca92725..9f39d1c82af8 100644
--- a/sys/x86/x86/identcpu.c
+++ b/sys/x86/x86/identcpu.c
@@ -1190,7 +1190,6 @@ hook_tsc_freq(void *arg __unused)
SYSINIT(hook_tsc_freq, SI_SUB_CONFIGURE, SI_ORDER_ANY, hook_tsc_freq, NULL);
-#ifndef XEN
static const char *const vm_bnames[] = {
"QEMU", /* QEMU */
"Plex86", /* Plex86 */
@@ -1281,7 +1280,6 @@ identify_hypervisor(void)
freeenv(p);
}
}
-#endif
/*
* Final stage of CPU identification.
@@ -1314,9 +1312,7 @@ identify_cpu(void)
cpu_feature2 = regs[2];
#endif
-#ifndef XEN
identify_hypervisor();
-#endif
cpu_vendor_id = find_cpu_vendor_id();
/*
diff --git a/sys/x86/x86/intr_machdep.c b/sys/x86/x86/intr_machdep.c
index b27df4a36c34..d81c9132dd8c 100644
--- a/sys/x86/x86/intr_machdep.c
+++ b/sys/x86/x86/intr_machdep.c
@@ -532,13 +532,6 @@ intr_shuffle_irqs(void *arg __unused)
struct intsrc *isrc;
int i;
-#ifdef XEN
- /*
- * Doesn't work yet
- */
- return;
-#endif
-
/* Don't bother on UP. */
if (mp_ncpus == 1)
return;
diff --git a/sys/x86/x86/local_apic.c b/sys/x86/x86/local_apic.c
index e0656ef1b8dc..d75a45236ea2 100644
--- a/sys/x86/x86/local_apic.c
+++ b/sys/x86/x86/local_apic.c
@@ -1579,17 +1579,13 @@ apic_setup_io(void *dummy __unused)
* Local APIC must be registered before other PICs and pseudo PICs
* for proper suspend/resume order.
*/
-#ifndef XEN
intr_register_pic(&lapic_pic);
-#endif
retval = best_enum->apic_setup_io();
if (retval != 0)
printf("%s: Failed to setup I/O APICs: returned %d\n",
best_enum->apic_name, retval);
-#ifdef XEN
- return;
-#endif
+
/*
* Finish setting up the local APIC on the BSP once we know
* how to properly program the LINT pins. In particular, this
diff --git a/sys/x86/x86/mca.c b/sys/x86/x86/mca.c
index 5c895a8c1329..8026b15096c6 100644
--- a/sys/x86/x86/mca.c
+++ b/sys/x86/x86/mca.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2009 Advanced Computing Technologies LLC
+ * Copyright (c) 2009 Hudson River Trading LLC
* Written by: John H. Baldwin <jhb@FreeBSD.org>
* All rights reserved.
*
diff --git a/sys/x86/x86/mp_x86.c b/sys/x86/x86/mp_x86.c
new file mode 100644
index 000000000000..b4c66a58faa5
--- /dev/null
+++ b/sys/x86/x86/mp_x86.c
@@ -0,0 +1,1120 @@
+/*-
+ * Copyright (c) 1996, by Steve Passe
+ * Copyright (c) 2003, by Peter Wemm
+ * 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. The name of the developer 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 AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#ifdef __i386__
+#include "opt_apic.h"
+#endif
+#include "opt_cpu.h"
+#include "opt_kstack_pages.h"
+#include "opt_pmap.h"
+#include "opt_sched.h"
+#include "opt_smp.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/cons.h> /* cngetc() */
+#include <sys/cpuset.h>
+#ifdef GPROF
+#include <sys/gmon.h>
+#endif
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/memrange.h>
+#include <sys/mutex.h>
+#include <sys/pcpu.h>
+#include <sys/proc.h>
+#include <sys/sched.h>
+#include <sys/smp.h>
+#include <sys/sysctl.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_extern.h>
+
+#include <x86/apicreg.h>
+#include <machine/clock.h>
+#include <machine/cputypes.h>
+#include <x86/mca.h>
+#include <machine/md_var.h>
+#include <machine/pcb.h>
+#include <machine/psl.h>
+#include <machine/smp.h>
+#include <machine/specialreg.h>
+#include <machine/cpu.h>
+
+#define WARMBOOT_TARGET 0
+#define WARMBOOT_OFF (KERNBASE + 0x0467)
+#define WARMBOOT_SEG (KERNBASE + 0x0469)
+
+#define CMOS_REG (0x70)
+#define CMOS_DATA (0x71)
+#define BIOS_RESET (0x0f)
+#define BIOS_WARM (0x0a)
+
+/* lock region used by kernel profiling */
+int mcount_lock;
+
+int mp_naps; /* # of Applications processors */
+int boot_cpu_id = -1; /* designated BSP */
+
+extern struct pcpu __pcpu[];
+
+/* AP uses this during bootstrap. Do not staticize. */
+char *bootSTK;
+int bootAP;
+
+/* Free these after use */
+void *bootstacks[MAXCPU];
+void *dpcpu;
+
+struct pcb stoppcbs[MAXCPU];
+struct susppcb **susppcbs;
+
+#ifdef COUNT_IPIS
+/* Interrupt counts. */
+static u_long *ipi_preempt_counts[MAXCPU];
+static u_long *ipi_ast_counts[MAXCPU];
+u_long *ipi_invltlb_counts[MAXCPU];
+u_long *ipi_invlrng_counts[MAXCPU];
+u_long *ipi_invlpg_counts[MAXCPU];
+u_long *ipi_invlcache_counts[MAXCPU];
+u_long *ipi_rendezvous_counts[MAXCPU];
+static u_long *ipi_hardclock_counts[MAXCPU];
+#endif
+
+/* Default cpu_ops implementation. */
+struct cpu_ops cpu_ops;
+
+/*
+ * Local data and functions.
+ */
+
+static volatile cpuset_t ipi_nmi_pending;
+
+/* used to hold the AP's until we are ready to release them */
+struct mtx ap_boot_mtx;
+
+/* Set to 1 once we're ready to let the APs out of the pen. */
+volatile int aps_ready = 0;
+
+/*
+ * Store data from cpu_add() until later in the boot when we actually setup
+ * the APs.
+ */
+struct cpu_info cpu_info[MAX_APIC_ID + 1];
+int cpu_apic_ids[MAXCPU];
+int apic_cpuids[MAX_APIC_ID + 1];
+
+/* Holds pending bitmap based IPIs per CPU */
+volatile u_int cpu_ipi_pending[MAXCPU];
+
+int cpu_logical; /* logical cpus per core */
+int cpu_cores; /* cores per package */
+
+static void release_aps(void *dummy);
+
+static u_int hyperthreading_cpus; /* logical cpus sharing L1 cache */
+static int hyperthreading_allowed = 1;
+
+void
+mem_range_AP_init(void)
+{
+
+ if (mem_range_softc.mr_op && mem_range_softc.mr_op->initAP)
+ mem_range_softc.mr_op->initAP(&mem_range_softc);
+}
+
+static void
+topo_probe_amd(void)
+{
+ int core_id_bits;
+ int id;
+
+ /* AMD processors do not support HTT. */
+ cpu_logical = 1;
+
+ if ((amd_feature2 & AMDID2_CMP) == 0) {
+ cpu_cores = 1;
+ return;
+ }
+
+ core_id_bits = (cpu_procinfo2 & AMDID_COREID_SIZE) >>
+ AMDID_COREID_SIZE_SHIFT;
+ if (core_id_bits == 0) {
+ cpu_cores = (cpu_procinfo2 & AMDID_CMP_CORES) + 1;
+ return;
+ }
+
+ /* Fam 10h and newer should get here. */
+ for (id = 0; id <= MAX_APIC_ID; id++) {
+ /* Check logical CPU availability. */
+ if (!cpu_info[id].cpu_present || cpu_info[id].cpu_disabled)
+ continue;
+ /* Check if logical CPU has the same package ID. */
+ if ((id >> core_id_bits) != (boot_cpu_id >> core_id_bits))
+ continue;
+ cpu_cores++;
+ }
+}
+
+/*
+ * Round up to the next power of two, if necessary, and then
+ * take log2.
+ * Returns -1 if argument is zero.
+ */
+static __inline int
+mask_width(u_int x)
+{
+
+ return (fls(x << (1 - powerof2(x))) - 1);
+}
+
+static void
+topo_probe_0x4(void)
+{
+ u_int p[4];
+ int pkg_id_bits;
+ int core_id_bits;
+ int max_cores;
+ int max_logical;
+ int id;
+
+ /* Both zero and one here mean one logical processor per package. */
+ max_logical = (cpu_feature & CPUID_HTT) != 0 ?
+ (cpu_procinfo & CPUID_HTT_CORES) >> 16 : 1;
+ if (max_logical <= 1)
+ return;
+
+ /*
+ * Because of uniformity assumption we examine only
+ * those logical processors that belong to the same
+ * package as BSP. Further, we count number of
+ * logical processors that belong to the same core
+ * as BSP thus deducing number of threads per core.
+ */
+ if (cpu_high >= 0x4) {
+ cpuid_count(0x04, 0, p);
+ max_cores = ((p[0] >> 26) & 0x3f) + 1;
+ } else
+ max_cores = 1;
+ core_id_bits = mask_width(max_logical/max_cores);
+ if (core_id_bits < 0)
+ return;
+ pkg_id_bits = core_id_bits + mask_width(max_cores);
+
+ for (id = 0; id <= MAX_APIC_ID; id++) {
+ /* Check logical CPU availability. */
+ if (!cpu_info[id].cpu_present || cpu_info[id].cpu_disabled)
+ continue;
+ /* Check if logical CPU has the same package ID. */
+ if ((id >> pkg_id_bits) != (boot_cpu_id >> pkg_id_bits))
+ continue;
+ cpu_cores++;
+ /* Check if logical CPU has the same package and core IDs. */
+ if ((id >> core_id_bits) == (boot_cpu_id >> core_id_bits))
+ cpu_logical++;
+ }
+
+ KASSERT(cpu_cores >= 1 && cpu_logical >= 1,
+ ("topo_probe_0x4 couldn't find BSP"));
+
+ cpu_cores /= cpu_logical;
+ hyperthreading_cpus = cpu_logical;
+}
+
+static void
+topo_probe_0xb(void)
+{
+ u_int p[4];
+ int bits;
+ int cnt;
+ int i;
+ int logical;
+ int type;
+ int x;
+
+ /* We only support three levels for now. */
+ for (i = 0; i < 3; i++) {
+ cpuid_count(0x0b, i, p);
+
+ /* Fall back if CPU leaf 11 doesn't really exist. */
+ if (i == 0 && p[1] == 0) {
+ topo_probe_0x4();
+ return;
+ }
+
+ bits = p[0] & 0x1f;
+ logical = p[1] &= 0xffff;
+ type = (p[2] >> 8) & 0xff;
+ if (type == 0 || logical == 0)
+ break;
+ /*
+ * Because of uniformity assumption we examine only
+ * those logical processors that belong to the same
+ * package as BSP.
+ */
+ for (cnt = 0, x = 0; x <= MAX_APIC_ID; x++) {
+ if (!cpu_info[x].cpu_present ||
+ cpu_info[x].cpu_disabled)
+ continue;
+ if (x >> bits == boot_cpu_id >> bits)
+ cnt++;
+ }
+ if (type == CPUID_TYPE_SMT)
+ cpu_logical = cnt;
+ else if (type == CPUID_TYPE_CORE)
+ cpu_cores = cnt;
+ }
+ if (cpu_logical == 0)
+ cpu_logical = 1;
+ cpu_cores /= cpu_logical;
+}
+
+/*
+ * Both topology discovery code and code that consumes topology
+ * information assume top-down uniformity of the topology.
+ * That is, all physical packages must be identical and each
+ * core in a package must have the same number of threads.
+ * Topology information is queried only on BSP, on which this
+ * code runs and for which it can query CPUID information.
+ * Then topology is extrapolated on all packages using the
+ * uniformity assumption.
+ */
+void
+topo_probe(void)
+{
+ static int cpu_topo_probed = 0;
+
+ if (cpu_topo_probed)
+ return;
+
+ CPU_ZERO(&logical_cpus_mask);
+ if (mp_ncpus <= 1)
+ cpu_cores = cpu_logical = 1;
+ else if (cpu_vendor_id == CPU_VENDOR_AMD)
+ topo_probe_amd();
+ else if (cpu_vendor_id == CPU_VENDOR_INTEL) {
+ /*
+ * See Intel(R) 64 Architecture Processor
+ * Topology Enumeration article for details.
+ *
+ * Note that 0x1 <= cpu_high < 4 case should be
+ * compatible with topo_probe_0x4() logic when
+ * CPUID.1:EBX[23:16] > 0 (cpu_cores will be 1)
+ * or it should trigger the fallback otherwise.
+ */
+ if (cpu_high >= 0xb)
+ topo_probe_0xb();
+ else if (cpu_high >= 0x1)
+ topo_probe_0x4();
+ }
+
+ /*
+ * Fallback: assume each logical CPU is in separate
+ * physical package. That is, no multi-core, no SMT.
+ */
+ if (cpu_cores == 0 || cpu_logical == 0)
+ cpu_cores = cpu_logical = 1;
+ cpu_topo_probed = 1;
+}
+
+struct cpu_group *
+cpu_topo(void)
+{
+ int cg_flags;
+
+ /*
+ * Determine whether any threading flags are
+ * necessry.
+ */
+ topo_probe();
+ if (cpu_logical > 1 && hyperthreading_cpus)
+ cg_flags = CG_FLAG_HTT;
+ else if (cpu_logical > 1)
+ cg_flags = CG_FLAG_SMT;
+ else
+ cg_flags = 0;
+ if (mp_ncpus % (cpu_cores * cpu_logical) != 0) {
+ printf("WARNING: Non-uniform processors.\n");
+ printf("WARNING: Using suboptimal topology.\n");
+ return (smp_topo_none());
+ }
+ /*
+ * No multi-core or hyper-threaded.
+ */
+ if (cpu_logical * cpu_cores == 1)
+ return (smp_topo_none());
+ /*
+ * Only HTT no multi-core.
+ */
+ if (cpu_logical > 1 && cpu_cores == 1)
+ return (smp_topo_1level(CG_SHARE_L1, cpu_logical, cg_flags));
+ /*
+ * Only multi-core no HTT.
+ */
+ if (cpu_cores > 1 && cpu_logical == 1)
+ return (smp_topo_1level(CG_SHARE_L2, cpu_cores, cg_flags));
+ /*
+ * Both HTT and multi-core.
+ */
+ return (smp_topo_2level(CG_SHARE_L2, cpu_cores,
+ CG_SHARE_L1, cpu_logical, cg_flags));
+}
+
+
+void
+cpu_add(u_int apic_id, char boot_cpu)
+{
+
+ if (apic_id > MAX_APIC_ID) {
+ panic("SMP: APIC ID %d too high", apic_id);
+ return;
+ }
+ KASSERT(cpu_info[apic_id].cpu_present == 0, ("CPU %d added twice",
+ apic_id));
+ cpu_info[apic_id].cpu_present = 1;
+ if (boot_cpu) {
+ KASSERT(boot_cpu_id == -1,
+ ("CPU %d claims to be BSP, but CPU %d already is", apic_id,
+ boot_cpu_id));
+ boot_cpu_id = apic_id;
+ cpu_info[apic_id].cpu_bsp = 1;
+ }
+ if (mp_ncpus < MAXCPU) {
+ mp_ncpus++;
+ mp_maxid = mp_ncpus - 1;
+ }
+ if (bootverbose)
+ printf("SMP: Added CPU %d (%s)\n", apic_id, boot_cpu ? "BSP" :
+ "AP");
+}
+
+void
+cpu_mp_setmaxid(void)
+{
+
+ /*
+ * mp_maxid should be already set by calls to cpu_add().
+ * Just sanity check its value here.
+ */
+ if (mp_ncpus == 0)
+ KASSERT(mp_maxid == 0,
+ ("%s: mp_ncpus is zero, but mp_maxid is not", __func__));
+ else if (mp_ncpus == 1)
+ mp_maxid = 0;
+ else
+ KASSERT(mp_maxid >= mp_ncpus - 1,
+ ("%s: counters out of sync: max %d, count %d", __func__,
+ mp_maxid, mp_ncpus));
+}
+
+int
+cpu_mp_probe(void)
+{
+
+ /*
+ * Always record BSP in CPU map so that the mbuf init code works
+ * correctly.
+ */
+ CPU_SETOF(0, &all_cpus);
+ if (mp_ncpus == 0) {
+ /*
+ * No CPUs were found, so this must be a UP system. Setup
+ * the variables to represent a system with a single CPU
+ * with an id of 0.
+ */
+ mp_ncpus = 1;
+ return (0);
+ }
+
+ /* At least one CPU was found. */
+ if (mp_ncpus == 1) {
+ /*
+ * One CPU was found, so this must be a UP system with
+ * an I/O APIC.
+ */
+ mp_maxid = 0;
+ return (0);
+ }
+
+ /* At least two CPUs were found. */
+ return (1);
+}
+
+/*
+ * Print various information about the SMP system hardware and setup.
+ */
+void
+cpu_mp_announce(void)
+{
+ const char *hyperthread;
+ int i;
+
+ printf("FreeBSD/SMP: %d package(s) x %d core(s)",
+ mp_ncpus / (cpu_cores * cpu_logical), cpu_cores);
+ if (hyperthreading_cpus > 1)
+ printf(" x %d HTT threads", cpu_logical);
+ else if (cpu_logical > 1)
+ printf(" x %d SMT threads", cpu_logical);
+ printf("\n");
+
+ /* List active CPUs first. */
+ printf(" cpu0 (BSP): APIC ID: %2d\n", boot_cpu_id);
+ for (i = 1; i < mp_ncpus; i++) {
+ if (cpu_info[cpu_apic_ids[i]].cpu_hyperthread)
+ hyperthread = "/HT";
+ else
+ hyperthread = "";
+ printf(" cpu%d (AP%s): APIC ID: %2d\n", i, hyperthread,
+ cpu_apic_ids[i]);
+ }
+
+ /* List disabled CPUs last. */
+ for (i = 0; i <= MAX_APIC_ID; i++) {
+ if (!cpu_info[i].cpu_present || !cpu_info[i].cpu_disabled)
+ continue;
+ if (cpu_info[i].cpu_hyperthread)
+ hyperthread = "/HT";
+ else
+ hyperthread = "";
+ printf(" cpu (AP%s): APIC ID: %2d (disabled)\n", hyperthread,
+ i);
+ }
+}
+
+void
+init_secondary_tail(void)
+{
+ u_int cpuid;
+
+ /*
+ * On real hardware, switch to x2apic mode if possible. Do it
+ * after aps_ready was signalled, to avoid manipulating the
+ * mode while BSP might still want to send some IPI to us
+ * (second startup IPI is ignored on modern hardware etc).
+ */
+ lapic_xapic_mode();
+
+ /* Initialize the PAT MSR. */
+ pmap_init_pat();
+
+ /* set up CPU registers and state */
+ cpu_setregs();
+
+ /* set up SSE/NX */
+ initializecpu();
+
+ /* set up FPU state on the AP */
+#ifdef __amd64__
+ fpuinit();
+#else
+ npxinit(false);
+#endif
+
+ if (cpu_ops.cpu_init)
+ cpu_ops.cpu_init();
+
+ /* A quick check from sanity claus */
+ cpuid = PCPU_GET(cpuid);
+ if (PCPU_GET(apic_id) != lapic_id()) {
+ printf("SMP: cpuid = %d\n", cpuid);
+ printf("SMP: actual apic_id = %d\n", lapic_id());
+ printf("SMP: correct apic_id = %d\n", PCPU_GET(apic_id));
+ panic("cpuid mismatch! boom!!");
+ }
+
+ /* Initialize curthread. */
+ KASSERT(PCPU_GET(idlethread) != NULL, ("no idle thread"));
+ PCPU_SET(curthread, PCPU_GET(idlethread));
+
+ mca_init();
+
+ mtx_lock_spin(&ap_boot_mtx);
+
+ /* Init local apic for irq's */
+ lapic_setup(1);
+
+ /* Set memory range attributes for this CPU to match the BSP */
+ mem_range_AP_init();
+
+ smp_cpus++;
+
+ CTR1(KTR_SMP, "SMP: AP CPU #%d Launched", cpuid);
+ printf("SMP: AP CPU #%d Launched!\n", cpuid);
+
+ /* Determine if we are a logical CPU. */
+ /* XXX Calculation depends on cpu_logical being a power of 2, e.g. 2 */
+ if (cpu_logical > 1 && PCPU_GET(apic_id) % cpu_logical != 0)
+ CPU_SET(cpuid, &logical_cpus_mask);
+
+ if (bootverbose)
+ lapic_dump("AP");
+
+ if (smp_cpus == mp_ncpus) {
+ /* enable IPI's, tlb shootdown, freezes etc */
+ atomic_store_rel_int(&smp_started, 1);
+ }
+
+#ifdef __amd64__
+ /*
+ * Enable global pages TLB extension
+ * This also implicitly flushes the TLB
+ */
+ load_cr4(rcr4() | CR4_PGE);
+ if (pmap_pcid_enabled)
+ load_cr4(rcr4() | CR4_PCIDE);
+ load_ds(_udatasel);
+ load_es(_udatasel);
+ load_fs(_ufssel);
+#endif
+
+ mtx_unlock_spin(&ap_boot_mtx);
+
+ /* Wait until all the AP's are up. */
+ while (smp_started == 0)
+ ia32_pause();
+
+ /* Start per-CPU event timers. */
+ cpu_initclocks_ap();
+
+ sched_throw(NULL);
+
+ panic("scheduler returned us to %s", __func__);
+ /* NOTREACHED */
+}
+
+/*******************************************************************
+ * local functions and data
+ */
+
+/*
+ * We tell the I/O APIC code about all the CPUs we want to receive
+ * interrupts. If we don't want certain CPUs to receive IRQs we
+ * can simply not tell the I/O APIC code about them in this function.
+ * We also do not tell it about the BSP since it tells itself about
+ * the BSP internally to work with UP kernels and on UP machines.
+ */
+void
+set_interrupt_apic_ids(void)
+{
+ u_int i, apic_id;
+
+ for (i = 0; i < MAXCPU; i++) {
+ apic_id = cpu_apic_ids[i];
+ if (apic_id == -1)
+ continue;
+ if (cpu_info[apic_id].cpu_bsp)
+ continue;
+ if (cpu_info[apic_id].cpu_disabled)
+ continue;
+
+ /* Don't let hyperthreads service interrupts. */
+ if (cpu_logical > 1 &&
+ apic_id % cpu_logical != 0)
+ continue;
+
+ intr_add_cpu(i);
+ }
+}
+
+/*
+ * Assign logical CPU IDs to local APICs.
+ */
+void
+assign_cpu_ids(void)
+{
+ u_int i;
+
+ TUNABLE_INT_FETCH("machdep.hyperthreading_allowed",
+ &hyperthreading_allowed);
+
+ /* Check for explicitly disabled CPUs. */
+ for (i = 0; i <= MAX_APIC_ID; i++) {
+ if (!cpu_info[i].cpu_present || cpu_info[i].cpu_bsp)
+ continue;
+
+ if (hyperthreading_cpus > 1 && i % hyperthreading_cpus != 0) {
+ cpu_info[i].cpu_hyperthread = 1;
+
+ /*
+ * Don't use HT CPU if it has been disabled by a
+ * tunable.
+ */
+ if (hyperthreading_allowed == 0) {
+ cpu_info[i].cpu_disabled = 1;
+ continue;
+ }
+ }
+
+ /* Don't use this CPU if it has been disabled by a tunable. */
+ if (resource_disabled("lapic", i)) {
+ cpu_info[i].cpu_disabled = 1;
+ continue;
+ }
+ }
+
+ if (hyperthreading_allowed == 0 && hyperthreading_cpus > 1) {
+ hyperthreading_cpus = 0;
+ cpu_logical = 1;
+ }
+
+ /*
+ * Assign CPU IDs to local APIC IDs and disable any CPUs
+ * beyond MAXCPU. CPU 0 is always assigned to the BSP.
+ *
+ * To minimize confusion for userland, we attempt to number
+ * CPUs such that all threads and cores in a package are
+ * grouped together. For now we assume that the BSP is always
+ * the first thread in a package and just start adding APs
+ * starting with the BSP's APIC ID.
+ */
+ mp_ncpus = 1;
+ cpu_apic_ids[0] = boot_cpu_id;
+ apic_cpuids[boot_cpu_id] = 0;
+ for (i = boot_cpu_id + 1; i != boot_cpu_id;
+ i == MAX_APIC_ID ? i = 0 : i++) {
+ if (!cpu_info[i].cpu_present || cpu_info[i].cpu_bsp ||
+ cpu_info[i].cpu_disabled)
+ continue;
+
+ if (mp_ncpus < MAXCPU) {
+ cpu_apic_ids[mp_ncpus] = i;
+ apic_cpuids[i] = mp_ncpus;
+ mp_ncpus++;
+ } else
+ cpu_info[i].cpu_disabled = 1;
+ }
+ KASSERT(mp_maxid >= mp_ncpus - 1,
+ ("%s: counters out of sync: max %d, count %d", __func__, mp_maxid,
+ mp_ncpus));
+}
+
+#ifdef COUNT_XINVLTLB_HITS
+u_int xhits_gbl[MAXCPU];
+u_int xhits_pg[MAXCPU];
+u_int xhits_rng[MAXCPU];
+static SYSCTL_NODE(_debug, OID_AUTO, xhits, CTLFLAG_RW, 0, "");
+SYSCTL_OPAQUE(_debug_xhits, OID_AUTO, global, CTLFLAG_RW, &xhits_gbl,
+ sizeof(xhits_gbl), "IU", "");
+SYSCTL_OPAQUE(_debug_xhits, OID_AUTO, page, CTLFLAG_RW, &xhits_pg,
+ sizeof(xhits_pg), "IU", "");
+SYSCTL_OPAQUE(_debug_xhits, OID_AUTO, range, CTLFLAG_RW, &xhits_rng,
+ sizeof(xhits_rng), "IU", "");
+
+u_int ipi_global;
+u_int ipi_page;
+u_int ipi_range;
+u_int ipi_range_size;
+SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_global, CTLFLAG_RW, &ipi_global, 0, "");
+SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_page, CTLFLAG_RW, &ipi_page, 0, "");
+SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_range, CTLFLAG_RW, &ipi_range, 0, "");
+SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_range_size, CTLFLAG_RW, &ipi_range_size,
+ 0, "");
+
+u_int ipi_masked_global;
+u_int ipi_masked_page;
+u_int ipi_masked_range;
+u_int ipi_masked_range_size;
+SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_masked_global, CTLFLAG_RW,
+ &ipi_masked_global, 0, "");
+SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_masked_page, CTLFLAG_RW,
+ &ipi_masked_page, 0, "");
+SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_masked_range, CTLFLAG_RW,
+ &ipi_masked_range, 0, "");
+SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_masked_range_size, CTLFLAG_RW,
+ &ipi_masked_range_size, 0, "");
+#endif /* COUNT_XINVLTLB_HITS */
+
+/*
+ * Init and startup IPI.
+ */
+void
+ipi_startup(int apic_id, int vector)
+{
+
+ /*
+ * This attempts to follow the algorithm described in the
+ * Intel Multiprocessor Specification v1.4 in section B.4.
+ * For each IPI, we allow the local APIC ~20us to deliver the
+ * IPI. If that times out, we panic.
+ */
+
+ /*
+ * first we do an INIT IPI: this INIT IPI might be run, resetting
+ * and running the target CPU. OR this INIT IPI might be latched (P5
+ * bug), CPU waiting for STARTUP IPI. OR this INIT IPI might be
+ * ignored.
+ */
+ lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_LEVEL |
+ APIC_LEVEL_ASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_INIT, apic_id);
+ lapic_ipi_wait(100);
+
+ /* Explicitly deassert the INIT IPI. */
+ lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_LEVEL |
+ APIC_LEVEL_DEASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_INIT,
+ apic_id);
+
+ DELAY(10000); /* wait ~10mS */
+
+ /*
+ * next we do a STARTUP IPI: the previous INIT IPI might still be
+ * latched, (P5 bug) this 1st STARTUP would then terminate
+ * immediately, and the previously started INIT IPI would continue. OR
+ * the previous INIT IPI has already run. and this STARTUP IPI will
+ * run. OR the previous INIT IPI was ignored. and this STARTUP IPI
+ * will run.
+ */
+ lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_EDGE |
+ APIC_LEVEL_ASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_STARTUP |
+ vector, apic_id);
+ if (!lapic_ipi_wait(100))
+ panic("Failed to deliver first STARTUP IPI to APIC %d",
+ apic_id);
+ DELAY(200); /* wait ~200uS */
+
+ /*
+ * finally we do a 2nd STARTUP IPI: this 2nd STARTUP IPI should run IF
+ * the previous STARTUP IPI was cancelled by a latched INIT IPI. OR
+ * this STARTUP IPI will be ignored, as only ONE STARTUP IPI is
+ * recognized after hardware RESET or INIT IPI.
+ */
+ lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_EDGE |
+ APIC_LEVEL_ASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_STARTUP |
+ vector, apic_id);
+ if (!lapic_ipi_wait(100))
+ panic("Failed to deliver second STARTUP IPI to APIC %d",
+ apic_id);
+
+ DELAY(200); /* wait ~200uS */
+}
+
+/*
+ * Send an IPI to specified CPU handling the bitmap logic.
+ */
+void
+ipi_send_cpu(int cpu, u_int ipi)
+{
+ u_int bitmap, old_pending, new_pending;
+
+ KASSERT(cpu_apic_ids[cpu] != -1, ("IPI to non-existent CPU %d", cpu));
+
+ if (IPI_IS_BITMAPED(ipi)) {
+ bitmap = 1 << ipi;
+ ipi = IPI_BITMAP_VECTOR;
+ do {
+ old_pending = cpu_ipi_pending[cpu];
+ new_pending = old_pending | bitmap;
+ } while (!atomic_cmpset_int(&cpu_ipi_pending[cpu],
+ old_pending, new_pending));
+ if (old_pending)
+ return;
+ }
+ lapic_ipi_vectored(ipi, cpu_apic_ids[cpu]);
+}
+
+void
+ipi_bitmap_handler(struct trapframe frame)
+{
+ struct trapframe *oldframe;
+ struct thread *td;
+ int cpu = PCPU_GET(cpuid);
+ u_int ipi_bitmap;
+
+ critical_enter();
+ td = curthread;
+ td->td_intr_nesting_level++;
+ oldframe = td->td_intr_frame;
+ td->td_intr_frame = &frame;
+ ipi_bitmap = atomic_readandclear_int(&cpu_ipi_pending[cpu]);
+ if (ipi_bitmap & (1 << IPI_PREEMPT)) {
+#ifdef COUNT_IPIS
+ (*ipi_preempt_counts[cpu])++;
+#endif
+ sched_preempt(td);
+ }
+ if (ipi_bitmap & (1 << IPI_AST)) {
+#ifdef COUNT_IPIS
+ (*ipi_ast_counts[cpu])++;
+#endif
+ /* Nothing to do for AST */
+ }
+ if (ipi_bitmap & (1 << IPI_HARDCLOCK)) {
+#ifdef COUNT_IPIS
+ (*ipi_hardclock_counts[cpu])++;
+#endif
+ hardclockintr();
+ }
+ td->td_intr_frame = oldframe;
+ td->td_intr_nesting_level--;
+ critical_exit();
+}
+
+/*
+ * send an IPI to a set of cpus.
+ */
+void
+ipi_selected(cpuset_t cpus, u_int ipi)
+{
+ int cpu;
+
+ /*
+ * IPI_STOP_HARD maps to a NMI and the trap handler needs a bit
+ * of help in order to understand what is the source.
+ * Set the mask of receiving CPUs for this purpose.
+ */
+ if (ipi == IPI_STOP_HARD)
+ CPU_OR_ATOMIC(&ipi_nmi_pending, &cpus);
+
+ while ((cpu = CPU_FFS(&cpus)) != 0) {
+ cpu--;
+ CPU_CLR(cpu, &cpus);
+ CTR3(KTR_SMP, "%s: cpu: %d ipi: %x", __func__, cpu, ipi);
+ ipi_send_cpu(cpu, ipi);
+ }
+}
+
+/*
+ * send an IPI to a specific CPU.
+ */
+void
+ipi_cpu(int cpu, u_int ipi)
+{
+
+ /*
+ * IPI_STOP_HARD maps to a NMI and the trap handler needs a bit
+ * of help in order to understand what is the source.
+ * Set the mask of receiving CPUs for this purpose.
+ */
+ if (ipi == IPI_STOP_HARD)
+ CPU_SET_ATOMIC(cpu, &ipi_nmi_pending);
+
+ CTR3(KTR_SMP, "%s: cpu: %d ipi: %x", __func__, cpu, ipi);
+ ipi_send_cpu(cpu, ipi);
+}
+
+/*
+ * send an IPI to all CPUs EXCEPT myself
+ */
+void
+ipi_all_but_self(u_int ipi)
+{
+ cpuset_t other_cpus;
+
+ other_cpus = all_cpus;
+ CPU_CLR(PCPU_GET(cpuid), &other_cpus);
+ if (IPI_IS_BITMAPED(ipi)) {
+ ipi_selected(other_cpus, ipi);
+ return;
+ }
+
+ /*
+ * IPI_STOP_HARD maps to a NMI and the trap handler needs a bit
+ * of help in order to understand what is the source.
+ * Set the mask of receiving CPUs for this purpose.
+ */
+ if (ipi == IPI_STOP_HARD)
+ CPU_OR_ATOMIC(&ipi_nmi_pending, &other_cpus);
+
+ CTR2(KTR_SMP, "%s: ipi: %x", __func__, ipi);
+ lapic_ipi_vectored(ipi, APIC_IPI_DEST_OTHERS);
+}
+
+int
+ipi_nmi_handler()
+{
+ u_int cpuid;
+
+ /*
+ * As long as there is not a simple way to know about a NMI's
+ * source, if the bitmask for the current CPU is present in
+ * the global pending bitword an IPI_STOP_HARD has been issued
+ * and should be handled.
+ */
+ cpuid = PCPU_GET(cpuid);
+ if (!CPU_ISSET(cpuid, &ipi_nmi_pending))
+ return (1);
+
+ CPU_CLR_ATOMIC(cpuid, &ipi_nmi_pending);
+ cpustop_handler();
+ return (0);
+}
+
+/*
+ * Handle an IPI_STOP by saving our current context and spinning until we
+ * are resumed.
+ */
+void
+cpustop_handler(void)
+{
+ u_int cpu;
+
+ cpu = PCPU_GET(cpuid);
+
+ savectx(&stoppcbs[cpu]);
+
+ /* Indicate that we are stopped */
+ CPU_SET_ATOMIC(cpu, &stopped_cpus);
+
+ /* Wait for restart */
+ while (!CPU_ISSET(cpu, &started_cpus))
+ ia32_pause();
+
+ CPU_CLR_ATOMIC(cpu, &started_cpus);
+ CPU_CLR_ATOMIC(cpu, &stopped_cpus);
+
+#if defined(__amd64__) && defined(DDB)
+ amd64_db_resume_dbreg();
+#endif
+
+ if (cpu == 0 && cpustop_restartfunc != NULL) {
+ cpustop_restartfunc();
+ cpustop_restartfunc = NULL;
+ }
+}
+
+/*
+ * Handle an IPI_SUSPEND by saving our current context and spinning until we
+ * are resumed.
+ */
+void
+cpususpend_handler(void)
+{
+ u_int cpu;
+
+ mtx_assert(&smp_ipi_mtx, MA_NOTOWNED);
+
+ cpu = PCPU_GET(cpuid);
+ if (savectx(&susppcbs[cpu]->sp_pcb)) {
+#ifdef __amd64__
+ fpususpend(susppcbs[cpu]->sp_fpususpend);
+#else
+ npxsuspend(susppcbs[cpu]->sp_fpususpend);
+#endif
+ wbinvd();
+ CPU_SET_ATOMIC(cpu, &suspended_cpus);
+ } else {
+#ifdef __amd64__
+ fpuresume(susppcbs[cpu]->sp_fpususpend);
+#else
+ npxresume(susppcbs[cpu]->sp_fpususpend);
+#endif
+ pmap_init_pat();
+ initializecpu();
+ PCPU_SET(switchtime, 0);
+ PCPU_SET(switchticks, ticks);
+
+ /* Indicate that we are resumed */
+ CPU_CLR_ATOMIC(cpu, &suspended_cpus);
+ }
+
+ /* Wait for resume */
+ while (!CPU_ISSET(cpu, &started_cpus))
+ ia32_pause();
+
+ if (cpu_ops.cpu_resume)
+ cpu_ops.cpu_resume();
+#ifdef __amd64__
+ if (vmm_resume_p)
+ vmm_resume_p();
+#endif
+
+ /* Resume MCA and local APIC */
+ lapic_xapic_mode();
+ mca_resume();
+ lapic_setup(0);
+
+ /* Indicate that we are resumed */
+ CPU_CLR_ATOMIC(cpu, &suspended_cpus);
+ CPU_CLR_ATOMIC(cpu, &started_cpus);
+}
+
+
+void
+invlcache_handler(void)
+{
+#ifdef COUNT_IPIS
+ (*ipi_invlcache_counts[PCPU_GET(cpuid)])++;
+#endif /* COUNT_IPIS */
+
+ wbinvd();
+ atomic_add_int(&smp_tlb_wait, 1);
+}
+
+/*
+ * This is called once the rest of the system is up and running and we're
+ * ready to let the AP's out of the pen.
+ */
+static void
+release_aps(void *dummy __unused)
+{
+
+ if (mp_ncpus == 1)
+ return;
+ atomic_store_rel_int(&aps_ready, 1);
+ while (smp_started == 0)
+ ia32_pause();
+}
+SYSINIT(start_aps, SI_SUB_SMP, SI_ORDER_FIRST, release_aps, NULL);
+
+#ifdef COUNT_IPIS
+/*
+ * Setup interrupt counters for IPI handlers.
+ */
+static void
+mp_ipi_intrcnt(void *dummy)
+{
+ char buf[64];
+ int i;
+
+ CPU_FOREACH(i) {
+ snprintf(buf, sizeof(buf), "cpu%d:invltlb", i);
+ intrcnt_add(buf, &ipi_invltlb_counts[i]);
+ snprintf(buf, sizeof(buf), "cpu%d:invlrng", i);
+ intrcnt_add(buf, &ipi_invlrng_counts[i]);
+ snprintf(buf, sizeof(buf), "cpu%d:invlpg", i);
+ intrcnt_add(buf, &ipi_invlpg_counts[i]);
+ snprintf(buf, sizeof(buf), "cpu%d:invlcache", i);
+ intrcnt_add(buf, &ipi_invlcache_counts[i]);
+ snprintf(buf, sizeof(buf), "cpu%d:preempt", i);
+ intrcnt_add(buf, &ipi_preempt_counts[i]);
+ snprintf(buf, sizeof(buf), "cpu%d:ast", i);
+ intrcnt_add(buf, &ipi_ast_counts[i]);
+ snprintf(buf, sizeof(buf), "cpu%d:rendezvous", i);
+ intrcnt_add(buf, &ipi_rendezvous_counts[i]);
+ snprintf(buf, sizeof(buf), "cpu%d:hardclock", i);
+ intrcnt_add(buf, &ipi_hardclock_counts[i]);
+ }
+}
+SYSINIT(mp_ipi_intrcnt, SI_SUB_INTR, SI_ORDER_MIDDLE, mp_ipi_intrcnt, NULL);
+#endif
diff --git a/sys/x86/xen/xen_intr.c b/sys/x86/xen/xen_intr.c
index 64979b136ead..3bc4b4399f5c 100644
--- a/sys/x86/xen/xen_intr.c
+++ b/sys/x86/xen/xen_intr.c
@@ -1,7 +1,7 @@
/******************************************************************************
* xen_intr.c
*
- * Xen event and interrupt services for x86 PV and HVM guests.
+ * Xen event and interrupt services for x86 HVM guests.
*
* Copyright (c) 2002-2005, K A Fraser
* Copyright (c) 2005, Intel Corporation <xiaofeng.ling@intel.com>
@@ -864,10 +864,8 @@ xen_intr_assign_cpu(struct intsrc *base_isrc, u_int apic_id)
u_int to_cpu, vcpu_id;
int error, masked;
-#ifdef XENHVM
if (xen_vector_callback_enabled == 0)
return (EOPNOTSUPP);
-#endif
to_cpu = apic_cpuid(apic_id);
vcpu_id = pcpu_find(to_cpu)->pc_vcpu_id;
diff --git a/sys/x86/xen/xen_nexus.c b/sys/x86/xen/xen_nexus.c
index f25f970c609b..73506fc955f0 100644
--- a/sys/x86/xen/xen_nexus.c
+++ b/sys/x86/xen/xen_nexus.c
@@ -66,14 +66,11 @@ static int
nexus_xen_attach(device_t dev)
{
int error;
-#ifndef XEN
device_t acpi_dev = NULL;
-#endif
nexus_init_resources();
bus_generic_probe(dev);
-#ifndef XEN
if (xen_initial_domain()) {
/* Disable some ACPI devices that are not usable by Dom0 */
acpi_cpu_disabled = true;
@@ -84,13 +81,10 @@ nexus_xen_attach(device_t dev)
if (acpi_dev == NULL)
panic("Unable to add ACPI bus to Xen Dom0");
}
-#endif
error = bus_generic_attach(dev);
-#ifndef XEN
if (xen_initial_domain() && (error == 0))
acpi_install_wakeup_handler(device_get_softc(acpi_dev));
-#endif
return (error);
}
diff --git a/tests/freebsd_test_suite/macros.h b/tests/freebsd_test_suite/macros.h
new file mode 100644
index 000000000000..8d95f05324a3
--- /dev/null
+++ b/tests/freebsd_test_suite/macros.h
@@ -0,0 +1,56 @@
+/*-
+ * Copyright (c) 2015 EMC / Isilon Storage Division
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _FREEBSD_TEST_MACROS_H_
+#define _FREEBSD_TEST_MACROS_H_
+
+#include <sys/param.h>
+#include <sys/module.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#define ATF_REQUIRE_KERNEL_MODULE(_mod_name) do { \
+ if (modfind(_mod_name) == -1) { \
+ atf_tc_skip("module %s could not be resolved: %s", \
+ _mod_name, strerror(errno)); \
+ } \
+} while(0)
+
+#define PLAIN_REQUIRE_KERNEL_MODULE(_mod_name, _exit_code) do { \
+ if (modfind(_mod_name) == -1) { \
+ printf("module %s could not be resolved: %s\n", \
+ _mod_name, strerror(errno)); \
+ _exit(_exit_code); \
+ } \
+} while(0)
+
+#endif
diff --git a/tests/sys/Makefile b/tests/sys/Makefile
index 9225eabcdb90..066c918188b4 100644
--- a/tests/sys/Makefile
+++ b/tests/sys/Makefile
@@ -4,9 +4,15 @@
TESTSDIR= ${TESTSBASE}/sys
+TESTS_SUBDIRS+= aio
+TESTS_SUBDIRS+= fifo
+TESTS_SUBDIRS+= file
TESTS_SUBDIRS+= kern
+TESTS_SUBDIRS+= kqueue
+TESTS_SUBDIRS+= mqueue
TESTS_SUBDIRS+= netinet
TESTS_SUBDIRS+= opencrypto
+TESTS_SUBDIRS+= vm
# Items not integrated into kyua runs by default
SUBDIR+= pjdfstest
diff --git a/tests/sys/aio/Makefile b/tests/sys/aio/Makefile
new file mode 100644
index 000000000000..851252def348
--- /dev/null
+++ b/tests/sys/aio/Makefile
@@ -0,0 +1,16 @@
+# $FreeBSD$
+
+TESTSDIR= ${TESTSBASE}/sys/aio
+
+PLAIN_TESTS_C+= aio_kqueue_test
+PLAIN_TESTS_C+= lio_kqueue_test
+ATF_TESTS_C+= aio_test
+
+DPADD.aio_test+= ${LIBUTIL}
+LDADD.aio_test+= -lutil
+
+CFLAGS+= -I${.CURDIR:H:H}
+
+WARNS?= 6
+
+.include <bsd.test.mk>
diff --git a/tools/regression/aio/kqueue/aio_kqueue.c b/tests/sys/aio/aio_kqueue_test.c
index 87b4125c327a..14e47297380d 100644
--- a/tools/regression/aio/kqueue/aio_kqueue.c
+++ b/tests/sys/aio/aio_kqueue_test.c
@@ -46,25 +46,29 @@
#include <string.h>
#include <unistd.h>
-#define PATH_TEMPLATE "/tmp/aio.XXXXXXXXXX"
+#include "freebsd_test_suite/macros.h"
-#define MAX 128
+#define PATH_TEMPLATE "aio.XXXXXXXXXX"
+
+#define MAX_IOCBS 128
#define MAX_RUNS 300
/* #define DEBUG */
int
main (int argc, char *argv[])
{
- int fd;
- struct aiocb *iocb[MAX], *kq_iocb;
- int i, result, run, error, j;
- char buffer[32768];
- int kq = kqueue();
+ struct aiocb *iocb[MAX_IOCBS], *kq_iocb;
+ char *file, pathname[sizeof(PATH_TEMPLATE)+1];
struct kevent ke, kq_returned;
struct timespec ts;
- int cancel, pending, tmp_file = 0, failed = 0;
- char *file, pathname[sizeof(PATH_TEMPLATE)+1];
+ char buffer[32768];
+ int cancel, error, failed = 0, fd, kq, pending, result, run;
+ int tmp_file = 0;
+ unsigned i, j;
+
+ PLAIN_REQUIRE_KERNEL_MODULE("aio", 0);
+ kq = kqueue();
if (kq < 0) {
perror("No kqeueue\n");
exit(1);
@@ -86,7 +90,7 @@ main (int argc, char *argv[])
#ifdef DEBUG
printf("Run %d\n", run);
#endif
- for (i = 0; i < MAX; i++) {
+ for (i = 0; i < nitems(iocb); i++) {
iocb[i] = (struct aiocb *)calloc(1,
sizeof(struct aiocb));
if (iocb[i] == NULL)
@@ -94,7 +98,7 @@ main (int argc, char *argv[])
}
pending = 0;
- for (i = 0; i < MAX; i++) {
+ for (i = 0; i < nitems(iocb); i++) {
pending++;
iocb[i]->aio_nbytes = sizeof(buffer);
iocb[i]->aio_buf = buffer;
@@ -129,8 +133,8 @@ main (int argc, char *argv[])
}
}
}
- cancel = MAX - pending;
-
+ cancel = nitems(iocb) - pending;
+
i = 0;
while (pending) {
@@ -159,11 +163,11 @@ main (int argc, char *argv[])
break;
#ifdef DEBUG
printf("Try again left %d out of %d %d\n",
- pending, MAX, cancel);
+ pending, nitems(iocb), cancel);
#endif
}
- for (j = 0; j < MAX && iocb[j] != kq_iocb;
+ for (j = 0; j < nitems(iocb) && iocb[j] != kq_iocb;
j++) ;
#ifdef DEBUG
printf("kq_iocb %p\n", kq_iocb);
@@ -190,7 +194,7 @@ main (int argc, char *argv[])
i++;
}
- for (i = 0; i < MAX; i++)
+ for (i = 0; i < nitems(iocb); i++)
free(iocb[i]);
}
diff --git a/tools/regression/aio/aiotest/aiotest.c b/tests/sys/aio/aio_test.c
index 6a3d612bfd31..4134e786dd74 100644
--- a/tools/regression/aio/aiotest/aiotest.c
+++ b/tests/sys/aio/aio_test.c
@@ -57,7 +57,11 @@
#include <termios.h>
#include <unistd.h>
-#define PATH_TEMPLATE "/tmp/aio.XXXXXXXXXX"
+#include <atf-c.h>
+
+#include "freebsd_test_suite/macros.h"
+
+#define PATH_TEMPLATE "aio.XXXXXXXXXX"
/*
* GLOBAL_MAX sets the largest usable buffer size to be read and written, as
@@ -69,7 +73,6 @@
#define BUFFER_MAX GLOBAL_MAX
struct aio_context {
- const char *ac_test;
int ac_read_fd, ac_write_fd;
long ac_seed;
char ac_buffer[GLOBAL_MAX];
@@ -81,16 +84,6 @@ struct aio_context {
static int aio_timedout;
-static void
-aio_available(void)
-{
-
- if (modfind("aio") == -1)
- errx(0,
- "aio support not available in the kernel; skipping "
- "testcases");
-}
-
/*
* Each test run specifies a timeout in seconds. Use the somewhat obsoleted
* signal(3) and alarm(3) APIs to set this up.
@@ -103,23 +96,21 @@ aio_timeout_signal(int sig __unused)
}
static void
-aio_timeout_start(const char *string1, const char *string2, int seconds)
+aio_timeout_start(int seconds)
{
aio_timedout = 0;
- if (signal(SIGALRM, aio_timeout_signal) == SIG_ERR)
- errx(1, "FAIL: %s: %s: aio_timeout_set: signal(SIGALRM): %s",
- string1, string2, strerror(errno));
+ ATF_REQUIRE_MSG(signal(SIGALRM, aio_timeout_signal) != SIG_ERR,
+ "failed to set SIGALRM handler: %s", strerror(errno));
alarm(seconds);
}
static void
-aio_timeout_stop(const char *string1, const char *string2)
+aio_timeout_stop(void)
{
- if (signal(SIGALRM, NULL) == SIG_ERR)
- errx(1, "FAIL: %s: %s: aio_timeout_stop: signal(NULL): %s",
- string1, string2, strerror(errno));
+ ATF_REQUIRE_MSG(signal(SIGALRM, NULL) != SIG_ERR,
+ "failed to reset SIGALRM handler to default: %s", strerror(errno));
alarm(0);
}
@@ -164,25 +155,23 @@ aio_test_buffer(char *buffer, int len, long seed)
* test setup.
*/
static void
-aio_context_init(struct aio_context *ac, const char *test, int read_fd,
+aio_context_init(struct aio_context *ac, int read_fd,
int write_fd, int buflen, int seconds, void (*cleanup)(void *),
void *cleanup_arg)
{
- if (buflen > BUFFER_MAX)
- errx(1, "FAIL: %s: aio_context_init: buffer too large",
- test);
+ ATF_REQUIRE_MSG(buflen <= BUFFER_MAX,
+ "aio_context_init: buffer too large (%d > %d)",
+ buflen, BUFFER_MAX);
bzero(ac, sizeof(*ac));
- ac->ac_test = test;
ac->ac_read_fd = read_fd;
ac->ac_write_fd = write_fd;
ac->ac_buflen = buflen;
srandomdev();
ac->ac_seed = random();
aio_fill_buffer(ac->ac_buffer, buflen, ac->ac_seed);
- if (aio_test_buffer(ac->ac_buffer, buflen, ac->ac_seed) == 0)
- errx(1, "%s: aio_context_init: aio_test_buffer: internal "
- "error", test);
+ ATF_REQUIRE_MSG(aio_test_buffer(ac->ac_buffer, buflen,
+ ac->ac_seed) != 0, "aio_test_buffer: internal error");
ac->ac_seconds = seconds;
ac->ac_cleanup = cleanup;
ac->ac_cleanup_arg = cleanup_arg;
@@ -215,7 +204,7 @@ aio_write_test(struct aio_context *ac)
struct aiocb aio, *aiop;
ssize_t len;
- aio_available();
+ ATF_REQUIRE_KERNEL_MODULE("aio");
bzero(&aio, sizeof(aio));
aio.aio_buf = ac->ac_buffer;
@@ -223,19 +212,17 @@ aio_write_test(struct aio_context *ac)
aio.aio_fildes = ac->ac_write_fd;
aio.aio_offset = 0;
- aio_timeout_start(ac->ac_test, "aio_write_test", ac->ac_seconds);
+ aio_timeout_start(ac->ac_seconds);
if (aio_write(&aio) < 0) {
if (errno == EINTR) {
if (aio_timedout) {
aio_cleanup(ac);
- errx(1, "FAIL: %s: aio_write_test: "
- "aio_write: timed out", ac->ac_test);
+ atf_tc_fail("aio_write timed out");
}
}
aio_cleanup(ac);
- errx(1, "FAIL: %s: aio_write_test: aio_write: %s",
- ac->ac_test, strerror(errno));
+ atf_tc_fail("aio_write failed: %s", strerror(errno));
}
len = aio_waitcomplete(&aiop, NULL);
@@ -243,22 +230,19 @@ aio_write_test(struct aio_context *ac)
if (errno == EINTR) {
if (aio_timedout) {
aio_cleanup(ac);
- errx(1, "FAIL: %s: aio_write_test: "
- "aio_waitcomplete: timed out",
- ac->ac_test);
+ atf_tc_fail("aio_waitcomplete timed out");
}
}
aio_cleanup(ac);
- errx(1, "FAIL: %s: aio_write_test: aio_waitcomplete: %s",
- ac->ac_test, strerror(errno));
+ atf_tc_fail("aio_waitcomplete failed: %s", strerror(errno));
}
- aio_timeout_stop(ac->ac_test, "aio_write_test");
+ aio_timeout_stop();
if (len != ac->ac_buflen) {
aio_cleanup(ac);
- errx(1, "FAIL: %s: aio_write_test: aio_waitcomplete: short "
- "write (%jd)", ac->ac_test, (intmax_t)len);
+ atf_tc_fail("aio_waitcomplete short write (%jd)",
+ (intmax_t)len);
}
}
@@ -272,7 +256,7 @@ aio_read_test(struct aio_context *ac)
struct aiocb aio, *aiop;
ssize_t len;
- aio_available();
+ ATF_REQUIRE_KERNEL_MODULE("aio");
bzero(ac->ac_buffer, ac->ac_buflen);
bzero(&aio, sizeof(aio));
@@ -281,19 +265,17 @@ aio_read_test(struct aio_context *ac)
aio.aio_fildes = ac->ac_read_fd;
aio.aio_offset = 0;
- aio_timeout_start(ac->ac_test, "aio_read_test", ac->ac_seconds);
+ aio_timeout_start(ac->ac_seconds);
if (aio_read(&aio) < 0) {
if (errno == EINTR) {
if (aio_timedout) {
aio_cleanup(ac);
- errx(1, "FAIL: %s: aio_read_test: "
- "aio_read: timed out", ac->ac_test);
+ atf_tc_fail("aio_write timed out");
}
}
aio_cleanup(ac);
- errx(1, "FAIL: %s: aio_read_test: aio_read %s", ac->ac_test,
- strerror(errno));
+ atf_tc_fail("aio_read failed: %s", strerror(errno));
}
len = aio_waitcomplete(&aiop, NULL);
@@ -301,28 +283,24 @@ aio_read_test(struct aio_context *ac)
if (errno == EINTR) {
if (aio_timedout) {
aio_cleanup(ac);
- errx(1, "FAIL: %s: aio_read_test: "
- "aio_waitcomplete: timed out",
- ac->ac_test);
+ atf_tc_fail("aio_waitcomplete timed out");
}
}
aio_cleanup(ac);
- errx(1, "FAIL: %s: aio_read_test: aio_waitcomplete: %s",
- ac->ac_test, strerror(errno));
+ atf_tc_fail("aio_waitcomplete failed: %s", strerror(errno));
}
- aio_timeout_stop(ac->ac_test, "aio_read_test");
+ aio_timeout_stop();
if (len != ac->ac_buflen) {
aio_cleanup(ac);
- errx(1, "FAIL: %s: aio_read_test: aio_waitcomplete: short "
- "read (%jd)", ac->ac_test, (intmax_t)len);
+ atf_tc_fail("aio_waitcomplete short read (%jd)",
+ (intmax_t)len);
}
if (aio_test_buffer(ac->ac_buffer, ac->ac_buflen, ac->ac_seed) == 0) {
aio_cleanup(ac);
- errx(1, "FAIL: %s: aio_read_test: buffer mismatch",
- ac->ac_test);
+ atf_tc_fail("buffer mismatched");
}
}
@@ -353,33 +331,29 @@ aio_file_cleanup(void *arg)
#define FILE_LEN GLOBAL_MAX
#define FILE_TIMEOUT 30
-static void
-aio_file_test(void)
+ATF_TC_WITHOUT_HEAD(aio_file_test);
+ATF_TC_BODY(aio_file_test, tc)
{
char pathname[PATH_MAX];
struct aio_file_arg arg;
struct aio_context ac;
int fd;
- aio_available();
+ ATF_REQUIRE_KERNEL_MODULE("aio");
strcpy(pathname, PATH_TEMPLATE);
fd = mkstemp(pathname);
- if (fd == -1)
- errx(1, "FAIL: aio_file_test: mkstemp: %s",
- strerror(errno));
+ ATF_REQUIRE_MSG(fd != -1, "mkstemp failed: %s", strerror(errno));
arg.afa_fd = fd;
arg.afa_pathname = pathname;
- aio_context_init(&ac, "aio_file_test", fd, fd, FILE_LEN,
+ aio_context_init(&ac, fd, fd, FILE_LEN,
FILE_TIMEOUT, aio_file_cleanup, &arg);
aio_write_test(&ac);
aio_read_test(&ac);
aio_file_cleanup(&arg);
-
- fprintf(stderr, "PASS: aio_file_test\n");
}
struct aio_fifo_arg {
@@ -403,15 +377,15 @@ aio_fifo_cleanup(void *arg)
#define FIFO_LEN 256
#define FIFO_TIMEOUT 30
-static void
-aio_fifo_test(void)
+ATF_TC_WITHOUT_HEAD(aio_fifo_test);
+ATF_TC_BODY(aio_fifo_test, tc)
{
int error, read_fd = -1, write_fd = -1;
struct aio_fifo_arg arg;
char pathname[PATH_MAX];
struct aio_context ac;
- aio_available();
+ ATF_REQUIRE_KERNEL_MODULE("aio");
/*
* In theory, mkstemp() can return a name that is then collided with.
@@ -419,12 +393,12 @@ aio_fifo_test(void)
* rather than retrying.
*/
strcpy(pathname, PATH_TEMPLATE);
- if (mkstemp(pathname) == -1)
- err(1, "FAIL: aio_fifo_test: mkstemp failed");
- if (unlink(pathname) == -1)
- err(1, "FAIL: aio_fifo_test: unlink failed");
- if (mkfifo(pathname, 0600) == -1)
- errx(1, "FAIL: aio_fifo_test: mkfifo: %s", strerror(errno));
+ ATF_REQUIRE_MSG(mkstemp(pathname) != -1,
+ "mkstemp failed: %s", strerror(errno));
+ ATF_REQUIRE_MSG(unlink(pathname) == 0,
+ "unlink failed: %s", strerror(errno));
+ ATF_REQUIRE_MSG(mkfifo(pathname, 0600) != -1,
+ "mkfifo failed: %s", strerror(errno));
arg.afa_pathname = pathname;
arg.afa_read_fd = -1;
arg.afa_write_fd = -1;
@@ -434,7 +408,7 @@ aio_fifo_test(void)
error = errno;
aio_fifo_cleanup(&arg);
errno = error;
- errx(1, "FAIL: aio_fifo_test: read_fd open: %s",
+ atf_tc_fail("read_fd open failed: %s",
strerror(errno));
}
arg.afa_read_fd = read_fd;
@@ -444,19 +418,17 @@ aio_fifo_test(void)
error = errno;
aio_fifo_cleanup(&arg);
errno = error;
- errx(1, "FAIL: aio_fifo_test: write_fd open: %s",
+ atf_tc_fail("write_fd open failed: %s",
strerror(errno));
}
arg.afa_write_fd = write_fd;
- aio_context_init(&ac, "aio_fifo_test", read_fd, write_fd, FIFO_LEN,
+ aio_context_init(&ac, read_fd, write_fd, FIFO_LEN,
FIFO_TIMEOUT, aio_fifo_cleanup, &arg);
aio_write_test(&ac);
aio_read_test(&ac);
aio_fifo_cleanup(&arg);
-
- fprintf(stderr, "PASS: aio_fifo_test\n");
}
struct aio_unix_socketpair_arg {
@@ -475,30 +447,27 @@ aio_unix_socketpair_cleanup(void *arg)
#define UNIX_SOCKETPAIR_LEN 256
#define UNIX_SOCKETPAIR_TIMEOUT 30
-static void
-aio_unix_socketpair_test(void)
+ATF_TC_WITHOUT_HEAD(aio_unix_socketpair_test);
+ATF_TC_BODY(aio_unix_socketpair_test, tc)
{
struct aio_unix_socketpair_arg arg;
struct aio_context ac;
int sockets[2];
- aio_available();
+ ATF_REQUIRE_KERNEL_MODULE("aio");
- if (socketpair(PF_UNIX, SOCK_STREAM, 0, sockets) < 0)
- errx(1, "FAIL: aio_socketpair_test: socketpair: %s",
- strerror(errno));
+ ATF_REQUIRE_MSG(socketpair(PF_UNIX, SOCK_STREAM, 0, sockets) != -1,
+ "socketpair failed: %s", strerror(errno));
arg.asa_sockets[0] = sockets[0];
arg.asa_sockets[1] = sockets[1];
- aio_context_init(&ac, "aio_unix_socketpair_test", sockets[0],
+ aio_context_init(&ac, sockets[0],
sockets[1], UNIX_SOCKETPAIR_LEN, UNIX_SOCKETPAIR_TIMEOUT,
aio_unix_socketpair_cleanup, &arg);
aio_write_test(&ac);
aio_read_test(&ac);
aio_unix_socketpair_cleanup(&arg);
-
- fprintf(stderr, "PASS: aio_unix_socketpair_test\n");
}
struct aio_pty_arg {
@@ -518,8 +487,8 @@ aio_pty_cleanup(void *arg)
#define PTY_LEN 256
#define PTY_TIMEOUT 30
-static void
-aio_pty_test(void)
+ATF_TC_WITHOUT_HEAD(aio_pty_test);
+ATF_TC_BODY(aio_pty_test, tc)
{
struct aio_pty_arg arg;
struct aio_context ac;
@@ -527,10 +496,10 @@ aio_pty_test(void)
struct termios ts;
int error;
- aio_available();
+ ATF_REQUIRE_KERNEL_MODULE("aio");
- if (openpty(&read_fd, &write_fd, NULL, NULL, NULL) < 0)
- errx(1, "FAIL: aio_pty_test: openpty: %s", strerror(errno));
+ ATF_REQUIRE_MSG(openpty(&read_fd, &write_fd, NULL, NULL, NULL) == 0,
+ "openpty failed: %s", strerror(errno));
arg.apa_read_fd = read_fd;
arg.apa_write_fd = write_fd;
@@ -539,26 +508,22 @@ aio_pty_test(void)
error = errno;
aio_pty_cleanup(&arg);
errno = error;
- errx(1, "FAIL: aio_pty_test: tcgetattr: %s",
- strerror(errno));
+ atf_tc_fail("tcgetattr failed: %s", strerror(errno));
}
cfmakeraw(&ts);
if (tcsetattr(write_fd, TCSANOW, &ts) < 0) {
error = errno;
aio_pty_cleanup(&arg);
errno = error;
- errx(1, "FAIL: aio_pty_test: tcsetattr: %s",
- strerror(errno));
+ atf_tc_fail("tcsetattr failed: %s", strerror(errno));
}
-
- aio_context_init(&ac, "aio_pty_test", read_fd, write_fd, PTY_LEN,
+ aio_context_init(&ac, read_fd, write_fd, PTY_LEN,
PTY_TIMEOUT, aio_pty_cleanup, &arg);
+
aio_write_test(&ac);
aio_read_test(&ac);
aio_pty_cleanup(&arg);
-
- fprintf(stderr, "PASS: aio_pty_test\n");
}
static void
@@ -572,25 +537,23 @@ aio_pipe_cleanup(void *arg)
#define PIPE_LEN 256
#define PIPE_TIMEOUT 30
-static void
-aio_pipe_test(void)
-{
+ATF_TC_WITHOUT_HEAD(aio_pipe_test);
+ATF_TC_BODY(aio_pipe_test, tc)
+{
struct aio_context ac;
int pipes[2];
- aio_available();
+ ATF_REQUIRE_KERNEL_MODULE("aio");
- if (pipe(pipes) < 0)
- errx(1, "FAIL: aio_pipe_test: pipe: %s", strerror(errno));
+ ATF_REQUIRE_MSG(pipe(pipes) != -1,
+ "pipe failed: %s", strerror(errno));
- aio_context_init(&ac, "aio_file_test", pipes[0], pipes[1], PIPE_LEN,
+ aio_context_init(&ac, pipes[0], pipes[1], PIPE_LEN,
PIPE_TIMEOUT, aio_pipe_cleanup, pipes);
aio_write_test(&ac);
aio_read_test(&ac);
aio_pipe_cleanup(pipes);
-
- fprintf(stderr, "PASS: aio_pipe_test\n");
}
struct aio_md_arg {
@@ -615,11 +578,11 @@ aio_md_cleanup(void *arg)
bzero(&mdio, sizeof(mdio));
mdio.md_version = MDIOVERSION;
mdio.md_unit = ama->ama_unit;
- if (ioctl(ama->ama_mdctl_fd, MDIOCDETACH, &mdio) < 0) {
+ if (ioctl(ama->ama_mdctl_fd, MDIOCDETACH, &mdio) == -1) {
error = errno;
close(ama->ama_mdctl_fd);
errno = error;
- warnx("FAIL: aio_md_test: MDIOCDETACH: %s",
+ atf_tc_fail("ioctl MDIOCDETACH failed: %s",
strerror(errno));
}
}
@@ -629,8 +592,13 @@ aio_md_cleanup(void *arg)
#define MD_LEN GLOBAL_MAX
#define MD_TIMEOUT 30
-static void
-aio_md_test(void)
+ATF_TC(aio_md_test);
+ATF_TC_HEAD(aio_md_test, tc)
+{
+
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+ATF_TC_BODY(aio_md_test, tc)
{
int error, fd, mdctl_fd, unit;
char pathname[PATH_MAX];
@@ -638,18 +606,11 @@ aio_md_test(void)
struct aio_context ac;
struct md_ioctl mdio;
- aio_available();
-
- if (geteuid() != 0) {
- fprintf(stderr, "WARNING: aio_md_test: skipped as euid "
- "!= 0\n");
- return;
- }
+ ATF_REQUIRE_KERNEL_MODULE("aio");
mdctl_fd = open("/dev/" MDCTL_NAME, O_RDWR, 0);
- if (mdctl_fd < 0)
- errx(1, "FAIL: aio_md_test: open(/dev/%s): %s", MDCTL_NAME,
- strerror(errno));
+ ATF_REQUIRE_MSG(mdctl_fd != -1,
+ "opening /dev/%s failed: %s", MDCTL_NAME, strerror(errno));
bzero(&mdio, sizeof(mdio));
mdio.md_version = MDIOVERSION;
@@ -665,42 +626,33 @@ aio_md_test(void)
error = errno;
aio_md_cleanup(&arg);
errno = error;
- errx(1, "FAIL: aio_md_test: MDIOCATTACH: %s",
- strerror(errno));
+ atf_tc_fail("ioctl MDIOCATTACH failed: %s", strerror(errno));
}
arg.ama_unit = unit = mdio.md_unit;
snprintf(pathname, PATH_MAX, "/dev/md%d", unit);
fd = open(pathname, O_RDWR);
- if (fd < 0) {
- error = errno;
- aio_md_cleanup(&arg);
- errno = error;
- errx(1, "FAIL: aio_md_test: open(%s): %s", pathname,
- strerror(errno));
- }
+ ATF_REQUIRE_MSG(fd != -1,
+ "opening %s failed: %s", pathname, strerror(errno));
arg.ama_fd = fd;
- aio_context_init(&ac, "aio_md_test", fd, fd, MD_LEN, MD_TIMEOUT,
+ aio_context_init(&ac, fd, fd, MD_LEN, MD_TIMEOUT,
aio_md_cleanup, &arg);
aio_write_test(&ac);
aio_read_test(&ac);
aio_md_cleanup(&arg);
-
- fprintf(stderr, "PASS: aio_md_test\n");
}
-int
-main(void)
+ATF_TP_ADD_TCS(tp)
{
- aio_file_test();
- aio_fifo_test();
- aio_unix_socketpair_test();
- aio_pty_test();
- aio_pipe_test();
- aio_md_test();
+ ATF_TP_ADD_TC(tp, aio_file_test);
+ ATF_TP_ADD_TC(tp, aio_fifo_test);
+ ATF_TP_ADD_TC(tp, aio_unix_socketpair_test);
+ ATF_TP_ADD_TC(tp, aio_pty_test);
+ ATF_TP_ADD_TC(tp, aio_pipe_test);
+ ATF_TP_ADD_TC(tp, aio_md_test);
- return (0);
+ return (atf_no_error());
}
diff --git a/tools/regression/aio/kqueue/lio/lio_kqueue.c b/tests/sys/aio/lio_kqueue_test.c
index ad7fc6886045..5cc87b38a2f2 100644
--- a/tools/regression/aio/kqueue/lio/lio_kqueue.c
+++ b/tests/sys/aio/lio_kqueue_test.c
@@ -48,16 +48,18 @@
#include <string.h>
#include <unistd.h>
-#define PATH_TEMPLATE "/tmp/aio.XXXXXXXXXX"
+#include "freebsd_test_suite/macros.h"
+
+#define PATH_TEMPLATE "aio.XXXXXXXXXX"
#define LIO_MAX 5
-#define MAX LIO_MAX * 16
+#define MAX_IOCBS LIO_MAX * 16
#define MAX_RUNS 300
int
main(int argc, char *argv[]){
int fd;
- struct aiocb *iocb[MAX];
+ struct aiocb *iocb[MAX_IOCBS];
struct aiocb **lio[LIO_MAX], **lio_element, **kq_lio;
int i, result, run, error, j, k;
char buffer[32768];
@@ -69,6 +71,8 @@ main(int argc, char *argv[]){
char *file, pathname[sizeof(PATH_TEMPLATE)-1];
int tmp_file = 0, failed = 0;
+ PLAIN_REQUIRE_KERNEL_MODULE("aio", 0);
+
if (kq < 0) {
perror("No kqeueue\n");
exit(1);
@@ -99,9 +103,9 @@ main(int argc, char *argv[]){
#endif
for (j = 0; j < LIO_MAX; j++) {
lio[j] = (struct aiocb **)
- malloc(sizeof(struct aiocb *) * MAX/LIO_MAX);
- for(i = 0; i < MAX / LIO_MAX; i++) {
- k = (MAX / LIO_MAX * j) + i;
+ malloc(sizeof(struct aiocb *) * MAX_IOCBS/LIO_MAX);
+ for(i = 0; i < MAX_IOCBS / LIO_MAX; i++) {
+ k = (MAX_IOCBS / LIO_MAX * j) + i;
lio_element = lio[j];
lio[j][i] = iocb[k] = (struct aiocb *)
malloc(sizeof(struct aiocb));
@@ -123,7 +127,7 @@ main(int argc, char *argv[]){
sig.sigev_notify = SIGEV_KEVENT;
time(&time1);
result = lio_listio(LIO_NOWAIT, lio[j],
- MAX / LIO_MAX, &sig);
+ MAX_IOCBS / LIO_MAX, &sig);
error = errno;
time(&time2);
#ifdef DEBUG
@@ -203,7 +207,7 @@ main(int argc, char *argv[]){
} else {
printf("PASS: run %d, operation %d result %d \n", run, LIO_MAX - i -1, result);
}
- for(k = 0; k < MAX / LIO_MAX; k++){
+ for(k = 0; k < MAX_IOCBS / LIO_MAX; k++){
result = aio_return(kq_lio[k]);
#ifdef DEBUG
printf("Return Resulto for %d %d is %d\n", j, k, result);
@@ -220,7 +224,7 @@ main(int argc, char *argv[]){
printf("\n");
#endif
- for(k = 0; k < MAX / LIO_MAX; k++) {
+ for(k = 0; k < MAX_IOCBS / LIO_MAX; k++) {
free(lio[j][k]);
}
free(lio[j]);
diff --git a/tests/sys/fifo/Makefile b/tests/sys/fifo/Makefile
new file mode 100644
index 000000000000..602bf1ed2940
--- /dev/null
+++ b/tests/sys/fifo/Makefile
@@ -0,0 +1,13 @@
+# $FreeBSD$
+
+TESTSDIR= ${TESTSBASE}/sys/fifo
+
+PLAIN_TESTS_C+= fifo_create
+PLAIN_TESTS_C+= fifo_io
+PLAIN_TESTS_C+= fifo_misc
+PLAIN_TESTS_C+= fifo_open
+
+TEST_METADATA.fifo_create+= required_user="root"
+TEST_METADATA.fifo_open+= required_user="root"
+
+.include <bsd.test.mk>
diff --git a/tools/regression/fifo/fifo_create/fifo_create.c b/tests/sys/fifo/fifo_create.c
index 4e8a8a4dc824..2eb01e577c53 100644
--- a/tools/regression/fifo/fifo_create/fifo_create.c
+++ b/tests/sys/fifo/fifo_create.c
@@ -75,7 +75,7 @@
* All activity occurs within a temporary directory created early in the
* test.
*/
-char temp_dir[PATH_MAX];
+static char temp_dir[PATH_MAX];
static void __unused
atexit_temp_dir(void)
@@ -94,7 +94,7 @@ fifo_create_test(int use_mkfifo)
{
struct stat old_dirsb, dirsb, fifosb;
const char *testname;
- char path[PATH_MAX];
+ char path[] = "testfifo";
int error;
if (use_mkfifo)
@@ -106,14 +106,12 @@ fifo_create_test(int use_mkfifo)
* Sleep to make sure that the time stamp on the directory will be
* updated.
*/
- if (stat(temp_dir, &old_dirsb) < 0)
+ if (stat(".", &old_dirsb) < 0)
err(-1, "basic_create_test: %s: stat: %s", testname,
temp_dir);
sleep(2);
- snprintf(path, PATH_MAX, "%s/testfifo", temp_dir);
-
if (use_mkfifo) {
if (mkfifo(path, 0600) < 0)
err(-1, "basic_create_test: %s: %s", testname, path);
@@ -149,7 +147,7 @@ fifo_create_test(int use_mkfifo)
err(-1, "basic_create_test: dup %s unexpected error",
testname);
- if (stat(temp_dir, &dirsb) < 0) {
+ if (stat(".", &dirsb) < 0) {
error = errno;
(void)unlink(path);
errno = error;
@@ -205,7 +203,7 @@ fifo_permission_test(int use_mkfifo)
{
const struct permission_test *ptp;
mode_t __unused old_umask;
- char path[PATH_MAX];
+ char path[] = "testfifo";
const char *testname;
struct stat sb;
int error, i;
@@ -215,7 +213,6 @@ fifo_permission_test(int use_mkfifo)
else
testname = "mknod";
- snprintf(path, PATH_MAX, "%s/testfifo", temp_dir);
old_umask = umask(0022);
for (i = 0; i < permission_test_count; i++) {
ptp = &permission_test[i];
@@ -256,14 +253,14 @@ fifo_permission_test(int use_mkfifo)
}
int
-main(int argc, char *argv[])
+main(void)
{
int i;
if (geteuid() != 0)
errx(-1, "must be run as root");
- strcpy(temp_dir, "/tmp/fifo_create.XXXXXXXXXXX");
+ strcpy(temp_dir, "fifo_create.XXXXXXXXXXX");
if (mkdtemp(temp_dir) == NULL)
err(-1, "mkdtemp");
atexit(atexit_temp_dir);
diff --git a/tools/regression/fifo/fifo_io/fifo_io.c b/tests/sys/fifo/fifo_io.c
index 4d3c54e8b2f4..93d4be7e2f17 100644
--- a/tools/regression/fifo/fifo_io/fifo_io.c
+++ b/tests/sys/fifo/fifo_io.c
@@ -88,7 +88,7 @@
* All activity occurs within a temporary directory created early in the
* test.
*/
-char temp_dir[PATH_MAX];
+static char temp_dir[PATH_MAX];
static void __unused
atexit_temp_dir(void)
@@ -130,8 +130,7 @@ cleanfifo3(const char *fifoname, int fd1, int fd2, int fd3)
* so using non-blocking opens in order to avoid deadlocking the process.
*/
static int
-openfifo(const char *fifoname, const char *testname, int *reader_fdp,
- int *writer_fdp)
+openfifo(const char *fifoname, int *reader_fdp, int *writer_fdp)
{
int error, fd1, fd2;
@@ -155,7 +154,7 @@ openfifo(const char *fifoname, const char *testname, int *reader_fdp,
* Open one file descriptor for the fifo, supporting both read and write.
*/
static int
-openfifo_rw(const char *fifoname, const char *testname, int *fdp)
+openfifo_rw(const char *fifoname, int *fdp)
{
int fd;
@@ -249,7 +248,7 @@ test_simpleio(void)
ssize_t len;
makefifo("testfifo", __func__);
- if (openfifo("testfifo", "test_simpleio", &reader_fd, &writer_fd)
+ if (openfifo("testfifo", &reader_fd, &writer_fd)
< 0) {
warn("test_simpleio: openfifo: testfifo");
cleanfifo2("testfifo", -1, -1);
@@ -296,12 +295,12 @@ test_simpleio(void)
cleanfifo2("testfifo", reader_fd, writer_fd);
}
-static int alarm_fired;
+static volatile int alarm_fired;
/*
* Non-destructive SIGALRM handler.
*/
static void
-sigalarm(int signum)
+sigalarm(int signum __unused)
{
alarm_fired = 1;
@@ -408,7 +407,7 @@ test_blocking_read_empty(void)
u_char ch;
makefifo("testfifo", __func__);
- if (openfifo("testfifo", __func__, &reader_fd, &writer_fd)
+ if (openfifo("testfifo", &reader_fd, &writer_fd)
< 0) {
warn("test_blocking_read_empty: openfifo: testfifo");
cleanfifo2("testfifo", -1, -1);
@@ -477,8 +476,7 @@ test_blocking_one_byte(void)
u_char ch;
makefifo("testfifo", __func__);
- if (openfifo("testfifo", __func__, &reader_fd, &writer_fd)
- < 0) {
+ if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
warn("test_blocking: openfifo: testfifo");
cleanfifo2("testfifo", -1, -1);
exit(-1);
@@ -544,8 +542,7 @@ test_nonblocking_one_byte(void)
u_char ch;
makefifo("testfifo", __func__);
- if (openfifo("testfifo", __func__, &reader_fd, &writer_fd)
- < 0) {
+ if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
warn("test_nonblocking: openfifo: testfifo");
cleanfifo2("testfifo", -1, -1);
exit(-1);
@@ -609,8 +606,7 @@ test_blocking_partial_write(void)
ssize_t len;
makefifo("testfifo", __func__);
- if (openfifo("testfifo", __func__, &reader_fd, &writer_fd)
- < 0) {
+ if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
warn("test_blocking_partial_write: openfifo: testfifo");
cleanfifo2("testfifo", -1, -1);
exit(-1);
@@ -668,8 +664,7 @@ test_nonblocking_partial_write(void)
ssize_t len;
makefifo("testfifo", __func__);
- if (openfifo("testfifo", __func__, &reader_fd, &writer_fd)
- < 0) {
+ if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
warn("test_blocking_partial_write: openfifo: testfifo");
cleanfifo2("testfifo", -1, -1);
exit(-1);
@@ -736,8 +731,7 @@ test_coalesce_big_read(void)
ssize_t len;
makefifo("testfifo", __func__);
- if (openfifo("testfifo", __func__, &reader_fd, &writer_fd)
- < 0) {
+ if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
warn("test_coalesce_big_read: openfifo: testfifo");
cleanfifo2("testfifo", -1, -1);
exit(-1);
@@ -808,8 +802,7 @@ test_coalesce_big_write(void)
ssize_t len;
makefifo("testfifo", __func__);
- if (openfifo("testfifo", __func__, &reader_fd, &writer_fd)
- < 0) {
+ if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
warn("test_coalesce_big_write: openfifo: testfifo");
cleanfifo2("testfifo", -1, -1);
exit(-1);
@@ -1078,7 +1071,7 @@ test_events_outofbox(void)
int kqueue_fd, reader_fd, writer_fd;
makefifo("testfifo", __func__);
- if (openfifo("testfifo", __func__, &reader_fd, &writer_fd) < 0) {
+ if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
warn("test_events_outofbox: openfifo: testfifo");
cleanfifo2("testfifo", -1, -1);
exit(-1);
@@ -1134,8 +1127,7 @@ test_events_write_read_byte(void)
u_char ch;
makefifo("testfifo", __func__);
- if (openfifo("testfifo", __func__, &reader_fd, &writer_fd)
- < 0) {
+ if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
warn("test_events_write_read_byte: openfifo: testfifo");
cleanfifo2("testfifo", -1, -1);
exit(-1);
@@ -1227,8 +1219,7 @@ test_events_partial_write(void)
ssize_t len;
makefifo("testfifo", __func__);
- if (openfifo("testfifo", __func__, &reader_fd, &writer_fd)
- < 0) {
+ if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
warn("test_events_partial_write: openfifo: testfifo");
cleanfifo2("testfifo", -1, -1);
exit(-1);
@@ -1313,8 +1304,7 @@ test_events_rdwr(void)
char ch;
makefifo("testfifo", __func__);
- if (openfifo_rw("testfifo", __func__, &fd)
- < 0) {
+ if (openfifo_rw("testfifo", &fd) < 0) {
warn("%s: openfifo_rw: testfifo", __func__);
cleanfifo2("testfifo", -1, -1);
exit(-1);
@@ -1381,10 +1371,10 @@ test_events_rdwr(void)
}
int
-main(int argc, char *argv[])
+main(void)
{
- strcpy(temp_dir, "/tmp/fifo_io.XXXXXXXXXXX");
+ strcpy(temp_dir, "fifo_io.XXXXXXXXXXX");
if (mkdtemp(temp_dir) == NULL)
err(-1, "mkdtemp");
atexit(atexit_temp_dir);
diff --git a/tools/regression/fifo/fifo_misc/fifo_misc.c b/tests/sys/fifo/fifo_misc.c
index 4215212a2ccf..888547e32fcd 100644
--- a/tools/regression/fifo/fifo_misc/fifo_misc.c
+++ b/tests/sys/fifo/fifo_misc.c
@@ -50,7 +50,7 @@
* All activity occurs within a temporary directory created early in the
* test.
*/
-char temp_dir[PATH_MAX];
+static char temp_dir[PATH_MAX];
static void __unused
atexit_temp_dir(void)
@@ -79,8 +79,7 @@ cleanfifo(const char *fifoname, int fd1, int fd2)
}
static int
-openfifo(const char *fifoname, const char *testname, int *reader_fdp,
- int *writer_fdp)
+openfifo(const char *fifoname, int *reader_fdp, int *writer_fdp)
{
int error, fd1, fd2;
@@ -110,7 +109,7 @@ test_lseek(void)
makefifo("testfifo", __func__);
- if (openfifo("testfifo", __func__, &reader_fd, &writer_fd) < 0) {
+ if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
warn("%s: openfifo", __func__);
cleanfifo("testfifo", -1, -1);
exit(-1);
@@ -185,7 +184,7 @@ test_ioctl(void)
makefifo("testfifo", __func__);
- if (openfifo("testfifo", __func__, &reader_fd, &writer_fd) < 0) {
+ if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
warn("%s: openfifo", __func__);
cleanfifo("testfifo", -1, -1);
exit(-1);
@@ -237,7 +236,7 @@ test_chmodchown(void)
makefifo("testfifo", __func__);
- if (openfifo("testfifo", __func__, &reader_fd, &writer_fd) < 0) {
+ if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
warn("%s: openfifo", __func__);
cleanfifo("testfifo", -1, -1);
exit(-1);
@@ -316,10 +315,10 @@ test_chmodchown(void)
}
int
-main(int argc, char *argv[])
+main(void)
{
- strcpy(temp_dir, "/tmp/fifo_misc.XXXXXXXXXXX");
+ strcpy(temp_dir, "fifo_misc.XXXXXXXXXXX");
if (mkdtemp(temp_dir) == NULL)
err(-1, "mkdtemp");
atexit(atexit_temp_dir);
diff --git a/tools/regression/fifo/fifo_open/fifo_open.c b/tests/sys/fifo/fifo_open.c
index 6899a3ac9ccf..892f481b170b 100644
--- a/tools/regression/fifo/fifo_open/fifo_open.c
+++ b/tests/sys/fifo/fifo_open.c
@@ -87,7 +87,7 @@
* All activity occurs within a temporary directory created early in the
* test.
*/
-char temp_dir[PATH_MAX];
+static char temp_dir[PATH_MAX];
static void __unused
atexit_temp_dir(void)
@@ -453,13 +453,13 @@ test_non_blocking_writer(void)
}
int
-main(int argc, char *argv[])
+main(void)
{
if (geteuid() != 0)
errx(-1, "must be run as root");
- strcpy(temp_dir, "/tmp/fifo_open.XXXXXXXXXXX");
+ strcpy(temp_dir, "fifo_open.XXXXXXXXXXX");
if (mkdtemp(temp_dir) == NULL)
err(-1, "mkdtemp");
if (chdir(temp_dir) < 0)
diff --git a/tests/sys/file/Makefile b/tests/sys/file/Makefile
new file mode 100644
index 000000000000..6151c9f3bf04
--- /dev/null
+++ b/tests/sys/file/Makefile
@@ -0,0 +1,25 @@
+# $FreeBSD$
+
+TESTSDIR= ${TESTSBASE}/sys/file
+
+BINDIR= ${TESTSDIR}
+
+TAP_TESTS_C+= closefrom_test
+TAP_TESTS_C+= dup_test
+TAP_TESTS_C+= fcntlflags_test
+TAP_TESTS_SH+= flock_test
+PLAIN_TESTS_C+= ftruncate_test
+PLAIN_TESTS_C+= newfileops_on_fork_test
+
+PROGS+= flock_helper
+
+DPADD.closefrom_test= ${LIBUTIL}
+LDADD.closefrom_test= -lutil
+
+DPADD.flock_helper= ${LIBPTHREAD}
+LDADD.flock_helper= -lpthread
+
+DPADD.newfileops_on_fork_test= ${LIBPTHREAD}
+LDADD.newfileops_on_fork_test= -lpthread
+
+.include <bsd.test.mk>
diff --git a/tests/sys/file/closefrom_test.c b/tests/sys/file/closefrom_test.c
new file mode 100644
index 000000000000..78cfeecae026
--- /dev/null
+++ b/tests/sys/file/closefrom_test.c
@@ -0,0 +1,275 @@
+/*-
+ * Copyright (c) 2009 Hudson River Trading LLC
+ * Written by: John H. Baldwin <jhb@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Regression tests for the closefrom(2) system call.
+ */
+
+#include <sys/param.h>
+#include <sys/mman.h>
+#include <sys/user.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <libutil.h>
+#include <paths.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+struct shared_info {
+ int failed;
+ char tag[64];
+ char message[0];
+};
+
+static int test = 1;
+
+static void
+ok(const char *descr)
+{
+
+ printf("ok %d - %s\n", test, descr);
+ test++;
+}
+
+static void
+fail(const char *descr, const char *fmt, ...)
+{
+ va_list ap;
+
+ printf("not ok %d - %s", test, descr);
+ test++;
+ if (fmt) {
+ va_start(ap, fmt);
+ printf(" # ");
+ vprintf(fmt, ap);
+ va_end(ap);
+ }
+ printf("\n");
+ exit(1);
+}
+
+#define fail_err(descr) fail((descr), "%s", strerror(errno))
+
+static void
+cok(struct shared_info *info, const char *descr)
+{
+
+ info->failed = 0;
+ strlcpy(info->tag, descr, sizeof(info->tag));
+ exit(0);
+}
+
+static void
+cfail(struct shared_info *info, const char *descr, const char *fmt, ...)
+{
+ va_list ap;
+
+ info->failed = 1;
+ strlcpy(info->tag, descr, sizeof(info->tag));
+ if (fmt) {
+ va_start(ap, fmt);
+ vsprintf(info->message, fmt, ap);
+ va_end(ap);
+ }
+ exit(0);
+}
+
+#define cfail_err(info, descr) cfail((info), (descr), "%s", strerror(errno))
+
+/*
+ * Use kinfo_getfile() to fetch the list of file descriptors and figure out
+ * the highest open file descriptor.
+ */
+static int
+highest_fd(void)
+{
+ struct kinfo_file *kif;
+ int cnt, i, highest;
+
+ kif = kinfo_getfile(getpid(), &cnt);
+ if (kif == NULL)
+ fail_err("kinfo_getfile");
+ highest = INT_MIN;
+ for (i = 0; i < cnt; i++)
+ if (kif[i].kf_fd > highest)
+ highest = kif[i].kf_fd;
+ free(kif);
+ return (highest);
+}
+
+static int
+devnull(void)
+{
+ int fd;
+
+ fd = open(_PATH_DEVNULL, O_RDONLY);
+ if (fd < 0)
+ fail_err("open(\" "_PATH_DEVNULL" \")");
+ return (fd);
+}
+
+int
+main(void)
+{
+ struct shared_info *info;
+ pid_t pid;
+ int fd, i, start;
+
+ printf("1..15\n");
+
+ /* We better start up with fd's 0, 1, and 2 open. */
+ start = devnull();
+ if (start == -1)
+ fail("open", "bad descriptor %d", start);
+ ok("open");
+
+ /* Make sure highest_fd() works. */
+ fd = highest_fd();
+ if (start != fd)
+ fail("highest_fd", "bad descriptor %d != %d", start, fd);
+ ok("highest_fd");
+
+ /* Try to use closefrom() for just closing fd 3. */
+ closefrom(start + 1);
+ fd = highest_fd();
+ if (fd != start)
+ fail("closefrom", "highest fd %d", fd);
+ ok("closefrom");
+
+ /* Eat up 16 descriptors. */
+ for (i = 0; i < 16; i++)
+ (void)devnull();
+ fd = highest_fd();
+ if (fd != start + 16)
+ fail("open 16", "highest fd %d", fd);
+ ok("open 16");
+
+ /* Close half of them. */
+ closefrom(11);
+ fd = highest_fd();
+ if (fd != 10)
+ fail("closefrom", "highest fd %d", fd);
+ ok("closefrom");
+
+ /* Explicitly close descriptors 6 and 8 to create holes. */
+ if (close(6) < 0 || close(8) < 0)
+ fail_err("close2 ");
+ ok("close 2");
+
+ /* Verify that close on 6 and 8 fails with EBADF. */
+ if (close(6) == 0)
+ fail("close(6)", "did not fail");
+ if (errno != EBADF)
+ fail_err("close(6)");
+ ok("close(6)");
+ if (close(8) == 0)
+ fail("close(8)", "did not fail");
+ if (errno != EBADF)
+ fail_err("close(8)");
+ ok("close(8)");
+
+ /* Close from 4 on. */
+ closefrom(4);
+ fd = highest_fd();
+ if (fd != 3)
+ fail("closefrom", "highest fd %d", fd);
+ ok("closefrom");
+
+ /* Allocate a small SHM region for IPC with our child. */
+ info = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE, MAP_ANON |
+ MAP_SHARED, -1, 0);
+ if (info == MAP_FAILED)
+ fail_err("mmap");
+ ok("mmap");
+
+ /* Fork a child process to test closefrom(0). */
+ pid = fork();
+ if (pid < 0)
+ fail_err("fork");
+ if (pid == 0) {
+ /* Child. */
+ closefrom(0);
+ fd = highest_fd();
+ if (fd >= 0)
+ cfail(info, "closefrom(0)", "highest fd %d", fd);
+ cok(info, "closefrom(0)");
+ }
+ if (wait(NULL) < 0)
+ fail_err("wait");
+ if (info->failed)
+ fail(info->tag, "%s", info->message);
+ ok(info->tag);
+
+ /* Fork a child process to test closefrom(-1). */
+ pid = fork();
+ if (pid < 0)
+ fail_err("fork");
+ if (pid == 0) {
+ /* Child. */
+ closefrom(-1);
+ fd = highest_fd();
+ if (fd >= 0)
+ cfail(info, "closefrom(-1)", "highest fd %d", fd);
+ cok(info, "closefrom(-1)");
+ }
+ if (wait(NULL) < 0)
+ fail_err("wait");
+ if (info->failed)
+ fail(info->tag, "%s", info->message);
+ ok(info->tag);
+
+ /* Dup stdout to 6. */
+ if (dup2(1, 6) < 0)
+ fail_err("dup2");
+ fd = highest_fd();
+ if (fd != 6)
+ fail("dup2", "highest fd %d", fd);
+ ok("dup2");
+
+ /* Do a closefrom() starting in a hole. */
+ closefrom(4);
+ fd = highest_fd();
+ if (fd != 3)
+ fail("closefrom", "highest fd %d", fd);
+ ok("closefrom");
+
+ /* Do a closefrom() beyond our highest open fd. */
+ closefrom(32);
+ fd = highest_fd();
+ if (fd != 3)
+ fail("closefrom", "highest fd %d", fd);
+ ok("closefrom");
+
+ return (0);
+}
diff --git a/tools/regression/file/dup/dup.c b/tests/sys/file/dup_test.c
index 817381889625..817381889625 100644
--- a/tools/regression/file/dup/dup.c
+++ b/tests/sys/file/dup_test.c
diff --git a/tools/regression/file/fcntlflags/fcntlflags.c b/tests/sys/file/fcntlflags_test.c
index bcb3b54d6048..bcb3b54d6048 100644
--- a/tools/regression/file/fcntlflags/fcntlflags.c
+++ b/tests/sys/file/fcntlflags_test.c
diff --git a/tools/regression/file/flock/flock.c b/tests/sys/file/flock_helper.c
index 49e47b830896..49e47b830896 100644
--- a/tools/regression/file/flock/flock.c
+++ b/tests/sys/file/flock_helper.c
diff --git a/tests/sys/file/flock_test.sh b/tests/sys/file/flock_test.sh
new file mode 100755
index 000000000000..ac3e79957329
--- /dev/null
+++ b/tests/sys/file/flock_test.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+#
+# Copyright 2014 EMC Corp.
+# 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 Google Inc. 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
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# $FreeBSD$
+
+# Testcase # 11 is racy; uses an undocumented kernel interface for testing
+# locking
+# Testcase # 16 is racy/doesn't handle EINTR properly
+last_testcase=16
+
+echo "1..$last_testcase"
+
+for n in `seq 1 $last_testcase`; do
+ todomsg=""
+
+ if [ $n -eq 11 ]; then
+ todomsg=" # TODO: racy testcase"
+ # Test 16 fails:
+ # F_SETLKW on locked region by two threads: FAIL ((uintptr_t)res != 0)
+ elif [ $n -eq 16 ]; then
+ todomsg=" # TODO: racy testcase (doesn't handle EINTR properly)"
+ fi
+
+ $(dirname $0)/flock_helper . $n | grep -q SUCCEED
+ if [ $? -eq 0 ]; then
+ echo "ok $n$todomsg"
+ else
+ echo "not ok $n$todomsg"
+ fi
+done
diff --git a/tools/regression/file/ftruncate/ftruncate.c b/tests/sys/file/ftruncate_test.c
index aebcdcd85b2c..7eaba14e2bfa 100644
--- a/tools/regression/file/ftruncate/ftruncate.c
+++ b/tests/sys/file/ftruncate_test.c
@@ -62,7 +62,7 @@ main(int argc, char *argv[])
int error, fd, fds[2], i, read_only_fd;
char path[PATH_MAX];
struct stat sb;
- size_t size;
+ ssize_t size;
off_t len;
char ch;
@@ -78,7 +78,7 @@ main(int argc, char *argv[])
snprintf(path, PATH_MAX, "/tmp/ftruncate.XXXXXXXXXXXXX");
fd = mkstemp(path);
if (fd < 0)
- err(-1, "makestemp");
+ err(-1, "mkstemp");
read_only_fd = open(path, O_RDONLY);
if (read_only_fd < 0) {
error = errno;
@@ -96,34 +96,34 @@ main(int argc, char *argv[])
for (i = 0; i < lengths_count; i++) {
len = lengths[i];
if (ftruncate(fd, len) < 0)
- err(-1, "ftruncate(%llu) up", len);
+ err(-1, "ftruncate(%jd) up", (intmax_t)len);
if (fstat(fd, &sb) < 0)
err(-1, "stat");
if (sb.st_size != len)
- errx(-1, "fstat(%llu) returned len %llu up", len,
- sb.st_size);
+ errx(-1, "fstat with len=%jd returned len %jd up",
+ (intmax_t)len, (intmax_t)sb.st_size);
if (len != 0) {
size = pread(fd, &ch, sizeof(ch), len - 1);
if (size < 0)
- err(-1, "pread on len %llu up", len);
+ err(-1, "pread on len %jd up", (intmax_t)len);
if (size != sizeof(ch))
- errx(-1, "pread len %llu size %jd up",
- len, (intmax_t)size);
+ errx(-1, "pread len %jd size %jd up",
+ (intmax_t)len, (intmax_t)size);
if (ch != 0)
errx(-1,
- "pread length %llu size %jd ch %d up",
- len, (intmax_t)size, ch);
+ "pread length %jd size %jd ch %d up",
+ (intmax_t)len, (intmax_t)size, ch);
}
}
for (i = lengths_count - 1; i >= 0; i--) {
len = lengths[i];
if (ftruncate(fd, len) < 0)
- err(-1, "ftruncate(%llu) down", len);
+ err(-1, "ftruncate(%jd) down", (intmax_t)len);
if (fstat(fd, &sb) < 0)
err(-1, "stat");
if (sb.st_size != len)
- errx(-1, "fstat(%llu) returned %llu down", len,
+ errx(-1, "fstat(%jd) returned %jd down", (intmax_t)len,
sb.st_size);
}
close(fd);
diff --git a/tools/regression/file/newfileops_on_fork/newfileops_on_fork.c b/tests/sys/file/newfileops_on_fork_test.c
index 8713a8264f3b..8713a8264f3b 100644
--- a/tools/regression/file/newfileops_on_fork/newfileops_on_fork.c
+++ b/tests/sys/file/newfileops_on_fork_test.c
diff --git a/tests/sys/kern/Makefile b/tests/sys/kern/Makefile
index 4a1e67147953..d366aa1d61ff 100644
--- a/tests/sys/kern/Makefile
+++ b/tests/sys/kern/Makefile
@@ -10,4 +10,6 @@ LDADD.unix_seqpacket_test+= -lpthread
WARNS?= 5
+TESTS_SUBDIRS+= execve
+
.include <bsd.test.mk>
diff --git a/tests/sys/kern/execve/Makefile b/tests/sys/kern/execve/Makefile
new file mode 100644
index 000000000000..82c5d4b85b10
--- /dev/null
+++ b/tests/sys/kern/execve/Makefile
@@ -0,0 +1,39 @@
+# $FreeBSD$
+
+TESTSDIR= ${TESTSBASE}/sys/kern/execve
+
+BINDIR= ${TESTSDIR}
+
+MAN=
+
+ATF_TESTS_SH+= execve_test
+
+PROGS+= good_aout
+PROGS+= execve_helper
+
+LDFLAGS.goodaout+= -static
+
+CLEANFILES+= empty
+CLEANFILES+= sparse_aout
+CLEANFILES+= trunc_aout
+
+SCRIPTS+= bad_interp_len
+SCRIPTS+= dev_null_script
+SCRIPTS+= empty
+SCRIPTS+= good_script
+SCRIPTS+= non_exist_shell
+SCRIPTS+= script_arg
+SCRIPTS+= script_arg_nospace
+SCRIPTS+= sparse_aout
+SCRIPTS+= trunc_aout
+
+empty:
+ @touch $@
+
+sparse_aout:
+ @truncate -s 20480 $@
+
+trunc_aout:
+ @truncate -s 16 $@
+
+.include <bsd.test.mk>
diff --git a/tools/regression/execve/tests/badinterplen b/tests/sys/kern/execve/bad_interp_len
index 96c049fdc839..96c049fdc839 100644
--- a/tools/regression/execve/tests/badinterplen
+++ b/tests/sys/kern/execve/bad_interp_len
diff --git a/tools/regression/execve/tests/devnullscript b/tests/sys/kern/execve/dev_null_script
index 73b10205cdbb..73b10205cdbb 100644
--- a/tools/regression/execve/tests/devnullscript
+++ b/tests/sys/kern/execve/dev_null_script
diff --git a/tools/regression/execve/doexec.c b/tests/sys/kern/execve/execve_helper.c
index 0aa82ec87959..164a8f3fc61e 100644
--- a/tools/regression/execve/doexec.c
+++ b/tests/sys/kern/execve/execve_helper.c
@@ -34,25 +34,21 @@
* $FreeBSD$
*/
+#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
#include <unistd.h>
int
-main(argc, argv)
- int argc;
- char *argv[];
+main(int argc, char **argv)
{
+
if (argc != 2) {
fprintf(stderr, "usage: %s <progname>\n", argv[0]);
exit(2);
}
- unsetenv("LANG"); /* we compare C error strings */
- if (execve(argv[1], &argv[1], NULL) == -1) {
- printf("%s\n", strerror(errno));
- exit(1);
- }
+ execve(argv[1], &argv[1], NULL);
+ err(1, "");
}
diff --git a/tests/sys/kern/execve/execve_test.sh b/tests/sys/kern/execve/execve_test.sh
new file mode 100644
index 000000000000..ef803a18d442
--- /dev/null
+++ b/tests/sys/kern/execve/execve_test.sh
@@ -0,0 +1,115 @@
+
+bad_interp_len_head()
+{
+ atf_set "descr" "Bad interpreter length"
+}
+bad_interp_len_body()
+{
+ atf_check -s exit:1 -e 'match:No such file or directory' -o empty \
+ -x "cd $(atf_get_srcdir) && ./execve_helper bad_interp_len"
+}
+
+empty_head()
+{
+ atf_set "descr" "Empty file"
+}
+empty_body()
+{
+ atf_check -s exit:1 -e 'match:Exec format error' -o empty \
+ -x "cd $(atf_get_srcdir) && ./execve_helper empty"
+}
+
+good_aout_head()
+{
+ atf_set "descr" "Good a.out"
+}
+good_aout_body()
+{
+ atf_check -s exit:0 -e empty -o 'match:succeeded' \
+ -x "cd $(atf_get_srcdir) && ./execve_helper ./good_aout"
+}
+
+good_script_head()
+{
+ atf_set "descr" "Good script"
+}
+good_script_body()
+{
+ atf_check -s exit:0 -e empty -o 'match:succeeded' \
+ -x "cd $(atf_get_srcdir) && ./execve_helper good_script"
+}
+
+non_exist_head()
+{
+ atf_set "descr" "Non-existent file"
+}
+non_exist_body()
+{
+ atf_check -s exit:1 -e 'match:No such file or directory' -o empty \
+ -x "cd $(atf_get_srcdir) && ./execve_helper non_exist"
+}
+
+non_exist_shell_head()
+{
+ atf_set "descr" "Non-existent shell"
+}
+non_exist_shell_body()
+{
+ atf_check -s exit:1 -e 'match:No such file or directory' -o empty \
+ -x "cd $(atf_get_srcdir) && ./execve_helper non_exist_shell"
+}
+
+script_arg_head()
+{
+ atf_set "descr" "-x in the shebang"
+}
+script_arg_body()
+{
+ atf_check -s exit:0 -e 'match:\+ echo succeeded' -o 'match:succeeded' \
+ -x "cd $(atf_get_srcdir) && ./execve_helper script_arg"
+}
+
+script_arg_nospace_head()
+{
+ atf_set "descr" '-x in the shebang; no space between #! and /bin/sh'
+}
+script_arg_nospace_body()
+{
+ atf_check -s exit:0 -e 'match:\+ echo succeeded' -o 'match:succeeded' \
+ -x "cd $(atf_get_srcdir) && ./execve_helper script_arg_nospace"
+}
+
+sparse_aout_head()
+{
+ atf_set "descr" 'Sparse file'
+}
+sparse_aout_body()
+{
+ atf_check -s exit:1 -e 'match:Exec format error' -o empty \
+ -x "cd $(atf_get_srcdir) && ./execve_helper sparse_aout"
+}
+
+trunc_aout_head()
+{
+ atf_set "descr" 'Truncated file'
+}
+trunc_aout_body()
+{
+ atf_check -s exit:1 -e 'match:Exec format error' -o empty \
+ -x "cd $(atf_get_srcdir) && ./execve_helper trunc_aout"
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case bad_interp_len
+ atf_add_test_case empty
+ atf_add_test_case good_aout
+ atf_add_test_case good_script
+ atf_add_test_case non_exist
+ atf_add_test_case non_exist_shell
+ atf_add_test_case script_arg
+ atf_add_test_case script_arg_nospace
+ atf_add_test_case sparse_aout
+ atf_add_test_case trunc_aout
+
+}
diff --git a/tools/regression/execve/tests/goodaout.c b/tests/sys/kern/execve/good_aout.c
index ebf476b2cf7f..39e986770c5d 100644
--- a/tools/regression/execve/tests/goodaout.c
+++ b/tests/sys/kern/execve/good_aout.c
@@ -38,9 +38,7 @@
#include <stdlib.h>
int
-main(argc, argv)
- int argc;
- char *argv[];
+main(void)
{
printf("succeeded\n");
exit(0);
diff --git a/tools/regression/execve/tests/goodscript b/tests/sys/kern/execve/good_script
index 51270dc38da1..11c76898ca2e 100644
--- a/tools/regression/execve/tests/goodscript
+++ b/tests/sys/kern/execve/good_script
@@ -1,4 +1,4 @@
-#! /bin/csh
+#!/bin/sh
# $FreeBSD$
echo succeeded
diff --git a/tools/regression/execve/tests/nonexistshell b/tests/sys/kern/execve/non_exist_shell
index f9ee705bd9e9..f9ee705bd9e9 100644
--- a/tools/regression/execve/tests/nonexistshell
+++ b/tests/sys/kern/execve/non_exist_shell
diff --git a/tools/regression/execve/tests/scriptarg b/tests/sys/kern/execve/script_arg
index 2700f1c3a38f..2700f1c3a38f 100644
--- a/tools/regression/execve/tests/scriptarg
+++ b/tests/sys/kern/execve/script_arg
diff --git a/tools/regression/execve/tests/scriptarg-nospace b/tests/sys/kern/execve/script_arg_nospace
index 6731ad50f4ac..6731ad50f4ac 100644
--- a/tools/regression/execve/tests/scriptarg-nospace
+++ b/tests/sys/kern/execve/script_arg_nospace
diff --git a/tools/regression/kqueue/Makefile b/tests/sys/kqueue/Makefile
index 12b7527525b3..43277ca0c86b 100644
--- a/tools/regression/kqueue/Makefile
+++ b/tests/sys/kqueue/Makefile
@@ -6,8 +6,14 @@
# libkqueue and test suite by Mark Heily <mark@heily.com>
#
-PROG=kqtest
-SRCS= \
+TAP_TESTS_SH= kqueue_test
+
+TESTSDIR= ${TESTSBASE}/sys/kqueue
+BINDIR= ${TESTSDIR}
+
+PROGS= kqtest
+
+SRCS.kqtest= \
main.c \
read.c \
timer.c \
@@ -15,7 +21,6 @@ SRCS= \
proc.c \
signal.c \
user.c
-MAN=
WARNS?= 2
-.include "bsd.prog.mk"
+.include <bsd.test.mk>
diff --git a/tools/regression/kqueue/common.h b/tests/sys/kqueue/common.h
index aada7786ad0c..aada7786ad0c 100644
--- a/tools/regression/kqueue/common.h
+++ b/tests/sys/kqueue/common.h
diff --git a/tools/regression/kqueue/config.h b/tests/sys/kqueue/config.h
index a204092a2ab2..a204092a2ab2 100644
--- a/tools/regression/kqueue/config.h
+++ b/tests/sys/kqueue/config.h
diff --git a/tests/sys/kqueue/kqueue_test.sh b/tests/sys/kqueue/kqueue_test.sh
new file mode 100755
index 000000000000..62a7e2305702
--- /dev/null
+++ b/tests/sys/kqueue/kqueue_test.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+cd $(dirname $0)
+i=1
+./kqtest | while read line; do
+ echo $line | grep -q passed
+ if [ $? -eq 0 ]; then
+ echo "ok - $i $line"
+ : $(( i += 1 ))
+ fi
+
+ echo $line | grep -q 'tests completed'
+ if [ $? -eq 0 ]; then
+ echo -n "1.."
+ echo $line | cut -d' ' -f3
+ fi
+done
diff --git a/tools/regression/kqueue/main.c b/tests/sys/kqueue/main.c
index f76c4e23be12..f76c4e23be12 100644
--- a/tools/regression/kqueue/main.c
+++ b/tests/sys/kqueue/main.c
diff --git a/tools/regression/kqueue/proc.c b/tests/sys/kqueue/proc.c
index 6288ee6d91b4..6288ee6d91b4 100644
--- a/tools/regression/kqueue/proc.c
+++ b/tests/sys/kqueue/proc.c
diff --git a/tools/regression/kqueue/read.c b/tests/sys/kqueue/read.c
index cc6542719fba..cc6542719fba 100644
--- a/tools/regression/kqueue/read.c
+++ b/tests/sys/kqueue/read.c
diff --git a/tools/regression/kqueue/signal.c b/tests/sys/kqueue/signal.c
index 14e751db95c2..14e751db95c2 100644
--- a/tools/regression/kqueue/signal.c
+++ b/tests/sys/kqueue/signal.c
diff --git a/tools/regression/kqueue/timer.c b/tests/sys/kqueue/timer.c
index 766125d857e8..766125d857e8 100644
--- a/tools/regression/kqueue/timer.c
+++ b/tests/sys/kqueue/timer.c
diff --git a/tools/regression/kqueue/user.c b/tests/sys/kqueue/user.c
index 9ba25f9df4d3..9ba25f9df4d3 100644
--- a/tools/regression/kqueue/user.c
+++ b/tests/sys/kqueue/user.c
diff --git a/tools/regression/kqueue/vnode.c b/tests/sys/kqueue/vnode.c
index dfa0b5e176f8..dfa0b5e176f8 100644
--- a/tools/regression/kqueue/vnode.c
+++ b/tests/sys/kqueue/vnode.c
diff --git a/tests/sys/mqueue/Makefile b/tests/sys/mqueue/Makefile
new file mode 100644
index 000000000000..5af8b2546a09
--- /dev/null
+++ b/tests/sys/mqueue/Makefile
@@ -0,0 +1,22 @@
+# $FreeBSD$
+
+TESTSDIR= ${TESTSBASE}/sys/mqueue
+
+ATF_TESTS_SH= mqueue_test
+
+BINDIR= ${TESTSDIR}
+
+CFLAGS+= -I${.CURDIR:H:H}
+
+PROGS+= mqtest1
+PROGS+= mqtest2
+PROGS+= mqtest3
+PROGS+= mqtest4
+PROGS+= mqtest5
+
+LDADD+= -lrt
+DPADD+= ${LIBRT}
+
+WARNS?= 6
+
+.include <bsd.test.mk>
diff --git a/tools/regression/mqueue/mqtest1/mqtest1.c b/tests/sys/mqueue/mqtest1.c
index 25fc1ba881eb..3accb286ae98 100644
--- a/tools/regression/mqueue/mqtest1/mqtest1.c
+++ b/tests/sys/mqueue/mqtest1.c
@@ -7,15 +7,20 @@
#include <signal.h>
#include <stdio.h>
+#include "freebsd_test_suite/macros.h"
+
#define MQNAME "/mytstqueue1"
-int main()
+int
+main(void)
{
struct mq_attr attr, attr2;
struct sigevent sigev;
mqd_t mq;
int status;
+ PLAIN_REQUIRE_KERNEL_MODULE("mqueuefs", 0);
+
attr.mq_maxmsg = 2;
attr.mq_msgsize = 100;
mq = mq_open(MQNAME, O_CREAT | O_RDWR | O_EXCL, 0666, &attr);
diff --git a/tools/regression/mqueue/mqtest2/mqtest2.c b/tests/sys/mqueue/mqtest2.c
index bfe6d97fc7dd..067e6190d22f 100644
--- a/tools/regression/mqueue/mqtest2/mqtest2.c
+++ b/tests/sys/mqueue/mqtest2.c
@@ -10,21 +10,28 @@
#include <stdlib.h>
#include <unistd.h>
+#include "freebsd_test_suite/macros.h"
+
#define MQNAME "/mytstqueue2"
#define LOOPS 1000
#define PRIO 10
-void alarmhandler(int sig)
+static void
+alarmhandler(int sig __unused)
{
write(1, "timeout\n", 8);
_exit(1);
}
-int main()
+int
+main(void)
{
struct mq_attr attr;
mqd_t mq;
- int status, pid;
+ int status;
+ pid_t pid;
+
+ PLAIN_REQUIRE_KERNEL_MODULE("mqueuefs", 0);
mq_unlink(MQNAME);
@@ -38,8 +45,9 @@ int main()
err(1, "mq_getattr");
pid = fork();
if (pid == 0) { /* child */
- int prio, j, i;
char *buf;
+ int j, i;
+ unsigned int prio;
mq_close(mq);
@@ -69,7 +77,7 @@ int main()
err(1, "fork()");
} else {
char *buf;
- int i, j, prio;
+ int i, j;
signal(SIGALRM, alarmhandler);
buf = malloc(attr.mq_msgsize);
diff --git a/tools/regression/mqueue/mqtest3/mqtest3.c b/tests/sys/mqueue/mqtest3.c
index aa47ffac3099..c4b849e64182 100644
--- a/tools/regression/mqueue/mqtest3/mqtest3.c
+++ b/tests/sys/mqueue/mqtest3.c
@@ -11,23 +11,29 @@
#include <stdlib.h>
#include <unistd.h>
+#include "freebsd_test_suite/macros.h"
+
#define MQNAME "/mytstqueue3"
#define LOOPS 1000
#define PRIO 10
-void sighandler(int sig)
+static void
+sighandler(int sig __unused)
{
write(1, "timeout\n", 8);
_exit(1);
}
-int main()
+int
+main(void)
{
- mqd_t mq;
- int status;
- struct mq_attr attr;
- int pid;
fd_set set;
+ struct mq_attr attr;
+ int status;
+ mqd_t mq;
+ pid_t pid;
+
+ PLAIN_REQUIRE_KERNEL_MODULE("mqueuefs", 0);
mq_unlink(MQNAME);
@@ -42,8 +48,9 @@ int main()
pid = fork();
if (pid == 0) { /* child */
- int prio, j, i;
char *buf;
+ int j, i;
+ unsigned int prio;
mq_close(mq);
@@ -77,7 +84,7 @@ int main()
err(1, "fork()");
} else {
char *buf;
- int i, j, prio;
+ int i, j;
signal(SIGALRM, sighandler);
buf = malloc(attr.mq_msgsize);
diff --git a/tools/regression/mqueue/mqtest4/mqtest4.c b/tests/sys/mqueue/mqtest4.c
index 80a7f88d9ed5..474d2121e0cc 100644
--- a/tools/regression/mqueue/mqtest4/mqtest4.c
+++ b/tests/sys/mqueue/mqtest4.c
@@ -12,25 +12,29 @@
#include <stdlib.h>
#include <unistd.h>
+#include "freebsd_test_suite/macros.h"
+
#define MQNAME "/mytstqueue4"
#define LOOPS 1000
#define PRIO 10
-void sighandler(int sig)
+static void
+sighandler(int sig __unused)
{
write(1, "timeout\n", 8);
_exit(1);
}
-int main()
+int
+main(void)
{
- mqd_t mq;
- int status;
- struct mq_attr attr;
- int pid;
- fd_set set;
- int kq;
struct kevent kev;
+ struct mq_attr attr;
+ mqd_t mq;
+ int kq, status;
+ pid_t pid;
+
+ PLAIN_REQUIRE_KERNEL_MODULE("mqueuefs", 0);
mq_unlink(MQNAME);
@@ -44,8 +48,9 @@ int main()
err(1, "mq_getattr()");
pid = fork();
if (pid == 0) { /* child */
- int prio, j, i;
char *buf;
+ int j, i;
+ unsigned int prio;
mq_close(mq);
kq = kqueue();
@@ -80,7 +85,7 @@ int main()
err(1, "fork()");
} else {
char *buf;
- int i, j, prio;
+ int i, j;
signal(SIGALRM, sighandler);
kq = kqueue();
diff --git a/tools/regression/mqueue/mqtest5/mqtest5.c b/tests/sys/mqueue/mqtest5.c
index 354a7bb30ceb..0c8aa895ead2 100644
--- a/tools/regression/mqueue/mqtest5/mqtest5.c
+++ b/tests/sys/mqueue/mqtest5.c
@@ -12,25 +12,31 @@
#include <stdlib.h>
#include <unistd.h>
+#include "freebsd_test_suite/macros.h"
+
#define MQNAME "/mytstqueue5"
#define LOOPS 1000
#define PRIO 10
-void sighandler(int sig)
+static void
+sighandler(int sig __unused)
{
write(1, "timeout\n", 8);
_exit(1);
}
-int main()
+int
+main(void)
{
- mqd_t mq;
int status;
struct mq_attr attr;
- int pid;
- sigset_t set;
struct sigaction sa;
+ sigset_t set;
siginfo_t info;
+ mqd_t mq;
+ pid_t pid;
+
+ PLAIN_REQUIRE_KERNEL_MODULE("mqueuefs", 0);
mq_unlink(MQNAME);
@@ -95,7 +101,7 @@ int main()
err(1, "fork()");
} else {
char *buf;
- int i, j, prio;
+ int i, j;
signal(SIGALRM, sighandler);
buf = malloc(attr.mq_msgsize);
diff --git a/tests/sys/mqueue/mqueue_test.sh b/tests/sys/mqueue/mqueue_test.sh
new file mode 100755
index 000000000000..48414184e2d3
--- /dev/null
+++ b/tests/sys/mqueue/mqueue_test.sh
@@ -0,0 +1,81 @@
+#
+# Copyright (c) 2015 EMC / Isilon Storage Division
+# 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$
+#
+
+mqtest1_head()
+{
+ :
+}
+mqtest1_body()
+{
+ atf_check -s exit:0 -x $(atf_get_srcdir)/mqtest1
+}
+
+mqtest2_head()
+{
+ :
+}
+mqtest2_body()
+{
+ atf_check -s exit:0 -x $(atf_get_srcdir)/mqtest2
+}
+
+mqtest3_head()
+{
+ :
+}
+mqtest3_body()
+{
+ atf_check -s exit:0 -x $(atf_get_srcdir)/mqtest3
+}
+
+mqtest4_head()
+{
+ :
+}
+mqtest4_body()
+{
+ atf_check -s exit:0 -x $(atf_get_srcdir)/mqtest4
+}
+
+mqtest5_head()
+{
+ :
+}
+mqtest5_body()
+{
+ atf_check -s exit:0 -x $(atf_get_srcdir)/mqtest5
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case mqtest1
+ atf_add_test_case mqtest2
+ atf_add_test_case mqtest3
+ atf_add_test_case mqtest4
+ atf_add_test_case mqtest5
+}
diff --git a/tests/sys/vm/Makefile b/tests/sys/vm/Makefile
new file mode 100644
index 000000000000..1795eefa6a52
--- /dev/null
+++ b/tests/sys/vm/Makefile
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+TESTSDIR= ${TESTSBASE}/sys/vm
+
+TAP_TESTS_C+= mmap_test
+
+.include <bsd.test.mk>
diff --git a/tools/regression/mmap/mmap.c b/tests/sys/vm/mmap_test.c
index 14c55a1aed19..7591a0996971 100644
--- a/tools/regression/mmap/mmap.c
+++ b/tests/sys/vm/mmap_test.c
@@ -31,10 +31,11 @@
#include <sys/sysctl.h>
#include <sys/types.h>
+#include <errno.h>
#include <stdio.h>
-#include <err.h>
+#include <string.h>
-const struct tests {
+static const struct {
void *addr;
int ok[2]; /* Depending on security.bsd.map_at_zero {0, !=0}. */
} tests[] = {
@@ -49,6 +50,8 @@ const struct tests {
{ (void *)(0x1000 * PAGE_SIZE), { 1, 1 } },
};
+#define MAP_AT_ZERO "security.bsd.map_at_zero"
+
int
main(void)
{
@@ -60,37 +63,43 @@ main(void)
/* Get the current sysctl value of security.bsd.map_at_zero. */
len = sizeof(mib) / sizeof(*mib);
- if (sysctlnametomib("security.bsd.map_at_zero", mib, &len) == -1)
- err(1, "sysctlnametomib(security.bsd.map_at_zero)");
+ if (sysctlnametomib(MAP_AT_ZERO, mib, &len) == -1) {
+ printf("1..0 # SKIP: sysctlnametomib(\"%s\") failed: %s\n",
+ MAP_AT_ZERO, strerror(errno));
+ return (0);
+ }
len = sizeof(map_at_zero);
- if (sysctl(mib, 3, &map_at_zero, &len, NULL, 0) == -1)
- err(1, "sysctl(security.bsd.map_at_zero)");
+ if (sysctl(mib, 3, &map_at_zero, &len, NULL, 0) == -1) {
+ printf("1..0 # SKIP: sysctl for %s failed: %s\n", MAP_AT_ZERO,
+ strerror(errno));
+ return (0);
+ }
/* Normalize to 0 or 1 for array access. */
map_at_zero = !!map_at_zero;
- for (i=0; i < (sizeof(tests) / sizeof(*tests)); i++) {
+ printf("1..%zu\n", nitems(tests));
+ for (i = 0; i < (int)nitems(tests); i++) {
p = mmap((void *)tests[i].addr, PAGE_SIZE,
PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_FIXED,
-1, 0);
if (p == MAP_FAILED) {
if (tests[i].ok[map_at_zero] != 0)
error++;
- warnx("%s: mmap(%p, ...) failed.",
- (tests[i].ok[map_at_zero] == 0) ? "OK " : "ERR",
- tests[i].addr);
+ printf("%sok %d # mmap(%p, ...) failed\n",
+ tests[i].ok[map_at_zero] == 0 ? "" : "not ",
+ i + 1,
+ tests[i].addr);
} else {
if (tests[i].ok[map_at_zero] != 1)
error++;
- warnx("%s: mmap(%p, ...) succeeded: p=%p",
- (tests[i].ok[map_at_zero] == 1) ? "OK " : "ERR",
+ printf("%sok %d # mmap(%p, ...) succeeded: p=%p\n",
+ tests[i].ok[map_at_zero] == 1 ? "" : "not ",
+ i + 1,
tests[i].addr, p);
}
}
- if (error)
- err(1, "---\nERROR: %d unexpected results.", error);
-
return (error != 0);
}
diff --git a/tools/build/check-links.sh b/tools/build/check-links.sh
index 1c58aa0c4c50..57c9437c0259 100755
--- a/tools/build/check-links.sh
+++ b/tools/build/check-links.sh
@@ -20,9 +20,11 @@ libkey() {
ret=0
CHECK_UNRESOLVED=1
-while getopts "U" flag; do
+VERBOSE_RESOLVED=0
+while getopts "Uv" flag; do
case "${flag}" in
U) CHECK_UNRESOLVED=0 ;;
+ v) VERBOSE_RESOLVED=1 ;;
esac
done
shift $((OPTIND-1))
@@ -83,7 +85,7 @@ if [ ${CHECK_UNRESOLVED} -eq 1 ]; then
libkey "crt1.o"
setvar "${libkey}" "${lib_symbols}"
- # No search libs for all symbols and report missing ones.
+ # Now search libs for all symbols and report missing ones.
for sym in ${unresolved_symbols}; do
found=0
for lib in ${list_libs}; do
@@ -91,7 +93,12 @@ if [ ${CHECK_UNRESOLVED} -eq 1 ]; then
eval "lib_symbols=\"\${${libkey}}\""
# lib_symbols now contains symbols for the lib.
case " ${lib_symbols} " in
- *\ ${sym}\ *) found=1 && break ;;
+ *\ ${sym}\ *)
+ [ ${VERBOSE_RESOLVED} -eq 1 ] &&
+ echo "Resolved symbol ${sym} from ${lib}"
+ found=1
+ break
+ ;;
esac
done
if [ $found -eq 0 ]; then
diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc
index 7a4549e57566..ab99fd95076a 100644
--- a/tools/build/mk/OptionalObsoleteFiles.inc
+++ b/tools/build/mk/OptionalObsoleteFiles.inc
@@ -1004,7 +1004,9 @@ OLD_DIRS+=usr/include/fs/cuse
.if ${MK_CXX} == no
OLD_FILES+=usr/bin/CC
OLD_FILES+=usr/bin/c++
+.if ${MK_ELFTOOLCHAIN_TOOLS} == no
OLD_FILES+=usr/bin/c++filt
+.endif
OLD_FILES+=usr/bin/g++
OLD_FILES+=usr/libexec/cc1plus
.if ${MK_GCC} == no
@@ -1720,7 +1722,9 @@ OLD_FILES+=usr/share/man/man8/unstr.8.gz
.endif
.if ${MK_GCC} == no
+.if ${MK_ELFTOOLCHAIN_TOOLS} == no
OLD_FILES+=usr/bin/c++filt
+.endif
OLD_FILES+=usr/bin/g++
OLD_FILES+=usr/bin/gcc
OLD_FILES+=usr/bin/gcov
diff --git a/tools/regression/aio/aiop/Makefile b/tools/regression/aio/aiop/Makefile
index aac9a3b89e45..38d9db62266a 100644
--- a/tools/regression/aio/aiop/Makefile
+++ b/tools/regression/aio/aiop/Makefile
@@ -3,4 +3,6 @@
PROG= aiop
MAN=
+WARNS= 6
+
.include <bsd.prog.mk>
diff --git a/tools/regression/aio/aiop/aiop.c b/tools/regression/aio/aiop/aiop.c
index 3e64dbe17ed3..98a176e5b230 100644
--- a/tools/regression/aio/aiop/aiop.c
+++ b/tools/regression/aio/aiop/aiop.c
@@ -39,21 +39,22 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/time.h>
#include <sys/types.h>
-#include <sys/stat.h>
-#include <time.h>
-#include <sys/ioctl.h>
#include <sys/disk.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/time.h>
#include <aio.h>
+#include <assert.h>
+#include <ctype.h>
+#include <err.h>
#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
-#include <assert.h>
+#include <time.h>
+#include <unistd.h>
/*
* This is a bit of a quick hack to do parallel IO testing through POSIX AIO.
@@ -84,14 +85,12 @@ disk_getsize(int fd)
{
off_t mediasize;
- if (ioctl(fd, DIOCGMEDIASIZE, &mediasize) < 0) {
- perror("ioctl(DIOCGMEDIASIZE)");
- exit(1);
- }
- return mediasize;
+ if (ioctl(fd, DIOCGMEDIASIZE, &mediasize) < 0)
+ err(1, "ioctl(DIOCGMEDIASIZE)");
+ return (mediasize);
}
-iot_t
+static iot_t
choose_aio(iot_t iomask)
{
/* choose a random read or write event, limited by the mask */
@@ -102,7 +101,7 @@ choose_aio(iot_t iomask)
return (random() & 0x01 ? IOT_READ : IOT_WRITE);
}
-void
+static void
set_aio(struct aiocb *a, iot_t iot, int fd, off_t offset, int size, char *buf)
{
int r;
@@ -115,10 +114,8 @@ set_aio(struct aiocb *a, iot_t iot, int fd, off_t offset, int size, char *buf)
r = aio_read(a);
else
r = aio_write(a);
- if (r != 0) {
- perror("set_aio");
- exit(1);
- }
+ if (r != 0)
+ err(1, "set_aio call failed");
}
int
@@ -134,30 +131,35 @@ main(int argc, char *argv[])
off_t file_size, offset;
struct aiocb *a;
int i, n;
- struct timeval st, et, rt;
- float f_rt;
+ struct timeval st, et, rt;
+ float f_rt;
iot_t iowhat;
if (argc < 6) {
- printf("Usage: %s <file> <io size> <number of runs> <concurrency> <ro|wo|rw>\n", argv[0]);
+ printf("Usage: %s <file> <io size> <number of runs> <concurrency> <ro|wo|rw>\n",
+ argv[0]);
exit(1);
}
fn = argv[1];
io_size = atoi(argv[2]);
+ if (io_size <= 0)
+ errx(1, "the I/O size must be >0");
nrun = atoi(argv[3]);
+ if (nrun <= 0)
+ errx(1, "the number of runs must be >0");
aio_len = atoi(argv[4]);
- if (strcmp(argv[5], "ro") == 0) {
+ if (aio_len <= 0)
+ errx(1, "AIO concurrency must be >0");
+ if (strcmp(argv[5], "ro") == 0)
iowhat = IOT_READ;
- } else if (strcmp(argv[5], "rw") == 0) {
+ else if (strcmp(argv[5], "rw") == 0)
iowhat = IOT_READ | IOT_WRITE;
- } else if (strcmp(argv[5], "wo") == 0) {
+ else if (strcmp(argv[5], "wo") == 0)
iowhat = IOT_WRITE;
- } else {
- fprintf(stderr, "needs to be ro, rw, wo!\n");
- exit(1);
- }
+ else
+ errx(1, "the I/O type needs to be \"ro\", \"rw\", or \"wo\"!\n");
/*
* Random returns values between 0 and (2^32)-1; only good for 4 gig.
@@ -171,35 +173,31 @@ main(int argc, char *argv[])
else
fd = open(fn, O_RDWR | O_DIRECT);
- if (fd < 0) {
- perror("open");
- exit(1);
- }
- if (fstat(fd, &sb) < 0) {
- perror("fstat");
- exit(1);
- }
+ if (fd < 0)
+ err(1, "open failed");
+ if (fstat(fd, &sb) < 0)
+ err(1, "fstat failed");
if (S_ISREG(sb.st_mode)) {
file_size = sb.st_size;
} else if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) {
file_size = disk_getsize(fd);
- } else {
- perror("unknown file type\n");
- exit(1);
- }
+ } else
+ errx(1, "unknown file type");
+ if (file_size <= 0)
+ errx(1, "path provided too small");
+
printf("File: %s; File size %jd bytes\n", fn, (intmax_t)file_size);
aio = calloc(aio_len, sizeof(struct aiocb));
abuf = calloc(aio_len, sizeof(char *));
- for (i = 0; i < aio_len; i++) {
+ for (i = 0; i < aio_len; i++)
abuf[i] = calloc(1, io_size * sizeof(char));
- }
/* Fill with the initial contents */
- gettimeofday(&st, NULL);
+ gettimeofday(&st, NULL);
for (i = 0; i < aio_len; i++) {
- offset = random() % (file_size / io_size);
- offset *= io_size;
+ offset = random() % (file_size / io_size);
+ offset *= io_size;
set_aio(aio + i, choose_aio(iowhat), fd, offset, io_size, abuf[i]);
}
@@ -208,18 +206,18 @@ main(int argc, char *argv[])
n = a - aio;
assert(n < aio_len);
assert(n >= 0);
- offset = random() % (file_size / io_size);
- offset *= io_size;
+ offset = random() % (file_size / io_size);
+ offset *= io_size;
set_aio(aio + n, choose_aio(iowhat), fd, offset, io_size, abuf[n]);
}
- gettimeofday(&et, NULL);
- timersub(&et, &st, &rt);
- f_rt = ((float) (rt.tv_usec)) / 1000000.0;
- f_rt += (float) (rt.tv_sec);
- printf("Runtime: %.2f seconds, ", f_rt);
- printf("Op rate: %.2f ops/sec, ", ((float) (nrun)) / f_rt);
- printf("Avg transfer rate: %.2f bytes/sec\n", ((float) (nrun)) * ((float)io_size) / f_rt);
+ gettimeofday(&et, NULL);
+ timersub(&et, &st, &rt);
+ f_rt = ((float) (rt.tv_usec)) / 1000000.0;
+ f_rt += (float) (rt.tv_sec);
+ printf("Runtime: %.2f seconds, ", f_rt);
+ printf("Op rate: %.2f ops/sec, ", ((float) (nrun)) / f_rt);
+ printf("Avg transfer rate: %.2f bytes/sec\n", ((float) (nrun)) * ((float)io_size) / f_rt);
diff --git a/tools/regression/aio/aiotest/Makefile b/tools/regression/aio/aiotest/Makefile
deleted file mode 100644
index 59d4316b6ced..000000000000
--- a/tools/regression/aio/aiotest/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-# $FreeBSD$
-
-PROG= aiotest
-MAN=
-
-DPADD= ${LIBUTIL}
-LDADD= -lutil
-
-WARNS?= 6
-
-.include <bsd.prog.mk>
diff --git a/tools/regression/aio/kqueue/Makefile b/tools/regression/aio/kqueue/Makefile
deleted file mode 100644
index 39c1aa1c510e..000000000000
--- a/tools/regression/aio/kqueue/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# $FreeBSD$
-
-PROG= aio_kqueue
-MAN=
-
-WARNS?= 6
-
-SUBDIR+= lio
-
-.include <bsd.prog.mk>
diff --git a/tools/regression/aio/kqueue/lio/Makefile b/tools/regression/aio/kqueue/lio/Makefile
deleted file mode 100644
index da054e49857b..000000000000
--- a/tools/regression/aio/kqueue/lio/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# $FreeBSD$
-
-PROG= lio_kqueue
-MAN=
-
-WARNS?= 6
-
-.include <bsd.prog.mk>
diff --git a/tools/regression/execve/Makefile b/tools/regression/execve/Makefile
deleted file mode 100644
index 018678cde02c..000000000000
--- a/tools/regression/execve/Makefile
+++ /dev/null
@@ -1,70 +0,0 @@
-# $FreeBSD$
-
-PROG= doexec
-MAN=
-
-RP= ./${PROG}
-TD= ${.CURDIR}/tests
-
-TESTSCRIPTS= nonexistshell devnullscript badinterplen goodscript \
- scriptarg scriptarg-nospace
-CLEANFILES= goodaout truncaout sparseaout empty ${TESTSCRIPTS}
-
-all: ${PROG} goodaout ${TESTSCRIPTS}
-
-.for x in ${TESTSCRIPTS}
-${x}: ${TD}/${x}
- ${CP} ${TD}/${x} .
- chmod +x ${x}
-.endfor
-
-regress: test-empty test-nonexist test-nonexistshell \
- test-devnullscript test-badinterplen test-goodscript \
- test-scriptarg test-scriptarg-nospace test-goodaout \
- test-truncaout test-sparseaout
-
-test-empty: ${PROG}
- rm -f empty
- touch empty
- chmod +x empty
- ${RP} empty | grep 'Exec format error'
-
-test-nonexist: ${PROG}
- ${RP} ${TD}/nonexistent | grep 'No such file or directory'
-
-test-nonexistshell: ${PROG} nonexistshell
- ${RP} nonexistshell | grep 'No such file or directory'
-
-test-devnullscript: ${PROG} devnullscript
- ${RP} devnullscript | grep 'Permission denied'
-
-test-badinterplen: ${PROG} badinterplen
- ${RP} badinterplen | grep 'No such file or directory'
-
-test-goodscript: ${PROG} goodscript
- ${RP} goodscript | grep 'succeeded'
-
-test-scriptarg: ${PROG} scriptarg
- ${RP} scriptarg 2>&1 | grep '+ echo succeeded'
-
-test-scriptarg-nospace: ${PROG} scriptarg-nospace
- ${RP} scriptarg-nospace 2>&1 | grep '+ echo succeeded'
-
-goodaout: ${TD}/goodaout.c
- ${CC} -static -o ${.TARGET} ${TD}/goodaout.c
-
-test-goodaout: ${PROG} goodaout
- ${RP} goodaout | grep 'succeeded'
-
-test-truncaout: ${PROG} goodaout
- truncate -s 16 truncaout
- chmod a+x truncaout
- ${RP} truncaout | grep 'Exec format error'
-
-test-sparseaout: ${PROG}
- /bin/rm -rf sparseaout
- truncate -s 20480 sparseaout
- chmod a+x sparseaout
- ${RP} sparseaout | grep 'Exec format error'
-
-.include <bsd.prog.mk>
diff --git a/tools/regression/execve/execve.t b/tools/regression/execve/execve.t
deleted file mode 100644
index dd2be9a9d0ea..000000000000
--- a/tools/regression/execve/execve.t
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/bin/sh
-# $FreeBSD$
-
-cd `dirname $0`
-cmd="./`basename $0 .t`"
-
-make >/dev/null 2>&1
-
-tests="test-empty test-nonexist test-nonexistshell \
- test-devnullscript test-badinterplen test-goodscript \
- test-scriptarg test-scriptarg-nospace test-goodaout \
- test-truncaout test-sparseaout"
-
-n=0
-
-echo "1..11"
-
-for atest in ${tests}
-do
- n=`expr ${n} + 1`
- if make ${atest}
- then
- echo "ok ${n} - ${atest}"
- else
- echo "not ok ${n} - ${atest}"
- fi
-done
diff --git a/tools/regression/fifo/fifo_create/Makefile b/tools/regression/fifo/fifo_create/Makefile
deleted file mode 100644
index 10e2b14f3bad..000000000000
--- a/tools/regression/fifo/fifo_create/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-# $FreeBSD$
-
-PROG= fifo_create
-MAN=
-WARNS?= 3
-
-.include <bsd.prog.mk>
diff --git a/tools/regression/fifo/fifo_io/Makefile b/tools/regression/fifo/fifo_io/Makefile
deleted file mode 100644
index 49bf5bd6d225..000000000000
--- a/tools/regression/fifo/fifo_io/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-# $FreeBSD$
-
-PROG= fifo_io
-MAN=
-WARNS?= 3
-
-.include <bsd.prog.mk>
diff --git a/tools/regression/fifo/fifo_misc/Makefile b/tools/regression/fifo/fifo_misc/Makefile
deleted file mode 100644
index 97f85ec9aa91..000000000000
--- a/tools/regression/fifo/fifo_misc/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-# $FreeBSD$
-
-PROG= fifo_misc
-MAN=
-WARNS?= 3
-
-.include <bsd.prog.mk>
diff --git a/tools/regression/fifo/fifo_open/Makefile b/tools/regression/fifo/fifo_open/Makefile
deleted file mode 100644
index d90811ce9222..000000000000
--- a/tools/regression/fifo/fifo_open/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-# $FreeBSD$
-
-PROG= fifo_open
-MAN=
-WARNS?= 3
-
-.include <bsd.prog.mk>
diff --git a/tools/regression/file/closefrom/closefrom.c b/tools/regression/file/closefrom/closefrom.c
index e119f20af48c..b27ec5107c50 100644
--- a/tools/regression/file/closefrom/closefrom.c
+++ b/tools/regression/file/closefrom/closefrom.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2009 Advanced Computing Technologies LLC
+ * Copyright (c) 2009 Hudson River Trading LLC
* Written by: John H. Baldwin <jhb@FreeBSD.org>
* All rights reserved.
*
diff --git a/tools/regression/file/dup/Makefile b/tools/regression/file/dup/Makefile
deleted file mode 100644
index 225c2e270cbf..000000000000
--- a/tools/regression/file/dup/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-# $FreeBSD$
-
-PROG= dup
-MAN=
-WARNS?= 6
-
-.include <bsd.prog.mk>
diff --git a/tools/regression/file/dup/dup.t b/tools/regression/file/dup/dup.t
deleted file mode 100644
index 8bdfd03be81b..000000000000
--- a/tools/regression/file/dup/dup.t
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-# $FreeBSD$
-
-cd `dirname $0`
-
-executable=`basename $0 .t`
-
-make $executable 2>&1 > /dev/null
-
-exec ./$executable
diff --git a/tools/regression/file/fcntlflags/Makefile b/tools/regression/file/fcntlflags/Makefile
deleted file mode 100644
index 9e7fc3e2ae6d..000000000000
--- a/tools/regression/file/fcntlflags/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-# $FreeBSD$
-
-PROG= fcntlflags
-MAN=
-WARNS?= 6
-
-.include <bsd.prog.mk>
diff --git a/tools/regression/file/fcntlflags/fcntlflags.t b/tools/regression/file/fcntlflags/fcntlflags.t
deleted file mode 100644
index 8bdfd03be81b..000000000000
--- a/tools/regression/file/fcntlflags/fcntlflags.t
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-# $FreeBSD$
-
-cd `dirname $0`
-
-executable=`basename $0 .t`
-
-make $executable 2>&1 > /dev/null
-
-exec ./$executable
diff --git a/tools/regression/file/flock/Makefile b/tools/regression/file/flock/Makefile
deleted file mode 100644
index cd1a46d8171b..000000000000
--- a/tools/regression/file/flock/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-# $FreeBSD$
-
-PROG= flock
-MAN=
-WARNS?= 6
-DPADD= ${LIBPTHREAD}
-LDADD= -lpthread
-
-.include <bsd.prog.mk>
diff --git a/tools/regression/file/ftruncate/Makefile b/tools/regression/file/ftruncate/Makefile
deleted file mode 100644
index 40b753e2314d..000000000000
--- a/tools/regression/file/ftruncate/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-# $FreeBSD$
-
-PROG= ftruncate
-MAN=
-WARNS?= 2
-
-.include <bsd.prog.mk>
diff --git a/tools/regression/file/newfileops_on_fork/Makefile b/tools/regression/file/newfileops_on_fork/Makefile
deleted file mode 100644
index be0c5feb0c42..000000000000
--- a/tools/regression/file/newfileops_on_fork/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# $FreeBSD$
-
-PROG= newfileops_on_fork
-MAN=
-WARNS?= 6
-LDFLAGS= -lpthread
-
-.include <bsd.prog.mk>
diff --git a/tools/regression/gaithrstress/gaithrstress.c b/tools/regression/gaithrstress/gaithrstress.c
index c76f94f353e0..25066250189f 100644
--- a/tools/regression/gaithrstress/gaithrstress.c
+++ b/tools/regression/gaithrstress/gaithrstress.c
@@ -230,7 +230,7 @@ usage:
err(1, "reading word file %s", wordfile);
if (nrandwords < 1)
errx(1, "word file %s did not have >0 words", wordfile);
- printf("Read %u random words from %s.\n", nrandwords, wordfile);
+ printf("Read %zu random words from %s.\n", nrandwords, wordfile);
workers = calloc(nworkers, sizeof(*workers));
if (workers == NULL)
err(1, "allocating workers");
@@ -242,8 +242,8 @@ usage:
for (i = 0; i < nworkers; i++) {
if (pthread_create(&workers[i].w_thread, NULL, work,
&workers[i]) != 0)
- err(1, "creating worker %u", i);
- printf("%u%s", i, i == nworkers - 1 ? ".\n" : ", ");
+ err(1, "creating worker %zu", i);
+ printf("%zu%s", i, i == nworkers - 1 ? ".\n" : ", ");
fflush(stdout);
}
@@ -255,7 +255,7 @@ usage:
fflush(stdout);
for (i = 0; i < nworkers; i++) {
pthread_join(workers[i].w_thread, NULL);
- printf("%u%s", i, i == nworkers - 1 ? ".\n" : ", ");
+ printf("%zu%s", i, i == nworkers - 1 ? ".\n" : ", ");
fflush(stdout);
}
@@ -264,7 +264,7 @@ usage:
printf("%-10s%-20s%-20s%-29s\n", "------", "--------------",
"----------", "---------------------------");
for (i = 0; i < nworkers; i++) {
- printf("%-10u%-20ju%-20ju%u:%s%.2f\n", i,
+ printf("%-10zu%-20ju%-20ju%ld:%s%.2f\n", i,
workers[i].w_lookup_success, workers[i].w_lookup_failure,
workers[i].w_max_lookup_time.tv_sec / 60,
workers[i].w_max_lookup_time.tv_sec % 60 < 10 ? "0" : "",
diff --git a/tools/regression/lib/libc/stdio/test-open_memstream.c b/tools/regression/lib/libc/stdio/test-open_memstream.c
index 1a168c65828d..fdbda30dc5d4 100644
--- a/tools/regression/lib/libc/stdio/test-open_memstream.c
+++ b/tools/regression/lib/libc/stdio/test-open_memstream.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2013 Advanced Computing Technologies LLC
+ * Copyright (c) 2013 Hudson River Trading LLC
* Written by: John H. Baldwin <jhb@FreeBSD.org>
* All rights reserved.
*
diff --git a/tools/regression/lib/libc/stdio/test-open_wmemstream.c b/tools/regression/lib/libc/stdio/test-open_wmemstream.c
index 4cd0ab9544d6..2a90fcd893fe 100644
--- a/tools/regression/lib/libc/stdio/test-open_wmemstream.c
+++ b/tools/regression/lib/libc/stdio/test-open_wmemstream.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2013 Advanced Computing Technologies LLC
+ * Copyright (c) 2013 Hudson River Trading LLC
* Written by: John H. Baldwin <jhb@FreeBSD.org>
* All rights reserved.
*
diff --git a/tools/regression/mmap/Makefile b/tools/regression/mmap/Makefile
deleted file mode 100644
index c9bb5c482795..000000000000
--- a/tools/regression/mmap/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-# $FreeBSD$
-
-PROG= mmap
-MAN=
-
-.include <bsd.prog.mk>
diff --git a/tools/regression/mqueue/Makefile b/tools/regression/mqueue/Makefile
deleted file mode 100644
index a4f386b6839d..000000000000
--- a/tools/regression/mqueue/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-# $FreeBSD$
-
-SUBDIR=mqtest1 mqtest2 mqtest3 mqtest4 mqtest5
-
-.include <bsd.subdir.mk>
diff --git a/tools/regression/mqueue/mqtest1/Makefile b/tools/regression/mqueue/mqtest1/Makefile
deleted file mode 100644
index 3a50cee8ffea..000000000000
--- a/tools/regression/mqueue/mqtest1/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-# $FreeBSD$
-
-PROG=mqtest1
-DPADD= ${LIBRT}
-LDADD= -lrt
-MAN=
-DEBUG_FLAGS=-g
-
-.include <bsd.prog.mk>
diff --git a/tools/regression/mqueue/mqtest2/Makefile b/tools/regression/mqueue/mqtest2/Makefile
deleted file mode 100644
index 07098543cc15..000000000000
--- a/tools/regression/mqueue/mqtest2/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-# $FreeBSD$
-
-PROG=mqtest2
-DPADD= ${LIBRT}
-LDADD= -lrt
-MAN=
-DEBUG_FLAGS=-g
-
-.include <bsd.prog.mk>
diff --git a/tools/regression/mqueue/mqtest3/Makefile b/tools/regression/mqueue/mqtest3/Makefile
deleted file mode 100644
index 514cbacb1708..000000000000
--- a/tools/regression/mqueue/mqtest3/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-# $FreeBSD$
-
-PROG=mqtest3
-DPADD= ${LIBRT}
-LDADD= -lrt
-MAN=
-DEBUG_FLAGS=-g
-
-.include <bsd.prog.mk>
diff --git a/tools/regression/mqueue/mqtest4/Makefile b/tools/regression/mqueue/mqtest4/Makefile
deleted file mode 100644
index 781d76da220b..000000000000
--- a/tools/regression/mqueue/mqtest4/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-# $FreeBSD$
-
-PROG=mqtest4
-DPADD= ${LIBRT}
-LDADD= -lrt
-MAN=
-DEBUG_FLAGS=-g
-
-.include <bsd.prog.mk>
diff --git a/tools/regression/mqueue/mqtest5/Makefile b/tools/regression/mqueue/mqtest5/Makefile
deleted file mode 100644
index d94e541f81f3..000000000000
--- a/tools/regression/mqueue/mqtest5/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-# $FreeBSD$
-
-PROG=mqtest5
-DPADD= ${LIBRT}
-LDADD= -lrt
-MAN=
-DEBUG_FLAGS=-g
-
-.include <bsd.prog.mk>
diff --git a/tools/regression/netinet/arphold/arphold.c b/tools/regression/netinet/arphold/arphold.c
index 8d694fec7e43..417a2d8c15d5 100644
--- a/tools/regression/netinet/arphold/arphold.c
+++ b/tools/regression/netinet/arphold/arphold.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Advanced Computing Technologies LLC
+ * Copyright (c) 2010 Hudson River Trading LLC
* Written by George Neville-Neil gnn@freebsd.org
* All rights reserved.
*
diff --git a/tools/regression/p1003_1b/Makefile b/tools/regression/p1003_1b/Makefile
index 8cf7d5a6d783..902666c2ec39 100644
--- a/tools/regression/p1003_1b/Makefile
+++ b/tools/regression/p1003_1b/Makefile
@@ -14,4 +14,5 @@ SRCS=\
MAN=
CFLAGS+=-DNO_MEMLOCK
+
.include <bsd.prog.mk>
diff --git a/tools/regression/p1003_1b/fifo.c b/tools/regression/p1003_1b/fifo.c
index 455f7f9adc5f..925e7c21368e 100644
--- a/tools/regression/p1003_1b/fifo.c
+++ b/tools/regression/p1003_1b/fifo.c
@@ -31,17 +31,17 @@
*
* $FreeBSD$
*/
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <err.h>
-#include <fcntl.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/time.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
#include <sched.h>
#include <signal.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
volatile int ticked;
#define CAN_USE_ALARMS
@@ -109,7 +109,7 @@ int fifo(int argc, char *argv[])
fifo_param.sched_priority = 1;
p = (long *)mmap(0, sizeof(*p),
- PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED|MAP_INHERIT, -1, 0);
+ PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0);
if (p == (long *)-1)
err(errno, "mmap");
diff --git a/tools/regression/p1003_1b/sched.c b/tools/regression/p1003_1b/sched.c
index bd978f8d4942..1814c79194e4 100644
--- a/tools/regression/p1003_1b/sched.c
+++ b/tools/regression/p1003_1b/sched.c
@@ -41,16 +41,17 @@
#define _POSIX_SOURCE
#define _POSIX_C_SOURCE 199309L
-#include <unistd.h>
-#include <stdlib.h>
-
-#include <stdio.h>
-#include <string.h>
+#include <sys/mman.h>
#include <errno.h>
#include <fcntl.h>
-#include <sys/mman.h>
-
+#include <limits.h>
#include <sched.h>
+#include <stdio.h>
+#define __XSI_VISIBLE 1
+#include <stdlib.h>
+#undef __XSI_VISIBLE
+#include <string.h>
+#include <unistd.h>
#include "prutil.h"
@@ -209,17 +210,14 @@ int sched(int ac, char *av[])
{
-#define NAM "P1003_1b_schedXXXX"
- char nam[L_tmpnam];
+ char nam[] = "P1003_1b_schedXXXXXX";
int fd;
pid_t p;
pid_t *lastrun;
- strcpy(nam, NAM);
- if (tmpnam(nam) != nam)
- q(__LINE__, errno, "tmpnam " NAM);
- q(__LINE__, (fd = open(nam, O_RDWR|O_CREAT, 0666)),
- "open " NAM);
+ fd = mkstemp(nam);
+ if (fd == -1)
+ q(__LINE__, errno, "mkstemp failed");
(void)unlink(nam);
diff --git a/tools/regression/p1003_1b/yield.c b/tools/regression/p1003_1b/yield.c
index ac31a99f250a..a9b7badb3452 100644
--- a/tools/regression/p1003_1b/yield.c
+++ b/tools/regression/p1003_1b/yield.c
@@ -89,7 +89,7 @@ int yield(int argc, char *argv[])
n = nslaves = atoi(argv[1]);
p = (int *)mmap(0, sizeof(int),
- PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED|MAP_INHERIT, -1, 0);
+ PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0);
if (p == (int *)-1)
err(errno, "mmap");
diff --git a/tools/tools/tscdrift/tscdrift.c b/tools/tools/tscdrift/tscdrift.c
index c607e489e473..13e754ef6776 100644
--- a/tools/tools/tscdrift/tscdrift.c
+++ b/tools/tools/tscdrift/tscdrift.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2014 Advanced Computing Technologies LLC
+ * Copyright (c) 2014 Hudson River Trading LLC
* Written by: John H. Baldwin <jhb@FreeBSD.org>
* All rights reserved.
*
diff --git a/usr.bin/Makefile b/usr.bin/Makefile
index 557c4078bc5c..8082a7fff468 100644
--- a/usr.bin/Makefile
+++ b/usr.bin/Makefile
@@ -36,6 +36,7 @@ SUBDIR= ${_addr2line} \
csplit \
ctlstat \
cut \
+ ${_cxxfilt} \
demandoc \
dirname \
dpv \
@@ -237,6 +238,7 @@ SUBDIR+= ee
.if ${MK_ELFTOOLCHAIN_TOOLS} != "no"
_addr2line= addr2line
+_cxxfilt= cxxfilt
_elfcopy= elfcopy
_nm= nm
_readelf= readelf
diff --git a/usr.bin/calendar/calendars/calendar.freebsd b/usr.bin/calendar/calendars/calendar.freebsd
index fc6df82b921c..9ea3d81aa8b1 100644
--- a/usr.bin/calendar/calendars/calendar.freebsd
+++ b/usr.bin/calendar/calendars/calendar.freebsd
@@ -359,6 +359,7 @@
12/01 Alexey Dokuchaev <danfe@FreeBSD.org> born in Magadan, USSR, 1980
12/02 Ermal Luçi <eri@FreeBSD.org> born in Tirane, Albania, 1980
12/03 Diane Bruce <db@FreeBSD.org> born in Ottawa, Ontario, Canada, 1952
+12/04 Mariusz Zaborski <oshogbo@FreeBSD.org> born in Skierniewice, Poland, 1990
12/05 Ivan Voras <ivoras@FreeBSD.org> born in Slavonski Brod, Croatia, 1981
12/06 Stefan Farfeleder <stefanf@FreeBSD.org> born in Wien, Austria, 1980
12/11 Ganael Laplanche <martymac@FreeBSD.org> born in Reims, France, 1980
diff --git a/usr.bin/calendar/calendars/calendar.holiday b/usr.bin/calendar/calendars/calendar.holiday
index 3fdee69be713..fe9029eb1128 100644
--- a/usr.bin/calendar/calendars/calendar.holiday
+++ b/usr.bin/calendar/calendars/calendar.holiday
@@ -144,8 +144,8 @@
04/26 Confederate Memorial Day in Florida & Georgia
04/26 Union Day in Tanzania
04/27 Independence Day in Togo
+04/27 King's Birthday in the Netherlands, the Netherlands Antilles
04/29 Showa Day in Japan
-04/30 Queen's Birthday in the Netherlands, the Netherlands Antilles
04/30 The Workers Day in Uruguay
04/MonLast Arbor Day in Wyoming (last Monday)
04/MonLast Confederate Memorial Day in Alabama & Mississippi (last Monday)
diff --git a/usr.bin/col/col.c b/usr.bin/col/col.c
index e811a5247c6c..fa98cdbc1aab 100644
--- a/usr.bin/col/col.c
+++ b/usr.bin/col/col.c
@@ -63,9 +63,9 @@ __FBSDID("$FreeBSD$");
#define SI '\017' /* shift in to normal character set */
#define SO '\016' /* shift out to alternate character set */
#define VT '\013' /* vertical tab (aka reverse line feed) */
-#define RLF '\007' /* ESC-07 reverse line feed */
-#define RHLF '\010' /* ESC-010 reverse half-line feed */
-#define FHLF '\011' /* ESC-011 forward half-line feed */
+#define RLF '7' /* ESC-7 reverse line feed */
+#define RHLF '8' /* ESC-8 reverse half-line feed */
+#define FHLF '9' /* ESC-9 forward half-line feed */
/* build up at least this many lines before flushing them out */
#define BUFFER_MARGIN 32
@@ -321,7 +321,7 @@ main(int argc, char **argv)
/* make sure we leave things in a sane state */
if (last_set != CS_NORMAL)
- PUTC('\017');
+ PUTC(SI);
/* flush out the last few blank lines */
nblank_lines = max_line - this_line;
@@ -377,8 +377,8 @@ flush_blanks(void)
for (i = nb; --i >= 0;)
PUTC('\n');
if (half) {
- PUTC('\033');
- PUTC('\011');
+ PUTC(ESC);
+ PUTC(FHLF);
if (!nb)
PUTC('\r');
}
@@ -480,10 +480,10 @@ flush_line(LINE *l)
if (c->c_set != last_set) {
switch (c->c_set) {
case CS_NORMAL:
- PUTC('\017');
+ PUTC(SI);
break;
case CS_ALTERNATE:
- PUTC('\016');
+ PUTC(SO);
}
last_set = c->c_set;
}
diff --git a/usr.bin/cxxfilt/Makefile b/usr.bin/cxxfilt/Makefile
new file mode 100644
index 000000000000..496b240a79d5
--- /dev/null
+++ b/usr.bin/cxxfilt/Makefile
@@ -0,0 +1,17 @@
+# $FreeBSD$
+
+.include <src.opts.mk>
+
+ELFTCDIR= ${.CURDIR}/../../contrib/elftoolchain
+SRCDIR= ${ELFTCDIR}/cxxfilt
+
+.PATH: ${SRCDIR}
+
+PROG= c++filt
+SRCS= cxxfilt.c
+
+LIBADD= elftc
+
+CFLAGS+=-I${ELFTCDIR}/libelftc -I${ELFTCDIR}/common
+
+.include <bsd.prog.mk>
diff --git a/usr.bin/hexdump/display.c b/usr.bin/hexdump/display.c
index a5f2a4799e7a..4ff33080780b 100644
--- a/usr.bin/hexdump/display.c
+++ b/usr.bin/hexdump/display.c
@@ -380,7 +380,7 @@ doskip(const char *fname, int statok)
return;
}
}
- if (S_ISREG(sb.st_mode)) {
+ if (statok && S_ISREG(sb.st_mode)) {
if (fseeko(stdin, skip, SEEK_SET))
err(1, "%s", fname);
address += skip;
diff --git a/usr.bin/kdump/kdump.c b/usr.bin/kdump/kdump.c
index fe7bcd279606..3b5a8474eaf8 100644
--- a/usr.bin/kdump/kdump.c
+++ b/usr.bin/kdump/kdump.c
@@ -586,6 +586,7 @@ dumpheader(struct ktr_header *kth)
static char unknown[64];
static struct timeval prevtime, prevtime_e, temp;
const char *type;
+ const char *sign;
switch (kth->ktr_type) {
case KTR_SYSCALL:
@@ -662,10 +663,20 @@ dumpheader(struct ktr_header *kth)
timevaladd(&kth->ktr_time, &prevtime_e);
}
if (timestamp & TIMESTAMP_RELATIVE) {
+ if (prevtime.tv_sec == 0)
+ prevtime = kth->ktr_time;
temp = kth->ktr_time;
timevalsub(&kth->ktr_time, &prevtime);
- prevtime = temp;
- printf("%jd.%06ld ", (intmax_t)kth->ktr_time.tv_sec,
+ if ((intmax_t)kth->ktr_time.tv_sec < 0) {
+ kth->ktr_time = prevtime;
+ prevtime = temp;
+ timevalsub(&kth->ktr_time, &prevtime);
+ sign = "-";
+ } else {
+ prevtime = temp;
+ sign = "";
+ }
+ printf("%s%jd.%06ld ", sign, (intmax_t)kth->ktr_time.tv_sec,
kth->ktr_time.tv_usec);
}
}
diff --git a/usr.bin/nfsstat/Makefile b/usr.bin/nfsstat/Makefile
index 10b0b31e50e7..fc92008775c9 100644
--- a/usr.bin/nfsstat/Makefile
+++ b/usr.bin/nfsstat/Makefile
@@ -6,6 +6,4 @@ CFLAGS+=-DNFS
LIBADD= kvm
-WARNS?= 3
-
.include <bsd.prog.mk>
diff --git a/usr.bin/nfsstat/nfsstat.1 b/usr.bin/nfsstat/nfsstat.1
index 5ec048fed26e..6568c6a10767 100644
--- a/usr.bin/nfsstat/nfsstat.1
+++ b/usr.bin/nfsstat/nfsstat.1
@@ -28,7 +28,7 @@
.\" From: @(#)nfsstat.1 8.1 (Berkeley) 6/6/93
.\" $FreeBSD$
.\"
-.Dd May 1, 2013
+.Dd April 23, 2015
.Dt NFSSTAT 1
.Os
.Sh NAME
@@ -38,7 +38,7 @@
statistics
.Sh SYNOPSIS
.Nm
-.Op Fl cemoszW
+.Op Fl cemszW
.Op Fl M Ar core
.Op Fl N Ar system
.Op Fl w Ar wait
@@ -58,10 +58,8 @@ The options are as follows:
.It Fl c
Only display client side statistics.
.It Fl e
-Report the extra statistics collected by the new NFS client and
+Report the extra statistics collected by the NFS client and
server for NFSv4.
-This option is incompatible with
-.Fl o .
.It Fl M
Extract values associated with the name list from the specified core
instead of the default
@@ -75,10 +73,6 @@ This option is only supported by the new NFS client.
.It Fl N
Extract the name list from the specified system instead of the default
.Pa /boot/kernel/kernel .
-.It Fl o
-Report statistics for the old NFS client and/or server.
-Without this
-option statistics for the new NFS client and/or server will be reported.
.It Fl s
Only display server side statistics.
.It Fl W
diff --git a/usr.bin/nfsstat/nfsstat.c b/usr.bin/nfsstat/nfsstat.c
index cea451905fa1..32fbc9658f41 100644
--- a/usr.bin/nfsstat/nfsstat.c
+++ b/usr.bin/nfsstat/nfsstat.c
@@ -70,31 +70,19 @@ static const char rcsid[] =
#include <paths.h>
#include <err.h>
-struct nlist nl[] = {
-#define N_NFSSTAT 0
- { .n_name = "nfsstats" },
-#define N_NFSRVSTAT 1
- { .n_name = "nfsrvstats" },
- { .n_name = NULL },
-};
-kvm_t *kd;
-
-static int deadkernel = 0;
static int widemode = 0;
static int zflag = 0;
-static int run_v4 = 1;
static int printtitle = 1;
static struct ext_nfsstats ext_nfsstats;
static int extra_output = 0;
-void intpr(int, int);
-void printhdr(int, int);
-void sidewaysintpr(u_int, int, int);
-void usage(void);
-char *sperc1(int, int);
-char *sperc2(int, int);
-void exp_intpr(int, int);
-void exp_sidewaysintpr(u_int, int, int);
+static void intpr(int, int);
+static void printhdr(int, int);
+static void usage(void);
+static char *sperc1(int, int);
+static char *sperc2(int, int);
+static void exp_intpr(int, int);
+static void exp_sidewaysintpr(u_int, int, int);
#define DELTA(field) (nfsstats.field - lastst.field)
@@ -106,7 +94,6 @@ main(int argc, char **argv)
int serverOnly = -1;
int ch;
char *memf, *nlistf;
- char errbuf[_POSIX2_LINE_MAX];
int mntlen, i;
char buf[1024];
struct statfs *mntbuf;
@@ -114,7 +101,7 @@ main(int argc, char **argv)
interval = 0;
memf = nlistf = NULL;
- while ((ch = getopt(argc, argv, "cesWM:mN:ow:z")) != -1)
+ while ((ch = getopt(argc, argv, "cesWM:mN:w:z")) != -1)
switch(ch) {
case 'M':
memf = optarg;
@@ -162,14 +149,7 @@ main(int argc, char **argv)
case 'z':
zflag = 1;
break;
- case 'o':
- if (extra_output != 0)
- err(1, "-o incompatible with -e");
- run_v4 = 0;
- break;
case 'e':
- if (run_v4 == 0)
- err(1, "-e incompatible with -o");
extra_output = 1;
break;
case '?':
@@ -190,26 +170,11 @@ main(int argc, char **argv)
}
}
#endif
- if (run_v4 != 0 && modfind("nfscommon") < 0)
- errx(1, "new client/server not loaded");
-
- if (run_v4 == 0 && (nlistf != NULL || memf != NULL)) {
- deadkernel = 1;
-
- if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY,
- errbuf)) == 0) {
- errx(1, "kvm_openfiles: %s", errbuf);
- }
- if (kvm_nlist(kd, nl) != 0) {
- errx(1, "kvm_nlist: can't get names");
- }
- }
+ if (modfind("nfscommon") < 0)
+ errx(1, "NFS client/server not loaded");
if (interval) {
- if (run_v4 > 0)
- exp_sidewaysintpr(interval, clientOnly, serverOnly);
- else
- sidewaysintpr(interval, clientOnly, serverOnly);
+ exp_sidewaysintpr(interval, clientOnly, serverOnly);
} else {
if (extra_output != 0)
exp_intpr(clientOnly, serverOnly);
@@ -220,434 +185,160 @@ main(int argc, char **argv)
}
/*
- * Read the nfs stats using sysctl(3) for live kernels, or kvm_read
- * for dead ones.
- */
-static void
-readstats(struct nfsstats **stp, struct nfsrvstats **srvstp, int zero)
-{
- union {
- struct nfsstats client;
- struct nfsrvstats server;
- } zerostat;
- size_t buflen;
-
- if (deadkernel) {
- if (*stp != NULL && kvm_read(kd, (u_long)nl[N_NFSSTAT].n_value,
- *stp, sizeof(struct nfsstats)) < 0) {
- *stp = NULL;
- }
- if (*srvstp != NULL && kvm_read(kd,
- (u_long)nl[N_NFSRVSTAT].n_value, *srvstp,
- sizeof(struct nfsrvstats)) < 0) {
- *srvstp = NULL;
- }
- } else {
- if (zero)
- bzero(&zerostat, sizeof(zerostat));
- buflen = sizeof(struct nfsrvstats);
- if (*srvstp != NULL && sysctlbyname("vfs.nfsrv.nfsrvstats",
- *srvstp, &buflen, zero ? &zerostat : NULL,
- zero ? buflen : 0) < 0) {
- if (errno != ENOENT)
- err(1, "sysctl: vfs.nfsrv.nfsrvstats");
- *srvstp = NULL;
- }
- }
-}
-
-/*
* Print a description of the nfs stats.
*/
-void
+static void
intpr(int clientOnly, int serverOnly)
{
- struct nfsstats nfsstats, *nfsstatsp;
- struct nfsrvstats nfsrvstats, *nfsrvstatsp;
int nfssvc_flag;
- if (run_v4 == 0) {
- /*
- * Only read the stats we are going to display to avoid zeroing
- * stats the user didn't request.
- */
- if (clientOnly)
- nfsstatsp = &nfsstats;
- else
- nfsstatsp = NULL;
- if (serverOnly)
- nfsrvstatsp = &nfsrvstats;
- else
- nfsrvstatsp = NULL;
-
- readstats(&nfsstatsp, &nfsrvstatsp, zflag);
-
- if (clientOnly && !nfsstatsp) {
- printf("Client not present!\n");
- clientOnly = 0;
- }
- } else {
- nfssvc_flag = NFSSVC_GETSTATS;
- if (zflag != 0) {
- if (clientOnly != 0)
- nfssvc_flag |= NFSSVC_ZEROCLTSTATS;
- if (serverOnly != 0)
- nfssvc_flag |= NFSSVC_ZEROSRVSTATS;
- }
- if (nfssvc(nfssvc_flag, &ext_nfsstats) < 0)
- err(1, "Can't get stats");
+ nfssvc_flag = NFSSVC_GETSTATS;
+ if (zflag != 0) {
+ if (clientOnly != 0)
+ nfssvc_flag |= NFSSVC_ZEROCLTSTATS;
+ if (serverOnly != 0)
+ nfssvc_flag |= NFSSVC_ZEROSRVSTATS;
}
+ if (nfssvc(nfssvc_flag, &ext_nfsstats) < 0)
+ err(1, "Can't get stats");
if (clientOnly) {
printf("Client Info:\n");
printf("Rpc Counts:\n");
printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
"Getattr", "Setattr", "Lookup", "Readlink", "Read",
"Write", "Create", "Remove");
- if (run_v4 == 0)
- printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
- nfsstats.rpccnt[NFSPROC_GETATTR],
- nfsstats.rpccnt[NFSPROC_SETATTR],
- nfsstats.rpccnt[NFSPROC_LOOKUP],
- nfsstats.rpccnt[NFSPROC_READLINK],
- nfsstats.rpccnt[NFSPROC_READ],
- nfsstats.rpccnt[NFSPROC_WRITE],
- nfsstats.rpccnt[NFSPROC_CREATE],
- nfsstats.rpccnt[NFSPROC_REMOVE]);
- else
- printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
- ext_nfsstats.rpccnt[NFSPROC_GETATTR],
- ext_nfsstats.rpccnt[NFSPROC_SETATTR],
- ext_nfsstats.rpccnt[NFSPROC_LOOKUP],
- ext_nfsstats.rpccnt[NFSPROC_READLINK],
- ext_nfsstats.rpccnt[NFSPROC_READ],
- ext_nfsstats.rpccnt[NFSPROC_WRITE],
- ext_nfsstats.rpccnt[NFSPROC_CREATE],
- ext_nfsstats.rpccnt[NFSPROC_REMOVE]);
+ printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
+ ext_nfsstats.rpccnt[NFSPROC_GETATTR],
+ ext_nfsstats.rpccnt[NFSPROC_SETATTR],
+ ext_nfsstats.rpccnt[NFSPROC_LOOKUP],
+ ext_nfsstats.rpccnt[NFSPROC_READLINK],
+ ext_nfsstats.rpccnt[NFSPROC_READ],
+ ext_nfsstats.rpccnt[NFSPROC_WRITE],
+ ext_nfsstats.rpccnt[NFSPROC_CREATE],
+ ext_nfsstats.rpccnt[NFSPROC_REMOVE]);
printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
"Rename", "Link", "Symlink", "Mkdir", "Rmdir",
"Readdir", "RdirPlus", "Access");
- if (run_v4 == 0)
- printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
- nfsstats.rpccnt[NFSPROC_RENAME],
- nfsstats.rpccnt[NFSPROC_LINK],
- nfsstats.rpccnt[NFSPROC_SYMLINK],
- nfsstats.rpccnt[NFSPROC_MKDIR],
- nfsstats.rpccnt[NFSPROC_RMDIR],
- nfsstats.rpccnt[NFSPROC_READDIR],
- nfsstats.rpccnt[NFSPROC_READDIRPLUS],
- nfsstats.rpccnt[NFSPROC_ACCESS]);
- else
- printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
- ext_nfsstats.rpccnt[NFSPROC_RENAME],
- ext_nfsstats.rpccnt[NFSPROC_LINK],
- ext_nfsstats.rpccnt[NFSPROC_SYMLINK],
- ext_nfsstats.rpccnt[NFSPROC_MKDIR],
- ext_nfsstats.rpccnt[NFSPROC_RMDIR],
- ext_nfsstats.rpccnt[NFSPROC_READDIR],
- ext_nfsstats.rpccnt[NFSPROC_READDIRPLUS],
- ext_nfsstats.rpccnt[NFSPROC_ACCESS]);
+ printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
+ ext_nfsstats.rpccnt[NFSPROC_RENAME],
+ ext_nfsstats.rpccnt[NFSPROC_LINK],
+ ext_nfsstats.rpccnt[NFSPROC_SYMLINK],
+ ext_nfsstats.rpccnt[NFSPROC_MKDIR],
+ ext_nfsstats.rpccnt[NFSPROC_RMDIR],
+ ext_nfsstats.rpccnt[NFSPROC_READDIR],
+ ext_nfsstats.rpccnt[NFSPROC_READDIRPLUS],
+ ext_nfsstats.rpccnt[NFSPROC_ACCESS]);
printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n",
"Mknod", "Fsstat", "Fsinfo", "PathConf", "Commit");
- if (run_v4 == 0)
- printf("%9d %9d %9d %9d %9d\n",
- nfsstats.rpccnt[NFSPROC_MKNOD],
- nfsstats.rpccnt[NFSPROC_FSSTAT],
- nfsstats.rpccnt[NFSPROC_FSINFO],
- nfsstats.rpccnt[NFSPROC_PATHCONF],
- nfsstats.rpccnt[NFSPROC_COMMIT]);
- else
- printf("%9d %9d %9d %9d %9d\n",
- ext_nfsstats.rpccnt[NFSPROC_MKNOD],
- ext_nfsstats.rpccnt[NFSPROC_FSSTAT],
- ext_nfsstats.rpccnt[NFSPROC_FSINFO],
- ext_nfsstats.rpccnt[NFSPROC_PATHCONF],
- ext_nfsstats.rpccnt[NFSPROC_COMMIT]);
+ printf("%9d %9d %9d %9d %9d\n",
+ ext_nfsstats.rpccnt[NFSPROC_MKNOD],
+ ext_nfsstats.rpccnt[NFSPROC_FSSTAT],
+ ext_nfsstats.rpccnt[NFSPROC_FSINFO],
+ ext_nfsstats.rpccnt[NFSPROC_PATHCONF],
+ ext_nfsstats.rpccnt[NFSPROC_COMMIT]);
printf("Rpc Info:\n");
printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n",
"TimedOut", "Invalid", "X Replies", "Retries",
"Requests");
- if (run_v4 == 0)
- printf("%9d %9d %9d %9d %9d\n",
- nfsstats.rpctimeouts,
- nfsstats.rpcinvalid,
- nfsstats.rpcunexpected,
- nfsstats.rpcretries,
- nfsstats.rpcrequests);
- else
- printf("%9d %9d %9d %9d %9d\n",
- ext_nfsstats.rpctimeouts,
- ext_nfsstats.rpcinvalid,
- ext_nfsstats.rpcunexpected,
- ext_nfsstats.rpcretries,
- ext_nfsstats.rpcrequests);
+ printf("%9d %9d %9d %9d %9d\n",
+ ext_nfsstats.rpctimeouts,
+ ext_nfsstats.rpcinvalid,
+ ext_nfsstats.rpcunexpected,
+ ext_nfsstats.rpcretries,
+ ext_nfsstats.rpcrequests);
printf("Cache Info:\n");
printf("%9.9s %9.9s %9.9s %9.9s",
"Attr Hits", "Misses", "Lkup Hits", "Misses");
printf(" %9.9s %9.9s %9.9s %9.9s\n",
"BioR Hits", "Misses", "BioW Hits", "Misses");
- if (run_v4 == 0) {
- printf("%9d %9d %9d %9d",
- nfsstats.attrcache_hits,
- nfsstats.attrcache_misses,
- nfsstats.lookupcache_hits,
- nfsstats.lookupcache_misses);
- printf(" %9d %9d %9d %9d\n",
- nfsstats.biocache_reads-nfsstats.read_bios,
- nfsstats.read_bios,
- nfsstats.biocache_writes-nfsstats.write_bios,
- nfsstats.write_bios);
- } else {
- printf("%9d %9d %9d %9d",
- ext_nfsstats.attrcache_hits,
- ext_nfsstats.attrcache_misses,
- ext_nfsstats.lookupcache_hits,
- ext_nfsstats.lookupcache_misses);
- printf(" %9d %9d %9d %9d\n",
- ext_nfsstats.biocache_reads -
- ext_nfsstats.read_bios,
- ext_nfsstats.read_bios,
- ext_nfsstats.biocache_writes -
- ext_nfsstats.write_bios,
- ext_nfsstats.write_bios);
- }
+ printf("%9d %9d %9d %9d",
+ ext_nfsstats.attrcache_hits,
+ ext_nfsstats.attrcache_misses,
+ ext_nfsstats.lookupcache_hits,
+ ext_nfsstats.lookupcache_misses);
+ printf(" %9d %9d %9d %9d\n",
+ ext_nfsstats.biocache_reads -
+ ext_nfsstats.read_bios,
+ ext_nfsstats.read_bios,
+ ext_nfsstats.biocache_writes -
+ ext_nfsstats.write_bios,
+ ext_nfsstats.write_bios);
printf("%9.9s %9.9s %9.9s %9.9s",
"BioRLHits", "Misses", "BioD Hits", "Misses");
printf(" %9.9s %9.9s %9.9s %9.9s\n", "DirE Hits", "Misses", "Accs Hits", "Misses");
- if (run_v4 == 0) {
- printf("%9d %9d %9d %9d",
- nfsstats.biocache_readlinks -
- nfsstats.readlink_bios,
- nfsstats.readlink_bios,
- nfsstats.biocache_readdirs -
- nfsstats.readdir_bios,
- nfsstats.readdir_bios);
- printf(" %9d %9d %9d %9d\n",
- nfsstats.direofcache_hits,
- nfsstats.direofcache_misses,
- nfsstats.accesscache_hits,
- nfsstats.accesscache_misses);
- } else {
- printf("%9d %9d %9d %9d",
- ext_nfsstats.biocache_readlinks -
- ext_nfsstats.readlink_bios,
- ext_nfsstats.readlink_bios,
- ext_nfsstats.biocache_readdirs -
- ext_nfsstats.readdir_bios,
- ext_nfsstats.readdir_bios);
- printf(" %9d %9d %9d %9d\n",
- ext_nfsstats.direofcache_hits,
- ext_nfsstats.direofcache_misses,
- ext_nfsstats.accesscache_hits,
- ext_nfsstats.accesscache_misses);
- }
- }
- if (run_v4 == 0 && serverOnly && !nfsrvstatsp) {
- printf("Server not present!\n");
- serverOnly = 0;
+ printf("%9d %9d %9d %9d",
+ ext_nfsstats.biocache_readlinks -
+ ext_nfsstats.readlink_bios,
+ ext_nfsstats.readlink_bios,
+ ext_nfsstats.biocache_readdirs -
+ ext_nfsstats.readdir_bios,
+ ext_nfsstats.readdir_bios);
+ printf(" %9d %9d %9d %9d\n",
+ ext_nfsstats.direofcache_hits,
+ ext_nfsstats.direofcache_misses,
+ ext_nfsstats.accesscache_hits,
+ ext_nfsstats.accesscache_misses);
}
if (serverOnly) {
printf("\nServer Info:\n");
printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
"Getattr", "Setattr", "Lookup", "Readlink", "Read",
"Write", "Create", "Remove");
- if (run_v4 == 0)
- printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
- nfsrvstats.srvrpccnt[NFSPROC_GETATTR],
- nfsrvstats.srvrpccnt[NFSPROC_SETATTR],
- nfsrvstats.srvrpccnt[NFSPROC_LOOKUP],
- nfsrvstats.srvrpccnt[NFSPROC_READLINK],
- nfsrvstats.srvrpccnt[NFSPROC_READ],
- nfsrvstats.srvrpccnt[NFSPROC_WRITE],
- nfsrvstats.srvrpccnt[NFSPROC_CREATE],
- nfsrvstats.srvrpccnt[NFSPROC_REMOVE]);
- else
- printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
- ext_nfsstats.srvrpccnt[NFSV4OP_GETATTR],
- ext_nfsstats.srvrpccnt[NFSV4OP_SETATTR],
- ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUP],
- ext_nfsstats.srvrpccnt[NFSV4OP_READLINK],
- ext_nfsstats.srvrpccnt[NFSV4OP_READ],
- ext_nfsstats.srvrpccnt[NFSV4OP_WRITE],
- ext_nfsstats.srvrpccnt[NFSV4OP_CREATE],
- ext_nfsstats.srvrpccnt[NFSV4OP_REMOVE]);
+ printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
+ ext_nfsstats.srvrpccnt[NFSV4OP_GETATTR],
+ ext_nfsstats.srvrpccnt[NFSV4OP_SETATTR],
+ ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUP],
+ ext_nfsstats.srvrpccnt[NFSV4OP_READLINK],
+ ext_nfsstats.srvrpccnt[NFSV4OP_READ],
+ ext_nfsstats.srvrpccnt[NFSV4OP_WRITE],
+ ext_nfsstats.srvrpccnt[NFSV4OP_CREATE],
+ ext_nfsstats.srvrpccnt[NFSV4OP_REMOVE]);
printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
"Rename", "Link", "Symlink", "Mkdir", "Rmdir",
"Readdir", "RdirPlus", "Access");
- if (run_v4 == 0)
- printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
- nfsrvstats.srvrpccnt[NFSPROC_RENAME],
- nfsrvstats.srvrpccnt[NFSPROC_LINK],
- nfsrvstats.srvrpccnt[NFSPROC_SYMLINK],
- nfsrvstats.srvrpccnt[NFSPROC_MKDIR],
- nfsrvstats.srvrpccnt[NFSPROC_RMDIR],
- nfsrvstats.srvrpccnt[NFSPROC_READDIR],
- nfsrvstats.srvrpccnt[NFSPROC_READDIRPLUS],
- nfsrvstats.srvrpccnt[NFSPROC_ACCESS]);
- else
- printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
- ext_nfsstats.srvrpccnt[NFSV4OP_RENAME],
- ext_nfsstats.srvrpccnt[NFSV4OP_LINK],
- ext_nfsstats.srvrpccnt[NFSV4OP_SYMLINK],
- ext_nfsstats.srvrpccnt[NFSV4OP_MKDIR],
- ext_nfsstats.srvrpccnt[NFSV4OP_RMDIR],
- ext_nfsstats.srvrpccnt[NFSV4OP_READDIR],
- ext_nfsstats.srvrpccnt[NFSV4OP_READDIRPLUS],
- ext_nfsstats.srvrpccnt[NFSV4OP_ACCESS]);
+ printf("%9d %9d %9d %9d %9d %9d %9d %9d\n",
+ ext_nfsstats.srvrpccnt[NFSV4OP_RENAME],
+ ext_nfsstats.srvrpccnt[NFSV4OP_LINK],
+ ext_nfsstats.srvrpccnt[NFSV4OP_SYMLINK],
+ ext_nfsstats.srvrpccnt[NFSV4OP_MKDIR],
+ ext_nfsstats.srvrpccnt[NFSV4OP_RMDIR],
+ ext_nfsstats.srvrpccnt[NFSV4OP_READDIR],
+ ext_nfsstats.srvrpccnt[NFSV4OP_READDIRPLUS],
+ ext_nfsstats.srvrpccnt[NFSV4OP_ACCESS]);
printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n",
"Mknod", "Fsstat", "Fsinfo", "PathConf", "Commit");
- if (run_v4 == 0)
- printf("%9d %9d %9d %9d %9d\n",
- nfsrvstats.srvrpccnt[NFSPROC_MKNOD],
- nfsrvstats.srvrpccnt[NFSPROC_FSSTAT],
- nfsrvstats.srvrpccnt[NFSPROC_FSINFO],
- nfsrvstats.srvrpccnt[NFSPROC_PATHCONF],
- nfsrvstats.srvrpccnt[NFSPROC_COMMIT]);
- else
- printf("%9d %9d %9d %9d %9d\n",
- ext_nfsstats.srvrpccnt[NFSV4OP_MKNOD],
- ext_nfsstats.srvrpccnt[NFSV4OP_FSSTAT],
- ext_nfsstats.srvrpccnt[NFSV4OP_FSINFO],
- ext_nfsstats.srvrpccnt[NFSV4OP_PATHCONF],
- ext_nfsstats.srvrpccnt[NFSV4OP_COMMIT]);
+ printf("%9d %9d %9d %9d %9d\n",
+ ext_nfsstats.srvrpccnt[NFSV4OP_MKNOD],
+ ext_nfsstats.srvrpccnt[NFSV4OP_FSSTAT],
+ ext_nfsstats.srvrpccnt[NFSV4OP_FSINFO],
+ ext_nfsstats.srvrpccnt[NFSV4OP_PATHCONF],
+ ext_nfsstats.srvrpccnt[NFSV4OP_COMMIT]);
printf("Server Ret-Failed\n");
- if (run_v4 == 0)
- printf("%17d\n", nfsrvstats.srvrpc_errs);
- else
- printf("%17d\n", ext_nfsstats.srvrpc_errs);
+ printf("%17d\n", ext_nfsstats.srvrpc_errs);
printf("Server Faults\n");
- if (run_v4 == 0)
- printf("%13d\n", nfsrvstats.srv_errs);
- else
- printf("%13d\n", ext_nfsstats.srv_errs);
+ printf("%13d\n", ext_nfsstats.srv_errs);
printf("Server Cache Stats:\n");
printf("%9.9s %9.9s %9.9s %9.9s\n",
"Inprog", "Idem", "Non-idem", "Misses");
- if (run_v4 == 0)
- printf("%9d %9d %9d %9d\n",
- nfsrvstats.srvcache_inproghits,
- nfsrvstats.srvcache_idemdonehits,
- nfsrvstats.srvcache_nonidemdonehits,
- nfsrvstats.srvcache_misses);
- else
- printf("%9d %9d %9d %9d\n",
- ext_nfsstats.srvcache_inproghits,
- ext_nfsstats.srvcache_idemdonehits,
- ext_nfsstats.srvcache_nonidemdonehits,
- ext_nfsstats.srvcache_misses);
+ printf("%9d %9d %9d %9d\n",
+ ext_nfsstats.srvcache_inproghits,
+ ext_nfsstats.srvcache_idemdonehits,
+ ext_nfsstats.srvcache_nonidemdonehits,
+ ext_nfsstats.srvcache_misses);
printf("Server Write Gathering:\n");
printf("%9.9s %9.9s %9.9s\n",
"WriteOps", "WriteRPC", "Opsaved");
- if (run_v4 == 0)
- printf("%9d %9d %9d\n",
- nfsrvstats.srvvop_writes,
- nfsrvstats.srvrpccnt[NFSPROC_WRITE],
- nfsrvstats.srvrpccnt[NFSPROC_WRITE] -
- nfsrvstats.srvvop_writes);
- else
- /*
- * The new client doesn't do write gathering. It was
- * only useful for NFSv2.
- */
- printf("%9d %9d %9d\n",
- ext_nfsstats.srvrpccnt[NFSV4OP_WRITE],
- ext_nfsstats.srvrpccnt[NFSV4OP_WRITE], 0);
- }
-}
-
-u_char signalled; /* set if alarm goes off "early" */
-
-/*
- * Print a running summary of nfs statistics.
- * Repeat display every interval seconds, showing statistics
- * collected over that interval. Assumes that interval is non-zero.
- * First line printed at top of screen is always cumulative.
- */
-void
-sidewaysintpr(u_int interval, int clientOnly, int serverOnly)
-{
- struct nfsstats nfsstats, lastst, *nfsstatsp;
- struct nfsrvstats nfsrvstats, lastsrvst, *nfsrvstatsp;
- int hdrcnt = 1;
-
- nfsstatsp = &lastst;
- nfsrvstatsp = &lastsrvst;
- readstats(&nfsstatsp, &nfsrvstatsp, 0);
- if (clientOnly && !nfsstatsp) {
- printf("Client not present!\n");
- clientOnly = 0;
- }
- if (serverOnly && !nfsrvstatsp) {
- printf("Server not present!\n");
- serverOnly = 0;
- }
- sleep(interval);
-
- for (;;) {
- nfsstatsp = &nfsstats;
- nfsrvstatsp = &nfsrvstats;
- readstats(&nfsstatsp, &nfsrvstatsp, 0);
-
- if (--hdrcnt == 0) {
- printhdr(clientOnly, serverOnly);
- if (clientOnly && serverOnly)
- hdrcnt = 10;
- else
- hdrcnt = 20;
- }
- if (clientOnly) {
- printf("%s %6d %6d %6d %6d %6d %6d %6d %6d",
- ((clientOnly && serverOnly) ? "Client:" : ""),
- DELTA(rpccnt[NFSPROC_GETATTR]),
- DELTA(rpccnt[NFSPROC_LOOKUP]),
- DELTA(rpccnt[NFSPROC_READLINK]),
- DELTA(rpccnt[NFSPROC_READ]),
- DELTA(rpccnt[NFSPROC_WRITE]),
- DELTA(rpccnt[NFSPROC_RENAME]),
- DELTA(rpccnt[NFSPROC_ACCESS]),
- DELTA(rpccnt[NFSPROC_READDIR]) +
- DELTA(rpccnt[NFSPROC_READDIRPLUS])
- );
- if (widemode) {
- printf(" %s %s %s %s %s %s",
- sperc1(DELTA(attrcache_hits),
- DELTA(attrcache_misses)),
- sperc1(DELTA(lookupcache_hits),
- DELTA(lookupcache_misses)),
- sperc2(DELTA(biocache_reads),
- DELTA(read_bios)),
- sperc2(DELTA(biocache_writes),
- DELTA(write_bios)),
- sperc1(DELTA(accesscache_hits),
- DELTA(accesscache_misses)),
- sperc2(DELTA(biocache_readdirs),
- DELTA(readdir_bios))
- );
- }
- printf("\n");
- lastst = nfsstats;
- }
- if (serverOnly) {
- printf("%s %6d %6d %6d %6d %6d %6d %6d %6d",
- ((clientOnly && serverOnly) ? "Server:" : ""),
- nfsrvstats.srvrpccnt[NFSPROC_GETATTR]-lastsrvst.srvrpccnt[NFSPROC_GETATTR],
- nfsrvstats.srvrpccnt[NFSPROC_LOOKUP]-lastsrvst.srvrpccnt[NFSPROC_LOOKUP],
- nfsrvstats.srvrpccnt[NFSPROC_READLINK]-lastsrvst.srvrpccnt[NFSPROC_READLINK],
- nfsrvstats.srvrpccnt[NFSPROC_READ]-lastsrvst.srvrpccnt[NFSPROC_READ],
- nfsrvstats.srvrpccnt[NFSPROC_WRITE]-lastsrvst.srvrpccnt[NFSPROC_WRITE],
- nfsrvstats.srvrpccnt[NFSPROC_RENAME]-lastsrvst.srvrpccnt[NFSPROC_RENAME],
- nfsrvstats.srvrpccnt[NFSPROC_ACCESS]-lastsrvst.srvrpccnt[NFSPROC_ACCESS],
- (nfsrvstats.srvrpccnt[NFSPROC_READDIR]-lastsrvst.srvrpccnt[NFSPROC_READDIR])
- +(nfsrvstats.srvrpccnt[NFSPROC_READDIRPLUS]-lastsrvst.srvrpccnt[NFSPROC_READDIRPLUS]));
- printf("\n");
- lastsrvst = nfsrvstats;
- }
- fflush(stdout);
- sleep(interval);
+ /*
+ * The new client doesn't do write gathering. It was
+ * only useful for NFSv2.
+ */
+ printf("%9d %9d %9d\n",
+ ext_nfsstats.srvrpccnt[NFSV4OP_WRITE],
+ ext_nfsstats.srvrpccnt[NFSV4OP_WRITE], 0);
}
- /*NOTREACHED*/
}
-void
+static void
printhdr(int clientOnly, int serverOnly)
{
printf("%s%6.6s %6.6s %6.6s %6.6s %6.6s %6.6s %6.6s %6.6s",
@@ -661,18 +352,18 @@ printhdr(int clientOnly, int serverOnly)
fflush(stdout);
}
-void
+static void
usage(void)
{
(void)fprintf(stderr,
- "usage: nfsstat [-cemoszW] [-M core] [-N system] [-w wait]\n");
+ "usage: nfsstat [-cemszW] [-M core] [-N system] [-w wait]\n");
exit(1);
}
static char SPBuf[64][8];
static int SPIndex;
-char *
+static char *
sperc1(int hits, int misses)
{
char *p = SPBuf[SPIndex];
@@ -687,7 +378,7 @@ sperc1(int hits, int misses)
return(p);
}
-char *
+static char *
sperc2(int ttl, int misses)
{
char *p = SPBuf[SPIndex];
@@ -705,7 +396,7 @@ sperc2(int ttl, int misses)
/*
* Print a description of the nfs stats for the experimental client/server.
*/
-void
+static void
exp_intpr(int clientOnly, int serverOnly)
{
int nfssvc_flag;
@@ -961,7 +652,7 @@ exp_intpr(int clientOnly, int serverOnly)
* collected over that interval. Assumes that interval is non-zero.
* First line printed at top of screen is always cumulative.
*/
-void
+static void
exp_sidewaysintpr(u_int interval, int clientOnly, int serverOnly)
{
struct ext_nfsstats nfsstats, lastst, *ext_nfsstatsp;
@@ -1035,4 +726,3 @@ exp_sidewaysintpr(u_int interval, int clientOnly, int serverOnly)
}
/*NOTREACHED*/
}
-
diff --git a/usr.bin/perror/perror.1 b/usr.bin/perror/perror.1
index 0b724b14ca65..6fa166429f15 100644
--- a/usr.bin/perror/perror.1
+++ b/usr.bin/perror/perror.1
@@ -1,5 +1,5 @@
.\"
-.\" Copyright (c) 2009 Advanced Computing Technologies LLC
+.\" Copyright (c) 2009 Hudson River Trading LLC
.\" Written by: George V. Neville-Neil <gnn@FreeBSD.org>
.\" All rights reserved.
.\"
diff --git a/usr.bin/perror/perror.c b/usr.bin/perror/perror.c
index ef3db35b64b2..62af5dfbac22 100644
--- a/usr.bin/perror/perror.c
+++ b/usr.bin/perror/perror.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2009 Advanced Computing Technologies LLC
+ * Copyright (c) 2009 Hudson River Trading LLC
* Written by: George V. Neville-Neil <gnn@FreeBSD.org>
* All rights reserved.
*
diff --git a/usr.bin/procstat/procstat_rusage.c b/usr.bin/procstat/procstat_rusage.c
index b3c9d9900cf2..63e5ab830a74 100644
--- a/usr.bin/procstat/procstat_rusage.c
+++ b/usr.bin/procstat/procstat_rusage.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2012 Advanced Computing Technologies LLC
+ * Copyright (c) 2012 Hudson River Trading LLC
* Written by: John H. Baldwin <jhb@FreeBSD.org>
* All rights reserved.
*
diff --git a/usr.bin/protect/protect.1 b/usr.bin/protect/protect.1
index 919714e9a1dc..b9be4afe04b8 100644
--- a/usr.bin/protect/protect.1
+++ b/usr.bin/protect/protect.1
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2013 Advanced Computing Technologies LLC
+.\" Copyright (c) 2013 Hudson River Trading LLC
.\" Written by: John H. Baldwin <jhb@FreeBSD.org>
.\" All rights reserved.
.\"
diff --git a/usr.bin/protect/protect.c b/usr.bin/protect/protect.c
index ba15aa642093..16b0d298f888 100644
--- a/usr.bin/protect/protect.c
+++ b/usr.bin/protect/protect.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2013 Advanced Computing Technologies LLC
+ * Copyright (c) 2013 Hudson River Trading LLC
* Written by: John H. Baldwin <jhb@FreeBSD.org>
* All rights reserved.
*
diff --git a/usr.bin/rctl/rctl.c b/usr.bin/rctl/rctl.c
index 185788d09756..b5342583958d 100644
--- a/usr.bin/rctl/rctl.c
+++ b/usr.bin/rctl/rctl.c
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/rctl.h>
+#include <sys/sysctl.h>
#include <assert.h>
#include <ctype.h>
#include <err.h>
@@ -305,13 +306,37 @@ print_rules(char *rules, int hflag, int nflag)
}
static void
+enosys(void)
+{
+ int error, racct_enable;
+ size_t racct_enable_len;
+
+ racct_enable_len = sizeof(racct_enable);
+ error = sysctlbyname("kern.racct.enable",
+ &racct_enable, &racct_enable_len, NULL, 0);
+
+ if (error != 0) {
+ if (errno == ENOENT)
+ errx(1, "RACCT/RCTL support not present in kernel; see rctl(8) for details");
+
+ err(1, "sysctlbyname");
+ }
+
+ if (racct_enable == 0)
+ errx(1, "RACCT/RCTL present, but disabled; enable using kern.racct.enable=1 tunable");
+}
+
+static void
add_rule(char *rule)
{
int error;
error = rctl_add_rule(rule, strlen(rule) + 1, NULL, 0);
- if (error != 0)
+ if (error != 0) {
+ if (errno == ENOSYS)
+ enosys();
err(1, "rctl_add_rule");
+ }
free(rule);
}
@@ -330,8 +355,11 @@ show_limits(char *filter, int hflag, int nflag)
error = rctl_get_limits(filter, strlen(filter) + 1, outbuf,
outbuflen);
- if (error && errno != ERANGE)
+ if (error && errno != ERANGE) {
+ if (errno == ENOSYS)
+ enosys();
err(1, "rctl_get_limits");
+ }
} while (error && errno == ERANGE);
print_rules(outbuf, hflag, nflag);
@@ -345,8 +373,11 @@ remove_rule(char *filter)
int error;
error = rctl_remove_rule(filter, strlen(filter) + 1, NULL, 0);
- if (error != 0)
+ if (error != 0) {
+ if (errno == ENOSYS)
+ enosys();
err(1, "rctl_remove_rule");
+ }
free(filter);
}
@@ -399,8 +430,11 @@ show_usage(char *filter, int hflag)
error = rctl_get_racct(filter, strlen(filter) + 1, outbuf,
outbuflen);
- if (error && errno != ERANGE)
+ if (error && errno != ERANGE) {
+ if (errno == ENOSYS)
+ enosys();
err(1, "rctl_get_racct");
+ }
} while (error && errno == ERANGE);
while ((tmp = strsep(&outbuf, ",")) != NULL) {
@@ -439,8 +473,11 @@ show_rules(char *filter, int hflag, int nflag)
err(1, "realloc");
error = rctl_get_rules(filter, filterlen, outbuf, outbuflen);
- if (error && errno != ERANGE)
+ if (error && errno != ERANGE) {
+ if (errno == ENOSYS)
+ enosys();
err(1, "rctl_get_rules");
+ }
} while (error && errno == ERANGE);
print_rules(outbuf, hflag, nflag);
diff --git a/usr.bin/whois/whois.c b/usr.bin/whois/whois.c
index 3f6f93a8751f..98b022648695 100644
--- a/usr.bin/whois/whois.c
+++ b/usr.bin/whois/whois.c
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/poll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
@@ -55,6 +56,8 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
#define ABUSEHOST "whois.abuse.net"
#define NICHOST "whois.crsnic.net"
@@ -280,21 +283,136 @@ whois(const char *query, const char *hostname, int flags)
FILE *fp;
struct addrinfo *hostres, *res;
char *buf, *host, *nhost, *p;
- int i, s;
+ int i, j, s = -1, count;
size_t c, len;
+ struct pollfd *fds;
+ int timeout = 180;
- s = -1;
hostres = gethostinfo(hostname, 1);
- for (res = hostres; res; res = res->ai_next) {
- s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ for (res = hostres, count = 0; res; res = res->ai_next)
+ count++;
+
+ fds = calloc(count, sizeof(*fds));
+ if (fds == NULL)
+ err(EX_OSERR, "calloc()");
+
+ /*
+ * Traverse the result list elements and make non-block
+ * connection attempts.
+ */
+ count = i = 0;
+ for (res = hostres; res != NULL; res = res->ai_next) {
+ s = socket(res->ai_family, res->ai_socktype | SOCK_NONBLOCK,
+ res->ai_protocol);
if (s < 0)
continue;
- if (connect(s, res->ai_addr, res->ai_addrlen) == 0)
- break;
- close(s);
+ if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
+ if (errno == EINPROGRESS) {
+ /* Add the socket to poll list */
+ fds[i].fd = s;
+ fds[i].events = POLLERR | POLLHUP |
+ POLLIN | POLLOUT;
+ count++;
+ i++;
+ } else {
+ close(s);
+ s = -1;
+
+ /*
+ * Poll only if we have something to poll,
+ * otherwise just go ahead and try next
+ * address
+ */
+ if (count == 0)
+ continue;
+ }
+ } else
+ goto done;
+
+ /*
+ * If we are at the last address, poll until a connection is
+ * established or we failed all connection attempts.
+ */
+ if (res->ai_next == NULL)
+ timeout = INFTIM;
+
+ /*
+ * Poll the watched descriptors for successful connections:
+ * if we still have more untried resolved addresses, poll only
+ * once; otherwise, poll until all descriptors have errors,
+ * which will be considered as ETIMEDOUT later.
+ */
+ do {
+ int n;
+
+ n = poll(fds, i, timeout);
+ if (n == 0) {
+ /*
+ * No event reported in time. Try with a
+ * smaller timeout (but cap at 2-3ms)
+ * after a new host have been added.
+ */
+ if (timeout >= 3)
+ timeout <<= 1;
+
+ break;
+ } else if (n < 0) {
+ /*
+ * errno here can only be EINTR which we would want
+ * to clean up and bail out.
+ */
+ s = -1;
+ goto done;
+ }
+
+ /*
+ * Check for the event(s) we have seen.
+ */
+ for (j = 0; j < i; j++) {
+ if (fds[j].fd == -1 || fds[j].events == 0 ||
+ fds[j].revents == 0)
+ continue;
+ if (fds[j].revents & ~(POLLIN | POLLOUT)) {
+ close(s);
+ fds[j].fd = -1;
+ fds[j].events = 0;
+ count--;
+ continue;
+ } else if (fds[j].revents & (POLLIN | POLLOUT)) {
+ /* Connect succeeded. */
+ s = fds[j].fd;
+
+ goto done;
+ }
+
+ }
+ } while (timeout == INFTIM && count != 0);
}
+
+ /* All attempts were failed */
+ s = -1;
+ if (count == 0)
+ errno = ETIMEDOUT;
+
+done:
+ /* Close all watched fds except the succeeded one */
+ for (j = 0; j < i; j++)
+ if (fds[j].fd != s && fds[j].fd != -1)
+ close(fds[j].fd);
+
+ if (s != -1) {
+ /* Restore default blocking behavior. */
+ if ((flags = fcntl(s, F_GETFL)) != -1) {
+ flags &= ~O_NONBLOCK;
+ if (fcntl(s, F_SETFL, flags) == -1)
+ err(EX_OSERR, "fcntl()");
+ } else
+ err(EX_OSERR, "fcntl()");
+ }
+
+ free(fds);
freeaddrinfo(hostres);
- if (res == NULL)
+ if (s == -1)
err(EX_OSERR, "connect()");
fp = fdopen(s, "r+");
diff --git a/usr.sbin/bhyve/acpi.c b/usr.sbin/bhyve/acpi.c
index a5a6559b580e..a9dd1cc733c3 100644
--- a/usr.sbin/bhyve/acpi.c
+++ b/usr.sbin/bhyve/acpi.c
@@ -386,7 +386,7 @@ basl_fwrite_fadt(FILE *fp)
EFPRINTF(fp, "[0001]\t\tDuty Cycle Width : 00\n");
EFPRINTF(fp, "[0001]\t\tRTC Day Alarm Index : 00\n");
EFPRINTF(fp, "[0001]\t\tRTC Month Alarm Index : 00\n");
- EFPRINTF(fp, "[0001]\t\tRTC Century Index : 00\n");
+ EFPRINTF(fp, "[0001]\t\tRTC Century Index : 32\n");
EFPRINTF(fp, "[0002]\t\tBoot Flags (decoded below) : 0000\n");
EFPRINTF(fp, "\t\t\tLegacy Devices Supported (V2) : 0\n");
EFPRINTF(fp, "\t\t\t8042 Present on ports 60/64 (V2) : 0\n");
diff --git a/usr.sbin/bhyve/ioapic.c b/usr.sbin/bhyve/ioapic.c
index 2950d9a3c6a4..0ad69d96a4a4 100644
--- a/usr.sbin/bhyve/ioapic.c
+++ b/usr.sbin/bhyve/ioapic.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2014 Advanced Computing Technologies LLC
+ * Copyright (c) 2014 Hudson River Trading LLC
* Written by: John H. Baldwin <jhb@FreeBSD.org>
* All rights reserved.
*
diff --git a/usr.sbin/bhyve/ioapic.h b/usr.sbin/bhyve/ioapic.h
index 3cfca4f4abd7..efdd3c67a4c2 100644
--- a/usr.sbin/bhyve/ioapic.h
+++ b/usr.sbin/bhyve/ioapic.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2014 Advanced Computing Technologies LLC
+ * Copyright (c) 2014 Hudson River Trading LLC
* Written by: John H. Baldwin <jhb@FreeBSD.org>
* All rights reserved.
*
diff --git a/usr.sbin/bhyve/pci_emul.c b/usr.sbin/bhyve/pci_emul.c
index 6b906ede42fc..a08ac4cd0503 100644
--- a/usr.sbin/bhyve/pci_emul.c
+++ b/usr.sbin/bhyve/pci_emul.c
@@ -59,17 +59,6 @@ __FBSDID("$FreeBSD$");
#define CONF1_ENABLE 0x80000000ul
-#define CFGWRITE(pi,off,val,b) \
-do { \
- if ((b) == 1) { \
- pci_set_cfgdata8((pi),(off),(val)); \
- } else if ((b) == 2) { \
- pci_set_cfgdata16((pi),(off),(val)); \
- } else { \
- pci_set_cfgdata32((pi),(off),(val)); \
- } \
-} while (0)
-
#define MAXBUSES (PCI_BUSMAX + 1)
#define MAXSLOTS (PCI_SLOTMAX + 1)
#define MAXFUNCS (PCI_FUNCMAX + 1)
@@ -124,6 +113,30 @@ static void pci_lintr_update(struct pci_devinst *pi);
static void pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot,
int func, int coff, int bytes, uint32_t *val);
+static __inline void
+CFGWRITE(struct pci_devinst *pi, int coff, uint32_t val, int bytes)
+{
+
+ if (bytes == 1)
+ pci_set_cfgdata8(pi, coff, val);
+ else if (bytes == 2)
+ pci_set_cfgdata16(pi, coff, val);
+ else
+ pci_set_cfgdata32(pi, coff, val);
+}
+
+static __inline uint32_t
+CFGREAD(struct pci_devinst *pi, int coff, int bytes)
+{
+
+ if (bytes == 1)
+ return (pci_get_cfgdata8(pi, coff));
+ else if (bytes == 2)
+ return (pci_get_cfgdata16(pi, coff));
+ else
+ return (pci_get_cfgdata32(pi, coff));
+}
+
/*
* I/O access
*/
@@ -1653,27 +1666,31 @@ pci_emul_hdrtype_fixup(int bus, int slot, int off, int bytes, uint32_t *rv)
}
}
-static uint32_t
-bits_changed(uint32_t old, uint32_t new, uint32_t mask)
-{
-
- return ((old ^ new) & mask);
-}
-
static void
-pci_emul_cmdwrite(struct pci_devinst *pi, uint32_t new, int bytes)
+pci_emul_cmdsts_write(struct pci_devinst *pi, int coff, uint32_t new, int bytes)
{
- int i;
- uint16_t old;
+ int i, rshift;
+ uint32_t cmd, cmd2, changed, old, readonly;
+
+ cmd = pci_get_cfgdata16(pi, PCIR_COMMAND); /* stash old value */
/*
- * The command register is at an offset of 4 bytes and thus the
- * guest could write 1, 2 or 4 bytes starting at this offset.
+ * From PCI Local Bus Specification 3.0 sections 6.2.2 and 6.2.3.
+ *
+ * XXX Bits 8, 11, 12, 13, 14 and 15 in the status register are
+ * 'write 1 to clear'. However these bits are not set to '1' by
+ * any device emulation so it is simpler to treat them as readonly.
*/
+ rshift = (coff & 0x3) * 8;
+ readonly = 0xFFFFF880 >> rshift;
+
+ old = CFGREAD(pi, coff, bytes);
+ new &= ~readonly;
+ new |= (old & readonly);
+ CFGWRITE(pi, coff, new, bytes); /* update config */
- old = pci_get_cfgdata16(pi, PCIR_COMMAND); /* stash old value */
- CFGWRITE(pi, PCIR_COMMAND, new, bytes); /* update config */
- new = pci_get_cfgdata16(pi, PCIR_COMMAND); /* get updated value */
+ cmd2 = pci_get_cfgdata16(pi, PCIR_COMMAND); /* get updated value */
+ changed = cmd ^ cmd2;
/*
* If the MMIO or I/O address space decoding has changed then
@@ -1686,7 +1703,7 @@ pci_emul_cmdwrite(struct pci_devinst *pi, uint32_t new, int bytes)
break;
case PCIBAR_IO:
/* I/O address space decoding changed? */
- if (bits_changed(old, new, PCIM_CMD_PORTEN)) {
+ if (changed & PCIM_CMD_PORTEN) {
if (porten(pi))
register_bar(pi, i);
else
@@ -1696,7 +1713,7 @@ pci_emul_cmdwrite(struct pci_devinst *pi, uint32_t new, int bytes)
case PCIBAR_MEM32:
case PCIBAR_MEM64:
/* MMIO address space decoding changed? */
- if (bits_changed(old, new, PCIM_CMD_MEMEN)) {
+ if (changed & PCIM_CMD_MEMEN) {
if (memen(pi))
register_bar(pi, i);
else
@@ -1776,14 +1793,8 @@ pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot, int func,
needcfg = 1;
}
- if (needcfg) {
- if (bytes == 1)
- *eax = pci_get_cfgdata8(pi, coff);
- else if (bytes == 2)
- *eax = pci_get_cfgdata16(pi, coff);
- else
- *eax = pci_get_cfgdata32(pi, coff);
- }
+ if (needcfg)
+ *eax = CFGREAD(pi, coff, bytes);
pci_emul_hdrtype_fixup(bus, slot, coff, bytes, eax);
} else {
@@ -1853,8 +1864,8 @@ pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot, int func,
} else if (pci_emul_iscap(pi, coff)) {
pci_emul_capwrite(pi, coff, bytes, *eax);
- } else if (coff == PCIR_COMMAND) {
- pci_emul_cmdwrite(pi, *eax, bytes);
+ } else if (coff >= PCIR_COMMAND && coff < PCIR_REVID) {
+ pci_emul_cmdsts_write(pi, coff, *eax, bytes);
} else {
CFGWRITE(pi, coff, *eax, bytes);
}
diff --git a/usr.sbin/bhyve/pci_irq.c b/usr.sbin/bhyve/pci_irq.c
index 20e033f2c40e..f22b15cefaaf 100644
--- a/usr.sbin/bhyve/pci_irq.c
+++ b/usr.sbin/bhyve/pci_irq.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2014 Advanced Computing Technologies LLC
+ * Copyright (c) 2014 Hudson River Trading LLC
* Written by: John H. Baldwin <jhb@FreeBSD.org>
* All rights reserved.
*
diff --git a/usr.sbin/bhyve/pci_irq.h b/usr.sbin/bhyve/pci_irq.h
index 9d331a5d6321..24f9c9987510 100644
--- a/usr.sbin/bhyve/pci_irq.h
+++ b/usr.sbin/bhyve/pci_irq.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2014 Advanced Computing Technologies LLC
+ * Copyright (c) 2014 Hudson River Trading LLC
* Written by: John H. Baldwin <jhb@FreeBSD.org>
* All rights reserved.
*
diff --git a/usr.sbin/bhyve/pm.c b/usr.sbin/bhyve/pm.c
index f5a2d438be7f..f7c1c2354561 100644
--- a/usr.sbin/bhyve/pm.c
+++ b/usr.sbin/bhyve/pm.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2013 Advanced Computing Technologies LLC
+ * Copyright (c) 2013 Hudson River Trading LLC
* Written by: John H. Baldwin <jhb@FreeBSD.org>
* All rights reserved.
*
diff --git a/usr.sbin/bluetooth/Makefile b/usr.sbin/bluetooth/Makefile
index 594b4402a9c7..1737107b1c0d 100644
--- a/usr.sbin/bluetooth/Makefile
+++ b/usr.sbin/bluetooth/Makefile
@@ -1,12 +1,10 @@
# $Id: Makefile,v 1.5 2003/09/08 02:28:35 max Exp $
# $FreeBSD$
+.include <src.opts.mk>
+
SUBDIR= \
- ath3kfw \
- bcmfw \
bt3cfw \
- bthidcontrol \
- bthidd \
btpand \
hccontrol \
hcsecd \
@@ -17,5 +15,12 @@ SUBDIR= \
sdpcontrol \
sdpd
+.if ${MK_USB} != "no"
+SUBDIR+= ath3kfw
+SUBDIR+= bcmfw
+SUBDIR+= bthidcontrol
+SUBDIR+= bthidd
+.endif
+
.include <bsd.subdir.mk>
diff --git a/usr.sbin/chown/chgrp.1 b/usr.sbin/chown/chgrp.1
index 8a4c2711edf7..6fb0a31283e1 100644
--- a/usr.sbin/chown/chgrp.1
+++ b/usr.sbin/chown/chgrp.1
@@ -31,7 +31,7 @@
.\" @(#)chgrp.1 8.3 (Berkeley) 3/31/94
.\" $FreeBSD$
.\"
-.Dd February 21, 2010
+.Dd April 20, 2015
.Dt CHGRP 1
.Os
.Sh NAME
@@ -60,8 +60,9 @@ The following options are available:
.It Fl H
If the
.Fl R
-option is specified, symbolic links on the command line are followed.
-(Symbolic links encountered in the tree traversal are not followed.)
+option is specified, symbolic links on the command line are followed
+and hence unaffected by the command.
+(Symbolic links encountered during traversal are not followed.)
.It Fl L
If the
.Fl R
@@ -72,8 +73,12 @@ If the
option is specified, no symbolic links are followed.
This is the default.
.It Fl R
-Change the group ID for the file hierarchies rooted
-in the files instead of just the files themselves.
+Change the group ID of the file hierarchies rooted in the files,
+instead of just the files themselves.
+Beware of unintentionally matching the
+.Dq Pa ".."
+hard link to the parent directory when using wildcards like
+.Dq Li ".*" .
.It Fl f
The force option ignores errors, except for usage errors and does not
query about strange modes (unless the user does not have proper permissions).
diff --git a/usr.sbin/chown/chown.8 b/usr.sbin/chown/chown.8
index b5882a3cc6af..6b827284f9d0 100644
--- a/usr.sbin/chown/chown.8
+++ b/usr.sbin/chown/chown.8
@@ -28,7 +28,7 @@
.\" @(#)chown.8 8.3 (Berkeley) 3/31/94
.\" $FreeBSD$
.\"
-.Dd February 21, 2010
+.Dd April 20, 2015
.Dt CHOWN 8
.Os
.Sh NAME
@@ -64,8 +64,9 @@ The options are as follows:
.It Fl H
If the
.Fl R
-option is specified, symbolic links on the command line are followed.
-(Symbolic links encountered in the tree traversal are not followed.)
+option is specified, symbolic links on the command line are followed
+and hence unaffected by the command.
+(Symbolic links encountered during traversal are not followed.)
.It Fl L
If the
.Fl R
@@ -76,8 +77,8 @@ If the
option is specified, no symbolic links are followed.
This is the default.
.It Fl R
-Change the user ID and/or the group ID of the specified directory trees
-(recursively, including their contents) and files.
+Change the user ID and/or the group ID of the file hierarchies rooted
+in the files, instead of just the files themselves.
Beware of unintentionally matching the
.Dq Pa ".."
hard link to the parent directory when using wildcards like
diff --git a/usr.sbin/chown/chown.c b/usr.sbin/chown/chown.c
index 9780f02f048d..457068a0f7bd 100644
--- a/usr.sbin/chown/chown.c
+++ b/usr.sbin/chown/chown.c
@@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include <err.h>
#include <errno.h>
+#include <fcntl.h>
#include <fts.h>
#include <grp.h>
#include <libgen.h>
@@ -119,18 +120,24 @@ main(int argc, char **argv)
usage();
if (Rflag) {
- fts_options = FTS_PHYSICAL;
if (hflag && (Hflag || Lflag))
errx(1, "the -R%c and -h options may not be "
"specified together", Hflag ? 'H' : 'L');
- if (Hflag)
- fts_options |= FTS_COMFOLLOW;
- else if (Lflag) {
- fts_options &= ~FTS_PHYSICAL;
- fts_options |= FTS_LOGICAL;
+ if (Lflag) {
+ fts_options = FTS_LOGICAL;
+ } else {
+ fts_options = FTS_PHYSICAL;
+
+ if (Hflag) {
+ fts_options |= FTS_COMFOLLOW;
+ }
}
- } else
- fts_options = hflag ? FTS_PHYSICAL : FTS_LOGICAL;
+ } else if (hflag) {
+ fts_options = FTS_PHYSICAL;
+ } else {
+ fts_options = FTS_LOGICAL;
+ }
+
if (xflag)
fts_options |= FTS_XDEV;
@@ -156,6 +163,15 @@ main(int argc, char **argv)
err(1, NULL);
for (rval = 0; (p = fts_read(ftsp)) != NULL;) {
+ int atflag;
+
+ if ((fts_options & FTS_LOGICAL) ||
+ ((fts_options & FTS_COMFOLLOW) &&
+ p->fts_level == FTS_ROOTLEVEL))
+ atflag = 0;
+ else
+ atflag = AT_SYMLINK_NOFOLLOW;
+
switch (p->fts_info) {
case FTS_D: /* Change it at FTS_DP. */
if (!Rflag)
@@ -170,58 +186,44 @@ main(int argc, char **argv)
warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
rval = 1;
continue;
- case FTS_SL:
- case FTS_SLNONE:
- /*
- * The only symlinks that end up here are ones that
- * don't point to anything and ones that we found
- * doing a physical walk.
- */
- if (hflag)
- break;
- else
- continue;
default:
break;
}
if ((uid == (uid_t)-1 || uid == p->fts_statp->st_uid) &&
(gid == (gid_t)-1 || gid == p->fts_statp->st_gid))
continue;
- if ((hflag ? lchown : chown)(p->fts_accpath, uid, gid) == -1) {
- if (!fflag) {
- chownerr(p->fts_path);
- rval = 1;
- }
- } else {
- if (vflag) {
- printf("%s", p->fts_path);
- if (vflag > 1) {
- if (ischown) {
- printf(": %ju:%ju -> %ju:%ju",
- (uintmax_t)
- p->fts_statp->st_uid,
- (uintmax_t)
- p->fts_statp->st_gid,
- (uid == (uid_t)-1) ?
- (uintmax_t)
- p->fts_statp->st_uid :
- (uintmax_t)uid,
- (gid == (gid_t)-1) ?
- (uintmax_t)
- p->fts_statp->st_gid :
- (uintmax_t)gid);
- } else {
- printf(": %ju -> %ju",
- (uintmax_t)
- p->fts_statp->st_gid,
- (gid == (gid_t)-1) ?
- (uintmax_t)
- p->fts_statp->st_gid :
- (uintmax_t)gid);
- }
+ if (fchownat(AT_FDCWD, p->fts_accpath, uid, gid, atflag)
+ == -1 && !fflag) {
+ chownerr(p->fts_path);
+ rval = 1;
+ } else if (vflag) {
+ printf("%s", p->fts_path);
+ if (vflag > 1) {
+ if (ischown) {
+ printf(": %ju:%ju -> %ju:%ju",
+ (uintmax_t)
+ p->fts_statp->st_uid,
+ (uintmax_t)
+ p->fts_statp->st_gid,
+ (uid == (uid_t)-1) ?
+ (uintmax_t)
+ p->fts_statp->st_uid :
+ (uintmax_t)uid,
+ (gid == (gid_t)-1) ?
+ (uintmax_t)
+ p->fts_statp->st_gid :
+ (uintmax_t)gid);
+ } else {
+ printf(": %ju -> %ju",
+ (uintmax_t)
+ p->fts_statp->st_gid,
+ (gid == (gid_t)-1) ?
+ (uintmax_t)
+ p->fts_statp->st_gid :
+ (uintmax_t)gid);
}
- printf("\n");
}
+ printf("\n");
}
}
if (errno)
diff --git a/usr.sbin/crunch/crunchide/exec_elf32.c b/usr.sbin/crunch/crunchide/exec_elf32.c
index ca802d87780e..89080e932e58 100644
--- a/usr.sbin/crunch/crunchide/exec_elf32.c
+++ b/usr.sbin/crunch/crunchide/exec_elf32.c
@@ -178,6 +178,9 @@ ELFNAMEEND(check)(int fd, const char *fn)
switch (xe16toh(eh.e_machine)) {
case EM_386: break;
case EM_ALPHA: break;
+#ifndef EM_AARCH64
+#define EM_AARCH64 183
+#endif
case EM_AARCH64: break;
case EM_ARM: break;
case EM_MIPS: break;
@@ -321,11 +324,14 @@ ELFNAMEEND(hide)(int fd, const char *fn)
*/
/* load section string table for debug use */
- if ((shstrtabp = xmalloc(xewtoh(shstrtabshdr->sh_size), fn,
- "section string table")) == NULL)
+ if ((size = xewtoh(shstrtabshdr->sh_size)) == 0)
+ goto bad;
+ if ((shstrtabp = xmalloc(size, fn, "section string table")) == NULL)
goto bad;
if ((size_t)xreadatoff(fd, shstrtabp, xewtoh(shstrtabshdr->sh_offset),
- xewtoh(shstrtabshdr->sh_size), fn) != xewtoh(shstrtabshdr->sh_size))
+ size, fn) != size)
+ goto bad;
+ if (shstrtabp[size - 1] != '\0')
goto bad;
/* we need symtab, strtab, and everything behind strtab */
@@ -346,7 +352,8 @@ ELFNAMEEND(hide)(int fd, const char *fn)
strtabidx = i;
if (layoutp[i].shdr == symtabshdr || i >= strtabidx) {
off = xewtoh(layoutp[i].shdr->sh_offset);
- size = xewtoh(layoutp[i].shdr->sh_size);
+ if ((size = xewtoh(layoutp[i].shdr->sh_size)) == 0)
+ goto bad;
layoutp[i].bufp = xmalloc(size, fn,
shstrtabp + xewtoh(layoutp[i].shdr->sh_name));
if (layoutp[i].bufp == NULL)
@@ -356,10 +363,13 @@ ELFNAMEEND(hide)(int fd, const char *fn)
goto bad;
/* set symbol table and string table */
- if (layoutp[i].shdr == symtabshdr)
+ if (layoutp[i].shdr == symtabshdr) {
symtabp = layoutp[i].bufp;
- else if (layoutp[i].shdr == strtabshdr)
+ } else if (layoutp[i].shdr == strtabshdr) {
strtabp = layoutp[i].bufp;
+ if (strtabp[size - 1] != '\0')
+ goto bad;
+ }
}
}
diff --git a/usr.sbin/ctld/login.c b/usr.sbin/ctld/login.c
index c7b8b95d25b3..c6b83d947adf 100644
--- a/usr.sbin/ctld/login.c
+++ b/usr.sbin/ctld/login.c
@@ -800,9 +800,6 @@ login(struct connection *conn)
}
conn->conn_initiator_name = checked_strdup(initiator_name);
log_set_peer_name(conn->conn_initiator_name);
- /*
- * XXX: This doesn't work (does nothing) because of Capsicum.
- */
setproctitle("%s (%s)", conn->conn_initiator_addr, conn->conn_initiator_name);
redirected = login_portal_redirect(conn, request);
diff --git a/usr.sbin/etcupdate/etcupdate.8 b/usr.sbin/etcupdate/etcupdate.8
index 1966179330d7..c5a74f36e32a 100644
--- a/usr.sbin/etcupdate/etcupdate.8
+++ b/usr.sbin/etcupdate/etcupdate.8
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2010-2013 Advanced Computing Technologies LLC
+.\" Copyright (c) 2010-2013 Hudson River Trading LLC
.\" Written by: John H. Baldwin <jhb@FreeBSD.org>
.\" All rights reserved.
.\"
diff --git a/usr.sbin/etcupdate/etcupdate.sh b/usr.sbin/etcupdate/etcupdate.sh
index a4728fa59b2e..6be57b6be630 100755
--- a/usr.sbin/etcupdate/etcupdate.sh
+++ b/usr.sbin/etcupdate/etcupdate.sh
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright (c) 2010-2013 Advanced Computing Technologies LLC
+# Copyright (c) 2010-2013 Hudson River Trading LLC
# Written by: John H. Baldwin <jhb@FreeBSD.org>
# All rights reserved.
#
diff --git a/usr.sbin/etcupdate/tests/always_test.sh b/usr.sbin/etcupdate/tests/always_test.sh
index 514481e85b0f..2055bb6347a1 100644
--- a/usr.sbin/etcupdate/tests/always_test.sh
+++ b/usr.sbin/etcupdate/tests/always_test.sh
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright (c) 2010 Advanced Computing Technologies LLC
+# Copyright (c) 2010 Hudson River Trading LLC
# Written by: John H. Baldwin <jhb@FreeBSD.org>
# All rights reserved.
#
diff --git a/usr.sbin/etcupdate/tests/conflicts_test.sh b/usr.sbin/etcupdate/tests/conflicts_test.sh
index 816c18021d27..71f16fabf35b 100644
--- a/usr.sbin/etcupdate/tests/conflicts_test.sh
+++ b/usr.sbin/etcupdate/tests/conflicts_test.sh
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright (c) 2010 Advanced Computing Technologies LLC
+# Copyright (c) 2010 Hudson River Trading LLC
# Written by: John H. Baldwin <jhb@FreeBSD.org>
# All rights reserved.
#
diff --git a/usr.sbin/etcupdate/tests/fbsdid_test.sh b/usr.sbin/etcupdate/tests/fbsdid_test.sh
index c062c0680bb6..d8d5cce993c6 100644
--- a/usr.sbin/etcupdate/tests/fbsdid_test.sh
+++ b/usr.sbin/etcupdate/tests/fbsdid_test.sh
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright (c) 2010 Advanced Computing Technologies LLC
+# Copyright (c) 2010 Hudson River Trading LLC
# Written by: John H. Baldwin <jhb@FreeBSD.org>
# All rights reserved.
#
diff --git a/usr.sbin/etcupdate/tests/ignore_test.sh b/usr.sbin/etcupdate/tests/ignore_test.sh
index 2d3d2f5f7687..571dd247150c 100644
--- a/usr.sbin/etcupdate/tests/ignore_test.sh
+++ b/usr.sbin/etcupdate/tests/ignore_test.sh
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright (c) 2010 Advanced Computing Technologies LLC
+# Copyright (c) 2010 Hudson River Trading LLC
# Written by: John H. Baldwin <jhb@FreeBSD.org>
# All rights reserved.
#
diff --git a/usr.sbin/etcupdate/tests/preworld_test.sh b/usr.sbin/etcupdate/tests/preworld_test.sh
index c73129339ca9..b7241542784f 100644
--- a/usr.sbin/etcupdate/tests/preworld_test.sh
+++ b/usr.sbin/etcupdate/tests/preworld_test.sh
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright (c) 2013 Advanced Computing Technologies LLC
+# Copyright (c) 2013 Hudson River Trading LLC
# Written by: John H. Baldwin <jhb@FreeBSD.org>
# All rights reserved.
#
diff --git a/usr.sbin/etcupdate/tests/tests_test.sh b/usr.sbin/etcupdate/tests/tests_test.sh
index b99bbefbc81f..5382de30da00 100644
--- a/usr.sbin/etcupdate/tests/tests_test.sh
+++ b/usr.sbin/etcupdate/tests/tests_test.sh
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright (c) 2010 Advanced Computing Technologies LLC
+# Copyright (c) 2010 Hudson River Trading LLC
# Written by: John H. Baldwin <jhb@FreeBSD.org>
# All rights reserved.
#
diff --git a/usr.sbin/etcupdate/tests/tzsetup_test.sh b/usr.sbin/etcupdate/tests/tzsetup_test.sh
index b10293890c7c..dbdcc0ed5980 100644
--- a/usr.sbin/etcupdate/tests/tzsetup_test.sh
+++ b/usr.sbin/etcupdate/tests/tzsetup_test.sh
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright (c) 2013 Advanced Computing Technologies LLC
+# Copyright (c) 2013 Hudson River Trading LLC
# Written by: John H. Baldwin <jhb@FreeBSD.org>
# All rights reserved.
#
diff --git a/usr.sbin/iovctl/iovctl.conf.5 b/usr.sbin/iovctl/iovctl.conf.5
index b46a40931cfc..f7a605265268 100644
--- a/usr.sbin/iovctl/iovctl.conf.5
+++ b/usr.sbin/iovctl/iovctl.conf.5
@@ -144,7 +144,7 @@ passthrough devices through the use of the default section.
VF-0 is not configured as a passthrough device as it explicitly overrides the
default.
VF-0 also sets a device-specific parameter named mac-addr.
-.Bd -literal .offset ident
+.Bd -literal -offset ident
PF {
device : "ix0";
num_vfs : 3;
@@ -160,8 +160,8 @@ VF-0 {
}
.Ed
.Sh SEE ALSO
-.Xr iovctl 8 ,
-.Xr rc.conf 5
+.Xr rc.conf 5 ,
+.Xr iovctl 8
.Sh AUTHORS
This manual page was written by
.An Ryan Stone Aq Mt rstone@FreeBSD.org .
diff --git a/usr.sbin/jail/jail.8 b/usr.sbin/jail/jail.8
index 8952ae32fb47..189fa36a59d1 100644
--- a/usr.sbin/jail/jail.8
+++ b/usr.sbin/jail/jail.8
@@ -1221,7 +1221,6 @@ environment of the first jail.
.Xr jls 8 ,
.Xr mount 8 ,
.Xr named 8 ,
-.Xr procfs 5 ,
.Xr reboot 8 ,
.Xr rpcbind 8 ,
.Xr sendmail 8 ,
diff --git a/usr.sbin/mountd/mountd.8 b/usr.sbin/mountd/mountd.8
index fe73743304f8..4dbf5ff2328e 100644
--- a/usr.sbin/mountd/mountd.8
+++ b/usr.sbin/mountd/mountd.8
@@ -38,7 +38,7 @@
mount requests
.Sh SYNOPSIS
.Nm
-.Op Fl 2delnorS
+.Op Fl 2delnrS
.Op Fl h Ar bindip
.Op Fl p Ar port
.Op Ar exportsfile ...
@@ -69,8 +69,7 @@ Output debugging information.
will not detach from the controlling terminal and will print
debugging messages to stderr.
.It Fl e
-The new NFS server that includes NFSv4 support is now the default, so this
-option is now a no-op and should be considered deprecated.
+Ignored; included for backward compatibility.
.It Fl h Ar bindip
Specify specific IP addresses to bind to for TCP and UDP requests.
This option may be specified multiple times.
@@ -98,9 +97,6 @@ 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
controls if the kernel will accept NFS requests from reserved ports only.
-.It Fl o
-This flag forces the system to run the old NFS server, which does not
-have NFSv4 support in it.
.It Fl p Ar port
Force
.Nm
diff --git a/usr.sbin/mountd/mountd.c b/usr.sbin/mountd/mountd.c
index d71f1d9e09be..3508f5047cd0 100644
--- a/usr.sbin/mountd/mountd.c
+++ b/usr.sbin/mountd/mountd.c
@@ -253,7 +253,6 @@ static int have_v6 = 1;
int v4root_phase = 0;
char v4root_dirpath[PATH_MAX + 1];
-int run_v4server = 1;
int has_publicfh = 0;
struct pidfh *pfh = NULL;
@@ -312,7 +311,7 @@ main(int argc, char **argv)
else
close(s);
- while ((c = getopt(argc, argv, "2deh:lnop:rS")) != -1)
+ while ((c = getopt(argc, argv, "2deh:lnp:rS")) != -1)
switch (c) {
case '2':
force_v2 = 1;
@@ -332,9 +331,6 @@ main(int argc, char **argv)
case 'l':
dolog = 1;
break;
- case 'o':
- run_v4server = 0;
- break;
case 'p':
endptr = NULL;
svcport = (in_port_t)strtoul(optarg, &endptr, 10);
@@ -371,19 +367,9 @@ main(int argc, char **argv)
usage();
};
- /*
- * Unless the "-o" option was specified, try and run "nfsd".
- * If "-o" was specified, try and run "nfsserver".
- */
- if (run_v4server > 0) {
- if (modfind("nfsd") < 0) {
- /* Not present in kernel, try loading it */
- if (kldload("nfsd") < 0 || modfind("nfsd") < 0)
- errx(1, "NFS server is not available");
- }
- } else if (modfind("nfsserver") < 0) {
+ if (modfind("nfsd") < 0) {
/* Not present in kernel, try loading it */
- if (kldload("nfsserver") < 0 || modfind("nfsserver") < 0)
+ if (kldload("nfsd") < 0 || modfind("nfsd") < 0)
errx(1, "NFS server is not available");
}
@@ -1697,8 +1683,7 @@ get_exportlist(void)
*/
bzero(&eargs, sizeof (eargs));
eargs.export.ex_flags = MNT_DELEXPORT;
- if (run_v4server > 0 &&
- nfssvc(NFSSVC_V4ROOTEXPORT, (caddr_t)&eargs) < 0 &&
+ if (nfssvc(NFSSVC_V4ROOTEXPORT, (caddr_t)&eargs) < 0 &&
errno != ENOENT)
syslog(LOG_ERR, "Can't delete exports for V4:");
@@ -1803,7 +1788,7 @@ get_exportlist(void)
/*
* If there was no public fh, clear any previous one set.
*/
- if (run_v4server > 0 && has_publicfh == 0)
+ if (has_publicfh == 0)
(void) nfssvc(NFSSVC_NOPUBLICFH, NULL);
/* Resume the nfsd. If they weren't suspended, this is harmless. */
@@ -2400,7 +2385,7 @@ do_mount(struct exportlist *ep, struct grouplist *grp, int exflags,
{
struct statfs fsb1;
struct addrinfo *ai;
- struct export_args ea, *eap;
+ struct export_args *eap;
char errmsg[255];
char *cp;
int done;
@@ -2410,10 +2395,7 @@ do_mount(struct exportlist *ep, struct grouplist *grp, int exflags,
int ret;
struct nfsex_args nfsea;
- if (run_v4server > 0)
- eap = &nfsea.export;
- else
- eap = &ea;
+ eap = &nfsea.export;
cp = NULL;
savedc = '\0';
@@ -2493,8 +2475,7 @@ do_mount(struct exportlist *ep, struct grouplist *grp, int exflags,
*/
if (v4root_phase == 2) {
nfsea.fspec = v4root_dirpath;
- if (run_v4server > 0 &&
- nfssvc(NFSSVC_V4ROOTEXPORT, (caddr_t)&nfsea) < 0) {
+ if (nfssvc(NFSSVC_V4ROOTEXPORT, (caddr_t)&nfsea) < 0) {
syslog(LOG_ERR, "Exporting V4: failed");
return (2);
}
@@ -2583,7 +2564,7 @@ do_mount(struct exportlist *ep, struct grouplist *grp, int exflags,
* If this is the public directory, get the file handle
* and load it into the kernel via the nfssvc() syscall.
*/
- if (run_v4server > 0 && (exflags & MNT_EXPUBLIC) != 0) {
+ if ((exflags & MNT_EXPUBLIC) != 0) {
fhandle_t fh;
char *public_name;
diff --git a/usr.sbin/nfsd/nfsd.8 b/usr.sbin/nfsd/nfsd.8
index 9f2c6d406e50..d014a019eee5 100644
--- a/usr.sbin/nfsd/nfsd.8
+++ b/usr.sbin/nfsd/nfsd.8
@@ -28,7 +28,7 @@
.\" @(#)nfsd.8 8.4 (Berkeley) 3/29/95
.\" $FreeBSD$
.\"
-.Dd January 1, 2015
+.Dd April 25, 2015
.Dt NFSD 8
.Os
.Sh NAME
@@ -38,7 +38,7 @@
server
.Sh SYNOPSIS
.Nm
-.Op Fl arduteo
+.Op Fl ardute
.Op Fl n Ar num_servers
.Op Fl h Ar bindip
.Op Fl Fl maxthreads Ar max_threads
@@ -112,10 +112,7 @@ Serve
.Tn UDP NFS
clients.
.It Fl e
-Enable NFSv4 support.
-It is enabled by default; this option should be considered deprecated.
-.It Fl o
-Disable NFSv4 support.
+Ignored; included for backward compatibility.
.El
.Pp
For example,
diff --git a/usr.sbin/nfsd/nfsd.c b/usr.sbin/nfsd/nfsd.c
index a0cb5a35677a..f58ed30023ae 100644
--- a/usr.sbin/nfsd/nfsd.c
+++ b/usr.sbin/nfsd/nfsd.c
@@ -87,8 +87,6 @@ static int nfsdcnt; /* number of children */
static int nfsdcnt_set;
static int minthreads;
static int maxthreads;
-static int new_syscall;
-static int run_v4server = 1; /* Force running of nfsv4 server */
static int nfssvc_nfsd; /* Set to correct NFSSVC_xxx flag */
static int stablefd = -1; /* Fd for the stable restart file */
static int backupfd; /* Fd for the backup stable restart file */
@@ -156,7 +154,7 @@ main(int argc, char **argv)
socklen_t len;
int on = 1, unregister, reregister, sock;
int tcp6sock, ip6flag, tcpflag, tcpsock;
- int udpflag, ecode, error, s, srvcnt;
+ int udpflag, ecode, error, s;
int bindhostc, bindanyflag, rpcbreg, rpcbregcnt;
int nfssvc_addsock;
int longindex = 0;
@@ -167,10 +165,10 @@ main(int argc, char **argv)
nfsdcnt = DEFNFSDCNT;
unregister = reregister = tcpflag = maxsock = 0;
bindanyflag = udpflag = connect_type_cnt = bindhostc = 0;
- getopt_shortopts = "ah:n:rdtueo";
+ getopt_shortopts = "ah:n:rdtue";
getopt_usage =
"usage:\n"
- " nfsd [-ardtueo] [-h bindip]\n"
+ " nfsd [-ardtue] [-h bindip]\n"
" [-n numservers] [--minthreads #] [--maxthreads #]\n";
while ((ch = getopt_long(argc, argv, getopt_shortopts, longopts,
&longindex)) != -1)
@@ -205,9 +203,6 @@ main(int argc, char **argv)
case 'e':
/* now a no-op, since this is the default */
break;
- case 'o':
- run_v4server = 0;
- break;
case 0:
lopt = longopts[longindex].name;
if (!strcmp(lopt, "minthreads")) {
@@ -242,15 +237,9 @@ main(int argc, char **argv)
* Unless the "-o" option was specified, try and run "nfsd".
* If "-o" was specified, try and run "nfsserver".
*/
- if (run_v4server > 0) {
- if (modfind("nfsd") < 0) {
- /* Not present in kernel, try loading it */
- if (kldload("nfsd") < 0 || modfind("nfsd") < 0)
- errx(1, "NFS server is not available");
- }
- } else if (modfind("nfsserver") < 0) {
+ if (modfind("nfsd") < 0) {
/* Not present in kernel, try loading it */
- if (kldload("nfsserver") < 0 || modfind("nfsserver") < 0)
+ if (kldload("nfsd") < 0 || modfind("nfsd") < 0)
errx(1, "NFS server is not available");
}
@@ -392,55 +381,21 @@ main(int argc, char **argv)
* level write-back caching. (See SCSI doc for more information
* on how to prevent write-back caching on SCSI disks.)
*/
- if (run_v4server > 0) {
- open_stable(&stablefd, &backupfd);
- if (stablefd < 0) {
- syslog(LOG_ERR, "Can't open %s: %m\n", NFSD_STABLERESTART);
- exit(1);
- }
- /* This system call will fail for old kernels, but that's ok. */
- nfssvc(NFSSVC_BACKUPSTABLE, NULL);
- if (nfssvc(NFSSVC_STABLERESTART, (caddr_t)&stablefd) < 0) {
- syslog(LOG_ERR, "Can't read stable storage file: %m\n");
- exit(1);
- }
- nfssvc_addsock = NFSSVC_NFSDADDSOCK;
- nfssvc_nfsd = NFSSVC_NFSDNFSD;
- new_syscall = TRUE;
- } else {
- nfssvc_addsock = NFSSVC_ADDSOCK;
- nfssvc_nfsd = NFSSVC_NFSD;
- /*
- * Figure out if the kernel supports the new-style
- * NFSSVC_NFSD. Old kernels will return ENXIO because they
- * don't recognise the flag value, new ones will return EINVAL
- * because argp is NULL.
- */
- new_syscall = FALSE;
- if (nfssvc(NFSSVC_NFSD, NULL) < 0 && errno == EINVAL)
- new_syscall = TRUE;
+ open_stable(&stablefd, &backupfd);
+ if (stablefd < 0) {
+ syslog(LOG_ERR, "Can't open %s: %m\n", NFSD_STABLERESTART);
+ exit(1);
}
+ /* This system call will fail for old kernels, but that's ok. */
+ nfssvc(NFSSVC_BACKUPSTABLE, NULL);
+ if (nfssvc(NFSSVC_STABLERESTART, (caddr_t)&stablefd) < 0) {
+ syslog(LOG_ERR, "Can't read stable storage file: %m\n");
+ exit(1);
+ }
+ nfssvc_addsock = NFSSVC_NFSDADDSOCK;
+ nfssvc_nfsd = NFSSVC_NFSDNFSD;
- if (!new_syscall) {
- /* If we use UDP only, we start the last server below. */
- srvcnt = tcpflag ? nfsdcnt : nfsdcnt - 1;
- for (i = 0; i < srvcnt; i++) {
- switch ((pid = fork())) {
- case -1:
- syslog(LOG_ERR, "fork: %m");
- nfsd_exit(1);
- case 0:
- break;
- default:
- children[i] = pid;
- continue;
- }
- (void)signal(SIGUSR1, child_cleanup);
- setproctitle("server");
-
- start_server(0);
- }
- } else if (tcpflag) {
+ if (tcpflag) {
/*
* For TCP mode, we fork once to start the first
* kernel nfsd thread. The kernel will add more
@@ -976,11 +931,6 @@ get_tuned_nfsdcount(void)
} else {
tuned_nfsdcnt = ncpu * 8;
}
- if (!new_syscall && tuned_nfsdcnt > MAXNFSDCNT) {
- warnx("nfsd count %d; truncated to %d", tuned_nfsdcnt,
- MAXNFSDCNT);
- tuned_nfsdcnt = MAXNFSDCNT;
- }
return tuned_nfsdcnt;
}
@@ -994,55 +944,48 @@ start_server(int master)
struct addrinfo *aip, hints;
status = 0;
- if (new_syscall) {
- gethostname(hostname, sizeof (hostname));
- snprintf(principal, sizeof (principal), "nfs@%s", hostname);
- if ((cp = strchr(hostname, '.')) == NULL ||
- *(cp + 1) == '\0') {
- /* If not fully qualified, try getaddrinfo() */
- memset((void *)&hints, 0, sizeof (hints));
- hints.ai_flags = AI_CANONNAME;
- error = getaddrinfo(hostname, NULL, &hints, &aip);
- if (error == 0) {
- if (aip->ai_canonname != NULL &&
- (cp = strchr(aip->ai_canonname, '.')) !=
- NULL && *(cp + 1) != '\0')
- snprintf(principal, sizeof (principal),
- "nfs@%s", aip->ai_canonname);
- freeaddrinfo(aip);
- }
+ gethostname(hostname, sizeof (hostname));
+ snprintf(principal, sizeof (principal), "nfs@%s", hostname);
+ if ((cp = strchr(hostname, '.')) == NULL ||
+ *(cp + 1) == '\0') {
+ /* If not fully qualified, try getaddrinfo() */
+ memset((void *)&hints, 0, sizeof (hints));
+ hints.ai_flags = AI_CANONNAME;
+ error = getaddrinfo(hostname, NULL, &hints, &aip);
+ if (error == 0) {
+ if (aip->ai_canonname != NULL &&
+ (cp = strchr(aip->ai_canonname, '.')) !=
+ NULL && *(cp + 1) != '\0')
+ snprintf(principal, sizeof (principal),
+ "nfs@%s", aip->ai_canonname);
+ freeaddrinfo(aip);
}
- nfsdargs.principal = principal;
+ }
+ nfsdargs.principal = principal;
- if (nfsdcnt_set)
- nfsdargs.minthreads = nfsdargs.maxthreads = nfsdcnt;
- else {
- nfsdargs.minthreads = minthreads_set ? minthreads : get_tuned_nfsdcount();
- nfsdargs.maxthreads = maxthreads_set ? maxthreads : nfsdargs.minthreads;
- if (nfsdargs.maxthreads < nfsdargs.minthreads)
- nfsdargs.maxthreads = nfsdargs.minthreads;
- }
+ if (nfsdcnt_set)
+ nfsdargs.minthreads = nfsdargs.maxthreads = nfsdcnt;
+ else {
+ nfsdargs.minthreads = minthreads_set ? minthreads : get_tuned_nfsdcount();
+ nfsdargs.maxthreads = maxthreads_set ? maxthreads : nfsdargs.minthreads;
+ if (nfsdargs.maxthreads < nfsdargs.minthreads)
+ nfsdargs.maxthreads = nfsdargs.minthreads;
+ }
+ error = nfssvc(nfssvc_nfsd, &nfsdargs);
+ if (error < 0 && errno == EAUTH) {
+ /*
+ * This indicates that it could not register the
+ * rpcsec_gss credentials, usually because the
+ * gssd daemon isn't running.
+ * (only the experimental server with nfsv4)
+ */
+ syslog(LOG_ERR, "No gssd, using AUTH_SYS only");
+ principal[0] = '\0';
error = nfssvc(nfssvc_nfsd, &nfsdargs);
- if (error < 0 && errno == EAUTH) {
- /*
- * This indicates that it could not register the
- * rpcsec_gss credentials, usually because the
- * gssd daemon isn't running.
- * (only the experimental server with nfsv4)
- */
- syslog(LOG_ERR, "No gssd, using AUTH_SYS only");
- principal[0] = '\0';
- error = nfssvc(nfssvc_nfsd, &nfsdargs);
- }
- if (error < 0) {
- syslog(LOG_ERR, "nfssvc: %m");
- status = 1;
- }
- } else {
- if (nfssvc(NFSSVC_OLDNFSD, NULL) < 0) {
- syslog(LOG_ERR, "nfssvc: %m");
- status = 1;
- }
+ }
+ if (error < 0) {
+ syslog(LOG_ERR, "nfssvc: %m");
+ status = 1;
}
if (master)
nfsd_exit(status);
diff --git a/usr.sbin/ntp/doc/ntptime.8 b/usr.sbin/ntp/doc/ntptime.8
index f130307457f3..bb3b41aeea26 100644
--- a/usr.sbin/ntp/doc/ntptime.8
+++ b/usr.sbin/ntp/doc/ntptime.8
@@ -1,7 +1,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 7, 2000
+.Dd April 27, 2015
.Dt NTPTIME 8
.Os
.Sh NAME
@@ -52,8 +52,6 @@ Specify estimated error, in microseconds.
Specify frequency offset, in parts per million.
.It Fl h
Display help information.
-.It Fl l
-Specify the leap bits as a code from 0 to 3.
.It Fl m Ar max_error
Specify max possible errors, in microseconds.
.It Fl o Ar offset
diff --git a/usr.sbin/pciconf/err.c b/usr.sbin/pciconf/err.c
index b67d1f55e81b..7a77903c3504 100644
--- a/usr.sbin/pciconf/err.c
+++ b/usr.sbin/pciconf/err.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2012 Advanced Computing Technologies LLC
+ * Copyright (c) 2012 Hudson River Trading LLC
* Written by: John H. Baldwin <jhb@FreeBSD.org>
* All rights reserved.
*
diff --git a/usr.sbin/smbmsg/smbmsg.c b/usr.sbin/smbmsg/smbmsg.c
index 425b782d2d33..4e7e609a7b07 100644
--- a/usr.sbin/smbmsg/smbmsg.c
+++ b/usr.sbin/smbmsg/smbmsg.c
@@ -163,7 +163,8 @@ do_io(void)
}
if (iflag == 1 && oflag == -1) {
/* command + 1 byte input: read byte op. */
- c.data.byte_ptr = ibuf;
+ c.rbuf = ibuf;
+ c.rcount = iflag;
if (ioctl(fd, SMB_READB, &c) == -1)
return (-1);
printf(fmt, (int)(unsigned char)ibuf[0]);
@@ -171,11 +172,12 @@ do_io(void)
return (0);
} else if (iflag == -1 && oflag == 1) {
/* command + 1 byte output: write byte op. */
- c.data.byte = obuf[0];
+ c.wdata.byte = obuf[0];
return (ioctl(fd, SMB_WRITEB, &c));
} else if (wflag && iflag == 2 && oflag == -1) {
/* command + 2 bytes input: read word op. */
- c.data.word_ptr = &iword;
+ c.rbuf = (char*) &iword;
+ c.rcount = iflag;
if (ioctl(fd, SMB_READW, &c) == -1)
return (-1);
printf(fmt, (int)(unsigned short)iword);
@@ -183,15 +185,16 @@ do_io(void)
return (0);
} else if (wflag && iflag == -1 && oflag == 2) {
/* command + 2 bytes output: write word op. */
- c.data.word = oword;
+ c.wdata.word = oword;
return (ioctl(fd, SMB_WRITEW, &c));
} else if (wflag && iflag == 2 && oflag == 2) {
/*
* command + 2 bytes output + 2 bytes input:
* "process call" op.
*/
- c.data.process.sdata = oword;
- c.data.process.rdata = &iword;
+ c.wdata.word = oword;
+ c.rbuf = (char*) &iword;
+ c.rcount = iflag;
if (ioctl(fd, SMB_PCALL, &c) == -1)
return (-1);
printf(fmt, (int)(unsigned short)iword);
@@ -199,8 +202,8 @@ do_io(void)
return (0);
} else if (iflag > 1 && oflag == -1) {
/* command + > 1 bytes of input: block read */
- c.data.byte_ptr = ibuf;
- c.count = iflag;
+ c.rbuf = ibuf;
+ c.rcount = iflag;
if (ioctl(fd, SMB_BREAD, &c) == -1)
return (-1);
for (i = 0; i < iflag; i++) {
@@ -212,8 +215,8 @@ do_io(void)
return (0);
} else if (iflag == -1 && oflag > 1) {
/* command + > 1 bytes of output: block write */
- c.data.byte_ptr = obuf;
- c.count = oflag;
+ c.wbuf = obuf;
+ c.wcount = oflag;
return (ioctl(fd, SMB_BWRITE, &c));
}