Index: projects/runtime-coverage/Makefile =================================================================== --- projects/runtime-coverage/Makefile (revision 321457) +++ projects/runtime-coverage/Makefile (revision 321458) @@ -1,596 +1,606 @@ # # $FreeBSD$ # # The user-driven targets are: # # universe - *Really* build *everything* (buildworld and # all kernels on all architectures). # tinderbox - Same as universe, but presents a list of failed build # targets and exits with an error if there were any. # buildworld - Rebuild *everything*, including glue to help do # upgrades. # installworld - Install everything built by "buildworld". # world - buildworld + installworld, no kernel. # buildkernel - Rebuild the kernel and the kernel-modules. # installkernel - Install the kernel and the kernel-modules. # installkernel.debug # reinstallkernel - Reinstall the kernel and the kernel-modules. # reinstallkernel.debug # kernel - buildkernel + installkernel. # kernel-toolchain - Builds the subset of world necessary to build a kernel # kernel-toolchains - Build kernel-toolchain for all universe targets. # doxygen - Build API documentation of the kernel, needs doxygen. # update - Convenient way to update your source tree(s). # checkworld - Run test suite on installed world. # check-old - List obsolete directories/files/libraries. # check-old-dirs - List obsolete directories. # check-old-files - List obsolete files. # check-old-libs - List obsolete libraries. # delete-old - Delete obsolete directories/files. # delete-old-dirs - Delete obsolete directories. # delete-old-files - Delete obsolete files. # delete-old-libs - Delete obsolete libraries. # targets - Print a list of supported TARGET/TARGET_ARCH pairs # for world and kernel targets. # toolchains - Build a toolchain for all world and kernel targets. # xdev - xdev-build + xdev-install for the architecture # specified with XDEV and XDEV_ARCH. # xdev-build - Build cross-development tools. # xdev-install - Install cross-development tools. # xdev-links - Create traditional links in /usr/bin for cc, etc # native-xtools - Create host binaries that produce target objects # for use in qemu user-mode jails. # # "quick" way to test all kernel builds: # _jflag=`sysctl -n hw.ncpu` # _jflag=$(($_jflag * 2)) # [ $_jflag -gt 12 ] && _jflag=12 # make universe -DMAKE_JUST_KERNELS JFLAG=-j${_jflag} # # This makefile is simple by design. The FreeBSD make automatically reads # the /usr/share/mk/sys.mk unless the -m argument is specified on the # command line. By keeping this makefile simple, it doesn't matter too # much how different the installed mk files are from those in the source # tree. This makefile executes a child make process, forcing it to use # the mk files from the source tree which are supposed to DTRT. # # Most of the user-driven targets (as listed above) are implemented in # Makefile.inc1. The exceptions are universe, tinderbox and targets. # # If you want to build your system from source be sure that /usr/obj has # at least 6GB of diskspace available. A complete 'universe' build requires # about 100GB of space. # # For individuals wanting to build from the sources currently on their # system, the simple instructions are: # # 1. `cd /usr/src' (or to the directory containing your source tree). # 2. Define `HISTORICAL_MAKE_WORLD' variable (see README). # 3. `make world' # # For individuals wanting to upgrade their sources (even if only a # delta of a few days): # # 1. `cd /usr/src' (or to the directory containing your source tree). # 2. `make buildworld' # 3. `make buildkernel KERNCONF=YOUR_KERNEL_HERE' (default is GENERIC). # 4. `make installkernel KERNCONF=YOUR_KERNEL_HERE' (default is GENERIC). # [steps 3. & 4. can be combined by using the "kernel" target] # 5. `reboot' (in single user mode: boot -s from the loader prompt). # 6. `mergemaster -p' # 7. `make installworld' # 8. `mergemaster' (you may wish to use -i, along with -U or -F). # 9. `make delete-old' # 10. `reboot' # 11. `make delete-old-libs' (in case no 3rd party program uses them anymore) # # See src/UPDATING `COMMON ITEMS' for more complete information. # # If TARGET=machine (e.g. powerpc, sparc64, ...) is specified you can # cross build world for other machine types using the buildworld target, # and once the world is built you can cross build a kernel using the # buildkernel target. # # Define the user-driven targets. These are listed here in alphabetical # order, but that's not important. # # Targets that begin with underscore are internal targets intended for # developer convenience only. They are intentionally not documented and # completely subject to change without notice. # # For more information, see the build(7) manual page. # # This is included so CC is set to ccache for -V, and COMPILER_TYPE/VERSION # can be cached for sub-makes. .if ${MAKE_VERSION} >= 20140620 && defined(.PARSEDIR) .include .endif # Note: we use this awkward construct to be compatible with FreeBSD's # old make used in 10.0 and 9.2 and earlier. .if defined(MK_DIRDEPS_BUILD) && ${MK_DIRDEPS_BUILD} == "yes" && \ !make(showconfig) && !make(print-dir) # targets/Makefile plays the role of top-level .include "targets/Makefile" .else TGTS= all all-man buildenv buildenvvars buildkernel buildworld \ check check-old check-old-dirs check-old-files check-old-libs \ checkdpadd checkworld clean cleandepend cleandir cleanworld \ delete-old delete-old-dirs delete-old-files delete-old-libs \ depend distribute distributekernel distributekernel.debug \ distributeworld distrib-dirs distribution doxygen \ everything hier hierarchy install installcheck installkernel \ installkernel.debug packagekernel packageworld \ reinstallkernel reinstallkernel.debug \ installworld kernel-toolchain libraries lint maninstall \ obj objlink rerelease showconfig tags toolchain update \ _worldtmp _legacy _bootstrap-tools _cleanobj _obj \ _build-tools _build-metadata _cross-tools _includes _libraries \ build32 distribute32 install32 buildsoft distributesoft installsoft \ builddtb xdev xdev-build xdev-install \ xdev-links native-xtools stageworld stagekernel stage-packages \ create-packages-world create-packages-kernel create-packages \ packages installconfig real-packages sign-packages package-pkg \ print-dir test-system-compiler # XXX: r156740: This can't work since bsd.subdir.mk is not included ever. # It will only work for SUBDIR_TARGETS in make.conf. TGTS+= ${SUBDIR_TARGETS} BITGTS= files includes BITGTS:=${BITGTS} ${BITGTS:S/^/build/} ${BITGTS:S/^/install/} TGTS+= ${BITGTS} # Only some targets are allowed to use meta mode. Others get it # disabled. In some cases, such as 'install', meta mode can be dangerous # as a cookie may be used to prevent redundant installations (such as # for WORLDTMP staging). For DESTDIR=/ we always want to install though. # For other cases, such as delete-old-libs, meta mode may break # the interactive tty prompt. The safest route is to just whitelist # the ones that benefit from it. META_TGT_WHITELIST+= \ _* build32 buildfiles buildincludes buildkernel buildsoft \ buildworld everything kernel-toolchain kernel-toolchains kernel \ kernels libraries native-xtools showconfig test-system-compiler \ tinderbox toolchain \ toolchains universe world worlds xdev xdev-build .ORDER: buildworld installworld +.ORDER: buildworld distrib-dirs +.ORDER: buildworld distribution +.ORDER: buildworld distribute .ORDER: buildworld distributeworld .ORDER: buildworld buildkernel +.ORDER: distrib-dirs distribute +.ORDER: distrib-dirs distributeworld +.ORDER: distrib-dirs installworld +.ORDER: distribution distribute +.ORDER: distributeworld distribute +.ORDER: distributeworld distribution +.ORDER: installworld distribute .ORDER: installworld distribution .ORDER: installworld installkernel .ORDER: buildkernel installkernel .ORDER: buildkernel installkernel.debug .ORDER: buildkernel reinstallkernel .ORDER: buildkernel reinstallkernel.debug PATH= /sbin:/bin:/usr/sbin:/usr/bin MAKEOBJDIRPREFIX?= /usr/obj _MAKEOBJDIRPREFIX!= /usr/bin/env -i PATH=${PATH} MK_AUTO_OBJ=no ${MAKE} \ ${.MAKEFLAGS:MMAKEOBJDIRPREFIX=*} __MAKE_CONF=${__MAKE_CONF} \ -f /dev/null -V MAKEOBJDIRPREFIX dummy .if !empty(_MAKEOBJDIRPREFIX) .error MAKEOBJDIRPREFIX can only be set in environment, not as a global\ (in make.conf(5)) or command-line variable. .endif # We often need to use the tree's version of make to build it. # Choices add to complexity though. # We cannot blindly use a make which may not be the one we want # so be exlicit - until all choice is removed. WANT_MAKE= bmake .if !empty(.MAKE.MODE:Mmeta) # 20160604 - support missing-meta,missing-filemon and performance improvements WANT_MAKE_VERSION= 20160604 .else # 20160220 - support .dinclude for FAST_DEPEND. WANT_MAKE_VERSION= 20160220 .endif MYMAKE= ${MAKEOBJDIRPREFIX}${.CURDIR}/make.${MACHINE}/${WANT_MAKE} .if defined(.PARSEDIR) HAVE_MAKE= bmake .else HAVE_MAKE= fmake .endif .if defined(ALWAYS_BOOTSTRAP_MAKE) || \ ${HAVE_MAKE} != ${WANT_MAKE} || \ (defined(WANT_MAKE_VERSION) && ${MAKE_VERSION} < ${WANT_MAKE_VERSION}) NEED_MAKE_UPGRADE= t .endif .if exists(${MYMAKE}) SUB_MAKE:= ${MYMAKE} -m ${.CURDIR}/share/mk .elif defined(NEED_MAKE_UPGRADE) # It may not exist yet but we may cause it to. # In the case of fmake, upgrade_checks may cause a newer version to be built. SUB_MAKE= `test -x ${MYMAKE} && echo ${MYMAKE} || echo ${MAKE}` \ -m ${.CURDIR}/share/mk .else SUB_MAKE= ${MAKE} -m ${.CURDIR}/share/mk .endif _MAKE= PATH=${PATH} MAKE_CMD=${MAKE} ${SUB_MAKE} -f Makefile.inc1 \ TARGET=${_TARGET} TARGET_ARCH=${_TARGET_ARCH} # Only allow meta mode for the whitelisted targets. See META_TGT_WHITELIST # above. .for _tgt in ${META_TGT_WHITELIST} .if make(${_tgt}) _CAN_USE_META_MODE?= yes .endif .endfor .if !defined(_CAN_USE_META_MODE) _MAKE+= MK_META_MODE=no .if defined(.PARSEDIR) .unexport META_MODE .endif .elif defined(MK_META_MODE) && ${MK_META_MODE} == "yes" .if !exists(/dev/filemon) && !defined(NO_FILEMON) && !make(showconfig) # Require filemon be loaded to provide a working incremental build .error ${.newline}ERROR: The filemon module (/dev/filemon) is not loaded. \ ${.newline}ERROR: WITH_META_MODE is enabled but requires filemon for an incremental build. \ ${.newline}ERROR: 'kldload filemon' or pass -DNO_FILEMON to suppress this error. .endif # !exists(/dev/filemon) && !defined(NO_FILEMON) .endif # !defined(_CAN_USE_META_MODE) # Guess machine architecture from machine type, and vice versa. .if !defined(TARGET_ARCH) && defined(TARGET) _TARGET_ARCH= ${TARGET:S/arm64/aarch64/} .elif !defined(TARGET) && defined(TARGET_ARCH) && \ ${TARGET_ARCH} != ${MACHINE_ARCH} _TARGET= ${TARGET_ARCH:C/mips(n32|64)?(el)?(hf)?/mips/:C/arm(v6)?(eb)?/arm/:C/aarch64/arm64/:C/powerpc64/powerpc/:C/powerpcspe/powerpc/:C/riscv64(sf)?/riscv/} .endif .if defined(TARGET) && !defined(_TARGET) _TARGET=${TARGET} .endif .if defined(TARGET_ARCH) && !defined(_TARGET_ARCH) _TARGET_ARCH=${TARGET_ARCH} .endif # for historical compatibility for xdev targets .if defined(XDEV) _TARGET= ${XDEV} .endif .if defined(XDEV_ARCH) _TARGET_ARCH= ${XDEV_ARCH} .endif # Otherwise, default to current machine type and architecture. _TARGET?= ${MACHINE} _TARGET_ARCH?= ${MACHINE_ARCH} .if make(print-dir) .SILENT: .endif # # Make sure we have an up-to-date make(1). Only world and buildworld # should do this as those are the initial targets used for upgrades. # The user can define ALWAYS_CHECK_MAKE to have this check performed # for all targets. # .if defined(ALWAYS_CHECK_MAKE) || !defined(.PARSEDIR) ${TGTS}: upgrade_checks .else buildworld: upgrade_checks .endif # # Handle the user-driven targets, using the source relative mk files. # tinderbox toolchains kernel-toolchains: .MAKE ${TGTS}: .PHONY .MAKE ${_+_}@cd ${.CURDIR}; ${_MAKE} ${.TARGET} # The historic default "all" target creates files which may cause stale # or (in the cross build case) unlinkable results. Fail with an error # when no target is given. The users can explicitly specify "all" # if they want the historic behavior. .MAIN: _guard _guard: .PHONY @echo @echo "Explicit target required. Likely \"${SUBDIR_OVERRIDE:Dall:Ubuildworld}\" is wanted. See build(7)." @echo @false STARTTIME!= LC_ALL=C date CHECK_TIME!= find ${.CURDIR}/sys/sys/param.h -mtime -0s ; echo .if !empty(CHECK_TIME) .error check your date/time: ${STARTTIME} .endif .if defined(HISTORICAL_MAKE_WORLD) || defined(DESTDIR) # # world # # Attempt to rebuild and reinstall everything. This target is not to be # used for upgrading an existing FreeBSD system, because the kernel is # not included. One can argue that this target doesn't build everything # then. # world: upgrade_checks .PHONY @echo "--------------------------------------------------------------" @echo ">>> make world started on ${STARTTIME}" @echo "--------------------------------------------------------------" .if target(pre-world) @echo @echo "--------------------------------------------------------------" @echo ">>> Making 'pre-world' target" @echo "--------------------------------------------------------------" ${_+_}@cd ${.CURDIR}; ${_MAKE} pre-world .endif ${_+_}@cd ${.CURDIR}; ${_MAKE} buildworld ${_+_}@cd ${.CURDIR}; ${_MAKE} installworld MK_META_MODE=no .if target(post-world) @echo @echo "--------------------------------------------------------------" @echo ">>> Making 'post-world' target" @echo "--------------------------------------------------------------" ${_+_}@cd ${.CURDIR}; ${_MAKE} post-world .endif @echo @echo "--------------------------------------------------------------" @echo ">>> make world completed on `LC_ALL=C date`" @echo " (started ${STARTTIME})" @echo "--------------------------------------------------------------" .else world: .PHONY @echo "WARNING: make world will overwrite your existing FreeBSD" @echo "installation without also building and installing a new" @echo "kernel. This can be dangerous. Please read the handbook," @echo "'Rebuilding world', for how to upgrade your system." @echo "Define DESTDIR to where you want to install FreeBSD," @echo "including /, to override this warning and proceed as usual." @echo "" @echo "Bailing out now..." @false .endif # # kernel # # Short hand for `make buildkernel installkernel' # kernel: buildkernel installkernel .PHONY # # Perform a few tests to determine if the installed tools are adequate # for building the world. # upgrade_checks: .PHONY .if defined(NEED_MAKE_UPGRADE) @${_+_}(cd ${.CURDIR} && ${MAKE} ${WANT_MAKE:S,^f,,}) .endif # # Upgrade make(1) to the current version using the installed # headers, libraries and tools. Also, allow the location of # the system bsdmake-like utility to be overridden. # MMAKEENV= MAKEOBJDIRPREFIX=${MYMAKE:H} \ DESTDIR= \ INSTALL="sh ${.CURDIR}/tools/install.sh" MMAKE= ${MMAKEENV} ${MAKE} \ MAN= -DNO_SHARED \ -DNO_CPU_CFLAGS -DNO_WERROR \ -DNO_SUBDIR \ DESTDIR= PROGNAME=${MYMAKE:T} bmake: .PHONY @echo @echo "--------------------------------------------------------------" @echo ">>> Building an up-to-date ${.TARGET}(1)" @echo "--------------------------------------------------------------" ${_+_}@cd ${.CURDIR}/usr.bin/${.TARGET}; \ ${MMAKE} obj; \ ${MMAKE} depend; \ ${MMAKE} all; \ ${MMAKE} install DESTDIR=${MYMAKE:H} BINDIR= regress: .PHONY @echo "'make regress' has been renamed 'make check'" | /usr/bin/fmt @false tinderbox toolchains kernel-toolchains kernels worlds: upgrade_checks tinderbox: .PHONY @cd ${.CURDIR}; ${SUB_MAKE} DOING_TINDERBOX=YES universe toolchains: .PHONY @cd ${.CURDIR}; ${SUB_MAKE} UNIVERSE_TARGET=toolchain universe kernel-toolchains: .PHONY @cd ${.CURDIR}; ${SUB_MAKE} UNIVERSE_TARGET=kernel-toolchain universe kernels: .PHONY @cd ${.CURDIR}; ${SUB_MAKE} UNIVERSE_TARGET=buildkernel universe worlds: .PHONY @cd ${.CURDIR}; ${SUB_MAKE} UNIVERSE_TARGET=buildworld universe # # universe # # Attempt to rebuild *everything* for all supported architectures, # with a reasonable chance of success, regardless of how old your # existing system is. # .if make(universe) || make(universe_kernels) || make(tinderbox) || make(targets) TARGETS?=amd64 arm arm64 i386 mips powerpc riscv sparc64 _UNIVERSE_TARGETS= ${TARGETS} TARGET_ARCHES_arm?= arm armeb armv6 TARGET_ARCHES_arm64?= aarch64 TARGET_ARCHES_mips?= mipsel mips mips64el mips64 mipsn32 mipselhf mipshf mips64elhf mips64hf TARGET_ARCHES_powerpc?= powerpc powerpc64 powerpcspe TARGET_ARCHES_riscv?= riscv64 riscv64sf .for target in ${TARGETS} TARGET_ARCHES_${target}?= ${target} .endfor MAKE_PARAMS_riscv?= CROSS_TOOLCHAIN=riscv64-gcc # XXX Remove riscv from universe if the required toolchain package is missing. .if !exists(/usr/local/share/toolchains/riscv64-gcc.mk) && ${TARGETS:Mriscv} _UNIVERSE_TARGETS:= ${_UNIVERSE_TARGETS:Nriscv} universe: universe_riscv_skip .PHONY universe_epilogue: universe_riscv_skip .PHONY universe_riscv_skip: universe_prologue .PHONY @echo ">> riscv skipped - install riscv64-xtoolchain-gcc port or package to build" .endif .if defined(UNIVERSE_TARGET) MAKE_JUST_WORLDS= YES .else UNIVERSE_TARGET?= buildworld .endif KERNSRCDIR?= ${.CURDIR}/sys targets: .PHONY @echo "Supported TARGET/TARGET_ARCH pairs for world and kernel targets" .for target in ${TARGETS} .for target_arch in ${TARGET_ARCHES_${target}} @echo " ${target}/${target_arch}" .endfor .endfor .if defined(DOING_TINDERBOX) FAILFILE=${.CURDIR}/_.tinderbox.failed MAKEFAIL=tee -a ${FAILFILE} .else MAKEFAIL=cat .endif universe_prologue: upgrade_checks universe: universe_prologue universe_prologue: .PHONY @echo "--------------------------------------------------------------" @echo ">>> make universe started on ${STARTTIME}" @echo "--------------------------------------------------------------" .if defined(DOING_TINDERBOX) @rm -f ${FAILFILE} .endif .for target in ${_UNIVERSE_TARGETS} universe: universe_${target} universe_epilogue: universe_${target} universe_${target}: universe_${target}_prologue .PHONY universe_${target}_prologue: universe_prologue .PHONY @echo ">> ${target} started on `LC_ALL=C date`" universe_${target}_worlds: .PHONY .if !defined(MAKE_JUST_KERNELS) universe_${target}_done: universe_${target}_worlds .PHONY .for target_arch in ${TARGET_ARCHES_${target}} universe_${target}_worlds: universe_${target}_${target_arch} .PHONY universe_${target}_${target_arch}: universe_${target}_prologue .MAKE .PHONY @echo ">> ${target}.${target_arch} ${UNIVERSE_TARGET} started on `LC_ALL=C date`" @(cd ${.CURDIR} && env __MAKE_CONF=/dev/null \ ${SUB_MAKE} ${JFLAG} ${UNIVERSE_TARGET} \ TARGET=${target} \ TARGET_ARCH=${target_arch} \ ${MAKE_PARAMS_${target}} \ > _.${target}.${target_arch}.${UNIVERSE_TARGET} 2>&1 || \ (echo "${target}.${target_arch} ${UNIVERSE_TARGET} failed," \ "check _.${target}.${target_arch}.${UNIVERSE_TARGET} for details" | \ ${MAKEFAIL})) @echo ">> ${target}.${target_arch} ${UNIVERSE_TARGET} completed on `LC_ALL=C date`" .endfor .endif # !MAKE_JUST_KERNELS .if !defined(MAKE_JUST_WORLDS) universe_${target}_done: universe_${target}_kernels .PHONY universe_${target}_kernels: universe_${target}_worlds .PHONY universe_${target}_kernels: universe_${target}_prologue .MAKE .PHONY .if exists(${KERNSRCDIR}/${target}/conf/NOTES) @(cd ${KERNSRCDIR}/${target}/conf && env __MAKE_CONF=/dev/null \ ${SUB_MAKE} LINT > ${.CURDIR}/_.${target}.makeLINT 2>&1 || \ (echo "${target} 'make LINT' failed," \ "check _.${target}.makeLINT for details"| ${MAKEFAIL})) .endif @cd ${.CURDIR}; ${SUB_MAKE} ${.MAKEFLAGS} TARGET=${target} \ universe_kernels .endif # !MAKE_JUST_WORLDS # Tell the user the worlds and kernels have completed universe_${target}: universe_${target}_done universe_${target}_done: @echo ">> ${target} completed on `LC_ALL=C date`" .endfor universe_kernels: universe_kernconfs .PHONY .if !defined(TARGET) TARGET!= uname -m .endif .if defined(MAKE_ALL_KERNELS) _THINNER=cat .elif defined(MAKE_LINT_KERNELS) _THINNER=grep 'LINT' || true .else _THINNER=xargs grep -L "^.NO_UNIVERSE" || true .endif KERNCONFS!= cd ${KERNSRCDIR}/${TARGET}/conf && \ find [[:upper:][:digit:]]*[[:upper:][:digit:]] \ -type f -maxdepth 0 \ ! -name DEFAULTS ! -name NOTES | \ ${_THINNER} universe_kernconfs: .PHONY .for kernel in ${KERNCONFS} TARGET_ARCH_${kernel}!= cd ${KERNSRCDIR}/${TARGET}/conf && \ config -m ${KERNSRCDIR}/${TARGET}/conf/${kernel} 2> /dev/null | \ grep -v WARNING: | cut -f 2 .if empty(TARGET_ARCH_${kernel}) .error "Target architecture for ${TARGET}/conf/${kernel} unknown. config(8) likely too old." .endif universe_kernconfs: universe_kernconf_${TARGET}_${kernel} universe_kernconf_${TARGET}_${kernel}: .MAKE @(cd ${.CURDIR} && env __MAKE_CONF=/dev/null \ ${SUB_MAKE} ${JFLAG} buildkernel \ TARGET=${TARGET} \ TARGET_ARCH=${TARGET_ARCH_${kernel}} \ ${MAKE_PARAMS_${TARGET}} \ KERNCONF=${kernel} \ > _.${TARGET}.${kernel} 2>&1 || \ (echo "${TARGET} ${kernel} kernel failed," \ "check _.${TARGET}.${kernel} for details"| ${MAKEFAIL})) .endfor universe: universe_epilogue universe_epilogue: .PHONY @echo "--------------------------------------------------------------" @echo ">>> make universe completed on `LC_ALL=C date`" @echo " (started ${STARTTIME})" @echo "--------------------------------------------------------------" .if defined(DOING_TINDERBOX) @if [ -e ${FAILFILE} ] ; then \ echo "Tinderbox failed:" ;\ cat ${FAILFILE} ;\ exit 1 ;\ fi .endif .endif buildLINT: .PHONY ${MAKE} -C ${.CURDIR}/sys/${_TARGET}/conf LINT .if defined(.PARSEDIR) # This makefile does not run in meta mode .MAKE.MODE= normal # Normally the things we run from here don't either. # Using -DWITH_META_MODE # we can buildworld with meta files created which are useful # for debugging, but without any of the rest of a meta mode build. MK_DIRDEPS_BUILD= no MK_STAGING= no # tell meta.autodep.mk to not even think about updating anything. UPDATE_DEPENDFILE= NO .if !make(showconfig) .export MK_DIRDEPS_BUILD MK_STAGING UPDATE_DEPENDFILE .endif .if make(universe) # we do not want a failure of one branch abort all. MAKE_JOB_ERROR_TOKEN= no .export MAKE_JOB_ERROR_TOKEN .endif .endif # bmake .endif # DIRDEPS_BUILD Index: projects/runtime-coverage/Makefile.inc1 =================================================================== --- projects/runtime-coverage/Makefile.inc1 (revision 321457) +++ projects/runtime-coverage/Makefile.inc1 (revision 321458) @@ -1,2853 +1,2862 @@ # # $FreeBSD$ # # Make command line options: # -DNO_CLEANDIR run ${MAKE} clean, instead of ${MAKE} cleandir # -DNO_CLEAN do not clean at all # -DDB_FROM_SRC use the user/group databases in src/etc instead of # the system database when installing. # -DNO_SHARE do not go into share subdir # -DKERNFAST define NO_KERNEL{CONFIG,CLEAN,OBJ} # -DNO_KERNELCONFIG do not run config in ${MAKE} buildkernel # -DNO_KERNELCLEAN do not run ${MAKE} clean in ${MAKE} buildkernel # -DNO_KERNELOBJ do not run ${MAKE} obj in ${MAKE} buildkernel # -DNO_PORTSUPDATE do not update ports in ${MAKE} update # -DNO_ROOT install without using root privilege # -DNO_DOCUPDATE do not update doc in ${MAKE} update # -DWITHOUT_CTF do not run the DTrace CTF conversion tools on built objects # LOCAL_DIRS="list of dirs" to add additional dirs to the SUBDIR list # LOCAL_ITOOLS="list of tools" to add additional tools to the ITOOLS list # LOCAL_LIB_DIRS="list of dirs" to add additional dirs to libraries target # LOCAL_MTREE="list of mtree files" to process to allow local directories # to be created before files are installed # LOCAL_TOOL_DIRS="list of dirs" to add additional dirs to the build-tools # list # LOCAL_XTOOL_DIRS="list of dirs" to add additional dirs to the # cross-tools target # METALOG="path to metadata log" to write permission and ownership # when NO_ROOT is set. (default: ${DESTDIR}/METALOG) # TARGET="machine" to crossbuild world for a different machine type # TARGET_ARCH= may be required when a TARGET supports multiple endians # BUILDENV_SHELL= shell to launch for the buildenv target (def:${SHELL}) # WORLD_FLAGS= additional flags to pass to make(1) during buildworld # KERNEL_FLAGS= additional flags to pass to make(1) during buildkernel # SUBDIR_OVERRIDE="list of dirs" to build rather than everything. # All libraries and includes, and some build tools will still build. # # The intended user-driven targets are: # buildworld - rebuild *everything*, including glue to help do upgrades # installworld- install everything built by "buildworld" # checkworld - run test suite on installed world # doxygen - build API documentation of the kernel # update - convenient way to update your source tree (eg: svn/svnup) # # Standard targets (not defined here) are documented in the makefiles in # /usr/share/mk. These include: # obj depend all install clean cleandepend cleanobj .if !defined(TARGET) || !defined(TARGET_ARCH) .error "Both TARGET and TARGET_ARCH must be defined." .endif SRCDIR?= ${.CURDIR} LOCALBASE?= /usr/local # Cross toolchain changes must be in effect before bsd.compiler.mk # so that gets the right CC, and pass CROSS_TOOLCHAIN to submakes. .if defined(CROSS_TOOLCHAIN) .include "${LOCALBASE}/share/toolchains/${CROSS_TOOLCHAIN}.mk" CROSSENV+=CROSS_TOOLCHAIN="${CROSS_TOOLCHAIN}" .endif .if defined(CROSS_TOOLCHAIN_PREFIX) CROSS_COMPILER_PREFIX?=${CROSS_TOOLCHAIN_PREFIX} .endif XCOMPILERS= CC CXX CPP .for COMPILER in ${XCOMPILERS} .if defined(CROSS_COMPILER_PREFIX) X${COMPILER}?= ${CROSS_COMPILER_PREFIX}${${COMPILER}} .else X${COMPILER}?= ${${COMPILER}} .endif .endfor # If a full path to an external cross compiler is given, don't build # a cross compiler. .if ${XCC:N${CCACHE_BIN}:M/*} MK_CLANG_BOOTSTRAP= no MK_GCC_BOOTSTRAP= no .endif MAKEOBJDIRPREFIX?= /usr/obj .if ${MACHINE} == ${TARGET} && ${MACHINE_ARCH} == ${TARGET_ARCH} && !defined(CROSS_BUILD_TESTING) OBJTREE= ${MAKEOBJDIRPREFIX} .else OBJTREE= ${MAKEOBJDIRPREFIX}/${TARGET}.${TARGET_ARCH} .endif # Pull in compiler metadata from buildworld/toolchain if possible to avoid # running CC from bsd.compiler.mk. .if make(installworld) || make(install) || make(distributeworld) || \ make(stageworld) .-include "${OBJTREE}${.CURDIR}/compiler-metadata.mk" .endif # Pull in COMPILER_TYPE and COMPILER_FREEBSD_VERSION early. .include .include "share/mk/src.opts.mk" # Check if there is a local compiler that can satisfy as an external compiler. # Which compiler is expected to be used? .if ${MK_CLANG_BOOTSTRAP} == "yes" WANT_COMPILER_TYPE= clang .elif ${MK_GCC_BOOTSTRAP} == "yes" WANT_COMPILER_TYPE= gcc .else WANT_COMPILER_TYPE= .endif .if !defined(WANT_COMPILER_FREEBSD_VERSION) .if ${WANT_COMPILER_TYPE} == "clang" WANT_COMPILER_FREEBSD_VERSION_FILE= lib/clang/freebsd_cc_version.h WANT_COMPILER_FREEBSD_VERSION!= \ awk '$$2 == "FREEBSD_CC_VERSION" {printf("%d\n", $$3)}' \ ${SRCDIR}/${WANT_COMPILER_FREEBSD_VERSION_FILE} || echo unknown WANT_COMPILER_VERSION_FILE= lib/clang/include/clang/Basic/Version.inc WANT_COMPILER_VERSION!= \ awk '$$2 == "CLANG_VERSION" {split($$3, a, "."); print a[1] * 10000 + a[2] * 100 + a[3]}' \ ${SRCDIR}/${WANT_COMPILER_VERSION_FILE} || echo unknown .elif ${WANT_COMPILER_TYPE} == "gcc" WANT_COMPILER_FREEBSD_VERSION_FILE= gnu/usr.bin/cc/cc_tools/freebsd-native.h WANT_COMPILER_FREEBSD_VERSION!= \ awk '$$2 == "FBSD_CC_VER" {printf("%d\n", $$3)}' \ ${SRCDIR}/${WANT_COMPILER_FREEBSD_VERSION_FILE} || echo unknown WANT_COMPILER_VERSION_FILE= contrib/gcc/BASE-VER WANT_COMPILER_VERSION!= \ awk -F. '{print $$1 * 10000 + $$2 * 100 + $$3}' \ ${SRCDIR}/${WANT_COMPILER_VERSION_FILE} || echo unknown .endif .export WANT_COMPILER_FREEBSD_VERSION WANT_COMPILER_VERSION .endif # !defined(WANT_COMPILER_FREEBSD_VERSION) # It needs to be the same revision as we would build for the bootstrap. # If the expected vs CC is different then we can't skip. # GCC cannot be used for cross-arch yet. For clang we pass -target later if # TARGET_ARCH!=MACHINE_ARCH. .if ${MK_SYSTEM_COMPILER} == "yes" && \ (${MK_CLANG_BOOTSTRAP} == "yes" || ${MK_GCC_BOOTSTRAP} == "yes") && \ !make(showconfig) && !make(native-xtools) && !make(xdev*) && \ ${WANT_COMPILER_TYPE} == ${COMPILER_TYPE} && \ (${COMPILER_TYPE} == "clang" || ${TARGET_ARCH} == ${MACHINE_ARCH}) && \ ${COMPILER_VERSION} == ${WANT_COMPILER_VERSION} && \ ${COMPILER_FREEBSD_VERSION} == ${WANT_COMPILER_FREEBSD_VERSION} # Everything matches, disable the bootstrap compiler. MK_CLANG_BOOTSTRAP= no MK_GCC_BOOTSTRAP= no USING_SYSTEM_COMPILER= yes .endif # ${WANT_COMPILER_TYPE} == ${COMPILER_TYPE} USING_SYSTEM_COMPILER?= no TEST_SYSTEM_COMPILER_VARS= \ USING_SYSTEM_COMPILER MK_SYSTEM_COMPILER \ MK_CROSS_COMPILER MK_CLANG_BOOTSTRAP MK_GCC_BOOTSTRAP \ WANT_COMPILER_TYPE WANT_COMPILER_VERSION WANT_COMPILER_VERSION_FILE \ WANT_COMPILER_FREEBSD_VERSION WANT_COMPILER_FREEBSD_VERSION_FILE \ CC COMPILER_TYPE COMPILER_FEATURES COMPILER_VERSION \ COMPILER_FREEBSD_VERSION \ LINKER_TYPE LINKER_VERSION test-system-compiler: .PHONY .for v in ${TEST_SYSTEM_COMPILER_VARS} ${_+_}@printf "%-35s= %s\n" "${v}" "${${v}}" .endfor .if ${USING_SYSTEM_COMPILER} == "yes" && \ (make(buildworld) || make(buildkernel) || make(kernel-toolchain) || \ make(toolchain) || make(_cross-tools)) .info SYSTEM_COMPILER: Determined that CC=${CC} matches the source tree. Not bootstrapping a cross-compiler. .endif # For installworld need to ensure that the looked-up compiler metadata is # passed along rather than trying to run cc from the restricted # STRICTTMPPATH. .if ${MK_CLANG_BOOTSTRAP} == "no" && ${MK_GCC_BOOTSTRAP} == "no" .if !defined(X_COMPILER_TYPE) CROSSENV+= COMPILER_VERSION=${COMPILER_VERSION} \ COMPILER_TYPE=${COMPILER_TYPE} \ COMPILER_FEATURES=${COMPILER_FEATURES} \ COMPILER_FREEBSD_VERSION=${COMPILER_FREEBSD_VERSION} .else CROSSENV+= COMPILER_VERSION=${X_COMPILER_VERSION} \ COMPILER_FEATURES=${X_COMPILER_FEATURES} \ COMPILER_TYPE=${X_COMPILER_TYPE} \ COMPILER_FREEBSD_VERSION=${X_COMPILER_FREEBSD_VERSION} .endif .endif # Store some compiler metadata for use in installworld where we don't # want to invoke CC at all. _COMPILER_METADATA_VARS= COMPILER_VERSION \ COMPILER_TYPE \ COMPILER_FEATURES \ COMPILER_FREEBSD_VERSION \ LINKER_VERSION \ LINKER_TYPE compiler-metadata.mk: .PHONY .META @: > ${.TARGET} @echo ".info Using cached compiler metadata from build at $$(hostname) on $$(date)" \ > ${.TARGET} .for v in ${_COMPILER_METADATA_VARS} @echo "${v}=${${v}}" >> ${.TARGET} .endfor @echo ".export ${_COMPILER_METADATA_VARS}" >> ${.TARGET} # Handle external binutils. .if defined(CROSS_TOOLCHAIN_PREFIX) CROSS_BINUTILS_PREFIX?=${CROSS_TOOLCHAIN_PREFIX} .endif # If we do not have a bootstrap binutils (because the in-tree one does not # support the target architecture), provide a default cross-binutils prefix. # This allows riscv64 builds, for example, to automatically use the # riscv64-binutils port or package. .if !make(showconfig) .if !empty(BROKEN_OPTIONS:MBINUTILS_BOOTSTRAP) && \ ${MK_LLD_BOOTSTRAP} == "no" && \ !defined(CROSS_BINUTILS_PREFIX) CROSS_BINUTILS_PREFIX=/usr/local/${TARGET_ARCH}-freebsd/bin/ .if !exists(${CROSS_BINUTILS_PREFIX}) .error In-tree binutils does not support the ${TARGET_ARCH} architecture. Install the ${TARGET_ARCH}-binutils port or package or set CROSS_BINUTILS_PREFIX. .endif .endif .endif XBINUTILS= AS AR LD NM OBJCOPY RANLIB SIZE STRINGS .for BINUTIL in ${XBINUTILS} .if defined(CROSS_BINUTILS_PREFIX) && \ exists(${CROSS_BINUTILS_PREFIX}${${BINUTIL}}) X${BINUTIL}?= ${CROSS_BINUTILS_PREFIX}${${BINUTIL}} .else X${BINUTIL}?= ${${BINUTIL}} .endif .endfor # We must do lib/ and libexec/ before bin/ in case of a mid-install error to # keep the users system reasonably usable. For static->dynamic root upgrades, # we don't want to install a dynamic binary without rtld and the needed # libraries. More commonly, for dynamic root, we don't want to install a # binary that requires a newer library version that hasn't been installed yet. # This ordering is not a guarantee though. The only guarantee of a working # system here would require fine-grained ordering of all components based # on their dependencies. .if !empty(SUBDIR_OVERRIDE) SUBDIR= ${SUBDIR_OVERRIDE} .else SUBDIR= lib libexec .if !defined(NO_ROOT) && (make(installworld) || make(install)) # Ensure libraries are installed before progressing. SUBDIR+=.WAIT .endif SUBDIR+=bin .if ${MK_CDDL} != "no" SUBDIR+=cddl .endif SUBDIR+=gnu include .if ${MK_KERBEROS} != "no" SUBDIR+=kerberos5 .endif .if ${MK_RESCUE} != "no" SUBDIR+=rescue .endif SUBDIR+=sbin .if ${MK_CRYPT} != "no" SUBDIR+=secure .endif .if !defined(NO_SHARE) SUBDIR+=share .endif SUBDIR+=sys usr.bin usr.sbin .if ${MK_TESTS} != "no" SUBDIR+= tests .endif .if ${MK_OFED} != "no" SUBDIR+=contrib/ofed .endif # Local directories are last, since it is nice to at least get the base # system rebuilt before you do them. .for _DIR in ${LOCAL_DIRS} .if exists(${.CURDIR}/${_DIR}/Makefile) SUBDIR+= ${_DIR} .endif .endfor # Add LOCAL_LIB_DIRS, but only if they will not be picked up as a SUBDIR # of a LOCAL_DIRS directory. This allows LOCAL_DIRS=foo and # LOCAL_LIB_DIRS=foo/lib to behave as expected. .for _DIR in ${LOCAL_DIRS:M*/} ${LOCAL_DIRS:N*/:S|$|/|} _REDUNDANT_LIB_DIRS+= ${LOCAL_LIB_DIRS:M${_DIR}*} .endfor .for _DIR in ${LOCAL_LIB_DIRS} .if empty(_REDUNDANT_LIB_DIRS:M${_DIR}) && exists(${.CURDIR}/${_DIR}/Makefile) SUBDIR+= ${_DIR} .endif .endfor # We must do etc/ last as it hooks into building the man whatis file # by calling 'makedb' in share/man. This is only relevant for # install/distribute so they build the whatis file after every manpage is # installed. .if make(installworld) || make(install) SUBDIR+=.WAIT .endif SUBDIR+=etc .endif # !empty(SUBDIR_OVERRIDE) .if defined(NOCLEAN) .warning NOCLEAN option is deprecated. Use NO_CLEAN instead. NO_CLEAN= ${NOCLEAN} .endif .if defined(NO_CLEANDIR) CLEANDIR= clean cleandepend .else CLEANDIR= cleandir .endif .if defined(WORLDFAST) NO_CLEAN= t NO_OBJ= t .endif .if ${MK_META_MODE} == "yes" # If filemon is used then we can rely on the build being incremental-safe. # The .meta files will also track the build command and rebuild should # it change. .if empty(.MAKE.MODE:Mnofilemon) NO_CLEAN= t .endif .endif .if defined(NO_OBJ) || ${MK_AUTO_OBJ} == "yes" NO_OBJ= t NO_KERNELOBJ= t .endif .if !defined(NO_OBJ) _obj= obj .endif LOCAL_TOOL_DIRS?= PACKAGEDIR?= ${DESTDIR}/${DISTDIR} .if empty(SHELL:M*csh*) BUILDENV_SHELL?=${SHELL} .else BUILDENV_SHELL?=/bin/sh .endif .if !defined(SVN) || empty(SVN) . for _P in /usr/bin /usr/local/bin . for _S in svn svnlite . if exists(${_P}/${_S}) SVN= ${_P}/${_S} . endif . endfor . endfor .endif SVNFLAGS?= -r HEAD .if !defined(OSRELDATE) .if exists(/usr/include/osreldate.h) OSRELDATE!= awk '/^\#define[[:space:]]*__FreeBSD_version/ { print $$3 }' \ /usr/include/osreldate.h .else OSRELDATE= 0 .endif .export OSRELDATE .endif # Set VERSION for CTFMERGE to use via the default CTFFLAGS=-L VERSION. .if !defined(_REVISION) _REVISION!= MK_AUTO_OBJ=no ${MAKE} -C ${SRCDIR}/release -V REVISION .export _REVISION .endif .if !defined(_BRANCH) _BRANCH!= MK_AUTO_OBJ=no ${MAKE} -C ${SRCDIR}/release -V BRANCH .export _BRANCH .endif .if !defined(SRCRELDATE) SRCRELDATE!= awk '/^\#define[[:space:]]*__FreeBSD_version/ { print $$3 }' \ ${SRCDIR}/sys/sys/param.h .export SRCRELDATE .endif .if !defined(VERSION) VERSION= FreeBSD ${_REVISION}-${_BRANCH:C/-p[0-9]+$//} ${TARGET_ARCH} ${SRCRELDATE} .export VERSION .endif .if !defined(PKG_VERSION) .if ${_BRANCH:MSTABLE*} || ${_BRANCH:MCURRENT*} || ${_BRANCH:MALPHA*} TIMENOW= %Y%m%d%H%M%S EXTRA_REVISION= .s${TIMENOW:gmtime} .endif .if ${_BRANCH:M*-p*} EXTRA_REVISION= _${_BRANCH:C/.*-p([0-9]+$)/\1/} .endif PKG_VERSION= ${_REVISION}${EXTRA_REVISION} .endif KNOWN_ARCHES?= aarch64/arm64 \ amd64 \ arm \ armeb/arm \ armv6/arm \ i386 \ mips \ mipsel/mips \ mips64el/mips \ mipsn32el/mips \ mips64/mips \ mipsn32/mips \ mipshf/mips \ mipselhf/mips \ mips64elhf/mips \ mips64hf/mips \ powerpc \ powerpc64/powerpc \ powerpcspe/powerpc \ riscv64/riscv \ riscv64sf/riscv \ sparc64 .if ${TARGET} == ${TARGET_ARCH} _t= ${TARGET} .else _t= ${TARGET_ARCH}/${TARGET} .endif .for _t in ${_t} .if empty(KNOWN_ARCHES:M${_t}) .error Unknown target ${TARGET_ARCH}:${TARGET}. .endif .endfor .if ${TARGET} == ${MACHINE} TARGET_CPUTYPE?=${CPUTYPE} .else TARGET_CPUTYPE?= .endif .if !empty(TARGET_CPUTYPE) _TARGET_CPUTYPE=${TARGET_CPUTYPE} .else _TARGET_CPUTYPE=dummy .endif _CPUTYPE!= MK_AUTO_OBJ=no MAKEFLAGS= CPUTYPE=${_TARGET_CPUTYPE} ${MAKE} \ -f /dev/null -m ${.CURDIR}/share/mk -V CPUTYPE .if ${_CPUTYPE} != ${_TARGET_CPUTYPE} .error CPUTYPE global should be set with ?=. .endif .if make(buildworld) BUILD_ARCH!= uname -p .if ${MACHINE_ARCH} != ${BUILD_ARCH} .error To cross-build, set TARGET_ARCH. .endif .endif WORLDTMP= ${OBJTREE}${.CURDIR}/tmp BPATH= ${WORLDTMP}/legacy/usr/sbin:${WORLDTMP}/legacy/usr/bin:${WORLDTMP}/legacy/bin XPATH= ${WORLDTMP}/usr/sbin:${WORLDTMP}/usr/bin STRICTTMPPATH= ${BPATH}:${XPATH} TMPPATH= ${STRICTTMPPATH}:${PATH} # # Avoid running mktemp(1) unless actually needed. # It may not be functional, e.g., due to new ABI # when in the middle of installing over this system. # .if make(distributeworld) || make(installworld) || make(stageworld) INSTALLTMP!= /usr/bin/mktemp -d -u -t install .endif .if make(stagekernel) || make(distributekernel) TAGS+= kernel PACKAGE= kernel .endif # # Building a world goes through the following stages # # 1. legacy stage [BMAKE] # This stage is responsible for creating compatibility # shims that are needed by the bootstrap-tools, # build-tools and cross-tools stages. These are generally # APIs that tools from one of those three stages need to # build that aren't present on the host. # 1. bootstrap-tools stage [BMAKE] # This stage is responsible for creating programs that # are needed for backward compatibility reasons. They # are not built as cross-tools. # 2. build-tools stage [TMAKE] # This stage is responsible for creating the object # tree and building any tools that are needed during # the build process. Some programs are listed during # this phase because they build binaries to generate # files needed to build these programs. This stage also # builds the 'build-tools' target rather than 'all'. # 3. cross-tools stage [XMAKE] # This stage is responsible for creating any tools that # are needed for building the system. A cross-compiler is one # of them. This differs from build tools in two ways: # 1. the 'all' target is built rather than 'build-tools' # 2. these tools are installed into TMPPATH for stage 4. # 4. world stage [WMAKE] # This stage actually builds the world. # 5. install stage (optional) [IMAKE] # This stage installs a previously built world. # BOOTSTRAPPING?= 0 # Keep these in sync -- see below for special case exception MINIMUM_SUPPORTED_OSREL?= 900044 MINIMUM_SUPPORTED_REL?= 9.1 # Common environment for world related stages CROSSENV+= MAKEOBJDIRPREFIX=${OBJTREE} \ MACHINE_ARCH=${TARGET_ARCH} \ MACHINE=${TARGET} \ CPUTYPE=${TARGET_CPUTYPE} .if ${MK_META_MODE} != "no" # Don't rebuild build-tools targets during normal build. CROSSENV+= BUILD_TOOLS_META=.NOMETA .endif .if defined(TARGET_CFLAGS) CROSSENV+= ${TARGET_CFLAGS} .endif # bootstrap-tools stage BMAKEENV= INSTALL="sh ${.CURDIR}/tools/install.sh" \ TOOLS_PREFIX=${WORLDTMP} \ PATH=${BPATH}:${PATH} \ WORLDTMP=${WORLDTMP} \ MAKEFLAGS="-m ${.CURDIR}/tools/build/mk ${.MAKEFLAGS}" # need to keep this in sync with targets/pseudo/bootstrap-tools/Makefile BSARGS= DESTDIR= \ BOOTSTRAPPING=${OSRELDATE} \ BWPHASE=${.TARGET:C,^_,,} \ SSP_CFLAGS= \ MK_COVERAGE=no MK_HTML=no NO_LINT=yes MK_MAN=no \ -DNO_PIC MK_PROFILE=no -DNO_SHARED \ -DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no \ MK_CLANG_EXTRAS=no MK_CLANG_FULL=no \ MK_LLDB=no MK_TESTS=no \ MK_INCLUDES=yes BMAKE= MAKEOBJDIRPREFIX=${WORLDTMP} \ ${BMAKEENV} ${MAKE} ${WORLD_FLAGS} -f Makefile.inc1 \ ${BSARGS} # build-tools stage TMAKE= MAKEOBJDIRPREFIX=${OBJTREE} \ ${BMAKEENV} ${MAKE} ${WORLD_FLAGS} -f Makefile.inc1 \ TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} \ DESTDIR= \ BOOTSTRAPPING=${OSRELDATE} \ BWPHASE=${.TARGET:C,^_,,} \ SSP_CFLAGS= \ -DNO_LINT \ -DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no \ MK_CLANG_EXTRAS=no MK_CLANG_FULL=no \ MK_LLDB=no MK_TESTS=no # cross-tools stage XMAKE= TOOLS_PREFIX=${WORLDTMP} ${BMAKE} \ TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} \ MK_GDB=no MK_TESTS=no # kernel-tools stage KTMAKEENV= INSTALL="sh ${.CURDIR}/tools/install.sh" \ PATH=${BPATH}:${PATH} \ WORLDTMP=${WORLDTMP} KTMAKE= TOOLS_PREFIX=${WORLDTMP} MAKEOBJDIRPREFIX=${WORLDTMP} \ ${KTMAKEENV} ${MAKE} ${WORLD_FLAGS} -f Makefile.inc1 \ DESTDIR= \ BOOTSTRAPPING=${OSRELDATE} \ SSP_CFLAGS= \ MK_COVERAGE=no MK_HTML=no -DNO_LINT MK_MAN=no \ -DNO_PIC MK_PROFILE=no -DNO_SHARED \ -DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no # world stage WMAKEENV= ${CROSSENV} \ INSTALL="sh ${.CURDIR}/tools/install.sh" \ PATH=${TMPPATH} \ SYSROOT=${WORLDTMP} # make hierarchy HMAKE= PATH=${TMPPATH} ${MAKE} LOCAL_MTREE=${LOCAL_MTREE:Q} .if defined(NO_ROOT) HMAKE+= PATH=${TMPPATH} METALOG=${METALOG} -DNO_ROOT .endif CROSSENV+= CC="${XCC} ${XCFLAGS}" CXX="${XCXX} ${XCXXFLAGS} ${XCFLAGS}" \ CPP="${XCPP} ${XCFLAGS}" \ AS="${XAS}" AR="${XAR}" LD="${XLD}" LLVM_LINK="${XLLVM_LINK}" \ NM=${XNM} OBJCOPY="${XOBJCOPY}" \ RANLIB=${XRANLIB} STRINGS=${XSTRINGS} \ SIZE="${XSIZE}" .if defined(CROSS_BINUTILS_PREFIX) && exists(${CROSS_BINUTILS_PREFIX}) # In the case of xdev-build tools, CROSS_BINUTILS_PREFIX won't be a # directory, but the compiler will look in the right place for its # tools so we don't need to tell it where to look. BFLAGS+= -B${CROSS_BINUTILS_PREFIX} .endif # The internal bootstrap compiler has a default sysroot set by TOOLS_PREFIX # and target set by TARGET/TARGET_ARCH. However, there are several needs to # always pass an explicit --sysroot and -target. # - External compiler needs sysroot and target flags. # - External ld needs sysroot. # - To be clear about the use of a sysroot when using the internal compiler. # - Easier debugging. # - Allowing WITH_SYSTEM_COMPILER+WITH_META_MODE to work together due to # the flip-flopping build command when sometimes using external and # sometimes using internal. # - Allow using lld which has no support for default paths. .if !defined(CROSS_BINUTILS_PREFIX) || !exists(${CROSS_BINUTILS_PREFIX}) BFLAGS+= -B${WORLDTMP}/usr/bin .endif .if ${TARGET} == "arm" .if ${TARGET_ARCH:Marmv6*} != "" && ${TARGET_CPUTYPE:M*soft*} == "" TARGET_ABI= gnueabihf .else TARGET_ABI= gnueabi .endif .endif .if ${WANT_COMPILER_TYPE} == gcc || \ (defined(X_COMPILER_TYPE) && ${X_COMPILER_TYPE} == gcc) # GCC requires -isystem and -L when using a cross-compiler. --sysroot # won't set header path and -L is used to ensure the base library path # is added before the port PREFIX library path. XCFLAGS+= -isystem ${WORLDTMP}/usr/include -L${WORLDTMP}/usr/lib # GCC requires -B to find /usr/lib/crti.o when using a cross-compiler # combined with --sysroot. XCFLAGS+= -B${WORLDTMP}/usr/lib # Force using libc++ for external GCC. # XXX: This should be checking MK_GNUCXX == no .if ${X_COMPILER_VERSION} >= 40800 XCXXFLAGS+= -isystem ${WORLDTMP}/usr/include/c++/v1 -std=c++11 \ -nostdinc++ .endif .elif ${WANT_COMPILER_TYPE} == clang || \ (defined(X_COMPILER_TYPE) && ${X_COMPILER_TYPE} == clang) TARGET_ABI?= unknown TARGET_TRIPLE?= ${TARGET_ARCH:C/amd64/x86_64/}-${TARGET_ABI}-freebsd12.0 XCFLAGS+= -target ${TARGET_TRIPLE} .endif XCFLAGS+= --sysroot=${WORLDTMP} .if !empty(BFLAGS) XCFLAGS+= ${BFLAGS} .endif .if ${MK_LIB32} != "no" && (${TARGET_ARCH} == "amd64" || \ ${TARGET_ARCH} == "powerpc64" || ${TARGET_ARCH:Mmips64*} != "") LIBCOMPAT= 32 .include "Makefile.libcompat" .elif ${MK_LIBSOFT} != "no" && ${TARGET_ARCH} == "armv6" LIBCOMPAT= SOFT .include "Makefile.libcompat" .endif # META_MODE normally ignores host file changes since every build updates # timestamps (see NO_META_IGNORE_HOST in sys.mk). There are known times # when the ABI breaks though that we want to force rebuilding WORLDTMP # to get updated host tools. .if ${MK_META_MODE} == "yes" && defined(NO_CLEAN) && \ !defined(NO_META_IGNORE_HOST) && !defined(NO_META_IGNORE_HOST_HEADERS) && \ !make(showconfig) # r318736 - ino64 major ABI breakage META_MODE_BAD_ABI_VERS+= 1200031 .if !defined(OBJDIR_HOST_OSRELDATE) .if exists(${OBJTREE}${.CURDIR}/host-osreldate.h) OBJDIR_HOST_OSRELDATE!= \ awk '/^\#define[[:space:]]*__FreeBSD_version/ { print $$3 }' \ ${OBJTREE}${.CURDIR}/host-osreldate.h .else OBJDIR_HOST_OSRELDATE= 0 .endif .export OBJDIR_HOST_OSRELDATE .endif # Note that this logic is the opposite of normal BOOTSTRAP handling. We want # to compare the WORLDTMP's OSRELDATE to the host's OSRELDATE. If the WORLDTMP # is older than the ABI-breakage OSRELDATE of the HOST then we rebuild. .for _ver in ${META_MODE_BAD_ABI_VERS} .if ${OSRELDATE} >= ${_ver} && ${OBJDIR_HOST_OSRELDATE} < ${_ver} _meta_mode_need_rebuild= ${_ver} .endif .endfor .if defined(_meta_mode_need_rebuild) .info META_MODE: Rebuilding host tools due to ABI breakage in __FreeBSD_version ${_meta_mode_need_rebuild}. NO_META_IGNORE_HOST_HEADERS= 1 .export NO_META_IGNORE_HOST_HEADERS .endif .endif # This is only used for META_MODE+filemon to track what the oldest # __FreeBSD_version is in WORLDTMP. This purposely does NOT have # a make dependency on /usr/include/osreldate.h as the file should # only be copied when it is missing or meta mode determines it has changed. # Since host files are normally ignored without NO_META_IGNORE_HOST # the file will never be updated unless that flag is specified. This # allows tracking the oldest osreldate to force rebuilds via # META_MODE_BADABI_REVS above. host-osreldate.h: # DO NOT ADD /usr/include/osreldate.h here @cp -f /usr/include/osreldate.h ${.TARGET} WMAKE= ${WMAKEENV} ${MAKE} ${WORLD_FLAGS} -f Makefile.inc1 \ BWPHASE=${.TARGET:C,^_,,} \ DESTDIR=${WORLDTMP} IMAKEENV= ${CROSSENV} IMAKE= ${IMAKEENV} ${MAKE} -f Makefile.inc1 \ ${IMAKE_INSTALL} ${IMAKE_MTREE} .if empty(.MAKEFLAGS:M-n) IMAKEENV+= PATH=${STRICTTMPPATH}:${INSTALLTMP} \ LD_LIBRARY_PATH=${INSTALLTMP} \ PATH_LOCALE=${INSTALLTMP}/locale IMAKE+= __MAKE_SHELL=${INSTALLTMP}/sh .else IMAKEENV+= PATH=${TMPPATH}:${INSTALLTMP} .endif .if defined(DB_FROM_SRC) INSTALLFLAGS+= -N ${.CURDIR}/etc MTREEFLAGS+= -N ${.CURDIR}/etc .endif _INSTALL_DDIR= ${DESTDIR}/${DISTDIR} INSTALL_DDIR= ${_INSTALL_DDIR:S://:/:g:C:/$::} .if defined(NO_ROOT) METALOG?= ${DESTDIR}/${DISTDIR}/METALOG METALOG:= ${METALOG:C,//+,/,g} IMAKE+= -DNO_ROOT METALOG=${METALOG} INSTALLFLAGS+= -U -M ${METALOG} -D ${INSTALL_DDIR} MTREEFLAGS+= -W .endif .if defined(BUILD_PKGS) INSTALLFLAGS+= -h sha256 .endif .if defined(DB_FROM_SRC) || defined(NO_ROOT) IMAKE_INSTALL= INSTALL="install ${INSTALLFLAGS}" IMAKE_MTREE= MTREE_CMD="mtree ${MTREEFLAGS}" .endif # kernel stage KMAKEENV= ${WMAKEENV:NSYSROOT=*} KMAKE= ${KMAKEENV} ${MAKE} ${.MAKEFLAGS} ${KERNEL_FLAGS} KERNEL=${INSTKERNNAME} # # buildworld # # Attempt to rebuild the entire system, with reasonable chance of # success, regardless of how old your existing system is. # _worldtmp: .PHONY .if ${.CURDIR:C/[^,]//g} != "" # The m4 build of sendmail files doesn't like it if ',' is used # anywhere in the path of it's files. @echo @echo "*** Error: path to source tree contains a comma ','" @echo false .endif @echo @echo "--------------------------------------------------------------" @echo ">>> Rebuilding the temporary build tree" @echo "--------------------------------------------------------------" .if !defined(NO_CLEAN) rm -rf ${WORLDTMP} .if defined(LIBCOMPAT) rm -rf ${LIBCOMPATTMP} .endif .else + ${_+_}cd ${.CURDIR}; ${WMAKE} -DBATCH_DELETE_OLD_FILES \ + delete-old delete-old-libs +.if defined(LIBCOMPAT) + ${_+_}cd ${.CURDIR}; ${WMAKE} -DBATCH_DELETE_OLD_FILES \ + DESTDIR=${LIBCOMPATTMP} \ + delete-old delete-old-libs +.endif rm -rf ${WORLDTMP}/legacy/usr/include .if ${USING_SYSTEM_COMPILER} == "yes" .for cc in cc c++ if [ -x ${WORLDTMP}/usr/bin/${cc} ]; then \ inum=$$(stat -f %i ${WORLDTMP}/usr/bin/${cc}); \ find ${WORLDTMP}/usr/bin -inum $${inum} -delete; \ fi .endfor .endif # ${USING_SYSTEM_COMPILER} == "yes" -.endif # !defined(NO_CLEAN) # Our current approach to dependency tracking cannot cope with certain source # tree changes, particularly with respect to removing source files and # replacing generated files. Handle these cases here in an ad-hoc fashion. # # Syscall stubs rewritten in C # Date SVN Rev Syscalls # 20160829 r305012 ptrace # 20170624 r320278 fstat fstatat fstatfs getdirentries getfsstat statfs .for f in fstat fstatat fstatfs getdirentries getfsstat ptrace statfs .if exists(${OBJTREE}${.CURDIR}/lib/libc/.depend.${f}.o) @if egrep -qw '${f}\.[sS]' \ ${OBJTREE}${.CURDIR}/lib/libc/.depend.${f}.o; then \ echo Removing stale dependencies for ${f} syscall wrappers; \ rm -f ${OBJTREE}${.CURDIR}/lib/libc/.depend.${f}.* \ ${OBJTREE}${.CURDIR}/world32/${.CURDIR}/lib/libc/.depend.${f}.*; \ fi .endif .endfor # 20170607 remove stale dependencies for utimens* wrappers removed in r319663 .for f in futimens utimensat .if exists(${OBJTREE}${.CURDIR}/lib/libc/.depend.${f}.o) @if egrep -q '/${f}.c' \ ${OBJTREE}${.CURDIR}/lib/libc/.depend.${f}.o; then \ echo Removing stale dependencies for ${f} syscall wrappers; \ rm -f ${OBJTREE}${.CURDIR}/lib/libc/.depend.${f}.* \ ${OBJTREE}${.CURDIR}/world32/${.CURDIR}/lib/libc/.depend.${f}.*; \ fi .endif .endfor # 20170523 remove stale generated asm files for functions which are no longer # syscalls after r302092 (pipe) and r318736 (others) .for f in getdents lstat mknod pipe stat .if exists(${OBJTREE}${.CURDIR}/lib/libc/${f}.s) || \ exists(${OBJTREE}${.CURDIR}/lib/libc/${f}.S) @echo Removing stale generated ${f} syscall files @rm -f ${OBJTREE}${.CURDIR}/lib/libc/${f}.* \ ${OBJTREE}${.CURDIR}/lib/libc/.depend.${f}.* \ ${OBJTREE}${.CURDIR}/world32/${.CURDIR}/lib/libc/${f}.* \ ${OBJTREE}${.CURDIR}/world32/${.CURDIR}/lib/libc/.depend.${f}.* .endif .endfor + +.endif # !defined(NO_CLEAN) + .for _dir in \ lib lib/casper usr legacy/bin legacy/usr mkdir -p ${WORLDTMP}/${_dir} .endfor mtree -deU -f ${.CURDIR}/etc/mtree/BSD.usr.dist \ -p ${WORLDTMP}/legacy/usr >/dev/null mtree -deU -f ${.CURDIR}/etc/mtree/BSD.include.dist \ -p ${WORLDTMP}/legacy/usr/include >/dev/null mtree -deU -f ${.CURDIR}/etc/mtree/BSD.usr.dist \ -p ${WORLDTMP}/usr >/dev/null mtree -deU -f ${.CURDIR}/etc/mtree/BSD.include.dist \ -p ${WORLDTMP}/usr/include >/dev/null ln -sf ${.CURDIR}/sys ${WORLDTMP} .if ${MK_DEBUG_FILES} != "no" # We could instead disable debug files for these build stages mtree -deU -f ${.CURDIR}/etc/mtree/BSD.debug.dist \ -p ${WORLDTMP}/legacy/usr/lib >/dev/null mtree -deU -f ${.CURDIR}/etc/mtree/BSD.debug.dist \ -p ${WORLDTMP}/usr/lib >/dev/null .endif .if defined(LIBCOMPAT) mtree -deU -f ${.CURDIR}/etc/mtree/BSD.lib${libcompat}.dist \ -p ${WORLDTMP}/usr >/dev/null .if ${MK_DEBUG_FILES} != "no" mtree -deU -f ${.CURDIR}/etc/mtree/BSD.lib${libcompat}.dist \ -p ${WORLDTMP}/legacy/usr/lib/debug/usr >/dev/null mtree -deU -f ${.CURDIR}/etc/mtree/BSD.lib${libcompat}.dist \ -p ${WORLDTMP}/usr/lib/debug/usr >/dev/null .endif .endif .if ${MK_TESTS} != "no" mkdir -p ${WORLDTMP}${TESTSBASE} mtree -deU -f ${.CURDIR}/etc/mtree/BSD.tests.dist \ -p ${WORLDTMP}${TESTSBASE} >/dev/null .if ${MK_DEBUG_FILES} != "no" mkdir -p ${WORLDTMP}/usr/lib/debug/${TESTSBASE} mtree -deU -f ${.CURDIR}/etc/mtree/BSD.tests.dist \ -p ${WORLDTMP}/usr/lib/debug/${TESTSBASE} >/dev/null .endif .endif .for _mtree in ${LOCAL_MTREE} mtree -deU -f ${.CURDIR}/${_mtree} -p ${WORLDTMP} > /dev/null .endfor _legacy: @echo @echo "--------------------------------------------------------------" @echo ">>> stage 1.1: legacy release compatibility shims" @echo "--------------------------------------------------------------" ${_+_}cd ${.CURDIR}; ${BMAKE} legacy _bootstrap-tools: @echo @echo "--------------------------------------------------------------" @echo ">>> stage 1.2: bootstrap tools" @echo "--------------------------------------------------------------" ${_+_}cd ${.CURDIR}; ${BMAKE} bootstrap-tools _cleanobj: .if !defined(NO_CLEAN) @echo @echo "--------------------------------------------------------------" @echo ">>> stage 2.1: cleaning up the object tree" @echo "--------------------------------------------------------------" ${_+_}cd ${.CURDIR}; ${WMAKE} ${CLEANDIR} .if defined(LIBCOMPAT) ${_+_}cd ${.CURDIR}; ${LIBCOMPATWMAKE} -f Makefile.inc1 ${CLEANDIR} .endif .endif _obj: @echo @echo "--------------------------------------------------------------" @echo ">>> stage 2.2: rebuilding the object tree" @echo "--------------------------------------------------------------" ${_+_}cd ${.CURDIR}; ${WMAKE} obj _build-tools: @echo @echo "--------------------------------------------------------------" @echo ">>> stage 2.3: build tools" @echo "--------------------------------------------------------------" ${_+_}cd ${.CURDIR}; ${TMAKE} build-tools _cross-tools: @echo @echo "--------------------------------------------------------------" @echo ">>> stage 3: cross tools" @echo "--------------------------------------------------------------" @rm -f ${OBJTREE}${.CURDIR}/compiler-metadata.mk ${_+_}cd ${.CURDIR}; ${XMAKE} cross-tools ${_+_}cd ${.CURDIR}; ${XMAKE} kernel-tools _build-metadata: @echo @echo "--------------------------------------------------------------" @echo ">>> stage 3.1: recording build metadata" @echo "--------------------------------------------------------------" ${_+_}cd ${.CURDIR}; ${WMAKE} compiler-metadata.mk ${_+_}cd ${.CURDIR}; ${WMAKE} host-osreldate.h _includes: @echo @echo "--------------------------------------------------------------" @echo ">>> stage 4.1: building includes" @echo "--------------------------------------------------------------" # Special handling for SUBDIR_OVERRIDE in buildworld as they most likely need # headers from default SUBDIR. Do SUBDIR_OVERRIDE includes last. ${_+_}cd ${.CURDIR}; ${WMAKE} SUBDIR_OVERRIDE= SHARED=symlinks \ MK_INCLUDES=yes includes .if !empty(SUBDIR_OVERRIDE) && make(buildworld) ${_+_}cd ${.CURDIR}; ${WMAKE} MK_INCLUDES=yes SHARED=symlinks includes .endif _libraries: @echo @echo "--------------------------------------------------------------" @echo ">>> stage 4.2: building libraries" @echo "--------------------------------------------------------------" ${_+_}cd ${.CURDIR}; \ ${WMAKE} -DNO_FSCHG MK_COVERAGE=no MK_HTML=no -DNO_LINT MK_MAN=no \ MK_PROFILE=no MK_TESTS=no MK_TESTS_SUPPORT=${MK_TESTS} libraries everything: .PHONY @echo @echo "--------------------------------------------------------------" @echo ">>> stage 4.3: building everything" @echo "--------------------------------------------------------------" ${_+_}cd ${.CURDIR}; _PARALLEL_SUBDIR_OK=1 ${WMAKE} all WMAKE_TGTS= .if !defined(WORLDFAST) WMAKE_TGTS+= _worldtmp _legacy .if empty(SUBDIR_OVERRIDE) WMAKE_TGTS+= _bootstrap-tools .endif WMAKE_TGTS+= _cleanobj .if !defined(NO_OBJ) WMAKE_TGTS+= _obj .endif WMAKE_TGTS+= _build-tools _cross-tools WMAKE_TGTS+= _build-metadata WMAKE_TGTS+= _includes .endif .if !defined(NO_LIBS) WMAKE_TGTS+= _libraries .endif WMAKE_TGTS+= everything .if defined(LIBCOMPAT) && empty(SUBDIR_OVERRIDE) WMAKE_TGTS+= build${libcompat} .endif buildworld: buildworld_prologue ${WMAKE_TGTS} buildworld_epilogue .PHONY .ORDER: buildworld_prologue ${WMAKE_TGTS} buildworld_epilogue buildworld_prologue: .PHONY @echo "--------------------------------------------------------------" @echo ">>> World build started on `LC_ALL=C date`" @echo "--------------------------------------------------------------" buildworld_epilogue: .PHONY @echo @echo "--------------------------------------------------------------" @echo ">>> World build completed on `LC_ALL=C date`" @echo "--------------------------------------------------------------" # # We need to have this as a target because the indirection between Makefile # and Makefile.inc1 causes the correct PATH to be used, rather than a # modification of the current environment's PATH. In addition, we need # to quote multiword values. # buildenvvars: .PHONY @echo ${WMAKEENV:Q} ${.MAKE.EXPORTED:@v@$v=\"${$v}\"@} .if ${.TARGETS:Mbuildenv} .if ${.MAKEFLAGS:M-j} .error The buildenv target is incompatible with -j .endif .endif BUILDENV_DIR?= ${.CURDIR} buildenv: .PHONY @echo Entering world for ${TARGET_ARCH}:${TARGET} .if ${BUILDENV_SHELL:M*zsh*} @echo For ZSH you must run: export CPUTYPE=${TARGET_CPUTYPE} .endif @cd ${BUILDENV_DIR} && env ${WMAKEENV} BUILDENV=1 ${BUILDENV_SHELL} \ || true TOOLCHAIN_TGTS= ${WMAKE_TGTS:Neverything:Nbuild${libcompat}} toolchain: ${TOOLCHAIN_TGTS} .PHONY kernel-toolchain: ${TOOLCHAIN_TGTS:N_includes:N_libraries} .PHONY # # installcheck # # Checks to be sure system is ready for installworld/installkernel. # installcheck: _installcheck_world _installcheck_kernel .PHONY _installcheck_world: .PHONY _installcheck_kernel: .PHONY # # Require DESTDIR to be set if installing for a different architecture or # using the user/group database in the source tree. # .if ${TARGET_ARCH} != ${MACHINE_ARCH} || ${TARGET} != ${MACHINE} || \ defined(DB_FROM_SRC) .if !make(distributeworld) _installcheck_world: __installcheck_DESTDIR _installcheck_kernel: __installcheck_DESTDIR __installcheck_DESTDIR: .PHONY .if !defined(DESTDIR) || empty(DESTDIR) @echo "ERROR: Please set DESTDIR!"; \ false .endif .endif .endif .if !defined(DB_FROM_SRC) # # Check for missing UIDs/GIDs. # CHECK_UIDS= auditdistd CHECK_GIDS= audit .if ${MK_SENDMAIL} != "no" CHECK_UIDS+= smmsp CHECK_GIDS+= smmsp .endif .if ${MK_PF} != "no" CHECK_UIDS+= proxy CHECK_GIDS+= proxy authpf .endif .if ${MK_UNBOUND} != "no" CHECK_UIDS+= unbound CHECK_GIDS+= unbound .endif _installcheck_world: __installcheck_UGID __installcheck_UGID: .PHONY .for uid in ${CHECK_UIDS} @if ! `id -u ${uid} >/dev/null 2>&1`; then \ echo "ERROR: Required ${uid} user is missing, see /usr/src/UPDATING."; \ false; \ fi .endfor .for gid in ${CHECK_GIDS} @if ! `find / -prune -group ${gid} >/dev/null 2>&1`; then \ echo "ERROR: Required ${gid} group is missing, see /usr/src/UPDATING."; \ false; \ fi .endfor .endif # # If installing over the running system (DESTDIR is / or unset) and the install # includes rescue, try running rescue from the objdir as a sanity check. If # rescue is not functional (e.g., because it depends on a system call not # supported by the currently running kernel), abort the installation. # .if !make(distributeworld) && ${MK_RESCUE} != "no" && \ (empty(DESTDIR) || ${DESTDIR} == "/") && empty(BYPASS_INSTALLCHECK_SH) _installcheck_world: __installcheck_sh_check __installcheck_sh_check: .PHONY @if [ "`${OBJTREE}${.CURDIR}/rescue/rescue/rescue sh -c 'echo OK'`" != \ OK ]; then \ echo "rescue/sh check failed, installation aborted" >&2; \ false; \ fi .endif # # Required install tools to be saved in a scratch dir for safety. # .if ${MK_ZONEINFO} != "no" _zoneinfo= zic tzsetup .endif ITOOLS= [ awk cap_mkdb cat chflags chmod chown cmp cp \ date echo egrep find grep id install ${_install-info} \ ln make mkdir mtree mv pwd_mkdb \ rm sed services_mkdb sh strip sysctl test true uname wc ${_zoneinfo} \ ${LOCAL_ITOOLS} # Needed for share/man .if ${MK_MAN_UTILS} != "no" ITOOLS+=makewhatis .endif # # distributeworld # # Distributes everything compiled by a `buildworld'. # # installworld # # Installs everything compiled by a 'buildworld'. # # Non-base distributions produced by the base system EXTRA_DISTRIBUTIONS= doc .if defined(LIBCOMPAT) EXTRA_DISTRIBUTIONS+= lib${libcompat} .endif .if ${MK_TESTS} != "no" EXTRA_DISTRIBUTIONS+= tests .endif DEBUG_DISTRIBUTIONS= .if ${MK_DEBUG_FILES} != "no" DEBUG_DISTRIBUTIONS+= base ${EXTRA_DISTRIBUTIONS:S,doc,,:S,tests,,} .endif MTREE_MAGIC?= mtree 2.0 distributeworld installworld stageworld: _installcheck_world .PHONY mkdir -p ${INSTALLTMP} progs=$$(for prog in ${ITOOLS}; do \ if progpath=`which $$prog`; then \ echo $$progpath; \ else \ echo "Required tool $$prog not found in PATH." >&2; \ exit 1; \ fi; \ done); \ libs=$$(ldd -f "%o %p\n" -f "%o %p\n" $$progs 2>/dev/null | sort -u | \ while read line; do \ set -- $$line; \ if [ "$$2 $$3" != "not found" ]; then \ echo $$2; \ else \ echo "Required library $$1 not found." >&2; \ exit 1; \ fi; \ done); \ cp $$libs $$progs ${INSTALLTMP} cp -R $${PATH_LOCALE:-"/usr/share/locale"} ${INSTALLTMP}/locale .if defined(NO_ROOT) -mkdir -p ${METALOG:H} echo "#${MTREE_MAGIC}" > ${METALOG} .endif .if make(distributeworld) .for dist in ${EXTRA_DISTRIBUTIONS} -mkdir ${DESTDIR}/${DISTDIR}/${dist} mtree -deU -f ${.CURDIR}/etc/mtree/BSD.root.dist \ -p ${DESTDIR}/${DISTDIR}/${dist} >/dev/null mtree -deU -f ${.CURDIR}/etc/mtree/BSD.usr.dist \ -p ${DESTDIR}/${DISTDIR}/${dist}/usr >/dev/null mtree -deU -f ${.CURDIR}/etc/mtree/BSD.include.dist \ -p ${DESTDIR}/${DISTDIR}/${dist}/usr/include >/dev/null .if ${MK_DEBUG_FILES} != "no" mtree -deU -f ${.CURDIR}/etc/mtree/BSD.debug.dist \ -p ${DESTDIR}/${DISTDIR}/${dist}/usr/lib >/dev/null .endif .if defined(LIBCOMPAT) mtree -deU -f ${.CURDIR}/etc/mtree/BSD.lib${libcompat}.dist \ -p ${DESTDIR}/${DISTDIR}/${dist}/usr >/dev/null .if ${MK_DEBUG_FILES} != "no" mtree -deU -f ${.CURDIR}/etc/mtree/BSD.lib${libcompat}.dist \ -p ${DESTDIR}/${DISTDIR}/${dist}/usr/lib/debug/usr >/dev/null .endif .endif .if ${MK_TESTS} != "no" && ${dist} == "tests" -mkdir -p ${DESTDIR}/${DISTDIR}/${dist}${TESTSBASE} mtree -deU -f ${.CURDIR}/etc/mtree/BSD.tests.dist \ -p ${DESTDIR}/${DISTDIR}/${dist}${TESTSBASE} >/dev/null .if ${MK_DEBUG_FILES} != "no" mtree -deU -f ${.CURDIR}/etc/mtree/BSD.tests.dist \ -p ${DESTDIR}/${DISTDIR}/${dist}/usr/lib/debug/${TESTSBASE} >/dev/null .endif .endif .if defined(NO_ROOT) ${IMAKEENV} mtree -C -f ${.CURDIR}/etc/mtree/BSD.root.dist | \ sed -e 's#^\./#./${dist}/#' >> ${METALOG} ${IMAKEENV} mtree -C -f ${.CURDIR}/etc/mtree/BSD.usr.dist | \ sed -e 's#^\./#./${dist}/usr/#' >> ${METALOG} ${IMAKEENV} mtree -C -f ${.CURDIR}/etc/mtree/BSD.include.dist | \ sed -e 's#^\./#./${dist}/usr/include/#' >> ${METALOG} .if defined(LIBCOMPAT) ${IMAKEENV} mtree -C -f ${.CURDIR}/etc/mtree/BSD.lib${libcompat}.dist | \ sed -e 's#^\./#./${dist}/usr/#' >> ${METALOG} .endif .endif .endfor -mkdir ${DESTDIR}/${DISTDIR}/base ${_+_}cd ${.CURDIR}/etc; ${CROSSENV} PATH=${TMPPATH} ${MAKE} \ METALOG=${METALOG} ${IMAKE_INSTALL} ${IMAKE_MTREE} \ DISTBASE=/base DESTDIR=${DESTDIR}/${DISTDIR}/base \ LOCAL_MTREE=${LOCAL_MTREE:Q} distrib-dirs .endif ${_+_}cd ${.CURDIR}; ${IMAKE} re${.TARGET:S/world$//}; \ ${IMAKEENV} rm -rf ${INSTALLTMP} .if make(distributeworld) .for dist in ${EXTRA_DISTRIBUTIONS} find ${DESTDIR}/${DISTDIR}/${dist} -mindepth 1 -type d -empty -delete .endfor .if defined(NO_ROOT) .for dist in base ${EXTRA_DISTRIBUTIONS} @# For each file that exists in this dist, print the corresponding @# line from the METALOG. This relies on the fact that @# a line containing only the filename will sort immediately before @# the relevant mtree line. cd ${DESTDIR}/${DISTDIR}; \ find ./${dist} | sort -u ${METALOG} - | \ awk 'BEGIN { print "#${MTREE_MAGIC}" } !/ type=/ { file = $$1 } / type=/ { if ($$1 == file) { sub(/^\.\/${dist}\//, "./"); print } }' > \ ${DESTDIR}/${DISTDIR}/${dist}.meta .endfor .for dist in ${DEBUG_DISTRIBUTIONS} @# For each file that exists in this dist, print the corresponding @# line from the METALOG. This relies on the fact that @# a line containing only the filename will sort immediately before @# the relevant mtree line. cd ${DESTDIR}/${DISTDIR}; \ find ./${dist}/usr/lib/debug | sort -u ${METALOG} - | \ awk 'BEGIN { print "#${MTREE_MAGIC}" } !/ type=/ { file = $$1 } / type=/ { if ($$1 == file) { sub(/^\.\/${dist}\//, "./"); print } }' > \ ${DESTDIR}/${DISTDIR}/${dist}.debug.meta .endfor .endif .endif packageworld: .PHONY .for dist in base ${EXTRA_DISTRIBUTIONS} .if defined(NO_ROOT) ${_+_}cd ${DESTDIR}/${DISTDIR}/${dist}; \ tar cvf - --exclude usr/lib/debug \ @${DESTDIR}/${DISTDIR}/${dist}.meta | \ ${XZ_CMD} > ${PACKAGEDIR}/${dist}.txz .else ${_+_}cd ${DESTDIR}/${DISTDIR}/${dist}; \ tar cvf - --exclude usr/lib/debug . | \ ${XZ_CMD} > ${PACKAGEDIR}/${dist}.txz .endif .endfor .for dist in ${DEBUG_DISTRIBUTIONS} . if defined(NO_ROOT) ${_+_}cd ${DESTDIR}/${DISTDIR}/${dist}; \ tar cvf - @${DESTDIR}/${DISTDIR}/${dist}.debug.meta | \ ${XZ_CMD} > ${PACKAGEDIR}/${dist}-dbg.txz . else ${_+_}cd ${DESTDIR}/${DISTDIR}/${dist}; \ tar cvLf - usr/lib/debug | \ ${XZ_CMD} > ${PACKAGEDIR}/${dist}-dbg.txz . endif .endfor # # reinstall # # If you have a build server, you can NFS mount the source and obj directories # and do a 'make reinstall' on the *client* to install new binaries from the # most recent server build. # restage reinstall: .MAKE .PHONY @echo "--------------------------------------------------------------" @echo ">>> Making hierarchy" @echo "--------------------------------------------------------------" ${_+_}cd ${.CURDIR}; ${MAKE} -f Makefile.inc1 \ LOCAL_MTREE=${LOCAL_MTREE:Q} hierarchy .if make(restage) @echo "--------------------------------------------------------------" @echo ">>> Making distribution" @echo "--------------------------------------------------------------" ${_+_}cd ${.CURDIR}; ${MAKE} -f Makefile.inc1 \ LOCAL_MTREE=${LOCAL_MTREE:Q} distribution .endif @echo @echo "--------------------------------------------------------------" @echo ">>> Installing everything" @echo "--------------------------------------------------------------" ${_+_}cd ${.CURDIR}; ${MAKE} -f Makefile.inc1 install .if defined(LIBCOMPAT) ${_+_}cd ${.CURDIR}; ${MAKE} -f Makefile.inc1 install${libcompat} .endif redistribute: .MAKE .PHONY @echo "--------------------------------------------------------------" @echo ">>> Distributing everything" @echo "--------------------------------------------------------------" ${_+_}cd ${.CURDIR}; ${MAKE} -f Makefile.inc1 distribute .if defined(LIBCOMPAT) ${_+_}cd ${.CURDIR}; ${MAKE} -f Makefile.inc1 distribute${libcompat} \ DISTRIBUTION=lib${libcompat} .endif distrib-dirs distribution: .MAKE .PHONY ${_+_}cd ${.CURDIR}/etc; ${CROSSENV} PATH=${TMPPATH} ${MAKE} \ ${IMAKE_INSTALL} ${IMAKE_MTREE} METALOG=${METALOG} ${.TARGET} .if make(distribution) ${_+_}cd ${.CURDIR}; ${CROSSENV} PATH=${TMPPATH} \ ${MAKE} -f Makefile.inc1 ${IMAKE_INSTALL} \ METALOG=${METALOG} MK_TESTS=no installconfig .endif # # buildkernel and installkernel # # Which kernels to build and/or install is specified by setting # KERNCONF. If not defined a GENERIC kernel is built/installed. # Only the existing (depending TARGET) config files are used # for building kernels and only the first of these is designated # as the one being installed. # # Note that we have to use TARGET instead of TARGET_ARCH when # we're in kernel-land. Since only TARGET_ARCH is (expected) to # be set to cross-build, we have to make sure TARGET is set # properly. .if defined(KERNFAST) NO_KERNELCLEAN= t NO_KERNELCONFIG= t NO_KERNELOBJ= t # Shortcut for KERNCONF=Blah -DKERNFAST is now KERNFAST=Blah .if !defined(KERNCONF) && ${KERNFAST} != "1" KERNCONF=${KERNFAST} .endif .endif .if ${TARGET_ARCH} == "powerpc64" KERNCONF?= GENERIC64 .else KERNCONF?= GENERIC .endif INSTKERNNAME?= kernel KERNSRCDIR?= ${.CURDIR}/sys KRNLCONFDIR= ${KERNSRCDIR}/${TARGET}/conf KRNLOBJDIR= ${OBJTREE}${KERNSRCDIR} KERNCONFDIR?= ${KRNLCONFDIR} BUILDKERNELS= INSTALLKERNEL= .if defined(NO_INSTALLKERNEL) # All of the BUILDKERNELS loops start at index 1. BUILDKERNELS+= dummy .endif .for _kernel in ${KERNCONF} .if exists(${KERNCONFDIR}/${_kernel}) BUILDKERNELS+= ${_kernel} .if empty(INSTALLKERNEL) && !defined(NO_INSTALLKERNEL) INSTALLKERNEL= ${_kernel} .endif .endif .endfor ${WMAKE_TGTS:N_worldtmp:Nbuild${libcompat}} ${.ALLTARGETS:M_*:N_worldtmp}: .MAKE .PHONY # # buildkernel # # Builds all kernels defined by BUILDKERNELS. # buildkernel: .MAKE .PHONY .if empty(BUILDKERNELS:Ndummy) @echo "ERROR: Missing kernel configuration file(s) (${KERNCONF})."; \ false .endif @echo .for _kernel in ${BUILDKERNELS:Ndummy} @echo "--------------------------------------------------------------" @echo ">>> Kernel build for ${_kernel} started on `LC_ALL=C date`" @echo "--------------------------------------------------------------" @echo "===> ${_kernel}" mkdir -p ${KRNLOBJDIR} .if !defined(NO_KERNELCONFIG) @echo @echo "--------------------------------------------------------------" @echo ">>> stage 1: configuring the kernel" @echo "--------------------------------------------------------------" cd ${KRNLCONFDIR}; \ PATH=${TMPPATH} \ config ${CONFIGARGS} -d ${KRNLOBJDIR}/${_kernel} \ -I '${KERNCONFDIR}' '${KERNCONFDIR}/${_kernel}' .endif .if !defined(NO_CLEAN) && !defined(NO_KERNELCLEAN) @echo @echo "--------------------------------------------------------------" @echo ">>> stage 2.1: cleaning up the object tree" @echo "--------------------------------------------------------------" ${_+_}cd ${KRNLOBJDIR}/${_kernel}; ${KMAKE} ${CLEANDIR} .endif .if !defined(NO_KERNELOBJ) @echo @echo "--------------------------------------------------------------" @echo ">>> stage 2.2: rebuilding the object tree" @echo "--------------------------------------------------------------" ${_+_}cd ${KRNLOBJDIR}/${_kernel}; ${KMAKE} obj .endif @echo @echo "--------------------------------------------------------------" @echo ">>> stage 2.3: build tools" @echo "--------------------------------------------------------------" ${_+_}cd ${.CURDIR}; ${KTMAKE} kernel-tools @echo @echo "--------------------------------------------------------------" @echo ">>> stage 3.1: building everything" @echo "--------------------------------------------------------------" ${_+_}cd ${KRNLOBJDIR}/${_kernel}; ${KMAKE} all -DNO_MODULES_OBJ @echo "--------------------------------------------------------------" @echo ">>> Kernel build for ${_kernel} completed on `LC_ALL=C date`" @echo "--------------------------------------------------------------" .endfor NO_INSTALLEXTRAKERNELS?= yes # # installkernel, etc. # # Install the kernel defined by INSTALLKERNEL # installkernel installkernel.debug \ reinstallkernel reinstallkernel.debug: _installcheck_kernel .PHONY .if !defined(NO_INSTALLKERNEL) .if empty(INSTALLKERNEL) @echo "ERROR: No kernel \"${KERNCONF}\" to install."; \ false .endif @echo "--------------------------------------------------------------" @echo ">>> Installing kernel ${INSTALLKERNEL}" @echo "--------------------------------------------------------------" cd ${KRNLOBJDIR}/${INSTALLKERNEL}; \ ${CROSSENV} PATH=${TMPPATH} \ ${MAKE} ${IMAKE_INSTALL} KERNEL=${INSTKERNNAME} ${.TARGET:S/kernel//} .endif .if ${BUILDKERNELS:[#]} > 1 && ${NO_INSTALLEXTRAKERNELS} != "yes" .for _kernel in ${BUILDKERNELS:[2..-1]} @echo "--------------------------------------------------------------" @echo ">>> Installing kernel ${_kernel}" @echo "--------------------------------------------------------------" cd ${KRNLOBJDIR}/${_kernel}; \ ${CROSSENV} PATH=${TMPPATH} \ ${MAKE} ${IMAKE_INSTALL} KERNEL=${INSTKERNNAME}.${_kernel} ${.TARGET:S/kernel//} .endfor .endif distributekernel distributekernel.debug: .PHONY .if !defined(NO_INSTALLKERNEL) .if empty(INSTALLKERNEL) @echo "ERROR: No kernel \"${KERNCONF}\" to install."; \ false .endif mkdir -p ${DESTDIR}/${DISTDIR} .if defined(NO_ROOT) @echo "#${MTREE_MAGIC}" > ${DESTDIR}/${DISTDIR}/kernel.premeta .endif cd ${KRNLOBJDIR}/${INSTALLKERNEL}; \ ${IMAKEENV} ${IMAKE_INSTALL:S/METALOG/kernel.premeta/} \ ${IMAKE_MTREE} PATH=${TMPPATH} ${MAKE} KERNEL=${INSTKERNNAME} \ DESTDIR=${INSTALL_DDIR}/kernel \ ${.TARGET:S/distributekernel/install/} .if defined(NO_ROOT) @sed -e 's|^./kernel|.|' ${DESTDIR}/${DISTDIR}/kernel.premeta > \ ${DESTDIR}/${DISTDIR}/kernel.meta .endif .endif .if ${BUILDKERNELS:[#]} > 1 && ${NO_INSTALLEXTRAKERNELS} != "yes" .for _kernel in ${BUILDKERNELS:[2..-1]} .if defined(NO_ROOT) @echo "#${MTREE_MAGIC}" > ${DESTDIR}/${DISTDIR}/kernel.${_kernel}.premeta .endif cd ${KRNLOBJDIR}/${_kernel}; \ ${IMAKEENV} ${IMAKE_INSTALL:S/METALOG/kernel.${_kernel}.premeta/} \ ${IMAKE_MTREE} PATH=${TMPPATH} ${MAKE} \ KERNEL=${INSTKERNNAME}.${_kernel} \ DESTDIR=${INSTALL_DDIR}/kernel.${_kernel} \ ${.TARGET:S/distributekernel/install/} .if defined(NO_ROOT) @sed -e "s|^./kernel.${_kernel}|.|" \ ${DESTDIR}/${DISTDIR}/kernel.${_kernel}.premeta > \ ${DESTDIR}/${DISTDIR}/kernel.${_kernel}.meta .endif .endfor .endif packagekernel: .PHONY .if defined(NO_ROOT) .if !defined(NO_INSTALLKERNEL) cd ${DESTDIR}/${DISTDIR}/kernel; \ tar cvf - --exclude '*.debug' \ @${DESTDIR}/${DISTDIR}/kernel.meta | \ ${XZ_CMD} > ${PACKAGEDIR}/kernel.txz .endif cd ${DESTDIR}/${DISTDIR}/kernel; \ tar cvf - --include '*/*/*.debug' \ @${DESTDIR}/${DISTDIR}/kernel.meta | \ ${XZ_CMD} > ${DESTDIR}/${DISTDIR}/kernel-dbg.txz .if ${BUILDKERNELS:[#]} > 1 && ${NO_INSTALLEXTRAKERNELS} != "yes" .for _kernel in ${BUILDKERNELS:[2..-1]} cd ${DESTDIR}/${DISTDIR}/kernel.${_kernel}; \ tar cvf - --exclude '*.debug' \ @${DESTDIR}/${DISTDIR}/kernel.${_kernel}.meta | \ ${XZ_CMD} > ${PACKAGEDIR}/kernel.${_kernel}.txz cd ${DESTDIR}/${DISTDIR}/kernel.${_kernel}; \ tar cvf - --include '*/*/*.debug' \ @${DESTDIR}/${DISTDIR}/kernel.${_kernel}.meta | \ ${XZ_CMD} > ${DESTDIR}/${DISTDIR}/kernel.${_kernel}-dbg.txz .endfor .endif .else .if !defined(NO_INSTALLKERNEL) cd ${DESTDIR}/${DISTDIR}/kernel; \ tar cvf - --exclude '*.debug' . | \ ${XZ_CMD} > ${PACKAGEDIR}/kernel.txz .endif cd ${DESTDIR}/${DISTDIR}/kernel; \ tar cvf - --include '*/*/*.debug' $$(eval find .) | \ ${XZ_CMD} > ${DESTDIR}/${DISTDIR}/kernel-dbg.txz .if ${BUILDKERNELS:[#]} > 1 && ${NO_INSTALLEXTRAKERNELS} != "yes" .for _kernel in ${BUILDKERNELS:[2..-1]} cd ${DESTDIR}/${DISTDIR}/kernel.${_kernel}; \ tar cvf - --exclude '*.debug' . | \ ${XZ_CMD} > ${PACKAGEDIR}/kernel.${_kernel}.txz cd ${DESTDIR}/${DISTDIR}/kernel.${_kernel}; \ tar cvf - --include '*/*/*.debug' $$(eval find .) | \ ${XZ_CMD} > ${DESTDIR}/${DISTDIR}/kernel.${_kernel}-dbg.txz .endfor .endif .endif stagekernel: .PHONY ${_+_}${MAKE} -C ${.CURDIR} ${.MAKEFLAGS} distributekernel PORTSDIR?= /usr/ports WSTAGEDIR?= ${MAKEOBJDIRPREFIX}${.CURDIR}/${TARGET}.${TARGET_ARCH}/worldstage KSTAGEDIR?= ${MAKEOBJDIRPREFIX}${.CURDIR}/${TARGET}.${TARGET_ARCH}/kernelstage REPODIR?= ${MAKEOBJDIRPREFIX}${.CURDIR}/repo PKGSIGNKEY?= # empty .ORDER: stage-packages create-packages .ORDER: create-packages create-world-packages .ORDER: create-packages create-kernel-packages .ORDER: create-packages sign-packages _pkgbootstrap: .PHONY .if !exists(${LOCALBASE}/sbin/pkg) @env ASSUME_ALWAYS_YES=YES pkg bootstrap .endif packages: .PHONY ${_+_}${MAKE} -C ${.CURDIR} PKG_VERSION=${PKG_VERSION} real-packages package-pkg: .PHONY rm -rf /tmp/ports.${TARGET} || : env ${WMAKEENV:Q} SRCDIR=${.CURDIR} PORTSDIR=${PORTSDIR} REVISION=${_REVISION} \ PKG_CMD=${PKG_CMD} PKG_VERSION=${PKG_VERSION} REPODIR=${REPODIR} \ WSTAGEDIR=${WSTAGEDIR} \ sh ${.CURDIR}/release/scripts/make-pkg-package.sh real-packages: stage-packages create-packages sign-packages .PHONY stage-packages-world: .PHONY @mkdir -p ${WSTAGEDIR} ${_+_}@cd ${.CURDIR}; \ ${MAKE} DESTDIR=${WSTAGEDIR} -DNO_ROOT stageworld stage-packages-kernel: .PHONY @mkdir -p ${KSTAGEDIR} ${_+_}@cd ${.CURDIR}; \ ${MAKE} DESTDIR=${KSTAGEDIR} -DNO_ROOT stagekernel stage-packages: .PHONY stage-packages-world stage-packages-kernel _repodir: .PHONY @mkdir -p ${REPODIR} create-packages-world: _pkgbootstrap _repodir .PHONY ${_+_}@cd ${.CURDIR}; \ ${MAKE} -f Makefile.inc1 \ DESTDIR=${WSTAGEDIR} \ PKG_VERSION=${PKG_VERSION} create-world-packages create-packages-kernel: _pkgbootstrap _repodir .PHONY ${_+_}@cd ${.CURDIR}; \ ${MAKE} -f Makefile.inc1 \ DESTDIR=${KSTAGEDIR} \ PKG_VERSION=${PKG_VERSION} DISTDIR=kernel \ create-kernel-packages create-packages: .PHONY create-packages-world create-packages-kernel create-world-packages: _pkgbootstrap .PHONY @rm -f ${WSTAGEDIR}/*.plist 2>/dev/null || : @cd ${WSTAGEDIR} ; \ awk -f ${SRCDIR}/release/scripts/mtree-to-plist.awk \ ${WSTAGEDIR}/METALOG @for plist in ${WSTAGEDIR}/*.plist; do \ plist=$${plist##*/} ; \ pkgname=$${plist%.plist} ; \ echo "_PKGS+= $${pkgname}" ; \ done > ${WSTAGEDIR}/packages.mk ${_+_}@cd ${.CURDIR}; \ ${MAKE} -f Makefile.inc1 create-world-packages-jobs \ .MAKE.JOB.PREFIX= .if make(create-world-packages-jobs) .include "${WSTAGEDIR}/packages.mk" .endif create-world-packages-jobs: .PHONY .for pkgname in ${_PKGS} create-world-packages-jobs: create-world-package-${pkgname} create-world-package-${pkgname}: .PHONY @sh ${SRCDIR}/release/packages/generate-ucl.sh -o ${pkgname} \ -s ${SRCDIR} -u ${WSTAGEDIR}/${pkgname}.ucl @awk -F\" ' \ /^name/ { printf("===> Creating %s-", $$2); next } \ /^version/ { print $$2; next } \ ' ${WSTAGEDIR}/${pkgname}.ucl ; \ ${PKG_CMD} -o ABI_FILE=${WSTAGEDIR}/bin/sh -o ALLOW_BASE_SHLIBS=yes \ create -M ${WSTAGEDIR}/${pkgname}.ucl \ -p ${WSTAGEDIR}/${pkgname}.plist \ -r ${WSTAGEDIR} \ -o ${REPODIR}/$$(${PKG_CMD} -o ABI_FILE=${WSTAGEDIR}/bin/sh config ABI)/${PKG_VERSION} .endfor create-kernel-packages: .PHONY _default_flavor= -default .if exists(${KSTAGEDIR}/kernel.meta) .for flavor in "" -debug create-kernel-packages: create-kernel-packages-flavor${flavor:C,^""$,${_default_flavor},} create-kernel-packages-flavor${flavor:C,^""$,${_default_flavor},}: _pkgbootstrap .PHONY @cd ${KSTAGEDIR}/${DISTDIR} ; \ awk -f ${SRCDIR}/release/scripts/mtree-to-plist.awk \ -v kernel=yes -v _kernconf=${INSTALLKERNEL} \ ${KSTAGEDIR}/kernel.meta ; \ cap_arg=`cd ${SRCDIR}/etc ; ${MAKE} -VCAP_MKDB_ENDIAN` ; \ pwd_arg=`cd ${SRCDIR}/etc ; ${MAKE} -VPWD_MKDB_ENDIAN` ; \ sed -e "s/%VERSION%/${PKG_VERSION}/" \ -e "s/%PKGNAME%/kernel-${INSTALLKERNEL:tl}${flavor}/" \ -e "s/%COMMENT%/FreeBSD ${INSTALLKERNEL} kernel ${flavor}/" \ -e "s/%DESC%/FreeBSD ${INSTALLKERNEL} kernel ${flavor}/" \ -e "s/%CAP_MKDB_ENDIAN%/$${cap_arg}/g" \ -e "s/%PWD_MKDB_ENDIAN%/$${pwd_arg}/g" \ ${SRCDIR}/release/packages/kernel.ucl \ > ${KSTAGEDIR}/${DISTDIR}/kernel.${INSTALLKERNEL}${flavor}.ucl ; \ awk -F\" ' \ /name/ { printf("===> Creating %s-", $$2); next } \ /version/ {print $$2; next } ' \ ${KSTAGEDIR}/${DISTDIR}/kernel.${INSTALLKERNEL}${flavor}.ucl ; \ ${PKG_CMD} -o ABI_FILE=${WSTAGEDIR}/bin/sh -o ALLOW_BASE_SHLIBS=yes \ create -M ${KSTAGEDIR}/${DISTDIR}/kernel.${INSTALLKERNEL}${flavor}.ucl \ -p ${KSTAGEDIR}/${DISTDIR}/kernel.${INSTALLKERNEL}${flavor}.plist \ -r ${KSTAGEDIR}/${DISTDIR} \ -o ${REPODIR}/$$(${PKG_CMD} -o ABI_FILE=${WSTAGEDIR}/bin/sh config ABI)/${PKG_VERSION} .endfor .endif .if ${BUILDKERNELS:[#]} > 1 && ${NO_INSTALLEXTRAKERNELS} != "yes" .for _kernel in ${BUILDKERNELS:[2..-1]} .if exists(${KSTAGEDIR}/kernel.${_kernel}.meta) .for flavor in "" -debug create-kernel-packages: create-kernel-packages-extra-flavor${flavor:C,^""$,${_default_flavor},}-${_kernel} create-kernel-packages-extra-flavor${flavor:C,^""$,${_default_flavor},}-${_kernel}: _pkgbootstrap .PHONY @cd ${KSTAGEDIR}/kernel.${_kernel} ; \ awk -f ${SRCDIR}/release/scripts/mtree-to-plist.awk \ -v kernel=yes -v _kernconf=${_kernel} \ ${KSTAGEDIR}/kernel.${_kernel}.meta ; \ cap_arg=`cd ${SRCDIR}/etc ; ${MAKE} -VCAP_MKDB_ENDIAN` ; \ pwd_arg=`cd ${SRCDIR}/etc ; ${MAKE} -VPWD_MKDB_ENDIAN` ; \ sed -e "s/%VERSION%/${PKG_VERSION}/" \ -e "s/%PKGNAME%/kernel-${_kernel:tl}${flavor}/" \ -e "s/%COMMENT%/FreeBSD ${_kernel} kernel ${flavor}/" \ -e "s/%DESC%/FreeBSD ${_kernel} kernel ${flavor}/" \ -e "s/%CAP_MKDB_ENDIAN%/$${cap_arg}/g" \ -e "s/%PWD_MKDB_ENDIAN%/$${pwd_arg}/g" \ ${SRCDIR}/release/packages/kernel.ucl \ > ${KSTAGEDIR}/kernel.${_kernel}/kernel.${_kernel}${flavor}.ucl ; \ awk -F\" ' \ /name/ { printf("===> Creating %s-", $$2); next } \ /version/ {print $$2; next } ' \ ${KSTAGEDIR}/kernel.${_kernel}/kernel.${_kernel}${flavor}.ucl ; \ ${PKG_CMD} -o ABI_FILE=${WSTAGEDIR}/bin/sh -o ALLOW_BASE_SHLIBS=yes \ create -M ${KSTAGEDIR}/kernel.${_kernel}/kernel.${_kernel}${flavor}.ucl \ -p ${KSTAGEDIR}/kernel.${_kernel}/kernel.${_kernel}${flavor}.plist \ -r ${KSTAGEDIR}/kernel.${_kernel} \ -o ${REPODIR}/$$(${PKG_CMD} -o ABI_FILE=${WSTAGEDIR}/bin/sh config ABI)/${PKG_VERSION} .endfor .endif .endfor .endif sign-packages: _pkgbootstrap .PHONY @[ -L "${REPODIR}/$$(${PKG_CMD} -o ABI_FILE=${WSTAGEDIR}/bin/sh config ABI)/latest" ] && \ unlink ${REPODIR}/$$(${PKG_CMD} -o ABI_FILE=${WSTAGEDIR}/bin/sh config ABI)/latest ; \ ${PKG_CMD} -o ABI_FILE=${WSTAGEDIR}/bin/sh repo \ -o ${REPODIR}/$$(${PKG_CMD} -o ABI_FILE=${WSTAGEDIR}/bin/sh config ABI)/${PKG_VERSION} \ ${REPODIR}/$$(${PKG_CMD} -o ABI_FILE=${WSTAGEDIR}/bin/sh config ABI)/${PKG_VERSION} \ ${PKGSIGNKEY} ; \ cd ${REPODIR}/$$(${PKG_CMD} -o ABI_FILE=${WSTAGEDIR}/bin/sh config ABI); \ ln -s ${PKG_VERSION} latest # # # checkworld # # Run test suite on installed world. # checkworld: .PHONY @if [ ! -x "${LOCALBASE}/bin/kyua" ]; then \ echo "You need kyua (devel/kyua) to run the test suite." | /usr/bin/fmt; \ exit 1; \ fi ${_+_}PATH="$$PATH:${LOCALBASE}/bin" kyua test -k ${TESTSBASE}/Kyuafile # # # doxygen # # Build the API documentation with doxygen # doxygen: .PHONY @if [ ! -x "${LOCALBASE}/bin/doxygen" ]; then \ echo "You need doxygen (devel/doxygen) to generate the API documentation of the kernel." | /usr/bin/fmt; \ exit 1; \ fi ${_+_}cd ${.CURDIR}/tools/kerneldoc/subsys; ${MAKE} obj all # # update # # Update the source tree(s), by running svn/svnup to update to the # latest copy. # update: .PHONY .if defined(SVN_UPDATE) @echo "--------------------------------------------------------------" @echo ">>> Updating ${.CURDIR} using Subversion" @echo "--------------------------------------------------------------" @(cd ${.CURDIR}; ${SVN} update ${SVNFLAGS}) .endif # # ------------------------------------------------------------------------ # # From here onwards are utility targets used by the 'make world' and # related targets. If your 'world' breaks, you may like to try to fix # the problem and manually run the following targets to attempt to # complete the build. Beware, this is *not* guaranteed to work, you # need to have a pretty good grip on the current state of the system # to attempt to manually finish it. If in doubt, 'make world' again. # # # legacy: Build compatibility shims for the next three targets. This is a # minimal set of tools and shims necessary to compensate for older systems # which don't have the APIs required by the targets built in bootstrap-tools, # build-tools or cross-tools. # # ELF Tool Chain libraries are needed for ELF tools and dtrace tools. # r296685 fix cross-endian objcopy .if ${BOOTSTRAPPING} < 1100102 _elftoolchain_libs= lib/libelf lib/libdwarf .endif legacy: .PHONY # Temporary special case for automatically detecting the clang compiler issue # Note: 9.x didn't have FreeBSD_version bumps often enough, so you may need to # set BOOTSTRAPPING to 0 if you're stable/9 tree post-dates r286035 but is before # the version bump in r296219 (from July 29, 2015 -> Feb 29, 2016). .if ${BOOTSTRAPPING} != 0 && \ ${WANT_COMPILER_TYPE} == "clang" && ${COMPILER_TYPE} == "clang" && ${COMPILER_VERSION} < 30601 .if ${BOOTSTRAPPING} > 10000000 && ${BOOTSTRAPPING} < 1002501 @echo "ERROR: Source upgrades from stable/10 prior to r286033 are not supported."; false .elif ${BOOTSTRAPPING} > 9000000 && ${BOOTSTRAPPING} < 903509 @echo "ERROR: Source upgrades from stable/9 prior to r286035 are not supported."; false .endif .endif .if ${BOOTSTRAPPING} < ${MINIMUM_SUPPORTED_OSREL} && ${BOOTSTRAPPING} != 0 @echo "ERROR: Source upgrades from versions prior to ${MINIMUM_SUPPORTED_REL} are not supported."; \ false .endif .for _tool in tools/build ${_elftoolchain_libs} ${_+_}@${ECHODIR} "===> ${_tool} (obj,includes,all,install)"; \ cd ${.CURDIR}/${_tool}; \ if [ -z "${NO_OBJ}" ]; then ${MAKE} DIRPRFX=${_tool}/ obj; fi; \ ${MAKE} DIRPRFX=${_tool}/ DESTDIR=${MAKEOBJDIRPREFIX}/legacy includes; \ ${MAKE} DIRPRFX=${_tool}/ MK_INCLUDES=no all; \ ${MAKE} DIRPRFX=${_tool}/ MK_INCLUDES=no \ DESTDIR=${MAKEOBJDIRPREFIX}/legacy install .endfor # # bootstrap-tools: Build tools needed for compatibility. These are binaries that # are built to build other binaries in the system. However, the focus of these # binaries is usually quite narrow. Bootstrap tools use the host's compiler and # libraries, augmented by -legacy. # _bt= _bootstrap-tools .if ${MK_GAMES} != "no" _strfile= usr.bin/fortune/strfile .endif .if ${MK_GCC} != "no" && ${MK_CXX} != "no" _gperf= gnu/usr.bin/gperf .endif .if ${MK_VT} != "no" _vtfontcvt= usr.bin/vtfontcvt .endif .if ${BOOTSTRAPPING} < 1000033 _libopenbsd= lib/libopenbsd _m4= usr.bin/m4 _lex= usr.bin/lex ${_bt}-usr.bin/m4: ${_bt}-lib/libopenbsd ${_bt}-usr.bin/lex: ${_bt}-usr.bin/m4 .endif # r245440 mtree -N support added # r313404 requires sha384.h for libnetbsd, added to libmd in r292782 .if ${BOOTSTRAPPING} < 1100093 _nmtree= lib/libmd \ lib/libnetbsd \ usr.sbin/nmtree ${_bt}-lib/libnetbsd: ${_bt}-lib/libmd ${_bt}-usr.sbin/nmtree: ${_bt}-lib/libnetbsd .endif # r246097: log addition login.conf.db, passwd, pwd.db, and spwd.db with cat -l .if ${BOOTSTRAPPING} < 1000027 _cat= bin/cat .endif # r277259 crunchide: Correct 64-bit section header offset # r281674 crunchide: always include both 32- and 64-bit ELF support .if ${BOOTSTRAPPING} < 1100078 _crunchide= usr.sbin/crunch/crunchide .endif # r285986 crunchen: use STRIPBIN rather than STRIP # 1100113: Support MK_AUTO_OBJ # 1200006: META_MODE fixes .if ${BOOTSTRAPPING} < 1100078 || \ (${MK_AUTO_OBJ} == "yes" && ${BOOTSTRAPPING} < 1100114) || \ (${MK_META_MODE} == "yes" && ${BOOTSTRAPPING} < 1200006) _crunchgen= usr.sbin/crunch/crunchgen .endif # r296926 -P keymap search path, MFC to stable/10 in r298297 .if ${BOOTSTRAPPING} < 1003501 || \ (${BOOTSTRAPPING} >= 1100000 && ${BOOTSTRAPPING} < 1100103) _kbdcontrol= usr.sbin/kbdcontrol .endif _yacc= lib/liby \ usr.bin/yacc ${_bt}-usr.bin/yacc: ${_bt}-lib/liby .if ${MK_BSNMP} != "no" _gensnmptree= usr.sbin/bsnmpd/gensnmptree .endif # We need to build tblgen when we're building clang or lld, either as # bootstrap tools, or as the part of the normal build. .if ${MK_CLANG_BOOTSTRAP} != "no" || ${MK_CLANG} != "no" || \ ${MK_LLD_BOOTSTRAP} != "no" || ${MK_LLD} != "no" _clang_tblgen= \ lib/clang/libllvmminimal \ usr.bin/clang/llvm-tblgen \ usr.bin/clang/clang-tblgen ${_bt}-usr.bin/clang/clang-tblgen: ${_bt}-lib/clang/libllvmminimal ${_bt}-usr.bin/clang/llvm-tblgen: ${_bt}-lib/clang/libllvmminimal .endif # Default to building the GPL DTC, but build the BSDL one if users explicitly # request it. _dtc= usr.bin/dtc .if ${MK_GPL_DTC} != "no" _dtc= gnu/usr.bin/dtc .endif .if ${MK_KERBEROS} != "no" _kerberos5_bootstrap_tools= \ kerberos5/tools/make-roken \ kerberos5/lib/libroken \ kerberos5/lib/libvers \ kerberos5/tools/asn1_compile \ kerberos5/tools/slc \ usr.bin/compile_et .ORDER: ${_kerberos5_bootstrap_tools:C/^/${_bt}-/g} .endif # r283777 makewhatis(1) replaced with mandoc version which builds a database. _libopenbsd?= lib/libopenbsd _makewhatis= usr.bin/mandoc ${_bt}-usr.bin/mandoc: ${_bt}-lib/libopenbsd bootstrap-tools: .PHONY # Please document (add comment) why something is in 'bootstrap-tools'. # Try to bound the building of the bootstrap-tool to just the # FreeBSD versions that need the tool built at this stage of the build. .for _tool in \ ${_clang_tblgen} \ ${_kerberos5_bootstrap_tools} \ ${_strfile} \ ${_gperf} \ ${_dtc} \ ${_cat} \ ${_kbdcontrol} \ usr.bin/lorder \ ${_libopenbsd} \ ${_makewhatis} \ usr.bin/rpcgen \ ${_yacc} \ ${_m4} \ ${_lex} \ usr.bin/xinstall \ ${_gensnmptree} \ usr.sbin/config \ ${_crunchide} \ ${_crunchgen} \ ${_nmtree} \ ${_vtfontcvt} \ usr.bin/localedef ${_bt}-${_tool}: .PHONY .MAKE ${_+_}@${ECHODIR} "===> ${_tool} (obj,all,install)"; \ cd ${.CURDIR}/${_tool}; \ if [ -z "${NO_OBJ}" ]; then ${MAKE} DIRPRFX=${_tool}/ obj; fi; \ ${MAKE} DIRPRFX=${_tool}/ all; \ ${MAKE} DIRPRFX=${_tool}/ DESTDIR=${MAKEOBJDIRPREFIX}/legacy install bootstrap-tools: ${_bt}-${_tool} .endfor # # build-tools: Build special purpose build tools # .if !defined(NO_SHARE) _share= share/syscons/scrnmaps .endif .if ${MK_GCC} != "no" _gcc_tools= gnu/usr.bin/cc/cc_tools .endif .if ${MK_RESCUE} != "no" # rescue includes programs that have build-tools targets _rescue=rescue/rescue .endif .for _tool in \ bin/csh \ bin/sh \ ${LOCAL_TOOL_DIRS} \ lib/ncurses/ncurses \ lib/ncurses/ncursesw \ ${_rescue} \ ${_share} \ usr.bin/awk \ lib/libmagic \ usr.bin/mkesdb_static \ usr.bin/mkcsmapper_static \ usr.bin/vi/catalog build-tools_${_tool}: .PHONY ${_+_}@${ECHODIR} "===> ${_tool} (obj,build-tools)"; \ cd ${.CURDIR}/${_tool}; \ if [ -z "${NO_OBJ}" ]; then ${MAKE} DIRPRFX=${_tool}/ obj; fi; \ ${MAKE} DIRPRFX=${_tool}/ build-tools build-tools: build-tools_${_tool} .endfor .for _tool in \ ${_gcc_tools} build-tools_${_tool}: .PHONY ${_+_}@${ECHODIR} "===> ${_tool} (obj,all)"; \ cd ${.CURDIR}/${_tool}; \ if [ -z "${NO_OBJ}" ]; then ${MAKE} DIRPRFX=${_tool}/ obj; fi; \ ${MAKE} DIRPRFX=${_tool}/ all build-tools: build-tools_${_tool} .endfor # # kernel-tools: Build kernel-building tools # kernel-tools: .PHONY mkdir -p ${MAKEOBJDIRPREFIX}/usr mtree -deU -f ${.CURDIR}/etc/mtree/BSD.usr.dist \ -p ${MAKEOBJDIRPREFIX}/usr >/dev/null # # cross-tools: All the tools needed to build the rest of the system after # we get done with the earlier stages. It is the last set of tools needed # to begin building the target binaries. # .if ${TARGET_ARCH} != ${MACHINE_ARCH} .if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "i386" _btxld= usr.sbin/btxld .endif .endif # Rebuild ctfconvert and ctfmerge to avoid difficult-to-diagnose failures # resulting from missing bug fixes or ELF Toolchain updates. .if ${MK_CDDL} != "no" _dtrace_tools= cddl/lib/libctf cddl/usr.bin/ctfconvert \ cddl/usr.bin/ctfmerge .endif # If we're given an XAS, don't build binutils. .if ${XAS:M/*} == "" .if ${MK_BINUTILS_BOOTSTRAP} != "no" _binutils= gnu/usr.bin/binutils .endif .if ${MK_ELFTOOLCHAIN_BOOTSTRAP} != "no" _elftctools= lib/libelftc \ lib/libpe \ usr.bin/elfcopy \ usr.bin/nm \ usr.bin/size \ usr.bin/strings # These are not required by the build, but can be useful for developers who # cross-build on a FreeBSD 10 host: _elftctools+= usr.bin/addr2line .endif .elif ${TARGET_ARCH} != ${MACHINE_ARCH} && ${MK_ELFTOOLCHAIN_BOOTSTRAP} != "no" # If cross-building with an external binutils we still need to build strip for # the target (for at least crunchide). _elftctools= lib/libelftc \ lib/libpe \ usr.bin/elfcopy .endif .if ${MK_CLANG_BOOTSTRAP} != "no" _clang= usr.bin/clang .endif .if ${MK_LLD_BOOTSTRAP} != "no" _lld= usr.bin/clang/lld .endif .if ${MK_CLANG_BOOTSTRAP} != "no" || ${MK_LLD_BOOTSTRAP} != "no" _clang_libs= lib/clang .endif .if ${MK_GCC_BOOTSTRAP} != "no" _gcc= gnu/usr.bin/cc .endif .if ${MK_USB} != "no" _usb_tools= sys/boot/usb/tools .endif cross-tools: .MAKE .PHONY .for _tool in \ ${LOCAL_XTOOL_DIRS} \ ${_clang_libs} \ ${_clang} \ ${_lld} \ ${_binutils} \ ${_elftctools} \ ${_dtrace_tools} \ ${_gcc} \ ${_btxld} \ ${_usb_tools} ${_+_}@${ECHODIR} "===> ${_tool} (obj,all,install)"; \ cd ${.CURDIR}/${_tool}; \ if [ -z "${NO_OBJ}" ]; then ${MAKE} DIRPRFX=${_tool}/ obj; fi; \ ${MAKE} DIRPRFX=${_tool}/ all; \ ${MAKE} DIRPRFX=${_tool}/ DESTDIR=${MAKEOBJDIRPREFIX} install .endfor NXBDESTDIR= ${OBJTREE}/nxb-bin NXBENV= MAKEOBJDIRPREFIX=${OBJTREE}/nxb \ TOOLS_PREFIX= \ INSTALL="sh ${.CURDIR}/tools/install.sh" \ PATH=${PATH}:${OBJTREE}/gperf_for_gcc/usr/bin NXBMAKE= ${NXBENV} ${MAKE} \ LLVM_TBLGEN=${NXBDESTDIR}/usr/bin/llvm-tblgen \ CLANG_TBLGEN=${NXBDESTDIR}/usr/bin/clang-tblgen \ MACHINE=${TARGET} MACHINE_ARCH=${TARGET_ARCH} \ MK_GDB=no MK_TESTS=no \ SSP_CFLAGS= \ MK_HTML=no NO_LINT=yes MK_MAN=no MK_MAN_UTILS=yes \ -DNO_PIC MK_PROFILE=no -DNO_SHARED \ -DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no \ MK_CLANG_EXTRAS=no MK_CLANG_FULL=no \ MK_LLDB=no MK_DEBUG_FILES=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: .PHONY .if ${MK_GCC_BOOTSTRAP} != "no" mkdir -p ${OBJTREE}/gperf_for_gcc/usr/bin ${_+_}@${ECHODIR} "===> ${_gperf} (obj,all,install)"; \ cd ${.CURDIR}/${_gperf}; \ if [ -z "${NO_OBJ}" ]; then ${NXBMAKE} DIRPRFX=${_gperf}/ obj; fi; \ ${NXBMAKE} DIRPRFX=${_gperf}/ all; \ ${NXBMAKE} DIRPRFX=${_gperf}/ DESTDIR=${OBJTREE}/gperf_for_gcc install .endif mkdir -p ${NXBDESTDIR}/bin ${NXBDESTDIR}/sbin ${NXBDESTDIR}/usr mtree -deU -f ${.CURDIR}/etc/mtree/BSD.usr.dist \ -p ${NXBDESTDIR}/usr >/dev/null mtree -deU -f ${.CURDIR}/etc/mtree/BSD.include.dist \ -p ${NXBDESTDIR}/usr/include >/dev/null .if ${MK_DEBUG_FILES} != "no" mtree -deU -f ${.CURDIR}/etc/mtree/BSD.debug.dist \ -p ${NXBDESTDIR}/usr/lib >/dev/null .endif .for _tool in \ bin/cat \ bin/chmod \ bin/cp \ bin/csh \ bin/echo \ bin/expr \ bin/hostname \ bin/ln \ bin/ls \ bin/mkdir \ bin/mv \ bin/ps \ bin/realpath \ bin/rm \ bin/rmdir \ bin/sh \ bin/sleep \ ${_clang_tblgen} \ usr.bin/ar \ ${_binutils} \ ${_elftctools} \ ${_gcc} \ ${_gcc_tools} \ ${_clang_libs} \ ${_clang} \ ${_lld} \ sbin/md5 \ sbin/sysctl \ usr.bin/diff \ usr.bin/awk \ usr.bin/basename \ usr.bin/bmake \ usr.bin/bzip2 \ usr.bin/cmp \ usr.bin/dirname \ usr.bin/env \ usr.bin/fetch \ usr.bin/find \ usr.bin/grep \ usr.bin/gzip \ usr.bin/id \ usr.bin/lex \ usr.bin/limits \ usr.bin/lorder \ ${_libopenbsd} \ ${_makewhatis} \ usr.bin/mktemp \ usr.bin/mt \ usr.bin/patch \ usr.bin/readelf \ usr.bin/sed \ usr.bin/sort \ usr.bin/tar \ usr.bin/touch \ usr.bin/tr \ usr.bin/true \ usr.bin/uniq \ usr.bin/unzip \ usr.bin/xargs \ usr.bin/xinstall \ usr.bin/xz \ usr.bin/yacc \ usr.sbin/chown ${_+_}@${ECHODIR} "===> ${_tool} (obj,all,install)"; \ cd ${.CURDIR}/${_tool}; \ if [ -z "${NO_OBJ}" ]; then ${NXBMAKE} DIRPRFX=${_tool}/ obj; fi; \ ${NXBMAKE} DIRPRFX=${_tool}/ all; \ ${NXBMAKE} DIRPRFX=${_tool}/ DESTDIR=${NXBDESTDIR} install .endfor # # hierarchy - ensure that all the needed directories are present # hierarchy hier: .MAKE .PHONY ${_+_}cd ${.CURDIR}/etc; ${HMAKE} distrib-dirs # # libraries - build all libraries, and install them under ${DESTDIR}. # # The list of libraries with dependents (${_prebuild_libs}) and their # interdependencies (__L) are built automatically by the # ${.CURDIR}/tools/make_libdeps.sh script. # libraries: .MAKE .PHONY ${_+_}cd ${.CURDIR}; \ ${MAKE} -f Makefile.inc1 _prereq_libs; \ ${MAKE} -f Makefile.inc1 _startup_libs; \ ${MAKE} -f Makefile.inc1 _prebuild_libs; \ ${MAKE} -f Makefile.inc1 _generic_libs # # static libgcc.a prerequisite for shared libc # _prereq_libs= lib/libcompiler_rt .if ${MK_SSP} != "no" _prereq_libs+= gnu/lib/libssp/libssp_nonshared .endif # These dependencies are not automatically generated: # # gnu/lib/csu, gnu/lib/libgcc, lib/csu and lib/libc must be built before # all shared libraries for ELF. # _startup_libs= gnu/lib/csu _startup_libs+= lib/csu _startup_libs+= lib/libcompiler_rt _startup_libs+= lib/libc _startup_libs+= lib/libc_nonshared .if ${MK_LIBCPLUSPLUS} != "no" _startup_libs+= lib/libcxxrt .endif .if ${MK_LLVM_LIBUNWIND} != "no" _prereq_libs+= lib/libgcc_eh lib/libgcc_s _startup_libs+= lib/libgcc_eh lib/libgcc_s lib/libgcc_s__L: lib/libc__L lib/libgcc_s__L: lib/libc_nonshared__L .if ${MK_LIBCPLUSPLUS} != "no" lib/libcxxrt__L: lib/libgcc_s__L .endif .else # MK_LLVM_LIBUNWIND == no _prereq_libs+= gnu/lib/libgcc _startup_libs+= gnu/lib/libgcc gnu/lib/libgcc__L: lib/libc__L gnu/lib/libgcc__L: lib/libc_nonshared__L .if ${MK_LIBCPLUSPLUS} != "no" lib/libcxxrt__L: gnu/lib/libgcc__L .endif .endif _prebuild_libs= ${_kerberos5_lib_libasn1} \ ${_kerberos5_lib_libhdb} \ ${_kerberos5_lib_libheimbase} \ ${_kerberos5_lib_libheimntlm} \ ${_libsqlite3} \ ${_kerberos5_lib_libheimipcc} \ ${_kerberos5_lib_libhx509} ${_kerberos5_lib_libkrb5} \ ${_kerberos5_lib_libroken} \ ${_kerberos5_lib_libwind} \ lib/libbz2 ${_libcom_err} lib/libcrypt \ lib/libelf lib/libexpat \ lib/libfigpar \ ${_lib_libgssapi} \ lib/libkiconv lib/libkvm lib/liblzma lib/libmd lib/libnv \ ${_lib_casper} \ lib/ncurses/ncurses lib/ncurses/ncursesw \ lib/libopie lib/libpam/libpam ${_lib_libthr} \ ${_lib_libradius} lib/libsbuf lib/libtacplus \ lib/libgeom \ ${_cddl_lib_libumem} ${_cddl_lib_libnvpair} \ ${_cddl_lib_libuutil} \ ${_cddl_lib_libavl} \ ${_cddl_lib_libzfs_core} \ ${_cddl_lib_libctf} \ lib/libutil lib/libpjdlog ${_lib_libypclnt} lib/libz lib/msun \ ${_secure_lib_libcrypto} ${_lib_libldns} \ ${_secure_lib_libssh} ${_secure_lib_libssl} .if ${MK_GNUCXX} != "no" _prebuild_libs+= gnu/lib/libstdc++ gnu/lib/libsupc++ gnu/lib/libstdc++__L: lib/msun__L gnu/lib/libsupc++__L: gnu/lib/libstdc++__L .endif .if ${MK_DIALOG} != "no" _prebuild_libs+= gnu/lib/libdialog gnu/lib/libdialog__L: lib/msun__L lib/ncurses/ncursesw__L .endif .if ${MK_LIBCPLUSPLUS} != "no" _prebuild_libs+= lib/libc++ .endif lib/libgeom__L: lib/libexpat__L lib/libkvm__L: lib/libelf__L .if ${MK_LIBTHR} != "no" _lib_libthr= lib/libthr .endif .if ${MK_RADIUS_SUPPORT} != "no" _lib_libradius= lib/libradius .endif .if ${MK_OFED} != "no" _ofed_lib= contrib/ofed/usr.lib _prebuild_libs+= contrib/ofed/usr.lib/libosmcomp _prebuild_libs+= contrib/ofed/usr.lib/libopensm _prebuild_libs+= contrib/ofed/usr.lib/libibcommon _prebuild_libs+= contrib/ofed/usr.lib/libibverbs _prebuild_libs+= contrib/ofed/usr.lib/libibumad contrib/ofed/usr.lib/libopensm__L: lib/libthr__L contrib/ofed/usr.lib/libosmcomp__L: lib/libthr__L contrib/ofed/usr.lib/libibumad__L: contrib/ofed/usr.lib/libibcommon__L .endif .if ${MK_CASPER} != "no" _lib_casper= lib/libcasper .endif lib/libpjdlog__L: lib/libutil__L lib/libcasper__L: lib/libnv__L lib/liblzma__L: lib/libthr__L _generic_libs= ${_cddl_lib} gnu/lib ${_kerberos5_lib} lib ${_secure_lib} usr.bin/lex/lib ${_ofed_lib} .for _DIR in ${LOCAL_LIB_DIRS} .if exists(${.CURDIR}/${_DIR}/Makefile) && empty(_generic_libs:M${_DIR}) _generic_libs+= ${_DIR} .endif .endfor lib/libopie__L lib/libtacplus__L: lib/libmd__L .if ${MK_CDDL} != "no" _cddl_lib_libumem= cddl/lib/libumem _cddl_lib_libnvpair= cddl/lib/libnvpair _cddl_lib_libavl= cddl/lib/libavl _cddl_lib_libuutil= cddl/lib/libuutil _cddl_lib_libzfs_core= cddl/lib/libzfs_core _cddl_lib_libctf= cddl/lib/libctf _cddl_lib= cddl/lib cddl/lib/libzfs_core__L: cddl/lib/libnvpair__L cddl/lib/libzfs__L: lib/libgeom__L cddl/lib/libctf__L: lib/libz__L .endif # cddl/lib/libdtrace requires lib/libproc and lib/librtld_db; it's only built # on select architectures though (see cddl/lib/Makefile) .if ${MACHINE_CPUARCH} != "sparc64" _prebuild_libs+= lib/libprocstat lib/libproc lib/librtld_db lib/libprocstat__L: lib/libelf__L lib/libkvm__L lib/libutil__L lib/libproc__L: lib/libprocstat__L lib/librtld_db__L: lib/libprocstat__L .endif .if ${MK_CRYPT} != "no" .if ${MK_OPENSSL} != "no" _secure_lib_libcrypto= secure/lib/libcrypto _secure_lib_libssl= secure/lib/libssl lib/libradius__L secure/lib/libssl__L: secure/lib/libcrypto__L .if ${MK_LDNS} != "no" _lib_libldns= lib/libldns lib/libldns__L: secure/lib/libcrypto__L .endif .if ${MK_OPENSSH} != "no" _secure_lib_libssh= secure/lib/libssh secure/lib/libssh__L: lib/libz__L secure/lib/libcrypto__L lib/libcrypt__L .if ${MK_LDNS} != "no" secure/lib/libssh__L: lib/libldns__L .endif .if ${MK_GSSAPI} != "no" && ${MK_KERBEROS_SUPPORT} != "no" secure/lib/libssh__L: lib/libgssapi__L kerberos5/lib/libkrb5__L \ kerberos5/lib/libhx509__L kerberos5/lib/libasn1__L lib/libcom_err__L \ lib/libmd__L kerberos5/lib/libroken__L .endif .endif .endif _secure_lib= secure/lib .endif .if ${MK_KERBEROS} != "no" kerberos5/lib/libasn1__L: lib/libcom_err__L kerberos5/lib/libroken__L kerberos5/lib/libhdb__L: kerberos5/lib/libasn1__L lib/libcom_err__L \ kerberos5/lib/libkrb5__L kerberos5/lib/libroken__L \ kerberos5/lib/libwind__L lib/libsqlite3__L kerberos5/lib/libheimntlm__L: secure/lib/libcrypto__L kerberos5/lib/libkrb5__L \ kerberos5/lib/libroken__L lib/libcom_err__L kerberos5/lib/libhx509__L: kerberos5/lib/libasn1__L lib/libcom_err__L \ secure/lib/libcrypto__L kerberos5/lib/libroken__L kerberos5/lib/libwind__L kerberos5/lib/libkrb5__L: kerberos5/lib/libasn1__L lib/libcom_err__L \ lib/libcrypt__L secure/lib/libcrypto__L kerberos5/lib/libhx509__L \ kerberos5/lib/libroken__L kerberos5/lib/libwind__L \ kerberos5/lib/libheimbase__L kerberos5/lib/libheimipcc__L kerberos5/lib/libroken__L: lib/libcrypt__L kerberos5/lib/libwind__L: kerberos5/lib/libroken__L lib/libcom_err__L kerberos5/lib/libheimbase__L: lib/libthr__L kerberos5/lib/libheimipcc__L: kerberos5/lib/libroken__L kerberos5/lib/libheimbase__L lib/libthr__L .endif lib/libsqlite3__L: lib/libthr__L .if ${MK_GSSAPI} != "no" _lib_libgssapi= lib/libgssapi .endif .if ${MK_KERBEROS} != "no" _kerberos5_lib= kerberos5/lib _kerberos5_lib_libasn1= kerberos5/lib/libasn1 _kerberos5_lib_libhdb= kerberos5/lib/libhdb _kerberos5_lib_libheimbase= kerberos5/lib/libheimbase _kerberos5_lib_libkrb5= kerberos5/lib/libkrb5 _kerberos5_lib_libhx509= kerberos5/lib/libhx509 _kerberos5_lib_libroken= kerberos5/lib/libroken _kerberos5_lib_libheimntlm= kerberos5/lib/libheimntlm _libsqlite3= lib/libsqlite3 _kerberos5_lib_libheimipcc= kerberos5/lib/libheimipcc _kerberos5_lib_libwind= kerberos5/lib/libwind _libcom_err= lib/libcom_err .endif .if ${MK_NIS} != "no" _lib_libypclnt= lib/libypclnt .endif .if ${MK_OPENSSL} == "no" lib/libradius__L: lib/libmd__L .endif lib/libproc__L: \ ${_cddl_lib_libctf:D${_cddl_lib_libctf}__L} lib/libelf__L lib/librtld_db__L lib/libutil__L .if ${MK_CXX} != "no" .if ${MK_LIBCPLUSPLUS} != "no" lib/libproc__L: lib/libcxxrt__L .else # This implies MK_GNUCXX != "no"; see lib/libproc lib/libproc__L: gnu/lib/libsupc++__L .endif .endif .for _lib in ${_prereq_libs} ${_lib}__PL: .PHONY .MAKE .if exists(${.CURDIR}/${_lib}) ${_+_}@${ECHODIR} "===> ${_lib} (obj,all,install)"; \ cd ${.CURDIR}/${_lib}; \ if [ -z "${NO_OBJ}" ]; then ${MAKE} MK_TESTS=no DIRPRFX=${_lib}/ obj; fi; \ ${MAKE} MK_TESTS=no MK_PROFILE=no -DNO_PIC \ DIRPRFX=${_lib}/ all; \ ${MAKE} MK_TESTS=no MK_PROFILE=no -DNO_PIC \ DIRPRFX=${_lib}/ install .endif .endfor .for _lib in ${_startup_libs} ${_prebuild_libs} ${_generic_libs} ${_lib}__L: .PHONY .MAKE .if exists(${.CURDIR}/${_lib}) ${_+_}@${ECHODIR} "===> ${_lib} (obj,all,install)"; \ cd ${.CURDIR}/${_lib}; \ if [ -z "${NO_OBJ}" ]; then ${MAKE} MK_TESTS=no DIRPRFX=${_lib}/ obj; fi; \ ${MAKE} MK_TESTS=no DIRPRFX=${_lib}/ all; \ ${MAKE} MK_TESTS=no DIRPRFX=${_lib}/ install .endif .endfor _prereq_libs: ${_prereq_libs:S/$/__PL/} _startup_libs: ${_startup_libs:S/$/__L/} _prebuild_libs: ${_prebuild_libs:S/$/__L/} _generic_libs: ${_generic_libs:S/$/__L/} # Enable SUBDIR_PARALLEL when not calling 'make all', unless called from # 'everything' with _PARALLEL_SUBDIR_OK set. This is because it is unlikely # that running 'make all' from the top-level, especially with a SUBDIR_OVERRIDE # or LOCAL_DIRS set, will have a reliable build if SUBDIRs are built in # parallel. This is safe for the world stage of buildworld though since it has # already built libraries in a proper order and installed includes into # WORLDTMP. Special handling is done for SUBDIR ordering for 'install*' to # avoid trashing a system if it crashes mid-install. .if !make(all) || defined(_PARALLEL_SUBDIR_OK) SUBDIR_PARALLEL= .endif .include .if make(check-old) || make(check-old-dirs) || \ make(check-old-files) || make(check-old-libs) || \ make(delete-old) || make(delete-old-dirs) || \ make(delete-old-files) || make(delete-old-libs) # # check for / delete old files section # .include "ObsoleteFiles.inc" OLD_LIBS_MESSAGE="Please be sure no application still uses those libraries, \ else you can not start such an application. Consult UPDATING for more \ information regarding how to cope with the removal/revision bump of a \ specific library." .if !defined(BATCH_DELETE_OLD_FILES) RM_I=-i .else RM_I=-v .endif delete-old-files: .PHONY @echo ">>> Removing old files (only deletes safe to delete libs)" # Ask for every old file if the user really wants to remove it. # It's annoying, but better safe than sorry. # NB: We cannot pass the list of OLD_FILES as a parameter because the # argument list will get too long. Using .for/.endfor make "loops" will make # the Makefile parser segfault. @exec 3<&0; \ cd ${.CURDIR}; \ ${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \ -V OLD_FILES -V "OLD_FILES:Musr/share/*.gz:R" | xargs -n1 | \ while read file; do \ if [ -f "${DESTDIR}/$${file}" -o -L "${DESTDIR}/$${file}" ]; then \ chflags noschg "${DESTDIR}/$${file}" 2>/dev/null || true; \ rm ${RM_I} "${DESTDIR}/$${file}" <&3; \ fi; \ for ext in debug symbols; do \ if ! [ -e "${DESTDIR}/$${file}" ] && [ -f \ "${DESTDIR}${DEBUGDIR}/$${file}.$${ext}" ]; then \ rm ${RM_I} "${DESTDIR}${DEBUGDIR}/$${file}.$${ext}" \ <&3; \ fi; \ done; \ done # Remove catpages without corresponding manpages. @exec 3<&0; \ find ${DESTDIR}/usr/share/man/cat* ! -type d | \ sed -ep -e's:${DESTDIR}/usr/share/man/cat:${DESTDIR}/usr/share/man/man:' | \ while read catpage; do \ read manpage; \ if [ ! -e "$${manpage}" ]; then \ rm ${RM_I} $${catpage} <&3; \ fi; \ done @echo ">>> Old files removed" check-old-files: .PHONY @echo ">>> Checking for old files" @cd ${.CURDIR}; \ ${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \ -V OLD_FILES -V "OLD_FILES:Musr/share/*.gz:R" | xargs -n1 | \ while read file; do \ if [ -f "${DESTDIR}/$${file}" -o -L "${DESTDIR}/$${file}" ]; then \ echo "${DESTDIR}/$${file}"; \ fi; \ for ext in debug symbols; do \ if [ -f "${DESTDIR}${DEBUGDIR}/$${file}.$${ext}" ]; then \ echo "${DESTDIR}${DEBUGDIR}/$${file}.$${ext}"; \ fi; \ done; \ done # Check for catpages without corresponding manpages. @find ${DESTDIR}/usr/share/man/cat* ! -type d | \ sed -ep -e's:${DESTDIR}/usr/share/man/cat:${DESTDIR}/usr/share/man/man:' | \ while read catpage; do \ read manpage; \ if [ ! -e "$${manpage}" ]; then \ echo $${catpage}; \ fi; \ done delete-old-libs: .PHONY @echo ">>> Removing old libraries" @echo "${OLD_LIBS_MESSAGE}" | fmt @exec 3<&0; \ cd ${.CURDIR}; \ ${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \ -V OLD_LIBS | xargs -n1 | \ while read file; do \ if [ -f "${DESTDIR}/$${file}" -o -L "${DESTDIR}/$${file}" ]; then \ chflags noschg "${DESTDIR}/$${file}" 2>/dev/null || true; \ rm ${RM_I} "${DESTDIR}/$${file}" <&3; \ fi; \ for ext in debug symbols; do \ if ! [ -e "${DESTDIR}/$${file}" ] && [ -f \ "${DESTDIR}${DEBUGDIR}/$${file}.$${ext}" ]; then \ rm ${RM_I} "${DESTDIR}${DEBUGDIR}/$${file}.$${ext}" \ <&3; \ fi; \ done; \ done @echo ">>> Old libraries removed" check-old-libs: .PHONY @echo ">>> Checking for old libraries" @cd ${.CURDIR}; \ ${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \ -V OLD_LIBS | xargs -n1 | \ while read file; do \ if [ -f "${DESTDIR}/$${file}" -o -L "${DESTDIR}/$${file}" ]; then \ echo "${DESTDIR}/$${file}"; \ fi; \ for ext in debug symbols; do \ if [ -f "${DESTDIR}${DEBUGDIR}/$${file}.$${ext}" ]; then \ echo "${DESTDIR}${DEBUGDIR}/$${file}.$${ext}"; \ fi; \ done; \ done delete-old-dirs: .PHONY @echo ">>> Removing old directories" @cd ${.CURDIR}; \ ${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \ -V OLD_DIRS | xargs -n1 | sort -r | \ while read dir; do \ if [ -d "${DESTDIR}/$${dir}" ]; then \ rmdir -v "${DESTDIR}/$${dir}" || true; \ elif [ -L "${DESTDIR}/$${dir}" ]; then \ echo "${DESTDIR}/$${dir} is a link, please remove everything manually."; \ fi; \ if [ -d "${DESTDIR}${DEBUGDIR}/$${dir}" ]; then \ rmdir -v "${DESTDIR}${DEBUGDIR}/$${dir}" || true; \ elif [ -L "${DESTDIR}${DEBUGDIR}/$${dir}" ]; then \ echo "${DESTDIR}${DEBUGDIR}/$${dir} is a link, please remove everything manually."; \ fi; \ done @echo ">>> Old directories removed" check-old-dirs: .PHONY @echo ">>> Checking for old directories" @cd ${.CURDIR}; \ ${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \ -V OLD_DIRS | xargs -n1 | \ while read dir; do \ if [ -d "${DESTDIR}/$${dir}" ]; then \ echo "${DESTDIR}/$${dir}"; \ elif [ -L "${DESTDIR}/$${dir}" ]; then \ echo "${DESTDIR}/$${dir} is a link, please remove everything manually."; \ fi; \ if [ -d "${DESTDIR}${DEBUGDIR}/$${dir}" ]; then \ echo "${DESTDIR}${DEBUGDIR}/$${dir}"; \ elif [ -L "${DESTDIR}${DEBUGDIR}/$${dir}" ]; then \ echo "${DESTDIR}${DEBUGDIR}/$${dir} is a link, please remove everything manually."; \ fi; \ done delete-old: delete-old-files delete-old-dirs .PHONY @echo "To remove old libraries run '${MAKE_CMD} delete-old-libs'." check-old: check-old-files check-old-libs check-old-dirs .PHONY @echo "To remove old files and directories run '${MAKE_CMD} delete-old'." @echo "To remove old libraries run '${MAKE_CMD} delete-old-libs'." .endif # # showconfig - show build configuration. # showconfig: .PHONY @(${MAKE} -n -f ${.CURDIR}/sys/conf/kern.opts.mk -V dummy -dg1 UPDATE_DEPENDFILE=no NO_OBJ=yes; \ ${MAKE} -n -f ${.CURDIR}/share/mk/src.opts.mk -V dummy -dg1 UPDATE_DEPENDFILE=no NO_OBJ=yes) 2>&1 | grep ^MK_ | sort -u .if !empty(KRNLOBJDIR) && !empty(KERNCONF) DTBOUTPUTPATH= ${KRNLOBJDIR}/${KERNCONF}/ .if !defined(FDT_DTS_FILE) || empty(FDT_DTS_FILE) .if exists(${KERNCONFDIR}/${KERNCONF}) FDT_DTS_FILE!= awk 'BEGIN {FS="="} /^makeoptions[[:space:]]+FDT_DTS_FILE/ {print $$2}' \ '${KERNCONFDIR}/${KERNCONF}' ; echo .endif .endif .endif .if !defined(DTBOUTPUTPATH) || !exists(${DTBOUTPUTPATH}) DTBOUTPUTPATH= ${.CURDIR} .endif # # Build 'standalone' Device Tree Blob # builddtb: .PHONY @PATH=${TMPPATH} MACHINE=${TARGET} \ ${.CURDIR}/sys/tools/fdt/make_dtb.sh ${.CURDIR}/sys \ "${FDT_DTS_FILE}" ${DTBOUTPUTPATH} ############### # cleanworld # In the following, the first 'rm' in a series will usually remove all # files and directories. If it does not, then there are probably some # files with file flags set, so this unsets them and tries the 'rm' a # second time. There are situations where this target will be cleaning # some directories via more than one method, but that duplication is # needed to correctly handle all the possible situations. Removing all # files without file flags set in the first 'rm' instance saves time, # because 'chflags' will need to operate on fewer files afterwards. # # It is expected that BW_CANONICALOBJDIR == the CANONICALOBJDIR as would be # created by bsd.obj.mk, except that we don't want to .include that file # in this makefile. # BW_CANONICALOBJDIR:=${OBJTREE}${.CURDIR} cleanworld: .PHONY .if exists(${BW_CANONICALOBJDIR}/) -rm -rf ${BW_CANONICALOBJDIR}/* -chflags -R 0 ${BW_CANONICALOBJDIR} rm -rf ${BW_CANONICALOBJDIR}/* .endif .if ${.CURDIR} == ${.OBJDIR} || ${.CURDIR}/obj == ${.OBJDIR} # To be safe in this case, fall back to a 'make cleandir' ${_+_}@cd ${.CURDIR}; ${MAKE} cleandir .endif .if defined(TARGET) && defined(TARGET_ARCH) .if ${TARGET} == ${MACHINE} && ${TARGET_ARCH} == ${MACHINE_ARCH} XDEV_CPUTYPE?=${CPUTYPE} .else XDEV_CPUTYPE?=${TARGET_CPUTYPE} .endif NOFUN=-DNO_FSCHG MK_HTML=no -DNO_LINT \ MK_MAN=no MK_NLS=no MK_PROFILE=no \ MK_KERBEROS=no MK_RESCUE=no MK_TESTS=no MK_WARNS=no \ TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} \ CPUTYPE=${XDEV_CPUTYPE} XDDIR=${TARGET_ARCH}-freebsd XDTP?=/usr/${XDDIR} .if ${XDTP:N/*} .error XDTP variable should be an absolute path .endif CDBENV=MAKEOBJDIRPREFIX=${MAKEOBJDIRPREFIX}/${XDDIR} \ INSTALL="sh ${.CURDIR}/tools/install.sh" CDENV= ${CDBENV} \ TOOLS_PREFIX=${XDTP} .if ${WANT_COMPILER_TYPE} == gcc || \ (defined(X_COMPILER_TYPE) && ${X_COMPILER_TYPE} == gcc) # GCC requires -isystem and -L when using a cross-compiler. --sysroot # won't set header path and -L is used to ensure the base library path # is added before the port PREFIX library path. CD2CFLAGS+= -isystem ${XDDESTDIR}/usr/include -L${XDDESTDIR}/usr/lib # GCC requires -B to find /usr/lib/crti.o when using a cross-compiler # combined with --sysroot. CD2CFLAGS+= -B${XDDESTDIR}/usr/lib # Force using libc++ for external GCC. # XXX: This should be checking MK_GNUCXX == no .if ${X_COMPILER_VERSION} >= 40800 CD2CXXFLAGS+= -isystem ${XDDESTDIR}/usr/include/c++/v1 -std=c++11 \ -nostdinc++ .endif .endif CD2CFLAGS+= --sysroot=${XDDESTDIR}/ CD2ENV=${CDENV} CC="${CC} ${CD2CFLAGS}" CXX="${CXX} ${CD2CXXFLAGS} ${CD2CFLAGS}" \ CPP="${CPP} ${CD2CFLAGS}" \ MACHINE=${TARGET} MACHINE_ARCH=${TARGET_ARCH} CDTMP= ${MAKEOBJDIRPREFIX}/${XDDIR}/${.CURDIR}/tmp CDMAKE=${CDENV} PATH=${CDTMP}/usr/bin:${PATH} ${MAKE} ${NOFUN} CD2MAKE=${CD2ENV} PATH=${CDTMP}/usr/bin:${XDDESTDIR}/usr/bin:${PATH} ${MAKE} ${NOFUN} .if ${MK_META_MODE} != "no" # Don't rebuild build-tools targets during normal build. CD2MAKE+= BUILD_TOOLS_META=.NOMETA .endif XDDESTDIR=${DESTDIR}/${XDTP} .if !defined(OSREL) OSREL!= uname -r | sed -e 's/[-(].*//' .endif .ORDER: xdev-build xdev-install xdev-links xdev: xdev-build xdev-install .PHONY .ORDER: _xb-worldtmp _xb-bootstrap-tools _xb-build-tools _xb-cross-tools xdev-build: _xb-worldtmp _xb-bootstrap-tools _xb-build-tools _xb-cross-tools .PHONY _xb-worldtmp: .PHONY mkdir -p ${CDTMP}/usr mtree -deU -f ${.CURDIR}/etc/mtree/BSD.usr.dist \ -p ${CDTMP}/usr >/dev/null _xb-bootstrap-tools: .PHONY .for _tool in \ ${_clang_tblgen} \ ${_gperf} \ ${_yacc} ${_+_}@${ECHODIR} "===> ${_tool} (obj,all,install)"; \ cd ${.CURDIR}/${_tool}; \ if [ -z "${NO_OBJ}" ]; then ${CDMAKE} DIRPRFX=${_tool}/ obj; fi; \ ${CDMAKE} DIRPRFX=${_tool}/ all; \ ${CDMAKE} DIRPRFX=${_tool}/ DESTDIR=${CDTMP} install .endfor _xb-build-tools: .PHONY ${_+_}@cd ${.CURDIR}; \ ${CDBENV} ${MAKE} -f Makefile.inc1 ${NOFUN} build-tools _xb-cross-tools: .PHONY .for _tool in \ ${_binutils} \ ${_elftctools} \ usr.bin/ar \ ${_clang_libs} \ ${_clang} \ ${_gcc} ${_+_}@${ECHODIR} "===> xdev ${_tool} (obj,all)"; \ cd ${.CURDIR}/${_tool}; \ if [ -z "${NO_OBJ}" ]; then ${CDMAKE} DIRPRFX=${_tool}/ obj; fi; \ ${CDMAKE} DIRPRFX=${_tool}/ all .endfor _xi-mtree: .PHONY ${_+_}@${ECHODIR} "mtree populating ${XDDESTDIR}" mkdir -p ${XDDESTDIR} mtree -deU -f ${.CURDIR}/etc/mtree/BSD.root.dist \ -p ${XDDESTDIR} >/dev/null mtree -deU -f ${.CURDIR}/etc/mtree/BSD.usr.dist \ -p ${XDDESTDIR}/usr >/dev/null mtree -deU -f ${.CURDIR}/etc/mtree/BSD.include.dist \ -p ${XDDESTDIR}/usr/include >/dev/null .if defined(LIBCOMPAT) mtree -deU -f ${.CURDIR}/etc/mtree/BSD.lib${libcompat}.dist \ -p ${XDDESTDIR}/usr >/dev/null .endif .if ${MK_TESTS} != "no" mkdir -p ${XDDESTDIR}${TESTSBASE} mtree -deU -f ${.CURDIR}/etc/mtree/BSD.tests.dist \ -p ${XDDESTDIR}${TESTSBASE} >/dev/null .endif .ORDER: xdev-build _xi-mtree _xi-cross-tools _xi-includes _xi-libraries xdev-install: xdev-build _xi-mtree _xi-cross-tools _xi-includes _xi-libraries .PHONY _xi-cross-tools: .PHONY @echo "_xi-cross-tools" .for _tool in \ ${_binutils} \ ${_elftctools} \ usr.bin/ar \ ${_clang_libs} \ ${_clang} \ ${_gcc} ${_+_}@${ECHODIR} "===> xdev ${_tool} (install)"; \ cd ${.CURDIR}/${_tool}; \ ${CDMAKE} DIRPRFX=${_tool}/ install DESTDIR=${XDDESTDIR} .endfor _xi-includes: .PHONY ${_+_}cd ${.CURDIR}; ${CD2MAKE} -f Makefile.inc1 includes \ DESTDIR=${XDDESTDIR} _xi-libraries: .PHONY ${_+_}cd ${.CURDIR}; ${CD2MAKE} -f Makefile.inc1 libraries \ DESTDIR=${XDDESTDIR} xdev-links: .PHONY ${_+_}cd ${XDDESTDIR}/usr/bin; \ mkdir -p ../../../../usr/bin; \ for i in *; do \ ln -sf ../../${XDTP}/usr/bin/$$i \ ../../../../usr/bin/${XDDIR}-$$i; \ ln -sf ../../${XDTP}/usr/bin/$$i \ ../../../../usr/bin/${XDDIR}${OSREL}-$$i; \ done .else xdev xdev-build xdev-install xdev-links: .PHONY @echo "*** Error: Both TARGET and TARGET_ARCH must be defined for \"${.TARGET}\" target" .endif Index: projects/runtime-coverage/contrib/netbsd-tests/usr.bin/grep/t_grep.sh =================================================================== --- projects/runtime-coverage/contrib/netbsd-tests/usr.bin/grep/t_grep.sh (revision 321457) +++ projects/runtime-coverage/contrib/netbsd-tests/usr.bin/grep/t_grep.sh (revision 321458) @@ -1,713 +1,732 @@ # $NetBSD: t_grep.sh,v 1.3 2017/01/14 20:43:52 christos Exp $ # # Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # atf_test_case basic basic_head() { atf_set "descr" "Checks basic functionality" } basic_body() { atf_check -o file:"$(atf_get_srcdir)/d_basic.out" -x \ 'jot 10000 | grep 123' } atf_test_case binary binary_head() { atf_set "descr" "Checks handling of binary files" } binary_body() { dd if=/dev/zero count=1 of=test.file echo -n "foobar" >> test.file atf_check -o file:"$(atf_get_srcdir)/d_binary.out" grep foobar test.file } atf_test_case recurse recurse_head() { atf_set "descr" "Checks recursive searching" } recurse_body() { mkdir -p recurse/a/f recurse/d echo -e "cod\ndover sole\nhaddock\nhalibut\npilchard" > recurse/d/fish echo -e "cod\nhaddock\nplaice" > recurse/a/f/favourite-fish atf_check -o file:"$(atf_get_srcdir)/d_recurse.out" -x "grep -r haddock recurse | sort" } atf_test_case recurse_symlink recurse_symlink_head() { atf_set "descr" "Checks symbolic link recursion" } recurse_symlink_body() { # Begin FreeBSD grep_type if [ $? -eq $GREP_TYPE_GNU ]; then atf_expect_fail "this test doesn't pass with gnu grep from ports" fi # End FreeBSD mkdir -p test/c/d (cd test/c/d && ln -s ../d .) echo "Test string" > test/c/match atf_check -o file:"$(atf_get_srcdir)/d_recurse_symlink.out" \ -e file:"$(atf_get_srcdir)/d_recurse_symlink.err" \ grep -r string test } atf_test_case word_regexps word_regexps_head() { atf_set "descr" "Checks word-regexps" } word_regexps_body() { atf_check -o file:"$(atf_get_srcdir)/d_word_regexps.out" \ grep -w separated $(atf_get_srcdir)/d_input # Begin FreeBSD printf "xmatch pmatch\n" > test1 atf_check -o inline:"pmatch\n" grep -Eow "(match )?pmatch" test1 # End FreeBSD } atf_test_case begin_end begin_end_head() { atf_set "descr" "Checks handling of line beginnings and ends" } begin_end_body() { atf_check -o file:"$(atf_get_srcdir)/d_begin_end_a.out" \ grep ^Front "$(atf_get_srcdir)/d_input" atf_check -o file:"$(atf_get_srcdir)/d_begin_end_b.out" \ grep ending$ "$(atf_get_srcdir)/d_input" } atf_test_case ignore_case ignore_case_head() { atf_set "descr" "Checks ignore-case option" } ignore_case_body() { atf_check -o file:"$(atf_get_srcdir)/d_ignore_case.out" \ grep -i Upper "$(atf_get_srcdir)/d_input" } atf_test_case invert invert_head() { atf_set "descr" "Checks selecting non-matching lines with -v option" } invert_body() { atf_check -o file:"$(atf_get_srcdir)/d_invert.out" \ grep -v fish "$(atf_get_srcdir)/d_invert.in" } atf_test_case whole_line whole_line_head() { atf_set "descr" "Checks whole-line matching with -x flag" } whole_line_body() { atf_check -o file:"$(atf_get_srcdir)/d_whole_line.out" \ grep -x matchme "$(atf_get_srcdir)/d_input" } atf_test_case negative negative_head() { atf_set "descr" "Checks handling of files with no matches" } negative_body() { atf_check -s ne:0 grep "not a hope in hell" "$(atf_get_srcdir)/d_input" } atf_test_case context context_head() { atf_set "descr" "Checks displaying context with -A, -B and -C flags" } context_body() { cp $(atf_get_srcdir)/d_context_*.* . atf_check -o file:d_context_a.out grep -C2 bamboo d_context_a.in atf_check -o file:d_context_b.out grep -A3 tilt d_context_a.in atf_check -o file:d_context_c.out grep -B4 Whig d_context_a.in atf_check -o file:d_context_d.out grep -C1 pig d_context_a.in d_context_b.in atf_check -o file:d_context_e.out \ grep -E -C1 '(banana|monkey)' d_context_e.in atf_check -o file:d_context_f.out \ grep -Ev -B2 '(banana|monkey|fruit)' d_context_e.in atf_check -o file:d_context_g.out \ grep -Ev -A1 '(banana|monkey|fruit)' d_context_e.in } atf_test_case file_exp file_exp_head() { atf_set "descr" "Checks reading expressions from file" } file_exp_body() { atf_check -o file:"$(atf_get_srcdir)/d_file_exp.out" -x \ 'jot 21 -1 1.00 | grep -f '"$(atf_get_srcdir)"'/d_file_exp.in' } atf_test_case egrep egrep_head() { atf_set "descr" "Checks matching special characters with egrep" } egrep_body() { atf_check -o file:"$(atf_get_srcdir)/d_egrep.out" \ egrep '\?|\*$$' "$(atf_get_srcdir)/d_input" } atf_test_case zgrep zgrep_head() { atf_set "descr" "Checks handling of gzipped files with zgrep" } zgrep_body() { cp "$(atf_get_srcdir)/d_input" . gzip d_input || atf_fail "gzip failed" atf_check -o file:"$(atf_get_srcdir)/d_zgrep.out" zgrep -h line d_input.gz } atf_test_case nonexistent nonexistent_head() { atf_set "descr" "Checks that -s flag suppresses error" \ "messages about nonexistent files" } nonexistent_body() { atf_check -s ne:0 grep -s foobar nonexistent } atf_test_case context2 context2_head() { atf_set "descr" "Checks displaying context with -z flag" } context2_body() { printf "haddock\000cod\000plaice\000" > test1 printf "mackeral\000cod\000crab\000" > test2 atf_check -o file:"$(atf_get_srcdir)/d_context2_a.out" \ grep -z -A1 cod test1 test2 atf_check -o file:"$(atf_get_srcdir)/d_context2_b.out" \ grep -z -B1 cod test1 test2 atf_check -o file:"$(atf_get_srcdir)/d_context2_c.out" \ grep -z -C1 cod test1 test2 } # Begin FreeBSD # What grep(1) are we working with? # - 0 : bsdgrep # - 1 : gnu grep 2.51 (base) # - 2 : gnu grep (ports) GREP_TYPE_BSD=0 GREP_TYPE_GNU_FREEBSD=1 GREP_TYPE_GNU=2 GREP_TYPE_UNKNOWN=3 grep_type() { local grep_version=$(grep --version) case "$grep_version" in *"BSD grep"*) return $GREP_TYPE_BSD ;; *"GNU grep"*) case "$grep_version" in *2.5.1-FreeBSD*) return $GREP_TYPE_GNU_FREEBSD ;; *) return $GREP_TYPE_GNU ;; esac ;; esac atf_fail "unknown grep type: $grep_version" } atf_test_case oflag_zerolen oflag_zerolen_head() { atf_set "descr" "Check behavior of zero-length matches with -o flag (PR 195763)" } oflag_zerolen_body() { grep_type if [ $? -eq $GREP_TYPE_GNU_FREEBSD ]; then atf_expect_fail "this test doesn't pass with gnu grep in base" fi atf_check -o file:"$(atf_get_srcdir)/d_oflag_zerolen_a.out" \ grep -Eo '(^|:)0*' "$(atf_get_srcdir)/d_oflag_zerolen_a.in" atf_check -o file:"$(atf_get_srcdir)/d_oflag_zerolen_b.out" \ grep -Eo '(^|:)0*' "$(atf_get_srcdir)/d_oflag_zerolen_b.in" atf_check -o file:"$(atf_get_srcdir)/d_oflag_zerolen_c.out" \ grep -Eo '[[:alnum:]]*' "$(atf_get_srcdir)/d_oflag_zerolen_c.in" atf_check -o empty grep -Eo '' "$(atf_get_srcdir)/d_oflag_zerolen_d.in" atf_check -o file:"$(atf_get_srcdir)/d_oflag_zerolen_e.out" \ grep -o -e 'ab' -e 'bc' "$(atf_get_srcdir)/d_oflag_zerolen_e.in" atf_check -o file:"$(atf_get_srcdir)/d_oflag_zerolen_e.out" \ grep -o -e 'bc' -e 'ab' "$(atf_get_srcdir)/d_oflag_zerolen_e.in" } atf_test_case xflag xflag_head() { atf_set "descr" "Check that we actually get a match with -x flag (PR 180990)" } xflag_body() { echo 128 > match_file seq 1 128 > pattern_file grep -xf pattern_file match_file } atf_test_case color color_head() { atf_set "descr" "Check --color support" } color_body() { grep_type if [ $? -eq $GREP_TYPE_GNU_FREEBSD ]; then atf_expect_fail "this test doesn't pass with gnu grep in base" fi echo 'abcd*' > grepfile echo 'abc$' >> grepfile echo '^abc' >> grepfile atf_check -o file:"$(atf_get_srcdir)/d_color_a.out" \ grep --color=auto -e '.*' -e 'a' "$(atf_get_srcdir)/d_color_a.in" atf_check -o file:"$(atf_get_srcdir)/d_color_b.out" \ grep --color=auto -f grepfile "$(atf_get_srcdir)/d_color_b.in" atf_check -o file:"$(atf_get_srcdir)/d_color_c.out" \ grep --color=always -f grepfile "$(atf_get_srcdir)/d_color_b.in" } atf_test_case f_file_empty f_file_empty_head() { atf_set "descr" "Check for handling of a null byte in empty file, specified by -f (PR 202022)" } f_file_empty_body() { printf "\0\n" > nulpat atf_check -s exit:1 grep -f nulpat "$(atf_get_srcdir)/d_f_file_empty.in" } atf_test_case escmap escmap_head() { atf_set "descr" "Check proper handling of escaped vs. unescaped dot expressions (PR 175314)" } escmap_body() { atf_check -s exit:1 grep -o 'f.o\.' "$(atf_get_srcdir)/d_escmap.in" atf_check -o not-empty grep -o 'f.o.' "$(atf_get_srcdir)/d_escmap.in" } atf_test_case egrep_empty_invalid egrep_empty_invalid_head() { atf_set "descr" "Check for handling of an invalid empty pattern (PR 194823)" } egrep_empty_invalid_body() { atf_check -e ignore -s not-exit:0 egrep '{' /dev/null } atf_test_case zerolen zerolen_head() { atf_set "descr" "Check for successful zero-length matches with ^$" } zerolen_body() { printf "Eggs\n\nCheese" > test1 atf_check -o inline:"\n" grep -e "^$" test1 atf_check -o inline:"Eggs\nCheese\n" grep -v -e "^$" test1 } atf_test_case wflag_emptypat wflag_emptypat_head() { atf_set "descr" "Check for proper handling of -w with an empty pattern (PR 105221)" } wflag_emptypat_body() { printf "" > test1 printf "\n" > test2 printf "qaz" > test3 printf " qaz\n" > test4 atf_check -s exit:1 -o empty grep -w -e "" test1 atf_check -o file:test2 grep -w -e "" test2 atf_check -s exit:1 -o empty grep -w -e "" test3 atf_check -o file:test4 grep -w -e "" test4 } atf_test_case excessive_matches excessive_matches_head() { atf_set "descr" "Check for proper handling of lines with excessive matches (PR 218811)" } excessive_matches_body() { grep_type if [ $? -eq $GREP_TYPE_GNU_FREEBSD ]; then atf_expect_fail "this test does not pass with GNU grep in base" fi for i in $(jot 4096); do printf "x" >> test.in done atf_check -s exit:0 -x '[ $(grep -o x test.in | wc -l) -eq 4096 ]' atf_check -s exit:1 -x 'grep -on x test.in | grep -v "1:x"' } atf_test_case fgrep_sanity fgrep_sanity_head() { atf_set "descr" "Check for fgrep sanity, literal expressions only" } fgrep_sanity_body() { printf "Foo" > test1 atf_check -o inline:"Foo\n" fgrep -e "Foo" test1 atf_check -s exit:1 -o empty fgrep -e "Fo." test1 } atf_test_case egrep_sanity egrep_sanity_head() { atf_set "descr" "Check for egrep sanity, EREs only" } egrep_sanity_body() { printf "Foobar(ed)" > test1 printf "M{1}" > test2 atf_check -o inline:"Foo\n" egrep -o -e "F.." test1 atf_check -o inline:"Foobar\n" egrep -o -e "F[a-z]*" test1 atf_check -o inline:"Fo\n" egrep -o -e "F(o|p)" test1 atf_check -o inline:"(ed)\n" egrep -o -e "\(ed\)" test1 atf_check -o inline:"M\n" egrep -o -e "M{1}" test2 atf_check -o inline:"M{1}\n" egrep -o -e "M\{1\}" test2 } atf_test_case grep_sanity grep_sanity_head() { atf_set "descr" "Check for basic grep sanity, BREs only" } grep_sanity_body() { printf "Foobar(ed)" > test1 printf "M{1}" > test2 atf_check -o inline:"Foo\n" grep -o -e "F.." test1 atf_check -o inline:"Foobar\n" grep -o -e "F[a-z]*" test1 atf_check -o inline:"Fo\n" grep -o -e "F\(o\)" test1 atf_check -o inline:"(ed)\n" grep -o -e "(ed)" test1 atf_check -o inline:"M{1}\n" grep -o -e "M{1}" test2 atf_check -o inline:"M\n" grep -o -e "M\{1\}" test2 } atf_test_case wv_combo_break wv_combo_break_head() { atf_set "descr" "Check for incorrectly matching lines with both -w and -v flags (PR 218467)" } wv_combo_break_body() { printf "x xx\n" > test1 printf "xx x\n" > test2 atf_check -o file:test1 grep -w "x" test1 atf_check -o file:test2 grep -w "x" test2 atf_check -s exit:1 grep -v -w "x" test1 atf_check -s exit:1 grep -v -w "x" test2 } atf_test_case ocolor_metadata ocolor_metadata_head() { atf_set "descr" "Check for -n/-b producing per-line metadata output" } ocolor_metadata_body() { grep_type if [ $? -eq $GREP_TYPE_GNU_FREEBSD ]; then atf_expect_fail "this test does not pass with GNU grep in base" fi printf "xxx\nyyyy\nzzz\nfoobarbaz\n" > test1 check_expr="^[^:]*[0-9][^:]*:[^:]+$" atf_check -o inline:"1:1:xx\n" grep -bon "xx$" test1 atf_check -o inline:"2:4:yyyy\n" grep -bn "yy" test1 atf_check -o inline:"2:6:yy\n" grep -bon "yy$" test1 # These checks ensure that grep isn't producing bogus line numbering # in the middle of a line. atf_check -s exit:1 -x \ "grep -Eon 'x|y|z|f' test1 | grep -Ev '${check_expr}'" atf_check -s exit:1 -x \ "grep -En 'x|y|z|f' --color=always test1 | grep -Ev '${check_expr}'" atf_check -s exit:1 -x \ "grep -Eon 'x|y|z|f' --color=always test1 | grep -Ev '${check_expr}'" } atf_test_case grep_nomatch_flags grep_nomatch_flags_head() { atf_set "descr" "Check for no match (-c, -l, -L, -q) flags not producing line matches or context (PR 219077)" } grep_nomatch_flags_body() { printf "A\nB\nC\n" > test1 atf_check -o inline:"1\n" grep -c -C 1 -e "B" test1 atf_check -o inline:"1\n" grep -c -B 1 -e "B" test1 atf_check -o inline:"1\n" grep -c -A 1 -e "B" test1 atf_check -o inline:"1\n" grep -c -C 1 -e "B" test1 atf_check -o inline:"test1\n" grep -l -e "B" test1 atf_check -o inline:"test1\n" grep -l -B 1 -e "B" test1 atf_check -o inline:"test1\n" grep -l -A 1 -e "B" test1 atf_check -o inline:"test1\n" grep -l -C 1 -e "B" test1 atf_check -s exit:1 -o inline:"test1\n" grep -L -e "D" test1 atf_check -o empty grep -q -e "B" test1 atf_check -o empty grep -q -B 1 -e "B" test1 atf_check -o empty grep -q -A 1 -e "B" test1 atf_check -o empty grep -q -C 1 -e "B" test1 } atf_test_case badcontext badcontext_head() { atf_set "descr" "Check for handling of invalid context arguments" } badcontext_body() { printf "A\nB\nC\n" > test1 atf_check -s not-exit:0 -e ignore grep -A "-1" "B" test1 atf_check -s not-exit:0 -e ignore grep -B "-1" "B" test1 atf_check -s not-exit:0 -e ignore grep -C "-1" "B" test1 atf_check -s not-exit:0 -e ignore grep -A "B" "B" test1 atf_check -s not-exit:0 -e ignore grep -B "B" "B" test1 atf_check -s not-exit:0 -e ignore grep -C "B" "B" test1 } atf_test_case binary_flags binary_flags_head() { atf_set "descr" "Check output for binary flags (-a, -I, -U, --binary-files)" } binary_flags_body() { printf "A\000B\000C" > test1 printf "A\n\000B\n\000C" > test2 binmatchtext="Binary file test1 matches\n" # Binaries not treated as text (default, -U) atf_check -o inline:"${binmatchtext}" grep 'B' test1 atf_check -o inline:"${binmatchtext}" grep 'B' -C 1 test1 atf_check -o inline:"${binmatchtext}" grep -U 'B' test1 atf_check -o inline:"${binmatchtext}" grep -U 'B' -C 1 test1 # Binary, -a, no newlines atf_check -o inline:"A\000B\000C\n" grep -a 'B' test1 atf_check -o inline:"A\000B\000C\n" grep -a 'B' -C 1 test1 # Binary, -a, newlines atf_check -o inline:"\000B\n" grep -a 'B' test2 atf_check -o inline:"A\n\000B\n\000C\n" grep -a 'B' -C 1 test2 # Binary files ignored atf_check -s exit:1 grep -I 'B' test2 # --binary-files equivalence atf_check -o inline:"${binmatchtext}" grep --binary-files=binary 'B' test1 atf_check -o inline:"A\000B\000C\n" grep --binary-files=text 'B' test1 atf_check -s exit:1 grep --binary-files=without-match 'B' test2 } atf_test_case mmap mmap_head() { atf_set "descr" "Check basic matching with --mmap flag" } mmap_body() { grep_type if [ $? -eq $GREP_TYPE_GNU ]; then atf_expect_fail "gnu grep from ports has no --mmap option" fi printf "A\nB\nC\n" > test1 atf_check -s exit:0 -o inline:"B\n" grep --mmap -oe "B" test1 atf_check -s exit:1 grep --mmap -e "Z" test1 } atf_test_case mmap_eof_not_eol mmap_eof_not_eol_head() { atf_set "descr" "Check --mmap flag handling of encountering EOF without EOL (PR 165471, 219402)" } mmap_eof_not_eol_body() { grep_type if [ $? -eq $GREP_TYPE_GNU ]; then atf_expect_fail "gnu grep from ports has no --mmap option" fi atf_expect_fail "relies on jemalloc feature no longer available; needs to be rewritten - bug 220309" printf "ABC" > test1 jot -b " " -s "" 4096 >> test2 atf_check -s exit:0 -o inline:"B\n" grep --mmap -oe "B" test1 # Dependency on jemalloc(3) to detect buffer overflow, otherwise this # unreliably produces a SIGSEGV or SIGBUS atf_check -s exit:0 -o not-empty \ env MALLOC_CONF="redzone:true" grep --mmap -e " " test2 } + +atf_test_case matchall +matchall_head() +{ + atf_set "descr" "Check proper behavior of matching all with an empty string" +} +matchall_body() +{ + printf "" > test1 + printf "A" > test2 + printf "A\nB" > test3 + + atf_check -o inline:"test2:A\ntest3:A\ntest3:B\n" grep "" test1 test2 test3 + atf_check -o inline:"test3:A\ntest3:B\ntest2:A\n" grep "" test3 test1 test2 + atf_check -o inline:"test2:A\ntest3:A\ntest3:B\n" grep "" test2 test3 test1 + + atf_check -s exit:1 grep "" test1 +} # End FreeBSD atf_init_test_cases() { atf_add_test_case basic atf_add_test_case binary atf_add_test_case recurse atf_add_test_case recurse_symlink atf_add_test_case word_regexps atf_add_test_case begin_end atf_add_test_case ignore_case atf_add_test_case invert atf_add_test_case whole_line atf_add_test_case negative atf_add_test_case context atf_add_test_case file_exp atf_add_test_case egrep atf_add_test_case zgrep atf_add_test_case nonexistent atf_add_test_case context2 # Begin FreeBSD atf_add_test_case oflag_zerolen atf_add_test_case xflag atf_add_test_case color atf_add_test_case f_file_empty atf_add_test_case escmap atf_add_test_case egrep_empty_invalid atf_add_test_case zerolen atf_add_test_case wflag_emptypat atf_add_test_case excessive_matches atf_add_test_case wv_combo_break atf_add_test_case fgrep_sanity atf_add_test_case egrep_sanity atf_add_test_case grep_sanity atf_add_test_case ocolor_metadata atf_add_test_case grep_nomatch_flags atf_add_test_case binary_flags atf_add_test_case badcontext atf_add_test_case mmap atf_add_test_case mmap_eof_not_eol + atf_add_test_case matchall # End FreeBSD } Index: projects/runtime-coverage/contrib/netbsd-tests =================================================================== --- projects/runtime-coverage/contrib/netbsd-tests (revision 321457) +++ projects/runtime-coverage/contrib/netbsd-tests (revision 321458) Property changes on: projects/runtime-coverage/contrib/netbsd-tests ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head/contrib/netbsd-tests:r321426-321457 Index: projects/runtime-coverage/etc/Makefile =================================================================== --- projects/runtime-coverage/etc/Makefile (revision 321457) +++ projects/runtime-coverage/etc/Makefile (revision 321458) @@ -1,469 +1,454 @@ # from: @(#)Makefile 5.11 (Berkeley) 5/21/91 # $FreeBSD$ .include FILESGROUPS= FILES # No need as it is empty and just causes rebuilds since this file does so much. UPDATE_DEPENDFILE= no .if ${MK_SENDMAIL} != "no" SUBDIR+=sendmail .endif BIN1= crontab \ devd.conf \ devfs.conf \ ddb.conf \ dhclient.conf \ disktab \ fbtab \ gettytab \ group \ hosts \ hosts.allow \ hosts.equiv \ libalias.conf \ libmap.conf \ login.access \ login.conf \ mac.conf \ motd \ netconfig \ network.subr \ networks \ newsyslog.conf \ nsswitch.conf \ phones \ profile \ protocols \ rc \ rc.bsdextended \ rc.firewall \ rc.initdiskless \ rc.shutdown \ rc.subr \ remote \ rpc \ services \ shells \ sysctl.conf \ syslog.conf \ termcap.small .if exists(${.CURDIR}/etc.${MACHINE}/ttys) BIN1+= etc.${MACHINE}/ttys .elif exists(${.CURDIR}/etc.${MACHINE_ARCH}/ttys) BIN1+= etc.${MACHINE_ARCH}/ttys .elif exists(${.CURDIR}/etc.${MACHINE_CPUARCH}/ttys) BIN1+= etc.${MACHINE_CPUARCH}/ttys .else .error etc.MACHINE/ttys missing .endif OPENBSMDIR= ${SRCTOP}/contrib/openbsm BSM_ETC_OPEN_FILES= ${OPENBSMDIR}/etc/audit_class \ ${OPENBSMDIR}/etc/audit_event BSM_ETC_RESTRICTED_FILES= ${OPENBSMDIR}/etc/audit_control \ ${OPENBSMDIR}/etc/audit_user BSM_ETC_EXEC_FILES= ${OPENBSMDIR}/etc/audit_warn BSM_ETC_DIR= ${DESTDIR}/etc/security # NB: keep these sorted by MK_* knobs .if ${MK_AMD} != "no" BIN1+= amd.map .endif .if ${MK_APM} != "no" BIN1+= apmd.conf .endif .if ${MK_AUTOFS} != "no" BIN1+= auto_master .endif .if ${MK_BLACKLIST} != "no" BIN1+= blacklistd.conf .endif .if ${MK_FREEBSD_UPDATE} != "no" BIN1+= freebsd-update.conf .endif .if ${MK_FTP} != "no" BIN1+= ftpusers .endif .if ${MK_INETD} != "no" BIN1+= inetd.conf .endif .if ${MK_LOCATE} != "no" BIN1+= ${SRCTOP}/usr.bin/locate/locate/locate.rc .endif .if ${MK_LPR} != "no" BIN1+= hosts.lpd printcap .endif .if ${MK_MAIL} != "no" BIN1+= ${SRCTOP}/usr.bin/mail/misc/mail.rc .endif .if ${MK_NTP} != "no" BIN1+= ntp.conf .endif .if ${MK_OPENSSH} != "no" SSH= ${SRCTOP}/crypto/openssh/ssh_config \ ${SRCTOP}/crypto/openssh/sshd_config \ ${SRCTOP}/crypto/openssh/moduli .endif .if ${MK_OPENSSL} != "no" SSL= ${SRCTOP}/crypto/openssl/apps/openssl.cnf .endif .if ${MK_NS_CACHING} != "no" BIN1+= nscd.conf .endif .if ${MK_PORTSNAP} != "no" BIN1+= portsnap.conf .endif .if ${MK_PF} != "no" BIN1+= pf.os .endif .if ${MK_SENDMAIL} != "no" BIN1+= rc.sendmail .endif .if ${MK_TCSH} != "no" BIN1+= csh.cshrc csh.login csh.logout .endif .if ${MK_WIRELESS} != "no" BIN1+= regdomain.xml .endif # -rwxr-xr-x root:wheel, for the new cron root:wheel BIN2= netstart pccard_ether rc.suspend rc.resume -MTREE= BSD.debug.dist BSD.include.dist BSD.root.dist BSD.usr.dist BSD.var.dist -.if ${MK_LIB32} != "no" -MTREE+= BSD.lib32.dist -.endif -.if ${MK_LIBSOFT} != "no" -MTREE+= BSD.libsoft.dist -.endif -.if ${MK_TESTS} != "no" -MTREE+= BSD.tests.dist -.endif -.if ${MK_SENDMAIL} != "no" -MTREE+= BSD.sendmail.dist -.endif - PPPCNF= ppp.conf .if ${MK_SENDMAIL} == "no" ETCMAIL=mailer.conf aliases .else ETCMAIL=Makefile README mailer.conf access.sample virtusertable.sample \ mailertable.sample aliases .endif # Special top level files for FreeBSD FREEBSD=COPYRIGHT # Sanitize DESTDIR DESTDIR:= ${DESTDIR:C://*:/:g} afterinstall: .if ${MK_MAN} != "no" ${_+_}cd ${SRCTOP}/share/man; ${MAKE} makedb .endif distribute: # Avoid installing tests here; "make distribution" will do this and # correctly place them in the right location. ${_+_}cd ${.CURDIR} ; ${MAKE} MK_TESTS=no install \ DESTDIR=${DISTDIR}/${DISTRIBUTION} ${_+_}cd ${.CURDIR} ; ${MAKE} distribution DESTDIR=${DISTDIR}/${DISTRIBUTION} .include .if ${TARGET_ENDIANNESS} == "1234" CAP_MKDB_ENDIAN?= -l .elif ${TARGET_ENDIANNESS} == "4321" CAP_MKDB_ENDIAN?= -b .else CAP_MKDB_ENDIAN?= .endif .if defined(NO_ROOT) METALOG.add?= cat -l >> ${METALOG} .endif distribution: .if !defined(DESTDIR) @echo "set DESTDIR before running \"make ${.TARGET}\"" @false .endif cd ${.CURDIR}; \ ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 644 \ ${BIN1} ${DESTDIR}/etc; \ cap_mkdb ${CAP_MKDB_ENDIAN} ${DESTDIR}/etc/login.conf; \ services_mkdb ${CAP_MKDB_ENDIAN} -q -o ${DESTDIR}/var/db/services.db \ ${DESTDIR}/etc/services; \ ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 755 \ ${BIN2} ${DESTDIR}/etc; \ ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 600 \ master.passwd nsmb.conf opieaccess ${DESTDIR}/etc; .if ${MK_BSNMP} != "no" cd ${.CURDIR}; \ ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 600 \ snmpd.config ${DESTDIR}/etc; .endif .if ${MK_AT} == "no" sed -i "" -e 's;.*/usr/libexec/atrun;#&;' ${DESTDIR}/etc/crontab .endif .if ${MK_TCSH} == "no" sed -i "" -e 's;/bin/csh;/bin/sh;' ${DESTDIR}/etc/master.passwd .endif pwd_mkdb -i -p -d ${DESTDIR}/etc ${DESTDIR}/etc/master.passwd .if defined(NO_ROOT) ( \ echo "./etc/login.conf.db type=file mode=0644 uname=root gname=wheel"; \ echo "./etc/passwd type=file mode=0644 uname=root gname=wheel"; \ echo "./etc/pwd.db type=file mode=0644 uname=root gname=wheel"; \ echo "./etc/spwd.db type=file mode=0600 uname=root gname=wheel"; \ ) | ${METALOG.add} .endif .if ${MK_AUTOFS} != "no" ${_+_}cd ${.CURDIR}/autofs; ${MAKE} install .endif .if ${MK_BLUETOOTH} != "no" ${_+_}cd ${.CURDIR}/bluetooth; ${MAKE} install .endif .if ${MK_CASPER} != "no" ${_+_}cd ${.CURDIR}/casper; ${MAKE} install .endif ${_+_}cd ${.CURDIR}/cron.d; ${MAKE} install ${_+_}cd ${.CURDIR}/defaults; ${MAKE} install ${_+_}cd ${.CURDIR}/devd; ${MAKE} install ${_+_}cd ${.CURDIR}/gss; ${MAKE} install + ${_+_}cd ${.CURDIR}/mtree; ${MAKE} install ${_+_}cd ${.CURDIR}/newsyslog.conf.d; ${MAKE} install .if ${MK_NTP} != "no" ${_+_}cd ${.CURDIR}/ntp; ${MAKE} install .endif ${_+_}cd ${.CURDIR}/periodic; ${MAKE} install .if ${MK_PKGBOOTSTRAP} != "no" ${_+_}cd ${.CURDIR}/pkg; ${MAKE} install .endif ${_+_}cd ${.CURDIR}/rc.d; ${MAKE} install ${_+_}cd ${SRCTOP}/share/termcap; ${MAKE} etc-termcap ${_+_}cd ${.CURDIR}/syslog.d; ${MAKE} install ${_+_}cd ${SRCTOP}/usr.sbin/rmt; ${MAKE} etc-rmt ${_+_}cd ${.CURDIR}/pam.d; ${MAKE} install cd ${.CURDIR}; ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 0444 \ ${BSM_ETC_OPEN_FILES} ${BSM_ETC_DIR} cd ${.CURDIR}; ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 0600 \ ${BSM_ETC_RESTRICTED_FILES} ${BSM_ETC_DIR} cd ${.CURDIR}; ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 0500 \ ${BSM_ETC_EXEC_FILES} ${BSM_ETC_DIR} .if ${MK_UNBOUND} != "no" if [ ! -e ${DESTDIR}/etc/unbound ]; then \ ${INSTALL_SYMLINK} ../var/unbound ${DESTDIR}/etc/unbound; \ fi .endif .if ${MK_SENDMAIL} != "no" ${_+_}cd ${.CURDIR}/sendmail; ${MAKE} distribution .endif .if ${MK_OPENSSH} != "no" cd ${.CURDIR}; ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 644 \ ${SSH} ${DESTDIR}/etc/ssh .endif .if ${MK_OPENSSL} != "no" cd ${.CURDIR}; ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 644 \ ${SSL} ${DESTDIR}/etc/ssl .endif .if ${MK_KERBEROS} != "no" cd ${.CURDIR}/root; \ ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 644 \ dot.k5login ${DESTDIR}/root/.k5login; .endif cd ${.CURDIR}/root; \ ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 644 \ dot.profile ${DESTDIR}/root/.profile; \ rm -f ${DESTDIR}/.profile; \ ln ${DESTDIR}/root/.profile ${DESTDIR}/.profile .if ${MK_TCSH} != "no" cd ${.CURDIR}/root; \ ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 644 \ dot.cshrc ${DESTDIR}/root/.cshrc; \ ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 644 \ dot.login ${DESTDIR}/root/.login; \ rm -f ${DESTDIR}/.cshrc; \ ln ${DESTDIR}/root/.cshrc ${DESTDIR}/.cshrc .endif - cd ${.CURDIR}/mtree; ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 444 \ - ${MTREE} ${DESTDIR}/etc/mtree .if ${MK_MAIL} != "no" cd ${.CURDIR}/mail; ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 644 \ ${ETCMAIL} ${DESTDIR}/etc/mail if [ -d ${DESTDIR}/etc/mail -a -f ${DESTDIR}/etc/mail/aliases -a \ ! -f ${DESTDIR}/etc/aliases ]; then \ ln -s mail/aliases ${DESTDIR}/etc/aliases; \ fi .endif ${INSTALL} -o ${BINOWN} -g operator -m 664 /dev/null \ ${DESTDIR}/etc/dumpdates .if ${MK_LOCATE} != "no" ${INSTALL} -o nobody -g ${BINGRP} -m 644 /dev/null \ ${DESTDIR}/var/db/locate.database .endif ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 644 ${.CURDIR}/minfree \ ${DESTDIR}/var/crash cd ${.CURDIR}/..; ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 444 \ ${FREEBSD} ${DESTDIR}/ .if ${MK_BOOT} != "no" .if exists(${SRCTOP}/sys/${MACHINE}/conf/GENERIC.hints) ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 444 \ ${SRCTOP}/sys/${MACHINE}/conf/GENERIC.hints \ ${DESTDIR}/boot/device.hints .endif .endif .if ${MK_NIS} == "no" sed -i "" -e 's/.*_compat:/# &/' -e 's/compat$$/files/' \ ${DESTDIR}/etc/nsswitch.conf .endif MTREE_CMD?= mtree MTREES= mtree/BSD.root.dist / \ mtree/BSD.var.dist /var \ mtree/BSD.usr.dist /usr \ mtree/BSD.include.dist /usr/include \ mtree/BSD.debug.dist /usr/lib .if ${MK_LIB32} != "no" MTREES+= mtree/BSD.lib32.dist /usr MTREES+= mtree/BSD.lib32.dist /usr/lib/debug/usr .endif .if ${MK_LIBSOFT} != "no" MTREES+= mtree/BSD.libsoft.dist /usr MTREES+= mtree/BSD.libsoft.dist /usr/lib/debug/usr .endif .if ${MK_TESTS} != "no" MTREES+= mtree/BSD.tests.dist ${TESTSBASE} MTREES+= mtree/BSD.tests.dist /usr/lib/debug/${TESTSBASE} .endif .if ${MK_SENDMAIL} != "no" MTREES+= mtree/BSD.sendmail.dist / .endif .for mtree in ${LOCAL_MTREE} MTREES+= ../${mtree} / .endfor # Clean up some directories that where mistakenly created as files that # should not have been as part of the nvi update in r281994. # This should be removed after 11.0-RELEASE. DISTRIB_CLEANUP_SHARE_FILES= ${SHAREDIR}/doc/usd/10.exref ${SHAREDIR}/doc/usd/11.edit DISTRIB_CLEANUP_SHARE_FILES+= ${SHAREDIR}/doc/usd/12.vi ${SHAREDIR}/doc/usd/13.viref distrib-cleanup: .PHONY for file in ${DISTRIB_CLEANUP_SHARE_FILES}; do \ if [ -f ${DESTDIR}/$${file} ]; then \ rm -f ${DESTDIR}/$${file}; \ fi; \ done distrib-dirs: ${MTREES:N/*} distrib-cleanup .PHONY @set ${MTREES}; \ while test $$# -ge 2; do \ m=${.CURDIR}/$$1; \ shift; \ d=${DESTDIR}$$1; \ shift; \ test -d $$d || mkdir -p $$d; \ ${ECHO} ${MTREE_CMD} -deU ${MTREE_FSCHG} \ ${MTREE_FOLLOWS_SYMLINKS} -f $$m -p $$d; \ ${MTREE_FILTER} $$m | \ ${MTREE_CMD} -deU ${MTREE_FSCHG} ${MTREE_FOLLOWS_SYMLINKS} \ -p $$d; \ done; true .if defined(NO_ROOT) @set ${MTREES}; \ while test $$# -ge 2; do \ m=${.CURDIR}/$$1; \ shift; \ d=$$1; \ test "$$d" == "/" && d=""; \ d=${DISTBASE}$$d; \ shift; \ test -d ${DESTDIR}/$$d || mkdir -p ${DESTDIR}/$$d; \ ${ECHO} "${MTREE_CMD:N-W} -C -f $$m -K uname,gname | " \ "sed s#^\.#.$$d# | ${METALOG.add}" ; \ ${MTREE_FILTER} $$m | \ ${MTREE_CMD:N-W} -C -K uname,gname | sed s#^\.#.$$d# | \ ${METALOG.add} ; \ done; true .endif ${INSTALL_SYMLINK} usr/src/sys ${DESTDIR}/sys .if ${MK_MAN} != "no" cd ${DESTDIR}${SHAREDIR}/man; \ for mandir in man*; do \ ${INSTALL_SYMLINK} ../$$mandir \ ${DESTDIR}${SHAREDIR}/man/en.ISO8859-1/; \ ${INSTALL_SYMLINK} ../$$mandir \ ${DESTDIR}${SHAREDIR}/man/en.UTF-8/; \ done .if ${MK_OPENSSL} != "no" cd ${DESTDIR}${SHAREDIR}/openssl/man; \ for mandir in man*; do \ ${INSTALL_SYMLINK} ../$$mandir \ ${DESTDIR}${SHAREDIR}/openssl/man/en.ISO8859-1/; \ done .endif set - `grep "^[a-zA-Z]" ${.CURDIR}/man.alias`; \ while [ $$# -gt 0 ] ; do \ ${INSTALL_SYMLINK} "$$2" "${DESTDIR}${SHAREDIR}/man/$$1"; \ if [ "${MK_OPENSSL}" != "no" ]; then \ ${INSTALL_SYMLINK} "$$2" \ "${DESTDIR}${SHAREDIR}/openssl/man/$$1"; \ fi; \ shift; shift; \ done .endif .if ${MK_NLS} != "no" set - `grep "^[a-zA-Z]" ${.CURDIR}/nls.alias`; \ while [ $$# -gt 0 ] ; do \ ${INSTALL_SYMLINK} "$$2" "${DESTDIR}${SHAREDIR}/nls/$$1"; \ shift; shift; \ done .endif etc-examples-install: ${META_DEPS} cd ${.CURDIR}; ${INSTALL} ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 \ ${BIN1} ${BIN2} nsmb.conf opieaccess \ ${DESTDIR}${SHAREDIR}/examples/etc etc-examples: etc-examples-install ${_+_}cd ${.CURDIR}/defaults; \ ${MAKE} ${${MK_STAGING} == "yes":?all:install} \ DESTDIR=${DESTDIR}${SHAREDIR}/examples .include .if ${MK_INSTALL_AS_USER} == "yes" && ${_uid} != 0 MTREE_FILTER= sed -e 's,\([gu]\)name=,\1id=,g' \ -e 's,\(uid=\)[^ ]* ,\1${_uid} ,' \ -e 's,\(gid=\)[^ ]* ,\1${_gid} ,' \ -e 's,\(uid=\)[^ ]*$$,\1${_uid},' \ -e 's,\(gid=\)[^ ]*$$,\1${_gid},' .else MTREE_FILTER= cat .if !defined(NO_FSCHG) MTREE_FSCHG= -i .endif .endif Index: projects/runtime-coverage/etc/mtree/Makefile =================================================================== --- projects/runtime-coverage/etc/mtree/Makefile (revision 321457) +++ projects/runtime-coverage/etc/mtree/Makefile (revision 321458) @@ -1,35 +1,34 @@ # $FreeBSD$ .include -FILES= ${_BSD.debug.dist} \ +# NOTE: BSD.debug.dist is unconditionally installed for developer ease-of-use. +FILES= \ + BSD.debug.dist \ ${_BSD.coverage.dist} \ BSD.include.dist \ BSD.root.dist \ ${_BSD.lib32.dist} \ ${_BSD.libsoft.dist} \ ${_BSD.sendmail.dist} \ ${_BSD.tests.dist} \ BSD.usr.dist \ BSD.var.dist -.if ${MK_DEBUG_FILES} != "no" -_BSD.debug.dist= BSD.debug.dist -.endif .if ${MK_LIB32} != "no" _BSD.lib32.dist= BSD.lib32.dist .endif .if ${MK_LIBSOFT} != "no" _BSD.libsoft.dist= BSD.libsoft.dist .endif .if ${MK_SENDMAIL} != "no" _BSD.sendmail.dist= BSD.sendmail.dist .endif .if ${MK_TESTS} != "no" _BSD.tests.dist= BSD.tests.dist .endif NO_OBJ= FILESDIR= /etc/mtree .include Index: projects/runtime-coverage/lib/clang/libllvm/Makefile =================================================================== --- projects/runtime-coverage/lib/clang/libllvm/Makefile (revision 321457) +++ projects/runtime-coverage/lib/clang/libllvm/Makefile (revision 321458) @@ -1,1419 +1,1429 @@ # $FreeBSD$ .include .include "../llvm.pre.mk" LIB= llvm INTERNALLIB= CFLAGS+= -I${.OBJDIR} .for arch in AArch64 ARM Mips PowerPC Sparc X86 CFLAGS+= -I${LLVM_SRCS}/lib/Target/${arch} .endfor SRCDIR= lib SRCS_MIN+= Analysis/AliasAnalysis.cpp SRCS_MIN+= Analysis/AliasAnalysisEvaluator.cpp SRCS_MIN+= Analysis/AliasAnalysisSummary.cpp SRCS_MIN+= Analysis/AliasSetTracker.cpp SRCS_EXT+= Analysis/Analysis.cpp SRCS_MIN+= Analysis/AssumptionCache.cpp SRCS_MIN+= Analysis/BasicAliasAnalysis.cpp SRCS_MIN+= Analysis/BlockFrequencyInfo.cpp SRCS_MIN+= Analysis/BlockFrequencyInfoImpl.cpp SRCS_MIN+= Analysis/BranchProbabilityInfo.cpp SRCS_MIN+= Analysis/CFG.cpp SRCS_MIN+= Analysis/CFGPrinter.cpp SRCS_MIN+= Analysis/CFLAndersAliasAnalysis.cpp SRCS_MIN+= Analysis/CFLSteensAliasAnalysis.cpp SRCS_MIN+= Analysis/CGSCCPassManager.cpp SRCS_MIN+= Analysis/CallGraph.cpp SRCS_MIN+= Analysis/CallGraphSCCPass.cpp SRCS_MIN+= Analysis/CallPrinter.cpp SRCS_MIN+= Analysis/CaptureTracking.cpp SRCS_MIN+= Analysis/CodeMetrics.cpp SRCS_MIN+= Analysis/ConstantFolding.cpp SRCS_MIN+= Analysis/CostModel.cpp SRCS_MIN+= Analysis/Delinearization.cpp SRCS_MIN+= Analysis/DemandedBits.cpp SRCS_MIN+= Analysis/DependenceAnalysis.cpp SRCS_MIN+= Analysis/DivergenceAnalysis.cpp SRCS_MIN+= Analysis/DomPrinter.cpp SRCS_MIN+= Analysis/DominanceFrontier.cpp SRCS_MIN+= Analysis/EHPersonalities.cpp SRCS_MIN+= Analysis/GlobalsModRef.cpp SRCS_MIN+= Analysis/IVUsers.cpp SRCS_MIN+= Analysis/IndirectCallPromotionAnalysis.cpp SRCS_MIN+= Analysis/InlineCost.cpp SRCS_MIN+= Analysis/InstCount.cpp SRCS_MIN+= Analysis/InstructionSimplify.cpp SRCS_MIN+= Analysis/Interval.cpp SRCS_MIN+= Analysis/IntervalPartition.cpp SRCS_MIN+= Analysis/IteratedDominanceFrontier.cpp SRCS_MIN+= Analysis/LazyBlockFrequencyInfo.cpp SRCS_MIN+= Analysis/LazyBranchProbabilityInfo.cpp SRCS_MIN+= Analysis/LazyCallGraph.cpp SRCS_MIN+= Analysis/LazyValueInfo.cpp SRCS_MIN+= Analysis/Lint.cpp SRCS_MIN+= Analysis/Loads.cpp SRCS_MIN+= Analysis/LoopAccessAnalysis.cpp SRCS_MIN+= Analysis/LoopAnalysisManager.cpp SRCS_MIN+= Analysis/LoopInfo.cpp SRCS_MIN+= Analysis/LoopPass.cpp SRCS_MIN+= Analysis/LoopUnrollAnalyzer.cpp SRCS_MIN+= Analysis/MemDepPrinter.cpp SRCS_MIN+= Analysis/MemDerefPrinter.cpp SRCS_MIN+= Analysis/MemoryBuiltins.cpp SRCS_MIN+= Analysis/MemoryDependenceAnalysis.cpp SRCS_MIN+= Analysis/MemoryLocation.cpp SRCS_MIN+= Analysis/MemorySSA.cpp SRCS_MIN+= Analysis/MemorySSAUpdater.cpp SRCS_MIN+= Analysis/ModuleDebugInfoPrinter.cpp SRCS_MIN+= Analysis/ModuleSummaryAnalysis.cpp SRCS_MIN+= Analysis/ObjCARCAliasAnalysis.cpp SRCS_MIN+= Analysis/ObjCARCAnalysisUtils.cpp SRCS_MIN+= Analysis/ObjCARCInstKind.cpp SRCS_MIN+= Analysis/OptimizationDiagnosticInfo.cpp SRCS_MIN+= Analysis/OrderedBasicBlock.cpp SRCS_MIN+= Analysis/PHITransAddr.cpp SRCS_MIN+= Analysis/PostDominators.cpp SRCS_MIN+= Analysis/ProfileSummaryInfo.cpp SRCS_MIN+= Analysis/PtrUseVisitor.cpp SRCS_MIN+= Analysis/RegionInfo.cpp SRCS_MIN+= Analysis/RegionPass.cpp SRCS_MIN+= Analysis/RegionPrinter.cpp SRCS_MIN+= Analysis/ScalarEvolution.cpp SRCS_MIN+= Analysis/ScalarEvolutionAliasAnalysis.cpp SRCS_MIN+= Analysis/ScalarEvolutionExpander.cpp SRCS_MIN+= Analysis/ScalarEvolutionNormalization.cpp SRCS_MIN+= Analysis/ScopedNoAliasAA.cpp SRCS_MIN+= Analysis/SparsePropagation.cpp SRCS_MIN+= Analysis/TargetLibraryInfo.cpp SRCS_MIN+= Analysis/TargetTransformInfo.cpp SRCS_MIN+= Analysis/Trace.cpp SRCS_MIN+= Analysis/TypeBasedAliasAnalysis.cpp SRCS_MIN+= Analysis/TypeMetadataUtils.cpp SRCS_MIN+= Analysis/ValueTracking.cpp SRCS_MIN+= Analysis/VectorUtils.cpp SRCS_MIN+= AsmParser/LLLexer.cpp SRCS_MIN+= AsmParser/LLParser.cpp SRCS_MIN+= AsmParser/Parser.cpp SRCS_MIN+= Bitcode/Reader/BitReader.cpp SRCS_MIN+= Bitcode/Reader/BitcodeReader.cpp SRCS_MIN+= Bitcode/Reader/BitstreamReader.cpp SRCS_MIN+= Bitcode/Reader/MetadataLoader.cpp SRCS_MIN+= Bitcode/Reader/ValueList.cpp SRCS_MIN+= Bitcode/Writer/BitWriter.cpp SRCS_MIN+= Bitcode/Writer/BitcodeWriter.cpp SRCS_MIN+= Bitcode/Writer/BitcodeWriterPass.cpp SRCS_MIN+= Bitcode/Writer/ValueEnumerator.cpp SRCS_MIN+= BinaryFormat/Dwarf.cpp SRCS_MIN+= BinaryFormat/Magic.cpp SRCS_MIN+= CodeGen/AggressiveAntiDepBreaker.cpp SRCS_MIN+= CodeGen/AllocationOrder.cpp SRCS_MIN+= CodeGen/Analysis.cpp SRCS_MIN+= CodeGen/AsmPrinter/ARMException.cpp SRCS_MIN+= CodeGen/AsmPrinter/AddressPool.cpp SRCS_MIN+= CodeGen/AsmPrinter/AsmPrinter.cpp SRCS_MIN+= CodeGen/AsmPrinter/AsmPrinterDwarf.cpp SRCS_MIN+= CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp SRCS_MIN+= CodeGen/AsmPrinter/CodeViewDebug.cpp SRCS_MIN+= CodeGen/AsmPrinter/DIE.cpp SRCS_MIN+= CodeGen/AsmPrinter/DIEHash.cpp SRCS_MIN+= CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp SRCS_MIN+= CodeGen/AsmPrinter/DebugHandlerBase.cpp SRCS_MIN+= CodeGen/AsmPrinter/DebugLocStream.cpp SRCS_MIN+= CodeGen/AsmPrinter/DwarfAccelTable.cpp SRCS_MIN+= CodeGen/AsmPrinter/DwarfCFIException.cpp SRCS_MIN+= CodeGen/AsmPrinter/DwarfCompileUnit.cpp SRCS_MIN+= CodeGen/AsmPrinter/DwarfDebug.cpp SRCS_MIN+= CodeGen/AsmPrinter/DwarfExpression.cpp SRCS_MIN+= CodeGen/AsmPrinter/DwarfFile.cpp SRCS_MIN+= CodeGen/AsmPrinter/DwarfStringPool.cpp SRCS_MIN+= CodeGen/AsmPrinter/DwarfUnit.cpp SRCS_MIN+= CodeGen/AsmPrinter/EHStreamer.cpp SRCS_MIN+= CodeGen/AsmPrinter/ErlangGCPrinter.cpp SRCS_MIN+= CodeGen/AsmPrinter/OcamlGCPrinter.cpp SRCS_MIN+= CodeGen/AsmPrinter/WinException.cpp SRCS_MIN+= CodeGen/AtomicExpandPass.cpp SRCS_MIN+= CodeGen/BasicTargetTransformInfo.cpp SRCS_MIN+= CodeGen/BranchCoalescing.cpp SRCS_MIN+= CodeGen/BranchFolding.cpp SRCS_MIN+= CodeGen/BranchRelaxation.cpp SRCS_MIN+= CodeGen/BuiltinGCs.cpp SRCS_MIN+= CodeGen/CalcSpillWeights.cpp SRCS_MIN+= CodeGen/CallingConvLower.cpp SRCS_MIN+= CodeGen/CodeGen.cpp SRCS_MIN+= CodeGen/CodeGenPrepare.cpp SRCS_MIN+= CodeGen/CountingFunctionInserter.cpp SRCS_MIN+= CodeGen/CriticalAntiDepBreaker.cpp SRCS_MIN+= CodeGen/DFAPacketizer.cpp SRCS_MIN+= CodeGen/DeadMachineInstructionElim.cpp SRCS_MIN+= CodeGen/DetectDeadLanes.cpp SRCS_MIN+= CodeGen/DwarfEHPrepare.cpp SRCS_MIN+= CodeGen/EarlyIfConversion.cpp SRCS_MIN+= CodeGen/EdgeBundles.cpp SRCS_MIN+= CodeGen/ExecutionDepsFix.cpp SRCS_MIN+= CodeGen/ExpandISelPseudos.cpp SRCS_MIN+= CodeGen/ExpandPostRAPseudos.cpp SRCS_MIN+= CodeGen/ExpandReductions.cpp SRCS_MIN+= CodeGen/FEntryInserter.cpp SRCS_MIN+= CodeGen/FaultMaps.cpp SRCS_MIN+= CodeGen/FuncletLayout.cpp SRCS_MIN+= CodeGen/GCMetadata.cpp SRCS_MIN+= CodeGen/GCMetadataPrinter.cpp SRCS_MIN+= CodeGen/GCRootLowering.cpp SRCS_MIN+= CodeGen/GCStrategy.cpp SRCS_MIN+= CodeGen/GlobalISel/CallLowering.cpp SRCS_MIN+= CodeGen/GlobalISel/GlobalISel.cpp SRCS_MIN+= CodeGen/GlobalISel/IRTranslator.cpp SRCS_MIN+= CodeGen/GlobalISel/InstructionSelect.cpp SRCS_MIN+= CodeGen/GlobalISel/InstructionSelector.cpp SRCS_MIN+= CodeGen/GlobalISel/Legalizer.cpp SRCS_MIN+= CodeGen/GlobalISel/LegalizerHelper.cpp SRCS_MIN+= CodeGen/GlobalISel/LegalizerInfo.cpp SRCS_MIN+= CodeGen/GlobalISel/Localizer.cpp SRCS_MIN+= CodeGen/GlobalISel/MachineIRBuilder.cpp SRCS_MIN+= CodeGen/GlobalISel/RegBankSelect.cpp SRCS_MIN+= CodeGen/GlobalISel/RegisterBank.cpp SRCS_MIN+= CodeGen/GlobalISel/RegisterBankInfo.cpp SRCS_MIN+= CodeGen/GlobalISel/Utils.cpp SRCS_MIN+= CodeGen/GlobalMerge.cpp SRCS_MIN+= CodeGen/IfConversion.cpp SRCS_MIN+= CodeGen/ImplicitNullChecks.cpp SRCS_MIN+= CodeGen/InlineSpiller.cpp SRCS_MIN+= CodeGen/InterferenceCache.cpp SRCS_MIN+= CodeGen/InterleavedAccessPass.cpp SRCS_MIN+= CodeGen/IntrinsicLowering.cpp SRCS_MIN+= CodeGen/LLVMTargetMachine.cpp SRCS_MIN+= CodeGen/LatencyPriorityQueue.cpp SRCS_MIN+= CodeGen/LazyMachineBlockFrequencyInfo.cpp SRCS_MIN+= CodeGen/LexicalScopes.cpp SRCS_MIN+= CodeGen/LiveDebugValues.cpp SRCS_MIN+= CodeGen/LiveDebugVariables.cpp SRCS_MIN+= CodeGen/LiveInterval.cpp SRCS_MIN+= CodeGen/LiveIntervalAnalysis.cpp SRCS_MIN+= CodeGen/LiveIntervalUnion.cpp SRCS_MIN+= CodeGen/LivePhysRegs.cpp SRCS_MIN+= CodeGen/LiveRangeCalc.cpp SRCS_MIN+= CodeGen/LiveRangeEdit.cpp SRCS_MIN+= CodeGen/LiveRangeShrink.cpp SRCS_MIN+= CodeGen/LiveRegMatrix.cpp SRCS_MIN+= CodeGen/LiveRegUnits.cpp SRCS_MIN+= CodeGen/LiveStackAnalysis.cpp SRCS_MIN+= CodeGen/LiveVariables.cpp SRCS_MIN+= CodeGen/LocalStackSlotAllocation.cpp SRCS_MIN+= CodeGen/LowLevelType.cpp SRCS_MIN+= CodeGen/LowerEmuTLS.cpp SRCS_EXT+= CodeGen/MIRParser/MILexer.cpp SRCS_EXT+= CodeGen/MIRParser/MIParser.cpp SRCS_EXT+= CodeGen/MIRParser/MIRParser.cpp SRCS_MIN+= CodeGen/MIRPrinter.cpp SRCS_MIN+= CodeGen/MIRPrintingPass.cpp SRCS_MIN+= CodeGen/MachineBasicBlock.cpp SRCS_MIN+= CodeGen/MachineBlockFrequencyInfo.cpp SRCS_MIN+= CodeGen/MachineBlockPlacement.cpp SRCS_MIN+= CodeGen/MachineBranchProbabilityInfo.cpp SRCS_MIN+= CodeGen/MachineCSE.cpp SRCS_MIN+= CodeGen/MachineCombiner.cpp SRCS_MIN+= CodeGen/MachineCopyPropagation.cpp SRCS_MIN+= CodeGen/MachineDominanceFrontier.cpp SRCS_MIN+= CodeGen/MachineDominators.cpp SRCS_MIN+= CodeGen/MachineFrameInfo.cpp SRCS_MIN+= CodeGen/MachineFunction.cpp SRCS_MIN+= CodeGen/MachineFunctionPass.cpp SRCS_MIN+= CodeGen/MachineFunctionPrinterPass.cpp SRCS_MIN+= CodeGen/MachineInstr.cpp SRCS_MIN+= CodeGen/MachineInstrBundle.cpp SRCS_MIN+= CodeGen/MachineLICM.cpp SRCS_MIN+= CodeGen/MachineLoopInfo.cpp SRCS_MIN+= CodeGen/MachineModuleInfo.cpp SRCS_MIN+= CodeGen/MachineModuleInfoImpls.cpp SRCS_MIN+= CodeGen/MachineOptimizationRemarkEmitter.cpp SRCS_MIN+= CodeGen/MachineOutliner.cpp SRCS_MIN+= CodeGen/MachinePassRegistry.cpp SRCS_MIN+= CodeGen/MachinePipeliner.cpp SRCS_MIN+= CodeGen/MachinePostDominators.cpp SRCS_MIN+= CodeGen/MachineRegionInfo.cpp SRCS_MIN+= CodeGen/MachineRegisterInfo.cpp SRCS_MIN+= CodeGen/MachineSSAUpdater.cpp SRCS_MIN+= CodeGen/MachineScheduler.cpp SRCS_MIN+= CodeGen/MachineSink.cpp SRCS_MIN+= CodeGen/MachineTraceMetrics.cpp SRCS_MIN+= CodeGen/MachineVerifier.cpp SRCS_MIN+= CodeGen/MacroFusion.cpp SRCS_MIN+= CodeGen/OptimizePHIs.cpp SRCS_MIN+= CodeGen/PHIElimination.cpp SRCS_MIN+= CodeGen/PHIEliminationUtils.cpp SRCS_MIN+= CodeGen/ParallelCG.cpp SRCS_MIN+= CodeGen/PatchableFunction.cpp SRCS_MIN+= CodeGen/PeepholeOptimizer.cpp SRCS_MIN+= CodeGen/PostRAHazardRecognizer.cpp SRCS_MIN+= CodeGen/PostRASchedulerList.cpp SRCS_MIN+= CodeGen/PreISelIntrinsicLowering.cpp SRCS_MIN+= CodeGen/ProcessImplicitDefs.cpp SRCS_MIN+= CodeGen/PrologEpilogInserter.cpp SRCS_MIN+= CodeGen/PseudoSourceValue.cpp SRCS_MIN+= CodeGen/RegAllocBase.cpp SRCS_MIN+= CodeGen/RegAllocBasic.cpp SRCS_MIN+= CodeGen/RegAllocFast.cpp SRCS_MIN+= CodeGen/RegAllocGreedy.cpp SRCS_MIN+= CodeGen/RegAllocPBQP.cpp SRCS_MIN+= CodeGen/RegUsageInfoCollector.cpp SRCS_MIN+= CodeGen/RegUsageInfoPropagate.cpp SRCS_MIN+= CodeGen/RegisterClassInfo.cpp SRCS_MIN+= CodeGen/RegisterCoalescer.cpp SRCS_MIN+= CodeGen/RegisterPressure.cpp SRCS_MIN+= CodeGen/RegisterScavenging.cpp SRCS_MIN+= CodeGen/RegisterUsageInfo.cpp SRCS_MIN+= CodeGen/RenameIndependentSubregs.cpp SRCS_MIN+= CodeGen/ResetMachineFunctionPass.cpp SRCS_MIN+= CodeGen/SafeStack.cpp SRCS_MIN+= CodeGen/SafeStackColoring.cpp SRCS_MIN+= CodeGen/SafeStackLayout.cpp SRCS_MIN+= CodeGen/ScalarizeMaskedMemIntrin.cpp SRCS_MIN+= CodeGen/ScheduleDAG.cpp SRCS_MIN+= CodeGen/ScheduleDAGInstrs.cpp SRCS_MIN+= CodeGen/ScheduleDAGPrinter.cpp SRCS_MIN+= CodeGen/ScoreboardHazardRecognizer.cpp SRCS_MIN+= CodeGen/SelectionDAG/DAGCombiner.cpp SRCS_MIN+= CodeGen/SelectionDAG/FastISel.cpp SRCS_MIN+= CodeGen/SelectionDAG/FunctionLoweringInfo.cpp SRCS_MIN+= CodeGen/SelectionDAG/InstrEmitter.cpp SRCS_MIN+= CodeGen/SelectionDAG/LegalizeDAG.cpp SRCS_MIN+= CodeGen/SelectionDAG/LegalizeFloatTypes.cpp SRCS_MIN+= CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp SRCS_MIN+= CodeGen/SelectionDAG/LegalizeTypes.cpp SRCS_MIN+= CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp SRCS_MIN+= CodeGen/SelectionDAG/LegalizeVectorOps.cpp SRCS_MIN+= CodeGen/SelectionDAG/LegalizeVectorTypes.cpp SRCS_MIN+= CodeGen/SelectionDAG/ResourcePriorityQueue.cpp SRCS_MIN+= CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp SRCS_MIN+= CodeGen/SelectionDAG/ScheduleDAGFast.cpp SRCS_MIN+= CodeGen/SelectionDAG/ScheduleDAGRRList.cpp SRCS_MIN+= CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp SRCS_MIN+= CodeGen/SelectionDAG/ScheduleDAGVLIW.cpp SRCS_MIN+= CodeGen/SelectionDAG/SelectionDAG.cpp SRCS_MIN+= CodeGen/SelectionDAG/SelectionDAGBuilder.cpp SRCS_MIN+= CodeGen/SelectionDAG/SelectionDAGDumper.cpp SRCS_MIN+= CodeGen/SelectionDAG/SelectionDAGISel.cpp SRCS_MIN+= CodeGen/SelectionDAG/SelectionDAGPrinter.cpp SRCS_MIN+= CodeGen/SelectionDAG/SelectionDAGTargetInfo.cpp SRCS_MIN+= CodeGen/SelectionDAG/StatepointLowering.cpp SRCS_MIN+= CodeGen/SelectionDAG/TargetLowering.cpp SRCS_MIN+= CodeGen/ShadowStackGCLowering.cpp SRCS_MIN+= CodeGen/ShrinkWrap.cpp SRCS_MIN+= CodeGen/SjLjEHPrepare.cpp SRCS_MIN+= CodeGen/SlotIndexes.cpp SRCS_MIN+= CodeGen/SpillPlacement.cpp SRCS_MIN+= CodeGen/SplitKit.cpp SRCS_MIN+= CodeGen/StackColoring.cpp SRCS_MIN+= CodeGen/StackMapLivenessAnalysis.cpp SRCS_MIN+= CodeGen/StackMaps.cpp SRCS_MIN+= CodeGen/StackProtector.cpp SRCS_MIN+= CodeGen/StackSlotColoring.cpp SRCS_MIN+= CodeGen/TailDuplication.cpp SRCS_MIN+= CodeGen/TailDuplicator.cpp SRCS_MIN+= CodeGen/TargetFrameLoweringImpl.cpp SRCS_MIN+= CodeGen/TargetInstrInfo.cpp SRCS_MIN+= CodeGen/TargetLoweringBase.cpp SRCS_MIN+= CodeGen/TargetLoweringObjectFileImpl.cpp SRCS_MIN+= CodeGen/TargetOptionsImpl.cpp SRCS_MIN+= CodeGen/TargetPassConfig.cpp SRCS_MIN+= CodeGen/TargetRegisterInfo.cpp SRCS_MIN+= CodeGen/TargetSchedule.cpp SRCS_MIN+= CodeGen/TargetSubtargetInfo.cpp SRCS_MIN+= CodeGen/TwoAddressInstructionPass.cpp SRCS_MIN+= CodeGen/UnreachableBlockElim.cpp SRCS_MIN+= CodeGen/VirtRegMap.cpp SRCS_MIN+= CodeGen/WinEHPrepare.cpp SRCS_MIN+= CodeGen/XRayInstrumentation.cpp SRCS_MIN+= DebugInfo/CodeView/CVSymbolVisitor.cpp SRCS_MIN+= DebugInfo/CodeView/CVTypeVisitor.cpp SRCS_MIN+= DebugInfo/CodeView/CodeViewError.cpp SRCS_MIN+= DebugInfo/CodeView/CodeViewRecordIO.cpp SRCS_EXT+= DebugInfo/CodeView/DebugChecksumsSubsection.cpp SRCS_EXT+= DebugInfo/CodeView/DebugCrossExSubsection.cpp SRCS_EXT+= DebugInfo/CodeView/DebugCrossImpSubsection.cpp SRCS_EXT+= DebugInfo/CodeView/DebugFrameDataSubsection.cpp SRCS_EXT+= DebugInfo/CodeView/DebugInlineeLinesSubsection.cpp SRCS_EXT+= DebugInfo/CodeView/DebugLinesSubsection.cpp SRCS_EXT+= DebugInfo/CodeView/DebugStringTableSubsection.cpp SRCS_EXT+= DebugInfo/CodeView/DebugSubsection.cpp SRCS_EXT+= DebugInfo/CodeView/DebugSubsectionRecord.cpp SRCS_EXT+= DebugInfo/CodeView/DebugSubsectionVisitor.cpp SRCS_EXT+= DebugInfo/CodeView/DebugSymbolRVASubsection.cpp SRCS_EXT+= DebugInfo/CodeView/DebugSymbolsSubsection.cpp SRCS_EXT+= DebugInfo/CodeView/EnumTables.cpp SRCS_MIN+= DebugInfo/CodeView/Formatters.cpp SRCS_EXT+= DebugInfo/CodeView/LazyRandomTypeCollection.cpp SRCS_MIN+= DebugInfo/CodeView/Line.cpp SRCS_MIN+= DebugInfo/CodeView/RecordSerialization.cpp SRCS_EXT+= DebugInfo/CodeView/StringsAndChecksums.cpp SRCS_MIN+= DebugInfo/CodeView/SymbolDumper.cpp SRCS_MIN+= DebugInfo/CodeView/SymbolRecordMapping.cpp SRCS_EXT+= DebugInfo/CodeView/SymbolSerializer.cpp SRCS_MIN+= DebugInfo/CodeView/TypeDumpVisitor.cpp SRCS_MIN+= DebugInfo/CodeView/TypeIndex.cpp SRCS_MIN+= DebugInfo/CodeView/TypeIndexDiscovery.cpp SRCS_MIN+= DebugInfo/CodeView/TypeName.cpp SRCS_MIN+= DebugInfo/CodeView/TypeRecordMapping.cpp SRCS_MIN+= DebugInfo/CodeView/TypeSerializer.cpp SRCS_MIN+= DebugInfo/CodeView/TypeStreamMerger.cpp SRCS_MIN+= DebugInfo/CodeView/TypeTableCollection.cpp SRCS_MIW+= DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp SRCS_MIW+= DebugInfo/DWARF/DWARFAcceleratorTable.cpp SRCS_MIW+= DebugInfo/DWARF/DWARFCompileUnit.cpp SRCS_MIW+= DebugInfo/DWARF/DWARFContext.cpp SRCS_MIW+= DebugInfo/DWARF/DWARFDataExtractor.cpp SRCS_MIW+= DebugInfo/DWARF/DWARFDebugAbbrev.cpp SRCS_MIW+= DebugInfo/DWARF/DWARFDebugArangeSet.cpp SRCS_MIW+= DebugInfo/DWARF/DWARFDebugAranges.cpp SRCS_MIW+= DebugInfo/DWARF/DWARFDebugFrame.cpp SRCS_MIW+= DebugInfo/DWARF/DWARFDebugInfoEntry.cpp SRCS_MIW+= DebugInfo/DWARF/DWARFDebugLine.cpp SRCS_MIW+= DebugInfo/DWARF/DWARFDebugLoc.cpp SRCS_MIW+= DebugInfo/DWARF/DWARFDebugMacro.cpp SRCS_MIW+= DebugInfo/DWARF/DWARFDebugPubTable.cpp SRCS_MIW+= DebugInfo/DWARF/DWARFDebugRangeList.cpp SRCS_MIW+= DebugInfo/DWARF/DWARFDie.cpp SRCS_MIW+= DebugInfo/DWARF/DWARFFormValue.cpp SRCS_MIW+= DebugInfo/DWARF/DWARFGdbIndex.cpp SRCS_MIW+= DebugInfo/DWARF/DWARFTypeUnit.cpp SRCS_MIW+= DebugInfo/DWARF/DWARFUnit.cpp SRCS_MIW+= DebugInfo/DWARF/DWARFUnitIndex.cpp SRCS_MIW+= DebugInfo/DWARF/DWARFVerifier.cpp SRCS_MIW+= DebugInfo/DWARF/SyntaxHighlighting.cpp SRCS_MIN+= DebugInfo/MSF/MSFBuilder.cpp SRCS_MIN+= DebugInfo/MSF/MSFCommon.cpp SRCS_MIN+= DebugInfo/MSF/MSFError.cpp SRCS_MIN+= DebugInfo/MSF/MappedBlockStream.cpp SRCS_EXT+= DebugInfo/PDB/GenericError.cpp SRCS_EXT+= DebugInfo/PDB/IPDBSourceFile.cpp SRCS_EXT+= DebugInfo/PDB/Native/DbiModuleDescriptor.cpp SRCS_EXT+= DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp SRCS_EXT+= DebugInfo/PDB/Native/DbiModuleList.cpp SRCS_EXT+= DebugInfo/PDB/Native/DbiStream.cpp SRCS_EXT+= DebugInfo/PDB/Native/DbiStreamBuilder.cpp SRCS_EXT+= DebugInfo/PDB/Native/EnumTables.cpp SRCS_EXT+= DebugInfo/PDB/Native/GSI.cpp SRCS_EXT+= DebugInfo/PDB/Native/GlobalsStream.cpp SRCS_EXT+= DebugInfo/PDB/Native/Hash.cpp SRCS_EXT+= DebugInfo/PDB/Native/HashTable.cpp SRCS_EXT+= DebugInfo/PDB/Native/InfoStream.cpp SRCS_EXT+= DebugInfo/PDB/Native/InfoStreamBuilder.cpp SRCS_EXT+= DebugInfo/PDB/Native/ModuleDebugStream.cpp SRCS_EXT+= DebugInfo/PDB/Native/NamedStreamMap.cpp SRCS_EXT+= DebugInfo/PDB/Native/NativeBuiltinSymbol.cpp SRCS_EXT+= DebugInfo/PDB/Native/NativeCompilandSymbol.cpp SRCS_EXT+= DebugInfo/PDB/Native/NativeEnumModules.cpp SRCS_EXT+= DebugInfo/PDB/Native/NativeExeSymbol.cpp SRCS_EXT+= DebugInfo/PDB/Native/NativeRawSymbol.cpp SRCS_EXT+= DebugInfo/PDB/Native/NativeSession.cpp SRCS_EXT+= DebugInfo/PDB/Native/PDBFile.cpp SRCS_EXT+= DebugInfo/PDB/Native/PDBFileBuilder.cpp SRCS_EXT+= DebugInfo/PDB/Native/PDBStringTable.cpp SRCS_EXT+= DebugInfo/PDB/Native/PDBStringTableBuilder.cpp SRCS_EXT+= DebugInfo/PDB/Native/PublicsStream.cpp SRCS_EXT+= DebugInfo/PDB/Native/PublicsStreamBuilder.cpp SRCS_EXT+= DebugInfo/PDB/Native/RawError.cpp SRCS_EXT+= DebugInfo/PDB/Native/SymbolStream.cpp SRCS_EXT+= DebugInfo/PDB/Native/TpiHashing.cpp SRCS_EXT+= DebugInfo/PDB/Native/TpiStream.cpp SRCS_EXT+= DebugInfo/PDB/Native/TpiStreamBuilder.cpp SRCS_EXT+= DebugInfo/PDB/PDB.cpp SRCS_EXT+= DebugInfo/PDB/PDBContext.cpp SRCS_EXT+= DebugInfo/PDB/PDBExtras.cpp SRCS_EXT+= DebugInfo/PDB/PDBInterfaceAnchors.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymDumper.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbol.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolAnnotation.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolBlock.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolCompiland.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolCompilandDetails.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolCompilandEnv.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolCustom.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolData.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolExe.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolFunc.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolFuncDebugEnd.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolFuncDebugStart.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolLabel.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolPublicSymbol.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolThunk.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolTypeArray.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolTypeBaseClass.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolTypeBuiltin.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolTypeCustom.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolTypeDimension.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolTypeEnum.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolTypeFriend.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolTypeFunctionArg.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolTypeManaged.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolTypePointer.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolTypeTypedef.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolTypeUDT.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolTypeVTable.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolTypeVTableShape.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolUnknown.cpp SRCS_EXT+= DebugInfo/PDB/PDBSymbolUsingNamespace.cpp SRCS_EXT+= DebugInfo/PDB/UDTLayout.cpp SRCS_EXT+= DebugInfo/Symbolize/DIPrinter.cpp SRCS_MIW+= DebugInfo/Symbolize/SymbolizableObjectFile.cpp SRCS_MIW+= DebugInfo/Symbolize/Symbolize.cpp SRCS_MIN+= Demangle/ItaniumDemangle.cpp SRCS_XDB+= ExecutionEngine/ExecutionEngine.cpp SRCS_XDB+= ExecutionEngine/ExecutionEngineBindings.cpp SRCS_XDB+= ExecutionEngine/GDBRegistrationListener.cpp SRCS_XDB+= ExecutionEngine/Interpreter/Execution.cpp SRCS_XDB+= ExecutionEngine/Interpreter/ExternalFunctions.cpp SRCS_XDB+= ExecutionEngine/Interpreter/Interpreter.cpp SRCS_XDB+= ExecutionEngine/MCJIT/MCJIT.cpp SRCS_EXT+= ExecutionEngine/Orc/ExecutionUtils.cpp SRCS_EXT+= ExecutionEngine/Orc/IndirectionUtils.cpp SRCS_EXT+= ExecutionEngine/Orc/NullResolver.cpp SRCS_EXT+= ExecutionEngine/Orc/OrcABISupport.cpp SRCS_EXT+= ExecutionEngine/Orc/OrcCBindings.cpp SRCS_EXT+= ExecutionEngine/Orc/OrcError.cpp SRCS_EXT+= ExecutionEngine/Orc/OrcMCJITReplacement.cpp SRCS_EXT+= ExecutionEngine/Orc/RPCUtils.cpp SRCS_XDB+= ExecutionEngine/RuntimeDyld/JITSymbol.cpp SRCS_XDB+= ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp SRCS_XDB+= ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp SRCS_XDB+= ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp SRCS_XDB+= ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp SRCS_XDB+= ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp SRCS_XDB+= ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp SRCS_XDB+= ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldELFMips.cpp SRCS_XDB+= ExecutionEngine/SectionMemoryManager.cpp SRCS_XDB+= ExecutionEngine/TargetSelect.cpp SRCS_MIN+= IR/AsmWriter.cpp SRCS_MIN+= IR/Attributes.cpp SRCS_MIN+= IR/AutoUpgrade.cpp SRCS_MIN+= IR/BasicBlock.cpp SRCS_MIN+= IR/Comdat.cpp SRCS_MIN+= IR/ConstantFold.cpp SRCS_MIN+= IR/ConstantRange.cpp SRCS_MIN+= IR/Constants.cpp SRCS_MIN+= IR/Core.cpp SRCS_MIN+= IR/DIBuilder.cpp SRCS_MIN+= IR/DataLayout.cpp SRCS_MIN+= IR/DebugInfo.cpp SRCS_MIN+= IR/DebugInfoMetadata.cpp SRCS_MIN+= IR/DebugLoc.cpp SRCS_MIN+= IR/DiagnosticInfo.cpp SRCS_MIN+= IR/DiagnosticPrinter.cpp SRCS_MIN+= IR/Dominators.cpp SRCS_MIN+= IR/Function.cpp SRCS_MIN+= IR/GCOV.cpp SRCS_MIN+= IR/GVMaterializer.cpp SRCS_MIN+= IR/Globals.cpp SRCS_MIN+= IR/IRBuilder.cpp SRCS_MIN+= IR/IRPrintingPasses.cpp SRCS_MIN+= IR/InlineAsm.cpp SRCS_MIN+= IR/Instruction.cpp SRCS_MIN+= IR/Instructions.cpp SRCS_MIN+= IR/IntrinsicInst.cpp SRCS_MIN+= IR/LLVMContext.cpp SRCS_MIN+= IR/LLVMContextImpl.cpp SRCS_MIN+= IR/LegacyPassManager.cpp SRCS_MIN+= IR/MDBuilder.cpp SRCS_MIN+= IR/Mangler.cpp SRCS_MIN+= IR/Metadata.cpp SRCS_MIN+= IR/Module.cpp SRCS_MIN+= IR/ModuleSummaryIndex.cpp SRCS_MIN+= IR/Operator.cpp SRCS_MIN+= IR/OptBisect.cpp SRCS_MIN+= IR/Pass.cpp SRCS_MIN+= IR/PassManager.cpp SRCS_MIN+= IR/PassRegistry.cpp SRCS_MIN+= IR/ProfileSummary.cpp SRCS_MIN+= IR/SafepointIRVerifier.cpp SRCS_MIN+= IR/Statepoint.cpp SRCS_MIN+= IR/Type.cpp SRCS_MIN+= IR/TypeFinder.cpp SRCS_MIN+= IR/Use.cpp SRCS_MIN+= IR/User.cpp SRCS_MIN+= IR/Value.cpp SRCS_MIN+= IR/ValueSymbolTable.cpp SRCS_MIN+= IR/ValueTypes.cpp SRCS_MIN+= IR/Verifier.cpp SRCS_MIN+= IRReader/IRReader.cpp SRCS_EXL+= LTO/Caching.cpp SRCS_MIN+= LTO/LTO.cpp SRCS_MIN+= LTO/LTOBackend.cpp SRCS_EXL+= LTO/LTOCodeGenerator.cpp SRCS_EXL+= LTO/LTOModule.cpp SRCS_EXL+= LTO/ThinLTOCodeGenerator.cpp SRCS_MIN+= LTO/UpdateCompilerUsed.cpp SRCS_MIN+= LineEditor/LineEditor.cpp SRCS_MIN+= Linker/IRMover.cpp SRCS_MIN+= Linker/LinkModules.cpp SRCS_MIN+= MC/ConstantPools.cpp SRCS_MIN+= MC/ELFObjectWriter.cpp SRCS_MIN+= MC/MCAsmBackend.cpp SRCS_MIN+= MC/MCAsmInfo.cpp SRCS_MIN+= MC/MCAsmInfoCOFF.cpp SRCS_MIN+= MC/MCAsmInfoDarwin.cpp SRCS_MIN+= MC/MCAsmInfoELF.cpp SRCS_MIN+= MC/MCAsmStreamer.cpp SRCS_MIN+= MC/MCAssembler.cpp SRCS_MIN+= MC/MCCodeEmitter.cpp SRCS_MIN+= MC/MCCodeView.cpp SRCS_MIN+= MC/MCContext.cpp SRCS_XDL+= MC/MCDisassembler/Disassembler.cpp SRCS_XDW+= MC/MCDisassembler/MCDisassembler.cpp SRCS_XDW+= MC/MCDisassembler/MCExternalSymbolizer.cpp SRCS_MIN+= MC/MCDisassembler/MCRelocationInfo.cpp SRCS_XDW+= MC/MCDisassembler/MCSymbolizer.cpp SRCS_MIN+= MC/MCDwarf.cpp SRCS_MIN+= MC/MCELFObjectTargetWriter.cpp SRCS_MIN+= MC/MCELFStreamer.cpp SRCS_MIN+= MC/MCExpr.cpp SRCS_MIN+= MC/MCFragment.cpp SRCS_MIN+= MC/MCInst.cpp SRCS_MIN+= MC/MCInstPrinter.cpp SRCS_MIN+= MC/MCInstrAnalysis.cpp SRCS_MIN+= MC/MCInstrDesc.cpp SRCS_MIN+= MC/MCLinkerOptimizationHint.cpp SRCS_MIN+= MC/MCMachOStreamer.cpp SRCS_MIN+= MC/MCMachObjectTargetWriter.cpp SRCS_MIN+= MC/MCNullStreamer.cpp SRCS_MIN+= MC/MCObjectFileInfo.cpp SRCS_MIN+= MC/MCObjectStreamer.cpp SRCS_MIN+= MC/MCObjectWriter.cpp SRCS_MIN+= MC/MCParser/AsmLexer.cpp SRCS_MIN+= MC/MCParser/AsmParser.cpp SRCS_MIN+= MC/MCParser/COFFAsmParser.cpp SRCS_MIN+= MC/MCParser/DarwinAsmParser.cpp SRCS_MIN+= MC/MCParser/ELFAsmParser.cpp SRCS_MIN+= MC/MCParser/MCAsmLexer.cpp SRCS_MIN+= MC/MCParser/MCAsmParser.cpp SRCS_MIN+= MC/MCParser/MCAsmParserExtension.cpp SRCS_MIN+= MC/MCParser/MCTargetAsmParser.cpp SRCS_MIN+= MC/MCRegisterInfo.cpp SRCS_MIN+= MC/MCSchedule.cpp SRCS_MIN+= MC/MCSection.cpp SRCS_MIN+= MC/MCSectionCOFF.cpp SRCS_MIN+= MC/MCSectionELF.cpp SRCS_MIN+= MC/MCSectionMachO.cpp SRCS_MIN+= MC/MCSectionWasm.cpp SRCS_MIN+= MC/MCStreamer.cpp SRCS_MIN+= MC/MCSubtargetInfo.cpp SRCS_MIN+= MC/MCSymbol.cpp SRCS_MIN+= MC/MCSymbolELF.cpp SRCS_MIN+= MC/MCTargetOptions.cpp SRCS_MIN+= MC/MCValue.cpp SRCS_MIN+= MC/MCWasmStreamer.cpp SRCS_MIN+= MC/MCWin64EH.cpp SRCS_MIN+= MC/MCWinCOFFStreamer.cpp SRCS_MIN+= MC/MCWinEH.cpp SRCS_MIN+= MC/MachObjectWriter.cpp SRCS_MIN+= MC/StringTableBuilder.cpp SRCS_MIN+= MC/SubtargetFeature.cpp SRCS_MIN+= MC/WinCOFFObjectWriter.cpp SRCS_MIN+= Object/Archive.cpp SRCS_MIN+= Object/ArchiveWriter.cpp SRCS_MIN+= Object/Binary.cpp SRCS_EXT+= Object/COFFImportFile.cpp SRCS_EXT+= Object/COFFModuleDefinition.cpp SRCS_MIN+= Object/COFFObjectFile.cpp SRCS_MIN+= Object/Decompressor.cpp SRCS_MIN+= Object/ELF.cpp SRCS_MIN+= Object/ELFObjectFile.cpp SRCS_MIN+= Object/Error.cpp SRCS_MIN+= Object/IRObjectFile.cpp SRCS_MIN+= Object/IRSymtab.cpp SRCS_MIN+= Object/MachOObjectFile.cpp SRCS_MIN+= Object/MachOUniversal.cpp SRCS_MIN+= Object/ModuleSymbolTable.cpp SRCS_EXT+= Object/Object.cpp SRCS_MIN+= Object/ObjectFile.cpp SRCS_MIN+= Object/RecordStreamer.cpp SRCS_MIW+= Object/SymbolSize.cpp SRCS_MIN+= Object/SymbolicFile.cpp SRCS_MIN+= Object/WasmObjectFile.cpp SRCS_MIW+= Object/WindowsResource.cpp SRCS_MIN+= ObjectYAML/COFFYAML.cpp SRCS_EXT+= ObjectYAML/CodeViewYAMLDebugSections.cpp SRCS_EXT+= ObjectYAML/CodeViewYAMLSymbols.cpp SRCS_EXT+= ObjectYAML/CodeViewYAMLTypes.cpp SRCS_MIN+= ObjectYAML/DWARFYAML.cpp SRCS_MIN+= ObjectYAML/ELFYAML.cpp SRCS_MIN+= ObjectYAML/MachOYAML.cpp SRCS_EXT+= ObjectYAML/YAML.cpp SRCS_MIN+= Option/Arg.cpp SRCS_MIN+= Option/ArgList.cpp SRCS_MIN+= Option/OptTable.cpp SRCS_MIN+= Option/Option.cpp SRCS_MIN+= Passes/PassBuilder.cpp SRCS_MIN+= ProfileData/Coverage/CoverageMapping.cpp SRCS_MIN+= ProfileData/Coverage/CoverageMappingReader.cpp SRCS_MIN+= ProfileData/Coverage/CoverageMappingWriter.cpp SRCS_MIN+= ProfileData/InstrProf.cpp SRCS_MIN+= ProfileData/InstrProfReader.cpp SRCS_MIN+= ProfileData/InstrProfWriter.cpp SRCS_MIN+= ProfileData/ProfileSummaryBuilder.cpp SRCS_MIN+= ProfileData/SampleProf.cpp SRCS_MIN+= ProfileData/SampleProfReader.cpp SRCS_EXT+= ProfileData/SampleProfWriter.cpp SRCS_MIN+= Support/APFloat.cpp SRCS_MIN+= Support/APInt.cpp SRCS_MIN+= Support/APSInt.cpp SRCS_MIN+= Support/ARMAttributeParser.cpp SRCS_MIN+= Support/ARMBuildAttrs.cpp SRCS_MIN+= Support/Allocator.cpp SRCS_MIN+= Support/Atomic.cpp SRCS_MIN+= Support/BinaryStreamError.cpp SRCS_MIN+= Support/BinaryStreamReader.cpp SRCS_MIN+= Support/BinaryStreamRef.cpp SRCS_MIN+= Support/BinaryStreamWriter.cpp SRCS_MIN+= Support/BlockFrequency.cpp SRCS_MIN+= Support/BranchProbability.cpp SRCS_EXT+= Support/COM.cpp SRCS_MIN+= Support/CachePruning.cpp SRCS_MIN+= Support/Chrono.cpp SRCS_MIN+= Support/CommandLine.cpp SRCS_MIN+= Support/Compression.cpp SRCS_MIN+= Support/ConvertUTF.cpp SRCS_MIN+= Support/ConvertUTFWrapper.cpp SRCS_MIN+= Support/CrashRecoveryContext.cpp SRCS_MIN+= Support/DAGDeltaAlgorithm.cpp SRCS_MIN+= Support/DataExtractor.cpp SRCS_MIN+= Support/Debug.cpp SRCS_MIN+= Support/DebugCounter.cpp SRCS_MIN+= Support/DeltaAlgorithm.cpp SRCS_MIN+= Support/DynamicLibrary.cpp SRCS_MIN+= Support/Errno.cpp SRCS_MIN+= Support/Error.cpp SRCS_MIN+= Support/ErrorHandling.cpp SRCS_EXL+= Support/FileOutputBuffer.cpp SRCS_EXT+= Support/FileUtilities.cpp SRCS_MIN+= Support/FoldingSet.cpp SRCS_MIN+= Support/FormatVariadic.cpp SRCS_MIN+= Support/FormattedStream.cpp SRCS_MIN+= Support/GlobPattern.cpp SRCS_MIN+= Support/GraphWriter.cpp SRCS_MIN+= Support/Hashing.cpp SRCS_MIN+= Support/Host.cpp SRCS_MIN+= Support/IntEqClasses.cpp SRCS_MIN+= Support/IntervalMap.cpp SRCS_MIN+= Support/JamCRC.cpp SRCS_MIN+= Support/LEB128.cpp SRCS_MIN+= Support/LineIterator.cpp SRCS_MIN+= Support/Locale.cpp SRCS_MIN+= Support/LockFileManager.cpp SRCS_MIN+= Support/LowLevelType.cpp SRCS_MIN+= Support/MD5.cpp SRCS_MIN+= Support/ManagedStatic.cpp SRCS_MIN+= Support/MathExtras.cpp SRCS_XDB+= Support/Memory.cpp SRCS_MIN+= Support/MemoryBuffer.cpp SRCS_MIN+= Support/Mutex.cpp SRCS_MIN+= Support/NativeFormatting.cpp SRCS_MIN+= Support/Options.cpp SRCS_LLD+= Support/Parallel.cpp SRCS_MIN+= Support/Path.cpp SRCS_MIN+= Support/PluginLoader.cpp SRCS_MIN+= Support/PrettyStackTrace.cpp SRCS_MIN+= Support/Process.cpp SRCS_MIN+= Support/Program.cpp SRCS_MIN+= Support/RWMutex.cpp SRCS_MIN+= Support/RandomNumberGenerator.cpp SRCS_MIN+= Support/Regex.cpp SRCS_MIN+= Support/SHA1.cpp SRCS_MIN+= Support/ScaledNumber.cpp SRCS_MIN+= Support/ScopedPrinter.cpp SRCS_MIN+= Support/Signals.cpp SRCS_MIN+= Support/SmallPtrSet.cpp SRCS_MIN+= Support/SmallVector.cpp SRCS_MIN+= Support/SourceMgr.cpp SRCS_MIN+= Support/SpecialCaseList.cpp SRCS_MIN+= Support/Statistic.cpp SRCS_MIN+= Support/StringExtras.cpp SRCS_MIN+= Support/StringMap.cpp SRCS_MIN+= Support/StringRef.cpp SRCS_MIN+= Support/StringSaver.cpp SRCS_EXT+= Support/SystemUtils.cpp SRCS_LLD+= Support/TarWriter.cpp SRCS_MIN+= Support/TargetParser.cpp SRCS_MIN+= Support/TargetRegistry.cpp SRCS_MIN+= Support/ThreadLocal.cpp SRCS_MIN+= Support/ThreadPool.cpp SRCS_MIN+= Support/Threading.cpp SRCS_MIN+= Support/Timer.cpp SRCS_MIN+= Support/ToolOutputFile.cpp SRCS_MIN+= Support/TrigramIndex.cpp SRCS_MIN+= Support/Triple.cpp SRCS_MIN+= Support/Twine.cpp SRCS_MIN+= Support/Unicode.cpp SRCS_MIN+= Support/Valgrind.cpp SRCS_MIN+= Support/YAMLParser.cpp SRCS_MIN+= Support/YAMLTraits.cpp SRCS_MIN+= Support/circular_raw_ostream.cpp SRCS_MIN+= Support/raw_os_ostream.cpp SRCS_MIN+= Support/raw_ostream.cpp SRCS_MIN+= Support/regcomp.c SRCS_MIN+= Support/regerror.c SRCS_MIN+= Support/regexec.c SRCS_MIN+= Support/regfree.c SRCS_MIN+= Support/regstrlcpy.c SRCS_LLD+= Support/xxhash.cpp SRCS_MIN+= TableGen/Error.cpp SRCS_MIN+= TableGen/Main.cpp SRCS_MIN+= TableGen/Record.cpp SRCS_MIN+= TableGen/SetTheory.cpp SRCS_MIN+= TableGen/StringMatcher.cpp SRCS_MIN+= TableGen/TGLexer.cpp SRCS_MIN+= TableGen/TGParser.cpp SRCS_MIN+= TableGen/TableGenBackend.cpp SRCS_MIN+= Target/AArch64/AArch64A53Fix835769.cpp SRCS_MIN+= Target/AArch64/AArch64A57FPLoadBalancing.cpp SRCS_MIN+= Target/AArch64/AArch64AdvSIMDScalarPass.cpp SRCS_MIN+= Target/AArch64/AArch64AsmPrinter.cpp SRCS_MIN+= Target/AArch64/AArch64CallLowering.cpp SRCS_MIN+= Target/AArch64/AArch64CleanupLocalDynamicTLSPass.cpp SRCS_MIN+= Target/AArch64/AArch64CollectLOH.cpp SRCS_MIN+= Target/AArch64/AArch64CondBrTuning.cpp SRCS_MIN+= Target/AArch64/AArch64ConditionOptimizer.cpp SRCS_MIN+= Target/AArch64/AArch64ConditionalCompares.cpp SRCS_MIN+= Target/AArch64/AArch64DeadRegisterDefinitionsPass.cpp SRCS_MIN+= Target/AArch64/AArch64ExpandPseudoInsts.cpp SRCS_MIN+= Target/AArch64/AArch64FalkorHWPFFix.cpp SRCS_MIN+= Target/AArch64/AArch64FastISel.cpp SRCS_MIN+= Target/AArch64/AArch64FrameLowering.cpp SRCS_MIN+= Target/AArch64/AArch64ISelDAGToDAG.cpp SRCS_MIN+= Target/AArch64/AArch64ISelLowering.cpp SRCS_MIN+= Target/AArch64/AArch64InstrInfo.cpp SRCS_MIN+= Target/AArch64/AArch64InstructionSelector.cpp SRCS_MIN+= Target/AArch64/AArch64LegalizerInfo.cpp SRCS_MIN+= Target/AArch64/AArch64LoadStoreOptimizer.cpp SRCS_MIN+= Target/AArch64/AArch64MCInstLower.cpp SRCS_MIN+= Target/AArch64/AArch64MacroFusion.cpp SRCS_MIN+= Target/AArch64/AArch64PBQPRegAlloc.cpp SRCS_MIN+= Target/AArch64/AArch64PromoteConstant.cpp SRCS_MIN+= Target/AArch64/AArch64RedundantCopyElimination.cpp SRCS_MIN+= Target/AArch64/AArch64RegisterBankInfo.cpp SRCS_MIN+= Target/AArch64/AArch64RegisterInfo.cpp SRCS_MIN+= Target/AArch64/AArch64SelectionDAGInfo.cpp SRCS_MIN+= Target/AArch64/AArch64StorePairSuppress.cpp SRCS_MIN+= Target/AArch64/AArch64Subtarget.cpp SRCS_MIN+= Target/AArch64/AArch64TargetMachine.cpp SRCS_MIN+= Target/AArch64/AArch64TargetObjectFile.cpp SRCS_MIN+= Target/AArch64/AArch64TargetTransformInfo.cpp SRCS_MIN+= Target/AArch64/AArch64VectorByElementOpt.cpp SRCS_MIN+= Target/AArch64/AsmParser/AArch64AsmParser.cpp SRCS_XDW+= Target/AArch64/Disassembler/AArch64Disassembler.cpp SRCS_XDW+= Target/AArch64/Disassembler/AArch64ExternalSymbolizer.cpp SRCS_MIN+= Target/AArch64/InstPrinter/AArch64InstPrinter.cpp SRCS_MIN+= Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp SRCS_MIN+= Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp SRCS_MIN+= Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp SRCS_MIN+= Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp SRCS_MIN+= Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp SRCS_MIN+= Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp SRCS_MIN+= Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp SRCS_MIN+= Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp SRCS_MIN+= Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp SRCS_MIN+= Target/AArch64/MCTargetDesc/AArch64WinCOFFObjectWriter.cpp SRCS_MIN+= Target/AArch64/MCTargetDesc/AArch64WinCOFFStreamer.cpp SRCS_MIN+= Target/AArch64/TargetInfo/AArch64TargetInfo.cpp SRCS_MIN+= Target/AArch64/Utils/AArch64BaseInfo.cpp SRCS_MIN+= Target/ARM/A15SDOptimizer.cpp SRCS_MIN+= Target/ARM/ARMAsmPrinter.cpp SRCS_MIN+= Target/ARM/ARMBaseInstrInfo.cpp SRCS_MIN+= Target/ARM/ARMBaseRegisterInfo.cpp SRCS_MIN+= Target/ARM/ARMCallLowering.cpp SRCS_MIN+= Target/ARM/ARMComputeBlockSize.cpp SRCS_MIN+= Target/ARM/ARMConstantIslandPass.cpp SRCS_MIN+= Target/ARM/ARMConstantPoolValue.cpp SRCS_MIN+= Target/ARM/ARMExpandPseudoInsts.cpp SRCS_MIN+= Target/ARM/ARMFastISel.cpp SRCS_MIN+= Target/ARM/ARMFrameLowering.cpp SRCS_MIN+= Target/ARM/ARMHazardRecognizer.cpp SRCS_MIN+= Target/ARM/ARMISelDAGToDAG.cpp SRCS_MIN+= Target/ARM/ARMISelLowering.cpp SRCS_MIN+= Target/ARM/ARMInstrInfo.cpp SRCS_MIN+= Target/ARM/ARMInstructionSelector.cpp SRCS_MIN+= Target/ARM/ARMLegalizerInfo.cpp SRCS_MIN+= Target/ARM/ARMLoadStoreOptimizer.cpp SRCS_MIN+= Target/ARM/ARMMCInstLower.cpp SRCS_MIN+= Target/ARM/ARMMachineFunctionInfo.cpp SRCS_MIN+= Target/ARM/ARMMacroFusion.cpp SRCS_MIN+= Target/ARM/ARMOptimizeBarriersPass.cpp SRCS_MIN+= Target/ARM/ARMRegisterBankInfo.cpp SRCS_MIN+= Target/ARM/ARMRegisterInfo.cpp SRCS_MIN+= Target/ARM/ARMSelectionDAGInfo.cpp SRCS_MIN+= Target/ARM/ARMSubtarget.cpp SRCS_MIN+= Target/ARM/ARMTargetMachine.cpp SRCS_MIN+= Target/ARM/ARMTargetObjectFile.cpp SRCS_MIN+= Target/ARM/ARMTargetTransformInfo.cpp SRCS_MIN+= Target/ARM/AsmParser/ARMAsmParser.cpp SRCS_MIN+= Target/ARM/Disassembler/ARMDisassembler.cpp SRCS_MIN+= Target/ARM/InstPrinter/ARMInstPrinter.cpp SRCS_MIN+= Target/ARM/MCTargetDesc/ARMAsmBackend.cpp SRCS_MIN+= Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp SRCS_MIN+= Target/ARM/MCTargetDesc/ARMELFStreamer.cpp SRCS_MIN+= Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp SRCS_MIN+= Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp SRCS_MIN+= Target/ARM/MCTargetDesc/ARMMCExpr.cpp SRCS_MIN+= Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp SRCS_MIN+= Target/ARM/MCTargetDesc/ARMMachORelocationInfo.cpp SRCS_MIN+= Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp SRCS_MIN+= Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp SRCS_MIN+= Target/ARM/MCTargetDesc/ARMUnwindOpAsm.cpp SRCS_MIN+= Target/ARM/MCTargetDesc/ARMWinCOFFObjectWriter.cpp SRCS_MIN+= Target/ARM/MCTargetDesc/ARMWinCOFFStreamer.cpp SRCS_MIN+= Target/ARM/MLxExpansionPass.cpp SRCS_MIN+= Target/ARM/TargetInfo/ARMTargetInfo.cpp SRCS_MIN+= Target/ARM/Thumb1FrameLowering.cpp SRCS_MIN+= Target/ARM/Thumb1InstrInfo.cpp SRCS_MIN+= Target/ARM/Thumb2ITBlockPass.cpp SRCS_MIN+= Target/ARM/Thumb2InstrInfo.cpp SRCS_MIN+= Target/ARM/Thumb2SizeReduction.cpp SRCS_MIN+= Target/ARM/ThumbRegisterInfo.cpp SRCS_MIN+= Target/Mips/AsmParser/MipsAsmParser.cpp SRCS_XDW+= Target/Mips/Disassembler/MipsDisassembler.cpp SRCS_MIN+= Target/Mips/InstPrinter/MipsInstPrinter.cpp SRCS_MIN+= Target/Mips/MCTargetDesc/MipsABIFlagsSection.cpp SRCS_MIN+= Target/Mips/MCTargetDesc/MipsABIInfo.cpp SRCS_MIN+= Target/Mips/MCTargetDesc/MipsAsmBackend.cpp SRCS_MIN+= Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp SRCS_MIN+= Target/Mips/MCTargetDesc/MipsELFStreamer.cpp SRCS_MIN+= Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp SRCS_MIN+= Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp SRCS_MIN+= Target/Mips/MCTargetDesc/MipsMCExpr.cpp SRCS_MIN+= Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp SRCS_MIN+= Target/Mips/MCTargetDesc/MipsNaClELFStreamer.cpp SRCS_MIN+= Target/Mips/MCTargetDesc/MipsOptionRecord.cpp SRCS_MIN+= Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp SRCS_MIN+= Target/Mips/MicroMipsSizeReduction.cpp SRCS_MIN+= Target/Mips/Mips16FrameLowering.cpp SRCS_MIN+= Target/Mips/Mips16HardFloat.cpp SRCS_MIN+= Target/Mips/Mips16HardFloatInfo.cpp SRCS_MIN+= Target/Mips/Mips16ISelDAGToDAG.cpp SRCS_MIN+= Target/Mips/Mips16ISelLowering.cpp SRCS_MIN+= Target/Mips/Mips16InstrInfo.cpp SRCS_MIN+= Target/Mips/Mips16RegisterInfo.cpp SRCS_MIN+= Target/Mips/MipsAnalyzeImmediate.cpp SRCS_MIN+= Target/Mips/MipsAsmPrinter.cpp SRCS_MIN+= Target/Mips/MipsCCState.cpp SRCS_MIN+= Target/Mips/MipsConstantIslandPass.cpp SRCS_MIN+= Target/Mips/MipsDelaySlotFiller.cpp SRCS_MIN+= Target/Mips/MipsFastISel.cpp SRCS_MIN+= Target/Mips/MipsFrameLowering.cpp SRCS_MIN+= Target/Mips/MipsHazardSchedule.cpp SRCS_MIN+= Target/Mips/MipsISelDAGToDAG.cpp SRCS_MIN+= Target/Mips/MipsISelLowering.cpp SRCS_MIN+= Target/Mips/MipsInstrInfo.cpp SRCS_MIN+= Target/Mips/MipsLongBranch.cpp SRCS_MIN+= Target/Mips/MipsMCInstLower.cpp SRCS_MIN+= Target/Mips/MipsMachineFunction.cpp SRCS_MIN+= Target/Mips/MipsModuleISelDAGToDAG.cpp SRCS_MIN+= Target/Mips/MipsOptimizePICCall.cpp SRCS_MIN+= Target/Mips/MipsOs16.cpp SRCS_MIN+= Target/Mips/MipsRegisterInfo.cpp SRCS_MIN+= Target/Mips/MipsSEFrameLowering.cpp SRCS_MIN+= Target/Mips/MipsSEISelDAGToDAG.cpp SRCS_MIN+= Target/Mips/MipsSEISelLowering.cpp SRCS_MIN+= Target/Mips/MipsSEInstrInfo.cpp SRCS_MIN+= Target/Mips/MipsSERegisterInfo.cpp SRCS_MIN+= Target/Mips/MipsSubtarget.cpp SRCS_MIN+= Target/Mips/MipsTargetMachine.cpp SRCS_MIN+= Target/Mips/MipsTargetObjectFile.cpp SRCS_MIN+= Target/Mips/TargetInfo/MipsTargetInfo.cpp SRCS_MIN+= Target/PowerPC/AsmParser/PPCAsmParser.cpp SRCS_MIN+= Target/PowerPC/Disassembler/PPCDisassembler.cpp SRCS_MIN+= Target/PowerPC/InstPrinter/PPCInstPrinter.cpp SRCS_MIN+= Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp SRCS_MIN+= Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp SRCS_MIN+= Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp SRCS_MIN+= Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp SRCS_MIN+= Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp SRCS_MIN+= Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp SRCS_MIN+= Target/PowerPC/MCTargetDesc/PPCMachObjectWriter.cpp SRCS_MIN+= Target/PowerPC/MCTargetDesc/PPCPredicates.cpp SRCS_MIN+= Target/PowerPC/PPCAsmPrinter.cpp SRCS_MIN+= Target/PowerPC/PPCBoolRetToInt.cpp SRCS_MIN+= Target/PowerPC/PPCBranchSelector.cpp SRCS_MIN+= Target/PowerPC/PPCCCState.cpp SRCS_MIN+= Target/PowerPC/PPCCTRLoops.cpp SRCS_MIN+= Target/PowerPC/PPCEarlyReturn.cpp SRCS_MIN+= Target/PowerPC/PPCExpandISEL.cpp SRCS_MIN+= Target/PowerPC/PPCFastISel.cpp SRCS_MIN+= Target/PowerPC/PPCFrameLowering.cpp SRCS_MIN+= Target/PowerPC/PPCHazardRecognizers.cpp SRCS_MIN+= Target/PowerPC/PPCISelDAGToDAG.cpp SRCS_MIN+= Target/PowerPC/PPCISelLowering.cpp SRCS_MIN+= Target/PowerPC/PPCInstrInfo.cpp SRCS_MIN+= Target/PowerPC/PPCLoopPreIncPrep.cpp SRCS_MIN+= Target/PowerPC/PPCMCInstLower.cpp SRCS_MIN+= Target/PowerPC/PPCMIPeephole.cpp SRCS_MIN+= Target/PowerPC/PPCMachineFunctionInfo.cpp SRCS_MIN+= Target/PowerPC/PPCQPXLoadSplat.cpp SRCS_MIN+= Target/PowerPC/PPCRegisterInfo.cpp SRCS_MIN+= Target/PowerPC/PPCSubtarget.cpp SRCS_MIN+= Target/PowerPC/PPCTLSDynamicCall.cpp SRCS_MIN+= Target/PowerPC/PPCTOCRegDeps.cpp SRCS_MIN+= Target/PowerPC/PPCTargetMachine.cpp SRCS_MIN+= Target/PowerPC/PPCTargetObjectFile.cpp SRCS_MIN+= Target/PowerPC/PPCTargetTransformInfo.cpp SRCS_MIN+= Target/PowerPC/PPCVSXCopy.cpp SRCS_MIN+= Target/PowerPC/PPCVSXFMAMutate.cpp SRCS_MIN+= Target/PowerPC/PPCVSXSwapRemoval.cpp SRCS_MIN+= Target/PowerPC/TargetInfo/PowerPCTargetInfo.cpp SRCS_MIN+= Target/Sparc/AsmParser/SparcAsmParser.cpp SRCS_MIN+= Target/Sparc/DelaySlotFiller.cpp SRCS_XDW+= Target/Sparc/Disassembler/SparcDisassembler.cpp SRCS_MIN+= Target/Sparc/InstPrinter/SparcInstPrinter.cpp SRCS_MIN+= Target/Sparc/LeonPasses.cpp SRCS_MIN+= Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp SRCS_MIN+= Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp SRCS_MIN+= Target/Sparc/MCTargetDesc/SparcMCAsmInfo.cpp SRCS_MIN+= Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp SRCS_MIN+= Target/Sparc/MCTargetDesc/SparcMCExpr.cpp SRCS_MIN+= Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp SRCS_MIN+= Target/Sparc/MCTargetDesc/SparcTargetStreamer.cpp SRCS_MIN+= Target/Sparc/SparcAsmPrinter.cpp SRCS_MIN+= Target/Sparc/SparcFrameLowering.cpp SRCS_MIN+= Target/Sparc/SparcISelDAGToDAG.cpp SRCS_MIN+= Target/Sparc/SparcISelLowering.cpp SRCS_MIN+= Target/Sparc/SparcInstrInfo.cpp SRCS_MIN+= Target/Sparc/SparcMCInstLower.cpp SRCS_MIN+= Target/Sparc/SparcMachineFunctionInfo.cpp SRCS_MIN+= Target/Sparc/SparcRegisterInfo.cpp SRCS_MIN+= Target/Sparc/SparcSubtarget.cpp SRCS_MIN+= Target/Sparc/SparcTargetMachine.cpp SRCS_MIN+= Target/Sparc/SparcTargetObjectFile.cpp SRCS_MIN+= Target/Sparc/TargetInfo/SparcTargetInfo.cpp SRCS_MIN+= Target/Target.cpp SRCS_MIN+= Target/TargetIntrinsicInfo.cpp SRCS_MIN+= Target/TargetLoweringObjectFile.cpp SRCS_MIN+= Target/TargetMachine.cpp SRCS_MIN+= Target/TargetMachineC.cpp SRCS_MIN+= Target/X86/AsmParser/X86AsmInstrumentation.cpp SRCS_MIN+= Target/X86/AsmParser/X86AsmParser.cpp SRCS_XDW+= Target/X86/Disassembler/X86Disassembler.cpp SRCS_XDW+= Target/X86/Disassembler/X86DisassemblerDecoder.cpp SRCS_MIN+= Target/X86/InstPrinter/X86ATTInstPrinter.cpp SRCS_MIN+= Target/X86/InstPrinter/X86InstComments.cpp SRCS_MIN+= Target/X86/InstPrinter/X86IntelInstPrinter.cpp SRCS_MIN+= Target/X86/MCTargetDesc/X86AsmBackend.cpp SRCS_MIN+= Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp SRCS_MIN+= Target/X86/MCTargetDesc/X86MCAsmInfo.cpp SRCS_MIN+= Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp SRCS_MIN+= Target/X86/MCTargetDesc/X86MCTargetDesc.cpp SRCS_MIN+= Target/X86/MCTargetDesc/X86MachObjectWriter.cpp SRCS_MIN+= Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp SRCS_MIN+= Target/X86/MCTargetDesc/X86WinCOFFStreamer.cpp SRCS_MIN+= Target/X86/TargetInfo/X86TargetInfo.cpp SRCS_MIN+= Target/X86/Utils/X86ShuffleDecode.cpp SRCS_MIN+= Target/X86/X86AsmPrinter.cpp SRCS_MIN+= Target/X86/X86CallFrameOptimization.cpp SRCS_MIN+= Target/X86/X86CallLowering.cpp SRCS_MIN+= Target/X86/X86CallingConv.cpp SRCS_MIN+= Target/X86/X86CmovConversion.cpp SRCS_MIN+= Target/X86/X86EvexToVex.cpp SRCS_MIN+= Target/X86/X86ExpandPseudo.cpp SRCS_MIN+= Target/X86/X86FastISel.cpp SRCS_MIN+= Target/X86/X86FixupBWInsts.cpp SRCS_MIN+= Target/X86/X86FixupLEAs.cpp SRCS_MIN+= Target/X86/X86FixupSetCC.cpp SRCS_MIN+= Target/X86/X86FloatingPoint.cpp SRCS_MIN+= Target/X86/X86FrameLowering.cpp SRCS_MIN+= Target/X86/X86ISelDAGToDAG.cpp SRCS_MIN+= Target/X86/X86ISelLowering.cpp SRCS_MIN+= Target/X86/X86InstrFMA3Info.cpp SRCS_MIN+= Target/X86/X86InstrInfo.cpp SRCS_MIN+= Target/X86/X86InstructionSelector.cpp SRCS_MIN+= Target/X86/X86InterleavedAccess.cpp SRCS_MIN+= Target/X86/X86LegalizerInfo.cpp SRCS_MIN+= Target/X86/X86MCInstLower.cpp SRCS_MIN+= Target/X86/X86MachineFunctionInfo.cpp SRCS_MIN+= Target/X86/X86MacroFusion.cpp SRCS_MIN+= Target/X86/X86OptimizeLEAs.cpp SRCS_MIN+= Target/X86/X86PadShortFunction.cpp SRCS_MIN+= Target/X86/X86RegisterBankInfo.cpp SRCS_MIN+= Target/X86/X86RegisterInfo.cpp SRCS_MIN+= Target/X86/X86SelectionDAGInfo.cpp SRCS_MIN+= Target/X86/X86ShuffleDecodeConstantPool.cpp SRCS_MIN+= Target/X86/X86Subtarget.cpp SRCS_MIN+= Target/X86/X86TargetMachine.cpp SRCS_MIN+= Target/X86/X86TargetObjectFile.cpp SRCS_MIN+= Target/X86/X86TargetTransformInfo.cpp SRCS_MIN+= Target/X86/X86VZeroUpper.cpp SRCS_MIN+= Target/X86/X86WinAllocaExpander.cpp SRCS_MIN+= Target/X86/X86WinEHState.cpp SRCS_EXT+= ToolDrivers/llvm-dlltool/DlltoolDriver.cpp SRCS_EXL+= ToolDrivers/llvm-lib/LibDriver.cpp SRCS_MIN+= Transforms/Coroutines/CoroCleanup.cpp SRCS_MIN+= Transforms/Coroutines/CoroEarly.cpp SRCS_MIN+= Transforms/Coroutines/CoroElide.cpp SRCS_MIN+= Transforms/Coroutines/CoroFrame.cpp SRCS_MIN+= Transforms/Coroutines/CoroSplit.cpp SRCS_MIN+= Transforms/Coroutines/Coroutines.cpp SRCS_MIN+= Transforms/IPO/AlwaysInliner.cpp SRCS_MIN+= Transforms/IPO/ArgumentPromotion.cpp SRCS_MIN+= Transforms/IPO/BarrierNoopPass.cpp SRCS_MIN+= Transforms/IPO/ConstantMerge.cpp SRCS_MIN+= Transforms/IPO/CrossDSOCFI.cpp SRCS_MIN+= Transforms/IPO/DeadArgumentElimination.cpp SRCS_MIN+= Transforms/IPO/ElimAvailExtern.cpp SRCS_MIN+= Transforms/IPO/ExtractGV.cpp SRCS_MIN+= Transforms/IPO/ForceFunctionAttrs.cpp SRCS_MIN+= Transforms/IPO/FunctionAttrs.cpp SRCS_MIN+= Transforms/IPO/FunctionImport.cpp SRCS_MIN+= Transforms/IPO/GlobalDCE.cpp SRCS_MIN+= Transforms/IPO/GlobalOpt.cpp SRCS_MIN+= Transforms/IPO/GlobalSplit.cpp SRCS_MIN+= Transforms/IPO/IPConstantPropagation.cpp SRCS_EXT+= Transforms/IPO/IPO.cpp SRCS_MIN+= Transforms/IPO/InferFunctionAttrs.cpp SRCS_MIN+= Transforms/IPO/InlineSimple.cpp SRCS_MIN+= Transforms/IPO/Inliner.cpp SRCS_MIN+= Transforms/IPO/Internalize.cpp SRCS_MIN+= Transforms/IPO/LoopExtractor.cpp SRCS_MIN+= Transforms/IPO/LowerTypeTests.cpp SRCS_MIN+= Transforms/IPO/MergeFunctions.cpp SRCS_MIN+= Transforms/IPO/PartialInlining.cpp SRCS_MIN+= Transforms/IPO/PassManagerBuilder.cpp SRCS_MIN+= Transforms/IPO/PruneEH.cpp SRCS_MIN+= Transforms/IPO/SampleProfile.cpp SRCS_MIN+= Transforms/IPO/StripDeadPrototypes.cpp SRCS_MIN+= Transforms/IPO/StripSymbols.cpp SRCS_MIN+= Transforms/IPO/ThinLTOBitcodeWriter.cpp SRCS_MIN+= Transforms/IPO/WholeProgramDevirt.cpp SRCS_MIN+= Transforms/InstCombine/InstCombineAddSub.cpp SRCS_MIN+= Transforms/InstCombine/InstCombineAndOrXor.cpp SRCS_MIN+= Transforms/InstCombine/InstCombineCalls.cpp SRCS_MIN+= Transforms/InstCombine/InstCombineCasts.cpp SRCS_MIN+= Transforms/InstCombine/InstCombineCompares.cpp SRCS_MIN+= Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp SRCS_MIN+= Transforms/InstCombine/InstCombineMulDivRem.cpp SRCS_MIN+= Transforms/InstCombine/InstCombinePHI.cpp SRCS_MIN+= Transforms/InstCombine/InstCombineSelect.cpp SRCS_MIN+= Transforms/InstCombine/InstCombineShifts.cpp SRCS_MIN+= Transforms/InstCombine/InstCombineSimplifyDemanded.cpp SRCS_MIN+= Transforms/InstCombine/InstCombineVectorOps.cpp SRCS_MIN+= Transforms/InstCombine/InstructionCombining.cpp SRCS_MIN+= Transforms/Instrumentation/AddressSanitizer.cpp SRCS_MIN+= Transforms/Instrumentation/BoundsChecking.cpp SRCS_MIN+= Transforms/Instrumentation/DataFlowSanitizer.cpp SRCS_MIN+= Transforms/Instrumentation/EfficiencySanitizer.cpp SRCS_MIN+= Transforms/Instrumentation/GCOVProfiling.cpp SRCS_MIN+= Transforms/Instrumentation/IndirectCallPromotion.cpp SRCS_MIN+= Transforms/Instrumentation/InstrProfiling.cpp SRCS_MIN+= Transforms/Instrumentation/Instrumentation.cpp SRCS_MIN+= Transforms/Instrumentation/MemorySanitizer.cpp SRCS_MIN+= Transforms/Instrumentation/PGOInstrumentation.cpp SRCS_MIN+= Transforms/Instrumentation/PGOMemOPSizeOpt.cpp SRCS_MIN+= Transforms/Instrumentation/SanitizerCoverage.cpp SRCS_MIN+= Transforms/Instrumentation/ThreadSanitizer.cpp SRCS_MIN+= Transforms/ObjCARC/DependencyAnalysis.cpp SRCS_EXT+= Transforms/ObjCARC/ObjCARC.cpp SRCS_MIN+= Transforms/ObjCARC/ObjCARCAPElim.cpp SRCS_MIN+= Transforms/ObjCARC/ObjCARCContract.cpp SRCS_MIN+= Transforms/ObjCARC/ObjCARCExpand.cpp SRCS_MIN+= Transforms/ObjCARC/ObjCARCOpts.cpp SRCS_MIN+= Transforms/ObjCARC/ProvenanceAnalysis.cpp SRCS_MIN+= Transforms/ObjCARC/ProvenanceAnalysisEvaluator.cpp SRCS_MIN+= Transforms/ObjCARC/PtrState.cpp SRCS_MIN+= Transforms/Scalar/ADCE.cpp SRCS_MIN+= Transforms/Scalar/AlignmentFromAssumptions.cpp SRCS_MIN+= Transforms/Scalar/BDCE.cpp SRCS_MIN+= Transforms/Scalar/ConstantHoisting.cpp SRCS_MIN+= Transforms/Scalar/ConstantProp.cpp SRCS_MIN+= Transforms/Scalar/CorrelatedValuePropagation.cpp SRCS_MIN+= Transforms/Scalar/DCE.cpp SRCS_MIN+= Transforms/Scalar/DeadStoreElimination.cpp SRCS_MIN+= Transforms/Scalar/EarlyCSE.cpp SRCS_MIN+= Transforms/Scalar/FlattenCFGPass.cpp SRCS_MIN+= Transforms/Scalar/Float2Int.cpp SRCS_MIN+= Transforms/Scalar/GVN.cpp SRCS_MIN+= Transforms/Scalar/GVNHoist.cpp SRCS_MIN+= Transforms/Scalar/GVNSink.cpp SRCS_MIN+= Transforms/Scalar/GuardWidening.cpp SRCS_MIN+= Transforms/Scalar/IVUsersPrinter.cpp SRCS_MIN+= Transforms/Scalar/IndVarSimplify.cpp SRCS_MIN+= Transforms/Scalar/InductiveRangeCheckElimination.cpp SRCS_EXT+= Transforms/Scalar/InferAddressSpaces.cpp SRCS_MIN+= Transforms/Scalar/JumpThreading.cpp SRCS_MIN+= Transforms/Scalar/LICM.cpp SRCS_MIN+= Transforms/Scalar/LoopAccessAnalysisPrinter.cpp SRCS_MIN+= Transforms/Scalar/LoopDataPrefetch.cpp SRCS_MIN+= Transforms/Scalar/LoopDeletion.cpp SRCS_MIN+= Transforms/Scalar/LoopDistribute.cpp SRCS_MIN+= Transforms/Scalar/LoopIdiomRecognize.cpp SRCS_MIN+= Transforms/Scalar/LoopInstSimplify.cpp SRCS_MIN+= Transforms/Scalar/LoopInterchange.cpp SRCS_MIN+= Transforms/Scalar/LoopLoadElimination.cpp SRCS_MIN+= Transforms/Scalar/LoopPassManager.cpp SRCS_MIN+= Transforms/Scalar/LoopPredication.cpp SRCS_MIN+= Transforms/Scalar/LoopRerollPass.cpp SRCS_MIN+= Transforms/Scalar/LoopRotation.cpp SRCS_MIN+= Transforms/Scalar/LoopSimplifyCFG.cpp SRCS_MIN+= Transforms/Scalar/LoopSink.cpp SRCS_MIN+= Transforms/Scalar/LoopStrengthReduce.cpp SRCS_MIN+= Transforms/Scalar/LoopUnrollPass.cpp SRCS_MIN+= Transforms/Scalar/LoopUnswitch.cpp SRCS_MIN+= Transforms/Scalar/LoopVersioningLICM.cpp SRCS_MIN+= Transforms/Scalar/LowerAtomic.cpp SRCS_MIN+= Transforms/Scalar/LowerExpectIntrinsic.cpp SRCS_MIN+= Transforms/Scalar/LowerGuardIntrinsic.cpp SRCS_MIN+= Transforms/Scalar/MemCpyOptimizer.cpp SRCS_MIN+= Transforms/Scalar/MergedLoadStoreMotion.cpp SRCS_MIN+= Transforms/Scalar/NaryReassociate.cpp SRCS_MIN+= Transforms/Scalar/NewGVN.cpp SRCS_MIN+= Transforms/Scalar/PartiallyInlineLibCalls.cpp SRCS_MIN+= Transforms/Scalar/PlaceSafepoints.cpp SRCS_MIN+= Transforms/Scalar/Reassociate.cpp SRCS_MIN+= Transforms/Scalar/Reg2Mem.cpp SRCS_MIN+= Transforms/Scalar/RewriteStatepointsForGC.cpp SRCS_MIN+= Transforms/Scalar/SCCP.cpp SRCS_MIN+= Transforms/Scalar/SROA.cpp SRCS_EXT+= Transforms/Scalar/Scalar.cpp SRCS_MIN+= Transforms/Scalar/Scalarizer.cpp SRCS_MIN+= Transforms/Scalar/SeparateConstOffsetFromGEP.cpp SRCS_MIN+= Transforms/Scalar/SimpleLoopUnswitch.cpp SRCS_MIN+= Transforms/Scalar/SimplifyCFGPass.cpp SRCS_MIN+= Transforms/Scalar/Sink.cpp SRCS_MIN+= Transforms/Scalar/SpeculativeExecution.cpp SRCS_MIN+= Transforms/Scalar/StraightLineStrengthReduce.cpp SRCS_MIN+= Transforms/Scalar/StructurizeCFG.cpp SRCS_MIN+= Transforms/Scalar/TailRecursionElimination.cpp SRCS_MIN+= Transforms/Utils/ASanStackFrameLayout.cpp SRCS_MIN+= Transforms/Utils/AddDiscriminators.cpp SRCS_MIN+= Transforms/Utils/BasicBlockUtils.cpp SRCS_MIN+= Transforms/Utils/BreakCriticalEdges.cpp SRCS_MIN+= Transforms/Utils/BuildLibCalls.cpp SRCS_MIN+= Transforms/Utils/BypassSlowDivision.cpp SRCS_MIN+= Transforms/Utils/CloneFunction.cpp SRCS_MIN+= Transforms/Utils/CloneModule.cpp SRCS_MIN+= Transforms/Utils/CmpInstAnalysis.cpp SRCS_MIN+= Transforms/Utils/CodeExtractor.cpp SRCS_MIN+= Transforms/Utils/CtorUtils.cpp SRCS_MIN+= Transforms/Utils/DemoteRegToStack.cpp SRCS_MIN+= Transforms/Utils/EscapeEnumerator.cpp SRCS_MIN+= Transforms/Utils/Evaluator.cpp SRCS_MIN+= Transforms/Utils/FlattenCFG.cpp SRCS_MIN+= Transforms/Utils/FunctionComparator.cpp SRCS_MIN+= Transforms/Utils/FunctionImportUtils.cpp SRCS_MIN+= Transforms/Utils/GlobalStatus.cpp SRCS_MIN+= Transforms/Utils/ImportedFunctionsInliningStatistics.cpp SRCS_MIN+= Transforms/Utils/InlineFunction.cpp SRCS_MIN+= Transforms/Utils/InstructionNamer.cpp SRCS_MIN+= Transforms/Utils/IntegerDivision.cpp SRCS_MIN+= Transforms/Utils/LCSSA.cpp SRCS_MIN+= Transforms/Utils/LibCallsShrinkWrap.cpp SRCS_MIN+= Transforms/Utils/Local.cpp SRCS_MIN+= Transforms/Utils/LoopSimplify.cpp SRCS_MIN+= Transforms/Utils/LoopUnroll.cpp SRCS_MIN+= Transforms/Utils/LoopUnrollPeel.cpp SRCS_MIN+= Transforms/Utils/LoopUnrollRuntime.cpp SRCS_MIN+= Transforms/Utils/LoopUtils.cpp SRCS_MIN+= Transforms/Utils/LoopVersioning.cpp SRCS_MIN+= Transforms/Utils/LowerInvoke.cpp SRCS_MIN+= Transforms/Utils/LowerSwitch.cpp SRCS_MIN+= Transforms/Utils/Mem2Reg.cpp SRCS_MIN+= Transforms/Utils/MetaRenamer.cpp SRCS_MIN+= Transforms/Utils/ModuleUtils.cpp SRCS_MIN+= Transforms/Utils/NameAnonGlobals.cpp SRCS_MIN+= Transforms/Utils/OrderedInstructions.cpp SRCS_MIN+= Transforms/Utils/PredicateInfo.cpp SRCS_MIN+= Transforms/Utils/PromoteMemoryToRegister.cpp SRCS_MIN+= Transforms/Utils/SSAUpdater.cpp SRCS_MIN+= Transforms/Utils/SanitizerStats.cpp SRCS_MIN+= Transforms/Utils/SimplifyCFG.cpp SRCS_MIN+= Transforms/Utils/SimplifyIndVar.cpp SRCS_MIN+= Transforms/Utils/SimplifyInstructions.cpp SRCS_MIN+= Transforms/Utils/SimplifyLibCalls.cpp SRCS_MIN+= Transforms/Utils/SplitModule.cpp SRCS_MIN+= Transforms/Utils/StripGCRelocates.cpp SRCS_MIN+= Transforms/Utils/StripNonLineTableDebugInfo.cpp SRCS_MIN+= Transforms/Utils/SymbolRewriter.cpp SRCS_MIN+= Transforms/Utils/UnifyFunctionExitNodes.cpp SRCS_EXT+= Transforms/Utils/Utils.cpp SRCS_MIN+= Transforms/Utils/VNCoercion.cpp SRCS_MIN+= Transforms/Utils/ValueMapper.cpp SRCS_MIN+= Transforms/Vectorize/LoadStoreVectorizer.cpp SRCS_MIN+= Transforms/Vectorize/LoopVectorize.cpp SRCS_MIN+= Transforms/Vectorize/SLPVectorizer.cpp SRCS_EXT+= Transforms/Vectorize/Vectorize.cpp SRCS_EXT+= XRay/InstrumentationMap.cpp SRCS_ALL+= ${SRCS_MIN} .if !defined(TOOLS_PREFIX) || ${MK_LLD_IS_LD} != "no" SRCS_ALL+= ${SRCS_MIW} .endif .if ${MK_CLANG_EXTRAS} != "no" SRCS_ALL+= ${SRCS_EXT} .endif .if ${MK_CLANG_FULL} != "no" SRCS_ALL+= ${SRCS_FUL} .endif .if ${MK_CLANG_EXTRAS} != "no" || ${MK_LLD} != "no" SRCS_ALL+= ${SRCS_EXL} .endif .if ${MK_LLD} != "no" SRCS_ALL+= ${SRCS_LLD} .endif .if ${MK_CLANG_EXTRAS} != "no" || ${MK_LLDB} != "no" SRCS_ALL+= ${SRCS_XDB} .endif .if ${MK_CLANG_EXTRAS} != "no" || ${MK_LLDB} != "no" || ${MK_LLD} != "no" SRCS_ALL+= ${SRCS_XDL} .endif .if ${MK_CLANG_EXTRAS} != "no" || ${MK_LLDB} != "no" || !defined(TOOLS_PREFIX) SRCS_ALL+= ${SRCS_XDW} .endif SRCS+= ${SRCS_ALL:O} llvm/IR/Attributes.gen: ${LLVM_SRCS}/include/llvm/IR/Attributes.td ${LLVM_TBLGEN} -gen-attrs \ -I ${LLVM_SRCS}/include -d ${.TARGET}.d -o ${.TARGET} \ ${LLVM_SRCS}/include/llvm/IR/Attributes.td TGHDRS+= llvm/IR/Attributes.gen llvm/IR/Intrinsics.gen: ${LLVM_SRCS}/include/llvm/IR/Intrinsics.td ${LLVM_TBLGEN} -gen-intrinsic \ -I ${LLVM_SRCS}/include -d ${.TARGET}.d -o ${.TARGET} \ ${LLVM_SRCS}/include/llvm/IR/Intrinsics.td TGHDRS+= llvm/IR/Intrinsics.gen AttributesCompatFunc.inc: ${LLVM_SRCS}/lib/IR/AttributesCompatFunc.td ${LLVM_TBLGEN} -gen-attrs \ -I ${LLVM_SRCS}/include -d ${.TARGET}.d -o ${.TARGET} \ ${LLVM_SRCS}/lib/IR/AttributesCompatFunc.td TGHDRS+= AttributesCompatFunc.inc llvm-lib/Options.inc: ${LLVM_SRCS}/lib/ToolDrivers/llvm-lib/Options.td ${LLVM_TBLGEN} -gen-opt-parser-defs \ -I ${LLVM_SRCS}/include -d ${.TARGET}.d -o ${.TARGET} \ ${LLVM_SRCS}/lib/ToolDrivers/llvm-lib/Options.td TGHDRS+= llvm-lib/Options.inc CFLAGS.LibDriver.cpp+= -I${.OBJDIR}/llvm-lib llvm-dlltool/Options.inc: ${LLVM_SRCS}/lib/ToolDrivers/llvm-dlltool/Options.td ${LLVM_TBLGEN} -gen-opt-parser-defs \ -I ${LLVM_SRCS}/include -d ${.TARGET}.d -o ${.TARGET} \ ${LLVM_SRCS}/lib/ToolDrivers/llvm-dlltool/Options.td TGHDRS+= llvm-dlltool/Options.inc CFLAGS.DlltoolDriver.cpp+= -I${.OBJDIR}/llvm-dlltool +beforebuild: +# 20170724 remove stale Options.inc file, of which there are two different +# versions after r308421, one for llvm-lib, one for llvm-dlltool +.for f in Options.inc +.if exists(${f}) || exists(${f}.d) + @echo Removing stale generated ${f} files + @rm -f ${f} ${f}.d +.endif +.endfor + # Note: some rules are superfluous, not every combination is valid. .for arch in \ AArch64/AArch64 ARM/ARM Mips/Mips PowerPC/PPC Sparc/Sparc X86/X86 . for hdr in \ AsmMatcher/-gen-asm-matcher \ AsmWriter1/-gen-asm-writer,-asmwriternum=1 \ AsmWriter/-gen-asm-writer \ CallingConv/-gen-callingconv \ CodeEmitter/-gen-emitter \ DAGISel/-gen-dag-isel \ DisassemblerTables/-gen-disassembler \ EVEX2VEXTables/-gen-x86-EVEX2VEX-tables \ FastISel/-gen-fast-isel \ GlobalISel/-gen-global-isel \ InstrInfo/-gen-instr-info \ MCCodeEmitter/-gen-emitter \ MCPseudoLowering/-gen-pseudo-lowering \ RegisterBank/-gen-register-bank \ RegisterInfo/-gen-register-info \ SubtargetInfo/-gen-subtarget \ SystemOperands/-gen-searchable-tables ${arch:T}Gen${hdr:H}.inc: ${LLVM_SRCS}/lib/Target/${arch:H}/${arch:T}.td ${LLVM_TBLGEN} ${hdr:T:C/,/ /g} \ -I ${LLVM_SRCS}/include -I ${LLVM_SRCS}/lib/Target/${arch:H} \ -d ${.TARGET}.d -o ${.TARGET} \ ${LLVM_SRCS}/lib/Target/${arch:H}/${arch:T}.td . endfor .endfor TGHDRS+= AArch64GenAsmMatcher.inc TGHDRS+= AArch64GenAsmWriter.inc TGHDRS+= AArch64GenAsmWriter1.inc TGHDRS+= AArch64GenCallingConv.inc TGHDRS+= AArch64GenDAGISel.inc TGHDRS+= AArch64GenDisassemblerTables.inc TGHDRS+= AArch64GenFastISel.inc TGHDRS+= AArch64GenGlobalISel.inc TGHDRS+= AArch64GenInstrInfo.inc TGHDRS+= AArch64GenMCCodeEmitter.inc TGHDRS+= AArch64GenMCPseudoLowering.inc TGHDRS+= AArch64GenRegisterBank.inc TGHDRS+= AArch64GenRegisterInfo.inc TGHDRS+= AArch64GenSubtargetInfo.inc TGHDRS+= AArch64GenSystemOperands.inc TGHDRS+= ARMGenAsmMatcher.inc TGHDRS+= ARMGenAsmWriter.inc TGHDRS+= ARMGenCallingConv.inc TGHDRS+= ARMGenDAGISel.inc TGHDRS+= ARMGenDisassemblerTables.inc TGHDRS+= ARMGenFastISel.inc TGHDRS+= ARMGenGlobalISel.inc TGHDRS+= ARMGenInstrInfo.inc TGHDRS+= ARMGenMCCodeEmitter.inc TGHDRS+= ARMGenMCPseudoLowering.inc TGHDRS+= ARMGenRegisterBank.inc TGHDRS+= ARMGenRegisterInfo.inc TGHDRS+= ARMGenSubtargetInfo.inc TGHDRS+= MipsGenAsmMatcher.inc TGHDRS+= MipsGenAsmWriter.inc TGHDRS+= MipsGenCallingConv.inc TGHDRS+= MipsGenDAGISel.inc TGHDRS+= MipsGenDisassemblerTables.inc TGHDRS+= MipsGenFastISel.inc TGHDRS+= MipsGenInstrInfo.inc TGHDRS+= MipsGenMCCodeEmitter.inc TGHDRS+= MipsGenMCPseudoLowering.inc TGHDRS+= MipsGenRegisterInfo.inc TGHDRS+= MipsGenSubtargetInfo.inc TGHDRS+= PPCGenAsmMatcher.inc TGHDRS+= PPCGenAsmWriter.inc TGHDRS+= PPCGenCallingConv.inc TGHDRS+= PPCGenDAGISel.inc TGHDRS+= PPCGenDisassemblerTables.inc TGHDRS+= PPCGenFastISel.inc TGHDRS+= PPCGenInstrInfo.inc TGHDRS+= PPCGenMCCodeEmitter.inc TGHDRS+= PPCGenRegisterInfo.inc TGHDRS+= PPCGenSubtargetInfo.inc TGHDRS+= SparcGenAsmMatcher.inc TGHDRS+= SparcGenAsmWriter.inc TGHDRS+= SparcGenCallingConv.inc TGHDRS+= SparcGenDAGISel.inc TGHDRS+= SparcGenDisassemblerTables.inc TGHDRS+= SparcGenInstrInfo.inc TGHDRS+= SparcGenMCCodeEmitter.inc TGHDRS+= SparcGenRegisterInfo.inc TGHDRS+= SparcGenSubtargetInfo.inc TGHDRS+= X86GenAsmMatcher.inc TGHDRS+= X86GenAsmWriter.inc TGHDRS+= X86GenAsmWriter1.inc TGHDRS+= X86GenCallingConv.inc TGHDRS+= X86GenDAGISel.inc TGHDRS+= X86GenDisassemblerTables.inc TGHDRS+= X86GenEVEX2VEXTables.inc TGHDRS+= X86GenFastISel.inc TGHDRS+= X86GenGlobalISel.inc TGHDRS+= X86GenInstrInfo.inc TGHDRS+= X86GenRegisterBank.inc TGHDRS+= X86GenRegisterInfo.inc TGHDRS+= X86GenSubtargetInfo.inc .for dep in ${TGHDRS:C/$/.d/} . if ${MAKE_VERSION} < 20160220 . if !make(depend) . sinclude "${dep}" . endif . else . dinclude "${dep}" . endif .endfor DPSRCS+= ${TGHDRS} CLEANFILES+= ${TGHDRS} ${TGHDRS:C/$/.d/} .include "../llvm.build.mk" .include Index: projects/runtime-coverage/sbin/savecore/savecore.c =================================================================== --- projects/runtime-coverage/sbin/savecore/savecore.c (revision 321457) +++ projects/runtime-coverage/sbin/savecore/savecore.c (revision 321458) @@ -1,976 +1,989 @@ /*- * Copyright (c) 2002 Poul-Henning Kamp * Copyright (c) 2002 Networks Associates Technology, Inc. * All rights reserved. * * This software was developed for the FreeBSD Project by Poul-Henning Kamp * and NAI Labs, 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. * 3. The names of the authors 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. * * Copyright (c) 1986, 1992, 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. 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. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* The size of the buffer used for I/O. */ #define BUFFERSIZE (1024*1024) #define STATUS_BAD 0 #define STATUS_GOOD 1 #define STATUS_UNKNOWN 2 static int checkfor, compress, clear, force, keep, verbose; /* flags */ static int nfound, nsaved, nerr; /* statistics */ static int maxdumps; extern FILE *zopen(const char *, const char *); static sig_atomic_t got_siginfo; static void infohandler(int); static void -printheader(xo_handle_t *xo, const struct kerneldumpheader *h, const char *device, - int bounds, const int status) +printheader(xo_handle_t *xo, const struct kerneldumpheader *h, + const char *device, int bounds, const int status) { uint64_t dumplen; time_t t; const char *stat_str; xo_flush_h(xo); - xo_emit_h(xo, "{Lwc:Dump header from device}{:dump_device/%s}\n", device); - xo_emit_h(xo, "{P: }{Lwc:Architecture}{:architecture/%s}\n", h->architecture); - xo_emit_h(xo, "{P: }{Lwc:Architecture Version}{:architecture_version/%u}\n", dtoh32(h->architectureversion)); + xo_emit_h(xo, "{Lwc:Dump header from device}{:dump_device/%s}\n", + device); + xo_emit_h(xo, "{P: }{Lwc:Architecture}{:architecture/%s}\n", + h->architecture); + xo_emit_h(xo, + "{P: }{Lwc:Architecture Version}{:architecture_version/%u}\n", + dtoh32(h->architectureversion)); dumplen = dtoh64(h->dumplength); - xo_emit_h(xo, "{P: }{Lwc:Dump Length}{:dump_length_bytes/%lld}\n", (long long)dumplen); - xo_emit_h(xo, "{P: }{Lwc:Blocksize}{:blocksize/%d}\n", dtoh32(h->blocksize)); + xo_emit_h(xo, "{P: }{Lwc:Dump Length}{:dump_length_bytes/%lld}\n", + (long long)dumplen); + xo_emit_h(xo, "{P: }{Lwc:Blocksize}{:blocksize/%d}\n", + dtoh32(h->blocksize)); + t = dtoh64(h->dumptime); xo_emit_h(xo, "{P: }{Lwc:Dumptime}{:dumptime/%s}", ctime(&t)); xo_emit_h(xo, "{P: }{Lwc:Hostname}{:hostname/%s}\n", h->hostname); xo_emit_h(xo, "{P: }{Lwc:Magic}{:magic/%s}\n", h->magic); - xo_emit_h(xo, "{P: }{Lwc:Version String}{:version_string/%s}", h->versionstring); - xo_emit_h(xo, "{P: }{Lwc:Panic String}{:panic_string/%s}\n", h->panicstring); + xo_emit_h(xo, "{P: }{Lwc:Version String}{:version_string/%s}", + h->versionstring); + xo_emit_h(xo, "{P: }{Lwc:Panic String}{:panic_string/%s}\n", + h->panicstring); xo_emit_h(xo, "{P: }{Lwc:Dump Parity}{:dump_parity/%u}\n", h->parity); xo_emit_h(xo, "{P: }{Lwc:Bounds}{:bounds/%d}\n", bounds); - switch(status) { + switch (status) { case STATUS_BAD: stat_str = "bad"; break; case STATUS_GOOD: stat_str = "good"; break; default: stat_str = "unknown"; + break; } xo_emit_h(xo, "{P: }{Lwc:Dump Status}{:dump_status/%s}\n", stat_str); xo_flush_h(xo); } static int -getbounds(void) { +getbounds(void) +{ FILE *fp; char buf[6]; int ret; ret = 0; if ((fp = fopen("bounds", "r")) == NULL) { if (verbose) printf("unable to open bounds file, using 0\n"); return (ret); } if (fgets(buf, sizeof buf, fp) == NULL) { if (feof(fp)) syslog(LOG_WARNING, "bounds file is empty, using 0"); else syslog(LOG_WARNING, "bounds file: %s", strerror(errno)); fclose(fp); return (ret); } errno = 0; ret = (int)strtol(buf, NULL, 10); if (ret == 0 && (errno == EINVAL || errno == ERANGE)) syslog(LOG_WARNING, "invalid value found in bounds, using 0"); fclose(fp); return (ret); } static void -writebounds(int bounds) { +writebounds(int bounds) +{ FILE *fp; if ((fp = fopen("bounds", "w")) == NULL) { syslog(LOG_WARNING, "unable to write to bounds file: %m"); return; } if (verbose) printf("bounds number: %d\n", bounds); fprintf(fp, "%d\n", bounds); fclose(fp); } static bool writekey(const char *keyname, uint8_t *dumpkey, uint32_t dumpkeysize) { int fd; fd = open(keyname, O_WRONLY | O_CREAT | O_TRUNC, 0600); if (fd == -1) { syslog(LOG_ERR, "Unable to open %s to write the key: %m.", keyname); return (false); } if (write(fd, dumpkey, dumpkeysize) != (ssize_t)dumpkeysize) { syslog(LOG_ERR, "Unable to write the key to %s: %m.", keyname); close(fd); return (false); } close(fd); return (true); } static off_t file_size(const char *path) { struct stat sb; /* Ignore all errors, those file may not exists. */ if (stat(path, &sb) == -1) return (0); return (sb.st_size); } static off_t saved_dump_size(int bounds) { static char path[PATH_MAX]; off_t dumpsize; dumpsize = 0; (void)snprintf(path, sizeof(path), "info.%d", bounds); dumpsize += file_size(path); (void)snprintf(path, sizeof(path), "vmcore.%d", bounds); dumpsize += file_size(path); (void)snprintf(path, sizeof(path), "vmcore.%d.gz", bounds); dumpsize += file_size(path); (void)snprintf(path, sizeof(path), "textdump.tar.%d", bounds); dumpsize += file_size(path); (void)snprintf(path, sizeof(path), "textdump.tar.%d.gz", bounds); dumpsize += file_size(path); return (dumpsize); } static void saved_dump_remove(int bounds) { static char path[PATH_MAX]; (void)snprintf(path, sizeof(path), "info.%d", bounds); (void)unlink(path); (void)snprintf(path, sizeof(path), "vmcore.%d", bounds); (void)unlink(path); (void)snprintf(path, sizeof(path), "vmcore.%d.gz", bounds); (void)unlink(path); (void)snprintf(path, sizeof(path), "textdump.tar.%d", bounds); (void)unlink(path); (void)snprintf(path, sizeof(path), "textdump.tar.%d.gz", bounds); (void)unlink(path); } static void symlinks_remove(void) { (void)unlink("info.last"); (void)unlink("key.last"); (void)unlink("vmcore.last"); (void)unlink("vmcore.last.gz"); (void)unlink("vmcore_encrypted.last"); (void)unlink("vmcore_encrypted.last.gz"); (void)unlink("textdump.tar.last"); (void)unlink("textdump.tar.last.gz"); } /* * Check that sufficient space is available on the disk that holds the * save directory. */ static int check_space(const char *savedir, off_t dumpsize, int bounds) { FILE *fp; off_t available, minfree, spacefree, totfree, needed; struct statfs fsbuf; char buf[100]; if (statfs(".", &fsbuf) < 0) { syslog(LOG_ERR, "%s: %m", savedir); exit(1); } spacefree = ((off_t) fsbuf.f_bavail * fsbuf.f_bsize) / 1024; totfree = ((off_t) fsbuf.f_bfree * fsbuf.f_bsize) / 1024; if ((fp = fopen("minfree", "r")) == NULL) minfree = 0; else { if (fgets(buf, sizeof(buf), fp) == NULL) minfree = 0; else { char *endp; errno = 0; minfree = strtoll(buf, &endp, 10); if (minfree == 0 && errno != 0) minfree = -1; else { while (*endp != '\0' && isspace(*endp)) endp++; if (*endp != '\0' || minfree < 0) minfree = -1; } if (minfree < 0) syslog(LOG_WARNING, "`minfree` didn't contain a valid size " "(`%s`). Defaulting to 0", buf); } (void)fclose(fp); } available = minfree > 0 ? spacefree - minfree : totfree; needed = dumpsize / 1024 + 2; /* 2 for info file */ needed -= saved_dump_size(bounds); if (available < needed) { syslog(LOG_WARNING, "no dump: not enough free space on device (need at least " "%jdkB for dump; %jdkB available; %jdkB reserved)", (intmax_t)needed, (intmax_t)available + minfree, (intmax_t)minfree); return (0); } if (spacefree - needed < 0) syslog(LOG_WARNING, "dump performed, but free space threshold crossed"); return (1); } static bool compare_magic(const struct kerneldumpheader *kdh, const char *magic) { return (strncmp(kdh->magic, magic, sizeof(kdh->magic)) == 0); } #define BLOCKSIZE (1<<12) #define BLOCKMASK (~(BLOCKSIZE-1)) static int DoRegularFile(int fd, bool isencrypted, off_t dumpsize, char *buf, const char *device, const char *filename, FILE *fp) { int he, hs, nr, nw, wl; off_t dmpcnt, origsize; dmpcnt = 0; origsize = dumpsize; he = 0; while (dumpsize > 0) { wl = BUFFERSIZE; if (wl > dumpsize) wl = dumpsize; nr = read(fd, buf, wl); if (nr != wl) { if (nr == 0) syslog(LOG_WARNING, "WARNING: EOF on dump device"); else syslog(LOG_ERR, "read error on %s: %m", device); nerr++; return (-1); } if (compress || isencrypted) { nw = fwrite(buf, 1, wl, fp); } else { for (nw = 0; nw < nr; nw = he) { /* find a contiguous block of zeroes */ for (hs = nw; hs < nr; hs += BLOCKSIZE) { for (he = hs; he < nr && buf[he] == 0; ++he) /* nothing */ ; /* is the hole long enough to matter? */ if (he >= hs + BLOCKSIZE) break; } /* back down to a block boundary */ he &= BLOCKMASK; /* * 1) Don't go beyond the end of the buffer. * 2) If the end of the buffer is less than * BLOCKSIZE bytes away, we're at the end * of the file, so just grab what's left. */ if (hs + BLOCKSIZE > nr) hs = he = nr; /* * At this point, we have a partial ordering: * nw <= hs <= he <= nr - * If hs > nw, buf[nw..hs] contains non-zero data. - * If he > hs, buf[hs..he] is all zeroes. + * If hs > nw, buf[nw..hs] contains non-zero + * data. If he > hs, buf[hs..he] is all zeroes. */ if (hs > nw) if (fwrite(buf + nw, hs - nw, 1, fp) != 1) break; if (he > hs) if (fseeko(fp, he - hs, SEEK_CUR) == -1) break; } } if (nw != wl) { syslog(LOG_ERR, "write error on %s file: %m", filename); syslog(LOG_WARNING, "WARNING: vmcore may be incomplete"); nerr++; return (-1); } if (verbose) { dmpcnt += wl; printf("%llu\r", (unsigned long long)dmpcnt); fflush(stdout); } dumpsize -= wl; if (got_siginfo) { printf("%s %.1lf%%\n", filename, (100.0 - (100.0 * (double)dumpsize / (double)origsize))); got_siginfo = 0; } } return (0); } /* * Specialized version of dump-reading logic for use with textdumps, which * are written backwards from the end of the partition, and must be reversed * before being written to the file. Textdumps are small, so do a bit less * work to optimize/sparsify. */ static int DoTextdumpFile(int fd, off_t dumpsize, off_t lasthd, char *buf, const char *device, const char *filename, FILE *fp) { int nr, nw, wl; off_t dmpcnt, totsize; totsize = dumpsize; dmpcnt = 0; wl = 512; if ((dumpsize % wl) != 0) { syslog(LOG_ERR, "textdump uneven multiple of 512 on %s", device); nerr++; return (-1); } while (dumpsize > 0) { nr = pread(fd, buf, wl, lasthd - (totsize - dumpsize) - wl); if (nr != wl) { if (nr == 0) syslog(LOG_WARNING, "WARNING: EOF on dump device"); else syslog(LOG_ERR, "read error on %s: %m", device); nerr++; return (-1); } nw = fwrite(buf, 1, wl, fp); if (nw != wl) { syslog(LOG_ERR, "write error on %s file: %m", filename); syslog(LOG_WARNING, "WARNING: textdump may be incomplete"); nerr++; return (-1); } if (verbose) { dmpcnt += wl; printf("%llu\r", (unsigned long long)dmpcnt); fflush(stdout); } dumpsize -= wl; } return (0); } static void DoFile(const char *savedir, const char *device) { xo_handle_t *xostdout, *xoinfo; static char infoname[PATH_MAX], corename[PATH_MAX], linkname[PATH_MAX]; static char keyname[PATH_MAX]; static char *buf = NULL; char *temp = NULL; struct kerneldumpheader kdhf, kdhl; uint8_t *dumpkey; off_t mediasize, dumpsize, firsthd, lasthd; FILE *info, *fp; mode_t oumask; int fd, fdinfo, error; int bounds, status; u_int sectorsize, xostyle; int istextdump; uint32_t dumpkeysize; bool isencrypted, ret; bounds = getbounds(); dumpkey = NULL; mediasize = 0; status = STATUS_UNKNOWN; xostdout = xo_create_to_file(stdout, XO_STYLE_TEXT, 0); if (xostdout == NULL) { syslog(LOG_ERR, "%s: %m", infoname); return; } if (maxdumps > 0 && bounds == maxdumps) bounds = 0; if (buf == NULL) { buf = malloc(BUFFERSIZE); if (buf == NULL) { syslog(LOG_ERR, "%m"); return; } } if (verbose) printf("checking for kernel dump on device %s\n", device); fd = open(device, (checkfor || keep) ? O_RDONLY : O_RDWR); if (fd < 0) { syslog(LOG_ERR, "%s: %m", device); return; } error = ioctl(fd, DIOCGMEDIASIZE, &mediasize); if (!error) error = ioctl(fd, DIOCGSECTORSIZE, §orsize); if (error) { syslog(LOG_ERR, "couldn't find media and/or sector size of %s: %m", device); goto closefd; } if (verbose) { printf("mediasize = %lld bytes\n", (long long)mediasize); printf("sectorsize = %u bytes\n", sectorsize); } if (sectorsize < sizeof(kdhl)) { syslog(LOG_ERR, "Sector size is less the kernel dump header %zu", sizeof(kdhl)); goto closefd; } lasthd = mediasize - sectorsize; temp = malloc(sectorsize); if (temp == NULL) { syslog(LOG_ERR, "%m"); goto closefd; } if (lseek(fd, lasthd, SEEK_SET) != lasthd || read(fd, temp, sectorsize) != (ssize_t)sectorsize) { syslog(LOG_ERR, "error reading last dump header at offset %lld in %s: %m", (long long)lasthd, device); goto closefd; } memcpy(&kdhl, temp, sizeof(kdhl)); istextdump = 0; if (compare_magic(&kdhl, TEXTDUMPMAGIC)) { if (verbose) printf("textdump magic on last dump header on %s\n", device); istextdump = 1; if (dtoh32(kdhl.version) != KERNELDUMP_TEXT_VERSION) { syslog(LOG_ERR, "unknown version (%d) in last dump header on %s", dtoh32(kdhl.version), device); status = STATUS_BAD; if (force == 0) goto closefd; } } else if (compare_magic(&kdhl, KERNELDUMPMAGIC)) { if (dtoh32(kdhl.version) != KERNELDUMPVERSION) { syslog(LOG_ERR, "unknown version (%d) in last dump header on %s", dtoh32(kdhl.version), device); status = STATUS_BAD; if (force == 0) goto closefd; } } else { if (verbose) printf("magic mismatch on last dump header on %s\n", device); status = STATUS_BAD; if (force == 0) goto closefd; if (compare_magic(&kdhl, KERNELDUMPMAGIC_CLEARED)) { if (verbose) printf("forcing magic on %s\n", device); memcpy(kdhl.magic, KERNELDUMPMAGIC, sizeof kdhl.magic); } else { syslog(LOG_ERR, "unable to force dump - bad magic"); goto closefd; } if (dtoh32(kdhl.version) != KERNELDUMPVERSION) { syslog(LOG_ERR, "unknown version (%d) in last dump header on %s", dtoh32(kdhl.version), device); status = STATUS_BAD; if (force == 0) goto closefd; } } nfound++; if (clear) goto nuke; if (kerneldump_parity(&kdhl)) { syslog(LOG_ERR, "parity error on last dump header on %s", device); nerr++; status = STATUS_BAD; if (force == 0) goto closefd; } dumpsize = dtoh64(kdhl.dumplength); dumpkeysize = dtoh32(kdhl.dumpkeysize); firsthd = lasthd - dumpsize - sectorsize - dumpkeysize; if (lseek(fd, firsthd, SEEK_SET) != firsthd || read(fd, temp, sectorsize) != (ssize_t)sectorsize) { syslog(LOG_ERR, "error reading first dump header at offset %lld in %s: %m", (long long)firsthd, device); nerr++; goto closefd; } memcpy(&kdhf, temp, sizeof(kdhf)); if (verbose >= 2) { printf("First dump headers:\n"); printheader(xostdout, &kdhf, device, bounds, -1); printf("\nLast dump headers:\n"); printheader(xostdout, &kdhl, device, bounds, -1); printf("\n"); } if (memcmp(&kdhl, &kdhf, sizeof(kdhl))) { syslog(LOG_ERR, "first and last dump headers disagree on %s", device); nerr++; status = STATUS_BAD; if (force == 0) goto closefd; } else { status = STATUS_GOOD; } if (checkfor) { printf("A dump exists on %s\n", device); close(fd); exit(0); } if (kdhl.panicstring[0] != '\0') syslog(LOG_ALERT, "reboot after panic: %.*s", (int)sizeof(kdhl.panicstring), kdhl.panicstring); else syslog(LOG_ALERT, "reboot"); if (verbose) printf("Checking for available free space\n"); if (!check_space(savedir, dumpsize, bounds)) { nerr++; goto closefd; } writebounds(bounds + 1); saved_dump_remove(bounds); snprintf(infoname, sizeof(infoname), "info.%d", bounds); /* * Create or overwrite any existing dump header files. */ fdinfo = open(infoname, O_WRONLY | O_CREAT | O_TRUNC, 0600); if (fdinfo < 0) { syslog(LOG_ERR, "%s: %m", infoname); nerr++; goto closefd; } - oumask = umask(S_IRWXG|S_IRWXO); /* Restrict access to the core file.*/ + oumask = umask(S_IRWXG|S_IRWXO); /* Restrict access to the core file. */ isencrypted = (dumpkeysize > 0); if (compress) { snprintf(corename, sizeof(corename), "%s.%d.gz", istextdump ? "textdump.tar" : (isencrypted ? "vmcore_encrypted" : "vmcore"), bounds); fp = zopen(corename, "w"); } else { snprintf(corename, sizeof(corename), "%s.%d", istextdump ? "textdump.tar" : (isencrypted ? "vmcore_encrypted" : "vmcore"), bounds); fp = fopen(corename, "w"); } if (fp == NULL) { syslog(LOG_ERR, "%s: %m", corename); close(fdinfo); nerr++; goto closefd; } (void)umask(oumask); info = fdopen(fdinfo, "w"); if (info == NULL) { syslog(LOG_ERR, "fdopen failed: %m"); nerr++; goto closeall; } xostyle = xo_get_style(NULL); xoinfo = xo_create_to_file(info, xostyle, 0); if (xoinfo == NULL) { syslog(LOG_ERR, "%s: %m", infoname); nerr++; goto closeall; } xo_open_container_h(xoinfo, "crashdump"); if (verbose) printheader(xostdout, &kdhl, device, bounds, status); printheader(xoinfo, &kdhl, device, bounds, status); xo_close_container_h(xoinfo, "crashdump"); xo_flush_h(xoinfo); xo_finish_h(xoinfo); fclose(info); if (isencrypted) { dumpkey = calloc(1, dumpkeysize); if (dumpkey == NULL) { syslog(LOG_ERR, "Unable to allocate kernel dump key."); nerr++; goto closeall; } if (read(fd, dumpkey, dumpkeysize) != (ssize_t)dumpkeysize) { syslog(LOG_ERR, "Unable to read kernel dump key: %m."); nerr++; goto closeall; } snprintf(keyname, sizeof(keyname), "key.%d", bounds); ret = writekey(keyname, dumpkey, dumpkeysize); explicit_bzero(dumpkey, dumpkeysize); if (!ret) { nerr++; goto closeall; } } syslog(LOG_NOTICE, "writing %s%score to %s/%s", isencrypted ? "encrypted " : "", compress ? "compressed " : "", savedir, corename); if (istextdump) { if (DoTextdumpFile(fd, dumpsize, lasthd, buf, device, corename, fp) < 0) goto closeall; } else { if (DoRegularFile(fd, isencrypted, dumpsize, buf, device, corename, fp) < 0) { goto closeall; } } if (verbose) printf("\n"); if (fclose(fp) < 0) { syslog(LOG_ERR, "error on %s: %m", corename); nerr++; goto closefd; } symlinks_remove(); if (symlink(infoname, "info.last") == -1) { syslog(LOG_WARNING, "unable to create symlink %s/%s: %m", savedir, "info.last"); } if (isencrypted) { if (symlink(keyname, "key.last") == -1) { syslog(LOG_WARNING, "unable to create symlink %s/%s: %m", savedir, "key.last"); } } if (compress) { snprintf(linkname, sizeof(linkname), "%s.last.gz", istextdump ? "textdump.tar" : (isencrypted ? "vmcore_encrypted" : "vmcore")); } else { snprintf(linkname, sizeof(linkname), "%s.last", istextdump ? "textdump.tar" : (isencrypted ? "vmcore_encrypted" : "vmcore")); } if (symlink(corename, linkname) == -1) { syslog(LOG_WARNING, "unable to create symlink %s/%s: %m", savedir, linkname); } nsaved++; if (verbose) printf("dump saved\n"); nuke: if (!keep) { if (verbose) printf("clearing dump header\n"); memcpy(kdhl.magic, KERNELDUMPMAGIC_CLEARED, sizeof(kdhl.magic)); memcpy(temp, &kdhl, sizeof(kdhl)); if (lseek(fd, lasthd, SEEK_SET) != lasthd || write(fd, temp, sectorsize) != (ssize_t)sectorsize) syslog(LOG_ERR, "error while clearing the dump header: %m"); } xo_close_container_h(xostdout, "crashdump"); xo_finish_h(xostdout); free(dumpkey); free(temp); close(fd); return; closeall: fclose(fp); closefd: free(dumpkey); free(temp); close(fd); } static void usage(void) { xo_error("%s\n%s\n%s\n", "usage: savecore -c [-v] [device ...]", " savecore -C [-v] [device ...]", " savecore [-fkvz] [-m maxdumps] [directory [device ...]]"); exit(1); } int main(int argc, char **argv) { const char *savedir = "."; struct fstab *fsp; int i, ch, error; checkfor = compress = clear = force = keep = verbose = 0; nfound = nsaved = nerr = 0; openlog("savecore", LOG_PERROR, LOG_DAEMON); signal(SIGINFO, infohandler); argc = xo_parse_args(argc, argv); if (argc < 0) exit(1); while ((ch = getopt(argc, argv, "Ccfkm:vz")) != -1) switch(ch) { case 'C': checkfor = 1; break; case 'c': clear = 1; break; case 'f': force = 1; break; case 'k': keep = 1; break; case 'm': maxdumps = atoi(optarg); if (maxdumps <= 0) { syslog(LOG_ERR, "Invalid maxdump value"); exit(1); } break; case 'v': verbose++; break; case 'z': compress = 1; break; case '?': default: usage(); } if (checkfor && (clear || force || keep)) usage(); if (clear && (compress || keep)) usage(); if (maxdumps > 0 && (checkfor || clear)) usage(); argc -= optind; argv += optind; if (argc >= 1 && !checkfor && !clear) { error = chdir(argv[0]); if (error) { syslog(LOG_ERR, "chdir(%s): %m", argv[0]); exit(1); } savedir = argv[0]; argc--; argv++; } if (argc == 0) { for (;;) { fsp = getfsent(); if (fsp == NULL) break; if (strcmp(fsp->fs_vfstype, "swap") && strcmp(fsp->fs_vfstype, "dump")) continue; DoFile(savedir, fsp->fs_spec); } endfsent(); } else { for (i = 0; i < argc; i++) DoFile(savedir, argv[i]); } /* Emit minimal output. */ if (nfound == 0) { if (checkfor) { if (verbose) printf("No dump exists\n"); exit(1); } if (verbose) syslog(LOG_WARNING, "no dumps found"); } else if (nsaved == 0) { if (nerr != 0) { if (verbose) - syslog(LOG_WARNING, "unsaved dumps found but not saved"); + syslog(LOG_WARNING, + "unsaved dumps found but not saved"); exit(1); } else if (verbose) syslog(LOG_WARNING, "no unsaved dumps found"); } return (0); } static void infohandler(int sig __unused) { got_siginfo = 1; } Index: projects/runtime-coverage/share/mk/bsd.dep.mk =================================================================== --- projects/runtime-coverage/share/mk/bsd.dep.mk (revision 321457) +++ projects/runtime-coverage/share/mk/bsd.dep.mk (revision 321458) @@ -1,340 +1,342 @@ # $FreeBSD$ # # The include file handles Makefile dependencies. # # # +++ variables +++ # # CLEANDEPENDDIRS Additional directories to remove for the cleandepend # target. # # CLEANDEPENDFILES Additional files to remove for the cleandepend target. # # CTAGS A tags file generation program [gtags] # # CTAGSFLAGS Options for ctags(1) [not set] # # DEPENDFILE dependencies file [.depend] # # GTAGSFLAGS Options for gtags(1) [-o] # # HTAGSFLAGS Options for htags(1) [not set] # # SRCS List of source files (c, c++, assembler) # # DPSRCS List of source files which are needed for generating # dependencies, ${SRCS} are always part of it. # # +++ targets +++ # # cleandepend: # remove ${CLEANDEPENDFILES}; remove ${CLEANDEPENDDIRS} and all # contents. # # depend: # Make the dependencies for the source files, and store # them in the file ${DEPENDFILE}. # # tags: # In "ctags" mode, create a tags file for the source files. # In "gtags" mode, create a (GLOBAL) gtags file for the # source files. If HTML is defined, htags(1) is also run # after gtags(1). .if !target(____) .error bsd.dep.mk cannot be included directly. .endif CTAGS?= gtags CTAGSFLAGS?= GTAGSFLAGS?= -o HTAGSFLAGS?= .if ${MK_DIRDEPS_BUILD} == "no" .MAKE.DEPENDFILE= ${DEPENDFILE} .endif CLEANDEPENDFILES+= ${DEPENDFILE} ${DEPENDFILE}.* .if ${MK_META_MODE} == "yes" CLEANDEPENDFILES+= *.meta .endif # Keep `tags' here, before SRCS are mangled below for `depend'. .if !target(tags) && defined(SRCS) && !defined(NO_TAGS) tags: ${SRCS} .if ${CTAGS:T} == "gtags" @cd ${.CURDIR} && ${CTAGS} ${GTAGSFLAGS} ${.OBJDIR} .if defined(HTML) @cd ${.CURDIR} && htags ${HTAGSFLAGS} -d ${.OBJDIR} ${.OBJDIR} .endif .else @${CTAGS} ${CTAGSFLAGS} -f /dev/stdout \ ${.ALLSRC:N*.h} | sed "s;${.CURDIR}/;;" > ${.TARGET} .endif .endif .if !empty(.MAKE.MODE:Mmeta) && empty(.MAKE.MODE:Mnofilemon) _meta_filemon= 1 .endif # By default META_MODE is disabled in bmake if there is no OBJDIR # unless .MAKE.MODE contains "curdirOk=[^0nNfF]" .if defined(_meta_filemon) && ${.OBJDIR} == ${.CURDIR} && \ (empty(.MAKE.MODE:tl:Mcurdirok=*) || \ !empty(.MAKE.MODE:tl:Mcurdirok=[0NnFf]*)) .undef _meta_filemon .endif # Skip reading .depend when not needed to speed up tree-walks and simple # lookups. See _SKIP_BUILD logic in bsd.init.mk for more details. # Also skip generating or including .depend.* files if in meta+filemon mode # since it will track dependencies itself. OBJS_DEPEND_GUESS is still used # for _meta_filemon but not for _SKIP_DEPEND. .if defined(_SKIP_BUILD) _SKIP_DEPEND= 1 .endif .if ${MK_DIRDEPS_BUILD} == "no" .if defined(_SKIP_DEPEND) || defined(_meta_filemon) .MAKE.DEPENDFILE= /dev/null .endif .endif .if defined(SRCS) CLEANFILES?= .for _S in ${SRCS:N*.[dhly]} OBJS_DEPEND_GUESS.${_S:R}.o+= ${_S} .endfor # Lexical analyzers .for _LSRC in ${SRCS:M*.l:N*/*} .for _LC in ${_LSRC:R}.c ${_LC}: ${_LSRC} ${LEX} ${LFLAGS} -o${.TARGET} ${.ALLSRC} OBJS_DEPEND_GUESS.${_LC:R}.o+= ${_LC} SRCS:= ${SRCS:S/${_LSRC}/${_LC}/} CLEANFILES+= ${_LC} .endfor .endfor # Yacc grammars .for _YSRC in ${SRCS:M*.y:N*/*} .for _YC in ${_YSRC:R}.c SRCS:= ${SRCS:S/${_YSRC}/${_YC}/} CLEANFILES+= ${_YC} .if !empty(YFLAGS:M-d) && !empty(SRCS:My.tab.h) .ORDER: ${_YC} y.tab.h y.tab.h: .NOMETA ${_YC} y.tab.h: ${_YSRC} ${YACC} ${YFLAGS} ${.ALLSRC} cp y.tab.c ${_YC} CLEANFILES+= y.tab.c y.tab.h .elif !empty(YFLAGS:M-d) .for _YH in ${_YC:R}.h .ORDER: ${_YC} ${_YH} ${_YH}: .NOMETA ${_YC} ${_YH}: ${_YSRC} ${YACC} ${YFLAGS} -o ${_YC} ${.ALLSRC} SRCS+= ${_YH} CLEANFILES+= ${_YH} .endfor .else ${_YC}: ${_YSRC} ${YACC} ${YFLAGS} -o ${_YC} ${.ALLSRC} .endif OBJS_DEPEND_GUESS.${_YC:R}.o+= ${_YC} .endfor .endfor # DTrace probe definitions .if ${SRCS:M*.d} CFLAGS+= -I${.OBJDIR} .endif .for _DSRC in ${SRCS:M*.d:N*/*} .for _D in ${_DSRC:R} SRCS+= ${_D}.h ${_D}.h: ${_DSRC} ${DTRACE} ${DTRACEFLAGS} -h -s ${.ALLSRC} SRCS:= ${SRCS:S/^${_DSRC}$//} OBJS+= ${_D}.o CLEANFILES+= ${_D}.h ${_D}.o ${_D}.o: ${_DSRC} ${OBJS:S/^${_D}.o$//} @rm -f ${.TARGET} ${DTRACE} ${DTRACEFLAGS} -G -o ${.TARGET} -s ${.ALLSRC:N*.h} .if defined(LIB) CLEANFILES+= ${_D}.pico ${_D}.po ${_D}.pico: ${_DSRC} ${SOBJS:S/^${_D}.pico$//} @rm -f ${.TARGET} ${DTRACE} ${DTRACEFLAGS} -G -o ${.TARGET} -s ${.ALLSRC:N*.h} ${_D}.po: ${_DSRC} ${POBJS:S/^${_D}.po$//} @rm -f ${.TARGET} ${DTRACE} ${DTRACEFLAGS} -G -o ${.TARGET} -s ${.ALLSRC:N*.h} .endif .endfor .endfor .if ${MAKE_VERSION} < 20160220 DEPEND_MP?= -MP .endif # Handle OBJS=../somefile.o hacks. Just replace '/' rather than use :T to # avoid collisions. DEPEND_FILTER= C,/,_,g DEPENDSRCS= ${SRCS:M*.[cSC]} ${SRCS:M*.cxx} ${SRCS:M*.cpp} ${SRCS:M*.cc} .if !empty(DEPENDSRCS) DEPENDOBJS+= ${DEPENDSRCS:R:S,$,.o,} .endif DEPENDFILES_OBJS= ${DEPENDOBJS:O:u:${DEPEND_FILTER}:C/^/${DEPENDFILE}./} .if defined(_SKIP_DEPEND) # Don't bother statting any .meta files for .depend* ${DEPENDOBJS}: .NOMETA ${DEPENDFILE}: .NOMETA # Unset these to avoid looping/statting on them later. .undef DEPENDSRCS .undef DEPENDOBJS .undef DEPENDFILES_OBJS .endif # defined(_SKIP_DEPEND) DEPEND_CFLAGS+= -MD ${DEPEND_MP} -MF${DEPENDFILE}.${.TARGET:${DEPEND_FILTER}} DEPEND_CFLAGS+= -MT${.TARGET} .if !defined(_meta_filemon) -.if defined(.PARSEDIR) +.if !empty(DEPEND_CFLAGS) # Only add in DEPEND_CFLAGS for CFLAGS on files we expect from DEPENDOBJS # as those are the only ones we will include. DEPEND_CFLAGS_CONDITION= "${DEPENDOBJS:${DEPEND_FILTER}:M${.TARGET:${DEPEND_FILTER}}}" != "" CFLAGS+= ${${DEPEND_CFLAGS_CONDITION}:?${DEPEND_CFLAGS}:} -.else -CFLAGS+= ${DEPEND_CFLAGS} .endif .for __depend_obj in ${DEPENDFILES_OBJS} .if ${MAKE_VERSION} < 20160220 .sinclude "${.OBJDIR}/${__depend_obj}" .else .dinclude "${.OBJDIR}/${__depend_obj}" .endif .endfor .endif # !defined(_meta_filemon) .endif # defined(SRCS) .if ${MK_DIRDEPS_BUILD} == "yes" && ${.MAKE.DEPENDFILE} != "/dev/null" # Prevent meta.autodep.mk from tracking "local dependencies". .depend: .include # If using filemon then _EXTRADEPEND is skipped since it is not needed. .if defined(_meta_filemon) # this depend: bypasses that below # the dependency helps when bootstrapping depend: beforedepend ${DPSRCS} ${SRCS} afterdepend beforedepend: afterdepend: beforedepend .endif .endif # Guess some dependencies for when no ${DEPENDFILE}.OBJ is generated yet. # For meta+filemon the .meta file is checked for since it is the dependency # file used. .for __obj in ${DEPENDOBJS:O:u} # If the obj has any '/', then replace with '_'. For meta files, this is # mimicing what bmake's meta_name() does and adding in the full path # as well to ensure that the expected meta file is read. .if ${__obj:M*/*} _meta_obj= ${.OBJDIR:C,/,_,g}_${__obj:C,/,_,g}.meta .else _meta_obj= ${__obj}.meta .endif _dep_obj= ${DEPENDFILE}.${__obj:${DEPEND_FILTER}} -.if (defined(_meta_filemon) && !exists(${.OBJDIR}/${_meta_obj})) || \ - (!defined(_meta_filemon) && !exists(${.OBJDIR}/${_dep_obj})) +.if defined(_meta_filemon) +_depfile= ${.OBJDIR}/${_meta_obj} +.else +_depfile= ${.OBJDIR}/${_dep_obj} +.endif +.if !exists(${_depfile}) ${__obj}: ${OBJS_DEPEND_GUESS} ${__obj}: ${OBJS_DEPEND_GUESS.${__obj}} .elif defined(_meta_filemon) # For meta mode we still need to know which file to depend on to avoid # ambiguous suffix transformation rules from .PATH. Meta mode does not # use .depend files. We really only need source files, not headers since # they are typically in SRCS/beforebuild already. For target-specific # guesses do include headers though since they may not be in SRCS. ${__obj}: ${OBJS_DEPEND_GUESS:N*.h} ${__obj}: ${OBJS_DEPEND_GUESS.${__obj}} -.endif +.endif # !exists(${_depfile}) .endfor # Always run 'make depend' to generate dependencies early and to avoid the # need for manually running it. The dirdeps build should only do this in # sub-makes though since MAKELEVEL0 is for dirdeps calculations. .if ${MK_DIRDEPS_BUILD} == "no" || ${.MAKE.LEVEL} > 0 beforebuild: depend .endif .if !target(depend) .if defined(SRCS) depend: beforedepend ${DEPENDFILE} afterdepend # Tell bmake not to look for generated files via .PATH .NOPATH: ${DEPENDFILE} ${DEPENDFILES_OBJS} DPSRCS+= ${SRCS} # A .depend file will only be generated if there are commands in # beforedepend/_EXTRADEPEND/afterdepend The _EXTRADEPEND target is # ignored if using meta+filemon since it handles all dependencies. The other # targets are kept as they be used for generating something. The target is # kept to allow 'make depend' to generate files. ${DEPENDFILE}: ${DPSRCS} .if !defined(_SKIP_DEPEND) .if exists(${.OBJDIR}/${DEPENDFILE}) || \ ((commands(beforedepend) || \ (!defined(_meta_filemon) && commands(_EXTRADEPEND)) || \ commands(afterdepend)) && !empty(.MAKE.MODE:Mmeta)) rm -f ${DEPENDFILE} .endif .endif .if !defined(_meta_filemon) && target(_EXTRADEPEND) _EXTRADEPEND: .USE ${DEPENDFILE}: _EXTRADEPEND .endif .ORDER: ${DEPENDFILE} afterdepend .else depend: beforedepend afterdepend .endif .if !target(beforedepend) beforedepend: .else .ORDER: beforedepend ${DEPENDFILE} .ORDER: beforedepend afterdepend .endif .if !target(afterdepend) afterdepend: .endif .endif .if defined(SRCS) .if ${CTAGS:T} == "gtags" CLEANDEPENDFILES+= GPATH GRTAGS GSYMS GTAGS .if defined(HTML) CLEANDEPENDDIRS+= HTML .endif .else CLEANDEPENDFILES+= tags .endif .endif .if !target(cleandepend) cleandepend: .if !empty(CLEANDEPENDFILES) rm -f ${CLEANDEPENDFILES} .endif .if !empty(CLEANDEPENDDIRS) rm -rf ${CLEANDEPENDDIRS} .endif .endif .ORDER: cleandepend all .ORDER: cleandepend depend .if !target(checkdpadd) && (defined(DPADD) || defined(LDADD)) _LDADD_FROM_DPADD= ${DPADD:R:T:C;^lib(.*)$;-l\1;g} # Ignore -Wl,--start-group/-Wl,--end-group as it might be required in the # LDADD list due to unresolved symbols _LDADD_CANONICALIZED= ${LDADD:N:R:T:C;^lib(.*)$;-l\1;g:N-Wl,--[es]*-group} checkdpadd: .if ${_LDADD_FROM_DPADD} != ${_LDADD_CANONICALIZED} @echo ${.CURDIR} @echo "DPADD -> ${_LDADD_FROM_DPADD}" @echo "LDADD -> ${_LDADD_CANONICALIZED}" .endif .endif Index: projects/runtime-coverage/share/mk/bsd.obj.mk =================================================================== --- projects/runtime-coverage/share/mk/bsd.obj.mk (revision 321457) +++ projects/runtime-coverage/share/mk/bsd.obj.mk (revision 321458) @@ -1,237 +1,237 @@ # $FreeBSD$ # # The include file handles creating the 'obj' directory # and cleaning up object files, etc. # # +++ variables +++ # # CLEANDIRS Additional directories to remove for the clean target. # # CLEANFILES Additional files to remove for the clean target. # # MAKEOBJDIR A pathname for the directory where the targets # are built. Note: MAKEOBJDIR is an *environment* variable # and works properly only if set as an environment variable, # not as a global or command line variable! # # E.g. use `env MAKEOBJDIR=temp-obj make' # # MAKEOBJDIRPREFIX Specifies somewhere other than /usr/obj to root the object # tree. Note: MAKEOBJDIRPREFIX is an *environment* variable # and works properly only if set as an environment variable, # not as a global or command line variable! # # E.g. use `env MAKEOBJDIRPREFIX=/somewhere/obj make' # # NO_OBJ Do not create object directories. This should not be set # if anything is built. # # +++ targets +++ # # clean: # remove ${CLEANFILES}; remove ${CLEANDIRS} and all contents. # # cleandir: # remove the build directory (and all its contents) created by obj # # obj: # create build directory. # .if !target(____) ____: .include .if ${MK_AUTO_OBJ} == "yes" # it is done by now objwarn: obj: CANONICALOBJDIR= ${.OBJDIR} .if defined(NO_OBJ) # but this makefile does not want it! .OBJDIR: ${.CURDIR} .endif # Handle special case where SRCS is full-pathed and requires # nested objdirs. This duplicates some auto.obj.mk logic. .if (!empty(SRCS:M*/*) || !empty(DPSRCS:M*/*)) && \ (${.TARGETS} == "" || ${.TARGETS:Nclean*:N*clean:Ndestroy*} != "") _wantdirs= ${SRCS:M*/*:H} ${DPSRCS:M*/*:H} .if !empty(_wantdirs) _wantdirs:= ${_wantdirs:O:u} _needdirs= .for _dir in ${_wantdirs} .if !exists(${.OBJDIR}/${_dir}/) _needdirs+= ${_dir} .endif .endfor .endif .if !empty(_needdirs) #_mkneededdirs!= umask ${OBJDIR_UMASK:U002}; ${Mkdirs} ${_needdirs} __objdir_made != umask ${OBJDIR_UMASK:U002}; ${Mkdirs}; \ for dir in ${_needdirs}; do \ dir=${.OBJDIR}/$${dir}; \ ${ECHO_TRACE} "[Creating nested objdir $${dir}...]" >&2; \ Mkdirs $${dir}; \ done .endif .endif # !empty(SRCS:M*/*) || !empty(DPSRCS:M*/*) .elif defined(MAKEOBJDIRPREFIX) CANONICALOBJDIR:=${MAKEOBJDIRPREFIX}${.CURDIR} .elif defined(MAKEOBJDIR) && ${MAKEOBJDIR:M/*} != "" CANONICALOBJDIR:=${MAKEOBJDIR} OBJTOP?= ${MAKEOBJDIR} .else CANONICALOBJDIR:=/usr/obj${.CURDIR} .endif OBJTOP?= ${.OBJDIR:S,${.CURDIR},,}${SRCTOP} # # Warn of unorthodox object directory. # # The following directories are tried in order for ${.OBJDIR}: # # 1. ${MAKEOBJDIRPREFIX}/`pwd` # 2. ${MAKEOBJDIR} # 3. obj.${MACHINE} # 4. obj # 5. /usr/obj/`pwd` # 6. ${.CURDIR} # # If ${.OBJDIR} is constructed using canonical cases 1 or 5, or # case 2 (using MAKEOBJDIR), don't issue a warning. Otherwise, # issue a warning differentiating between cases 6 and (3 or 4). # objwarn: .PHONY .if !defined(NO_OBJ) && ${.OBJDIR} != ${CANONICALOBJDIR} && \ !(defined(MAKEOBJDIRPREFIX) && exists(${CANONICALOBJDIR}/)) && \ !(defined(MAKEOBJDIR) && exists(${MAKEOBJDIR}/)) .if ${.OBJDIR} == ${.CURDIR} @${ECHO} "Warning: Object directory not changed from original ${.CURDIR}" .elif exists(${.CURDIR}/obj.${MACHINE}/) || exists(${.CURDIR}/obj/) @${ECHO} "Warning: Using ${.OBJDIR} as object directory instead of\ canonical ${CANONICALOBJDIR}" .endif .endif beforebuild: objwarn .if !defined(NO_OBJ) .if !target(obj) obj: .PHONY @if ! test -d ${CANONICALOBJDIR}/; then \ mkdir -p ${CANONICALOBJDIR}; \ if ! test -d ${CANONICALOBJDIR}/; then \ ${ECHO} "Unable to create ${CANONICALOBJDIR}."; \ exit 1; \ fi; \ ${ECHO} "${CANONICALOBJDIR} created for ${.CURDIR}"; \ fi .for dir in ${SRCS:H:O:u} ${DPSRCS:H:O:u} @if ! test -d ${CANONICALOBJDIR}/${dir}/; then \ mkdir -p ${CANONICALOBJDIR}/${dir}; \ if ! test -d ${CANONICALOBJDIR}/${dir}/; then \ ${ECHO} "Unable to create ${CANONICALOBJDIR}/${dir}."; \ exit 1; \ fi; \ ${ECHO} "${CANONICALOBJDIR}/${dir} created for ${.CURDIR}"; \ fi .endfor .endif .if !target(objlink) objlink: @if test -d ${CANONICALOBJDIR}/; then \ rm -f ${.CURDIR}/obj; \ ln -s ${CANONICALOBJDIR} ${.CURDIR}/obj; \ else \ echo "No ${CANONICALOBJDIR} to link to - do a make obj."; \ fi .endif .endif # !defined(NO_OBJ) # # where would that obj directory be? # .if !target(whereobj) whereobj: @echo ${.OBJDIR} .endif # Same check in bsd.progs.mk .if ${CANONICALOBJDIR} != ${.CURDIR} && exists(${CANONICALOBJDIR}/) cleanobj: -rm -rf ${CANONICALOBJDIR} .else cleanobj: clean cleandepend .endif @if [ -L ${.CURDIR}/obj ]; then rm -f ${.CURDIR}/obj; fi # Tell bmake not to look for generated files via .PATH NOPATH_FILES+= ${CLEANFILES} .if !empty(NOPATH_FILES) .NOPATH: ${NOPATH_FILES} .endif .if !target(clean) clean: .if defined(CLEANFILES) && !empty(CLEANFILES) rm -f ${CLEANFILES} .endif .if defined(CLEANDIRS) && !empty(CLEANDIRS) -rm -rf ${CLEANDIRS} .endif .endif .ORDER: clean all -cleandir: cleanobj - .include + +cleandir: .WAIT cleanobj .if make(destroy*) && defined(OBJROOT) # this (rm -rf objdir) is much faster and more reliable than cleaning. # just in case we are playing games with these... _OBJDIR?= ${.OBJDIR} _CURDIR?= ${.CURDIR} # destroy almost everything destroy: destroy-all destroy-all: # just remove our objdir destroy-arch: .NOMETA .if ${_OBJDIR} != ${_CURDIR} cd ${_CURDIR} && rm -rf ${_OBJDIR} .endif .if defined(HOST_OBJTOP) destroy-host: destroy.host destroy.host: .NOMETA cd ${_CURDIR} && rm -rf ${HOST_OBJTOP}/${RELDIR:N.} .endif .if make(destroy-all) && ${RELDIR} == "." destroy-all: destroy-stage .endif # remove the stage tree destroy-stage: .NOMETA .if defined(STAGE_ROOT) cd ${_CURDIR} && rm -rf ${STAGE_ROOT} .endif # allow parallel destruction _destroy_machine_list = common host ${ALL_MACHINE_LIST} .for m in ${_destroy_machine_list:O:u} destroy-all: destroy.$m .if !target(destroy.$m) destroy.$m: .NOMETA .if ${_OBJDIR} != ${_CURDIR} cd ${_CURDIR} && rm -rf ${OBJROOT}$m*/${RELDIR:N.} .endif .endif .endfor .endif .endif # !target(____) Index: projects/runtime-coverage/sys/conf/kern.post.mk =================================================================== --- projects/runtime-coverage/sys/conf/kern.post.mk (revision 321457) +++ projects/runtime-coverage/sys/conf/kern.post.mk (revision 321458) @@ -1,413 +1,415 @@ # $FreeBSD$ # Part of a unified Makefile for building kernels. This part includes all # the definitions that need to be after all the % directives except %RULES # and ones that act like they are part of %RULES. # # Most make variables should not be defined in this file. Instead, they # should be defined in the kern.pre.mk so that port makefiles can # override or augment them. # In case the config had a makeoptions DESTDIR... .if defined(DESTDIR) MKMODULESENV+= DESTDIR="${DESTDIR}" .endif SYSDIR?= ${S:C;^[^/];${.CURDIR}/&;:tA} MKMODULESENV+= KERNBUILDDIR="${.CURDIR}" SYSDIR="${SYSDIR}" .if defined(CONF_CFLAGS) MKMODULESENV+= CONF_CFLAGS="${CONF_CFLAGS}" .endif .if defined(WITH_CTF) MKMODULESENV+= WITH_CTF="${WITH_CTF}" .endif .if defined(WITH_EXTRA_TCP_STACKS) MKMODULESENV+= WITH_EXTRA_TCP_STACKS="${WITH_EXTRA_TCP_STACKS}" .endif # Allow overriding the kernel debug directory, so kernel and user debug may be # installed in different directories. Setting it to "" restores the historical # behavior of installing debug files in the kernel directory. KERN_DEBUGDIR?= ${DEBUGDIR} .MAIN: all .for target in all clean cleandepend cleandir clobber depend install \ ${_obj} reinstall tags ${target}: kernel-${target} .if !defined(MODULES_WITH_WORLD) && !defined(NO_MODULES) && exists($S/modules) ${target}: modules-${target} modules-${target}: cd $S/modules; ${MKMODULESENV} ${MAKE} \ ${target:S/^reinstall$/install/:S/^clobber$/cleandir/} .endif .endfor # Handle ports (as defined by the user) that build kernel modules .if !defined(NO_MODULES) && defined(PORTS_MODULES) # # The ports tree needs some environment variables defined to match the new kernel # # Ports search for some dependencies in PATH, so add the location of the installed files LOCALBASE?= /usr/local # SRC_BASE is how the ports tree refers to the location of the base source files .if !defined(SRC_BASE) SRC_BASE= ${SYSDIR:H:tA} .endif # OSVERSION is used by some ports to determine build options .if !defined(OSRELDATE) # Definition copied from src/Makefile.inc1 OSRELDATE!= awk '/^\#define[[:space:]]*__FreeBSD_version/ { print $$3 }' \ ${MAKEOBJDIRPREFIX}${SRC_BASE}/include/osreldate.h .endif # Keep the related ports builds in the obj directory so that they are only rebuilt once per kernel build WRKDIRPREFIX?= ${.OBJDIR} PORTSMODULESENV=\ env \ -u CC \ -u CXX \ -u CPP \ PATH=${PATH}:${LOCALBASE}/bin:${LOCALBASE}/sbin \ SRC_BASE=${SRC_BASE} \ OSVERSION=${OSRELDATE} \ WRKDIRPREFIX=${WRKDIRPREFIX} # The WRKDIR needs to be cleaned before building, and trying to change the target # with a :C pattern below results in install -> instclean all: .for __i in ${PORTS_MODULES} @${ECHO} "===> Ports module ${__i} (all)" cd $${PORTSDIR:-/usr/ports}/${__i}; ${PORTSMODULESENV} ${MAKE} -B clean build .endfor .for __target in install reinstall clean ${__target}: ports-${__target} ports-${__target}: .for __i in ${PORTS_MODULES} @${ECHO} "===> Ports module ${__i} (${__target})" cd $${PORTSDIR:-/usr/ports}/${__i}; ${PORTSMODULESENV} ${MAKE} -B ${__target:C/install/deinstall reinstall/:C/reinstall/deinstall reinstall/} .endfor .endfor .endif .ORDER: kernel-install modules-install beforebuild: .PHONY kernel-all: beforebuild .WAIT ${KERNEL_KO} ${KERNEL_EXTRA} kernel-cleandir: kernel-clean kernel-cleandepend kernel-clobber: find . -maxdepth 1 ! -type d ! -name version -delete kernel-obj: .if !defined(MODULES_WITH_WORLD) && !defined(NO_MODULES) && exists($S/modules) modules: modules-all .if !defined(NO_MODULES_OBJ) modules-all modules-depend: modules-obj .endif .endif .if !defined(DEBUG) FULLKERNEL= ${KERNEL_KO} .else FULLKERNEL= ${KERNEL_KO}.full ${KERNEL_KO}: ${FULLKERNEL} ${KERNEL_KO}.debug ${OBJCOPY} --strip-debug --add-gnu-debuglink=${KERNEL_KO}.debug \ ${FULLKERNEL} ${.TARGET} ${KERNEL_KO}.debug: ${FULLKERNEL} ${OBJCOPY} --only-keep-debug ${FULLKERNEL} ${.TARGET} install.debug reinstall.debug: gdbinit cd ${.CURDIR}; ${MAKE} ${.TARGET:R} # Install gdbinit files for kernel debugging. gdbinit: grep -v '# XXX' ${S}/../tools/debugscripts/dot.gdbinit | \ sed "s:MODPATH:${.OBJDIR}/modules:" > .gdbinit cp ${S}/../tools/debugscripts/gdbinit.kernel ${.CURDIR} .if exists(${S}/../tools/debugscripts/gdbinit.${MACHINE_CPUARCH}) cp ${S}/../tools/debugscripts/gdbinit.${MACHINE_CPUARCH} \ ${.CURDIR}/gdbinit.machine .endif .endif ${FULLKERNEL}: ${SYSTEM_DEP} vers.o @rm -f ${.TARGET} @echo linking ${.TARGET} ${SYSTEM_LD} .if !empty(MD_ROOT_SIZE_CONFIGURED) && defined(MFS_IMAGE) @sh ${S}/tools/embed_mfs.sh ${.TARGET} ${MFS_IMAGE} .endif .if ${MK_CTF} != "no" @echo ${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ... @${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${SYSTEM_OBJS} vers.o .endif .if !defined(DEBUG) ${OBJCOPY} --strip-debug ${.TARGET} .endif ${SYSTEM_LD_TAIL} OBJS_DEPEND_GUESS+= assym.s vnode_if.h ${BEFORE_DEPEND:M*.h} \ ${MFILES:T:S/.m$/.h/} LNFILES= ${CFILES:T:S/.c$/.ln/} .for mfile in ${MFILES} # XXX the low quality .m.o rules gnerated by config are normally used # instead of the .m.c rules here. ${mfile:T:S/.m$/.c/}: ${mfile} ${AWK} -f $S/tools/makeobjops.awk ${mfile} -c ${mfile:T:S/.m$/.h/}: ${mfile} ${AWK} -f $S/tools/makeobjops.awk ${mfile} -h .endfor kernel-clean: rm -f *.o *.so *.pico *.ko *.s eddep errs \ ${FULLKERNEL} ${KERNEL_KO} ${KERNEL_KO}.debug \ linterrs tags vers.c \ vnode_if.c vnode_if.h vnode_if_newproto.h vnode_if_typedef.h \ ${MFILES:T:S/.m$/.c/} ${MFILES:T:S/.m$/.h/} \ ${CLEAN} lint: ${LNFILES} ${LINT} ${LINTKERNFLAGS} ${CFLAGS:M-[DILU]*} ${.ALLSRC} 2>&1 | \ tee -a linterrs # This is a hack. BFD "optimizes" away dynamic mode if there are no # dynamic references. We could probably do a '-Bforcedynamic' mode like # in the a.out ld. For now, this works. HACK_EXTRA_FLAGS?= -shared hack.pico: Makefile :> hack.c ${CC} ${HACK_EXTRA_FLAGS} -nostdlib hack.c -o hack.pico rm -f hack.c assym.s: $S/kern/genassym.sh genassym.o NM='${NM}' NMFLAGS='${NMFLAGS}' sh $S/kern/genassym.sh genassym.o > ${.TARGET} genassym.o: $S/$M/$M/genassym.c ${CC} -c ${CFLAGS:N-flto:N-fno-common} $S/$M/$M/genassym.c ${SYSTEM_OBJS} genassym.o vers.o: opt_global.h .if !empty(.MAKE.MODE:Unormal:Mmeta) && empty(.MAKE.MODE:Unormal:Mnofilemon) _meta_filemon= 1 .endif # Skip reading .depend when not needed to speed up tree-walks and simple # lookups. For install, only do this if no other targets are specified. # Also skip generating or including .depend.* files if in meta+filemon mode # since it will track dependencies itself. OBJS_DEPEND_GUESS is still used # for _meta_filemon but not for _SKIP_DEPEND. .if !empty(.MAKEFLAGS:M-V${_V_READ_DEPEND}) || make(*obj) || \ ${.TARGETS:M*clean*} == ${.TARGETS} || \ ${.TARGETS:M*install*} == ${.TARGETS} _SKIP_DEPEND= 1 .endif .if defined(_SKIP_DEPEND) || defined(_meta_filemon) .MAKE.DEPENDFILE= /dev/null .endif kernel-depend: .depend SRCS= assym.s vnode_if.h ${BEFORE_DEPEND} ${CFILES} \ ${SYSTEM_CFILES} ${GEN_CFILES} ${SFILES} \ ${MFILES:T:S/.m$/.h/} DEPENDFILES= .depend .depend.* DEPENDOBJS+= ${SYSTEM_OBJS} genassym.o DEPENDFILES_OBJS= ${DEPENDOBJS:O:u:C/^/.depend./} .if ${MAKE_VERSION} < 20160220 DEPEND_MP?= -MP .endif .if defined(_SKIP_DEPEND) # Don't bother reading any .meta files ${DEPENDOBJS}: .NOMETA .depend: .NOMETA # Unset these to avoid looping/statting on them later. .undef DEPENDSRCS .undef DEPENDOBJS .undef DEPENDFILES_OBJS .endif # defined(_SKIP_DEPEND) DEPEND_CFLAGS+= -MD ${DEPEND_MP} -MF.depend.${.TARGET} DEPEND_CFLAGS+= -MT${.TARGET} .if !defined(_meta_filemon) -.if defined(.PARSEDIR) +.if !empty(DEPEND_CFLAGS) # Only add in DEPEND_CFLAGS for CFLAGS on files we expect from DEPENDOBJS # as those are the only ones we will include. DEPEND_CFLAGS_CONDITION= "${DEPENDOBJS:M${.TARGET}}" != "" CFLAGS+= ${${DEPEND_CFLAGS_CONDITION}:?${DEPEND_CFLAGS}:} -.else -CFLAGS+= ${DEPEND_CFLAGS} .endif .for __depend_obj in ${DEPENDFILES_OBJS} .if ${MAKE_VERSION} < 20160220 .sinclude "${.OBJDIR}/${__depend_obj}" .else .dinclude "${.OBJDIR}/${__depend_obj}" .endif .endfor .endif # !defined(_meta_filemon) # Always run 'make depend' to generate dependencies early and to avoid the # need for manually running it. For the kernel this is mostly a NOP since # all dependencies are correctly added or accounted for. This is mostly to # ensure downstream uses of kernel-depend are handled. beforebuild: kernel-depend # Guess some dependencies for when no ${DEPENDFILE}.OBJ is generated yet. # For meta+filemon the .meta file is checked for since it is the dependency # file used. .for __obj in ${DEPENDOBJS:O:u} -.if (defined(_meta_filemon) && !exists(${.OBJDIR}/${__obj}.meta)) || \ - (!defined(_meta_filemon) && !exists(${.OBJDIR}/.depend.${__obj})) +.if defined(_meta_filemon) +_depfile= ${.OBJDIR}/${__obj}.meta +.else +_depfile= ${.OBJDIR}/.depend.${__obj} +.endif +.if !exists(${_depfile}) .if ${SYSTEM_OBJS:M${__obj}} ${__obj}: ${OBJS_DEPEND_GUESS} .endif ${__obj}: ${OBJS_DEPEND_GUESS.${__obj}} .elif defined(_meta_filemon) # For meta mode we still need to know which file to depend on to avoid # ambiguous suffix transformation rules from .PATH. Meta mode does not # use .depend files. We really only need source files, not headers since # they are typically in SRCS/beforebuild already. For target-specific # guesses do include headers though since they may not be in SRCS. .if ${SYSTEM_OBJS:M${__obj}} ${__obj}: ${OBJS_DEPEND_GUESS:N*.h} .endif ${__obj}: ${OBJS_DEPEND_GUESS.${__obj}} -.endif +.endif # !exists(${_depfile}) .endfor .NOPATH: .depend ${DEPENDFILES_OBJS} .depend: .PRECIOUS ${SRCS} _ILINKS= machine .if ${MACHINE} != ${MACHINE_CPUARCH} && ${MACHINE} != "arm64" _ILINKS+= ${MACHINE_CPUARCH} .endif .if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" _ILINKS+= x86 .endif # Ensure that the link exists without depending on it when it exists. .for _link in ${_ILINKS} .if !exists(${.OBJDIR}/${_link}) ${SRCS} ${CLEAN:M*.o}: ${_link} .endif .endfor ${_ILINKS}: @case ${.TARGET} in \ machine) \ path=${S}/${MACHINE}/include ;; \ *) \ path=${S}/${.TARGET}/include ;; \ esac ; \ ${ECHO} ${.TARGET} "->" $$path ; \ ln -fhs $$path ${.TARGET} # .depend needs include links so we remove them only together. kernel-cleandepend: .PHONY rm -f ${DEPENDFILES} ${_ILINKS} kernel-tags: @[ -f .depend ] || { echo "you must make depend first"; exit 1; } sh $S/conf/systags.sh kernel-install: .PHONY @if [ ! -f ${KERNEL_KO} ] ; then \ echo "You must build a kernel first." ; \ exit 1 ; \ fi .if exists(${DESTDIR}${KODIR}) -thiskernel=`sysctl -n kern.bootfile` ; \ if [ ! "`dirname "$$thiskernel"`" -ef ${DESTDIR}${KODIR} ] ; then \ chflags -R noschg ${DESTDIR}${KODIR} ; \ rm -rf ${DESTDIR}${KODIR} ; \ rm -rf ${DESTDIR}${KERN_DEBUGDIR}${KODIR} ; \ else \ if [ -d ${DESTDIR}${KODIR}.old ] ; then \ chflags -R noschg ${DESTDIR}${KODIR}.old ; \ rm -rf ${DESTDIR}${KODIR}.old ; \ fi ; \ mv ${DESTDIR}${KODIR} ${DESTDIR}${KODIR}.old ; \ if [ -n "${KERN_DEBUGDIR}" -a \ -d ${DESTDIR}${KERN_DEBUGDIR}${KODIR} ]; then \ rm -rf ${DESTDIR}${KERN_DEBUGDIR}${KODIR}.old ; \ mv ${DESTDIR}${KERN_DEBUGDIR}${KODIR} ${DESTDIR}${KERN_DEBUGDIR}${KODIR}.old ; \ fi ; \ sysctl kern.bootfile=${DESTDIR}${KODIR}.old/"`basename "$$thiskernel"`" ; \ fi .endif mkdir -p ${DESTDIR}${KODIR} ${INSTALL} -p -m 555 -o ${KMODOWN} -g ${KMODGRP} ${KERNEL_KO} ${DESTDIR}${KODIR}/ .if defined(DEBUG) && !defined(INSTALL_NODEBUG) && ${MK_KERNEL_SYMBOLS} != "no" mkdir -p ${DESTDIR}${KERN_DEBUGDIR}${KODIR} ${INSTALL} -p -m 555 -o ${KMODOWN} -g ${KMODGRP} ${KERNEL_KO}.debug ${DESTDIR}${KERN_DEBUGDIR}${KODIR}/ .endif .if defined(KERNEL_EXTRA_INSTALL) ${INSTALL} -p -m 555 -o ${KMODOWN} -g ${KMODGRP} ${KERNEL_EXTRA_INSTALL} ${DESTDIR}${KODIR}/ .endif kernel-reinstall: @-chflags -R noschg ${DESTDIR}${KODIR} ${INSTALL} -p -m 555 -o ${KMODOWN} -g ${KMODGRP} ${KERNEL_KO} ${DESTDIR}${KODIR}/ .if defined(DEBUG) && !defined(INSTALL_NODEBUG) && ${MK_KERNEL_SYMBOLS} != "no" ${INSTALL} -p -m 555 -o ${KMODOWN} -g ${KMODGRP} ${KERNEL_KO}.debug ${DESTDIR}${KERN_DEBUGDIR}${KODIR}/ .endif config.o env.o hints.o vers.o vnode_if.o: ${NORMAL_C} ${NORMAL_CTFCONVERT} config.ln env.ln hints.ln vers.ln vnode_if.ln: ${NORMAL_LINT} .if ${MK_REPRODUCIBLE_BUILD} != "no" REPRO_FLAG="-r" .endif vers.c: $S/conf/newvers.sh $S/sys/param.h ${SYSTEM_DEP} MAKE=${MAKE} sh $S/conf/newvers.sh ${REPRO_FLAG} ${KERN_IDENT} vnode_if.c: $S/tools/vnode_if.awk $S/kern/vnode_if.src ${AWK} -f $S/tools/vnode_if.awk $S/kern/vnode_if.src -c vnode_if.h vnode_if_newproto.h vnode_if_typedef.h: $S/tools/vnode_if.awk \ $S/kern/vnode_if.src vnode_if.h: vnode_if_newproto.h vnode_if_typedef.h ${AWK} -f $S/tools/vnode_if.awk $S/kern/vnode_if.src -h vnode_if_newproto.h: ${AWK} -f $S/tools/vnode_if.awk $S/kern/vnode_if.src -p vnode_if_typedef.h: ${AWK} -f $S/tools/vnode_if.awk $S/kern/vnode_if.src -q .if ${MFS_IMAGE:Uno} != "no" .if empty(MD_ROOT_SIZE_CONFIGURED) # Generate an object file from the file system image to embed in the kernel # via linking. Make sure the contents are in the mfs section and rename the # start/end/size variables to __start_mfs, __stop_mfs, and mfs_size, # respectively. embedfs_${MFS_IMAGE:T:R}.o: ${MFS_IMAGE} ${OBJCOPY} --input-target binary \ --output-target ${EMBEDFS_FORMAT.${MACHINE_ARCH}} \ --binary-architecture ${EMBEDFS_ARCH.${MACHINE_ARCH}} \ ${MFS_IMAGE} ${.TARGET} ${OBJCOPY} \ --rename-section .data=mfs,contents,alloc,load,readonly,data \ --redefine-sym \ _binary_${MFS_IMAGE:C,[^[:alnum:]],_,g}_size=__mfs_root_size \ --redefine-sym \ _binary_${MFS_IMAGE:C,[^[:alnum:]],_,g}_start=mfs_root \ --redefine-sym \ _binary_${MFS_IMAGE:C,[^[:alnum:]],_,g}_end=mfs_root_end \ ${.TARGET} .endif .endif # XXX strictly, everything depends on Makefile because changes to ${PROF} # only appear there, but we don't handle that. .include "kern.mk" Index: projects/runtime-coverage/sys/dev/cxgbe/common/common.h =================================================================== --- projects/runtime-coverage/sys/dev/cxgbe/common/common.h (revision 321457) +++ projects/runtime-coverage/sys/dev/cxgbe/common/common.h (revision 321458) @@ -1,823 +1,832 @@ /*- * Copyright (c) 2011 Chelsio Communications, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ * */ #ifndef __CHELSIO_COMMON_H #define __CHELSIO_COMMON_H #include "t4_hw.h" #define GLBL_INTR_MASK (F_CIM | F_MPS | F_PL | F_PCIE | F_MC0 | F_EDC0 | \ F_EDC1 | F_LE | F_TP | F_MA | F_PM_TX | F_PM_RX | F_ULP_RX | \ F_CPL_SWITCH | F_SGE | F_ULP_TX) enum { MAX_NPORTS = 4, /* max # of ports */ SERNUM_LEN = 24, /* Serial # length */ EC_LEN = 16, /* E/C length */ ID_LEN = 16, /* ID length */ PN_LEN = 16, /* Part Number length */ MACADDR_LEN = 12, /* MAC Address length */ }; enum { T4_REGMAP_SIZE = (160 * 1024), T5_REGMAP_SIZE = (332 * 1024), }; enum { MEM_EDC0, MEM_EDC1, MEM_MC, MEM_MC0 = MEM_MC, MEM_MC1 }; enum dev_master { MASTER_CANT, MASTER_MAY, MASTER_MUST }; enum dev_state { DEV_STATE_UNINIT, DEV_STATE_INIT, DEV_STATE_ERR }; enum { PAUSE_RX = 1 << 0, PAUSE_TX = 1 << 1, PAUSE_AUTONEG = 1 << 2 }; enum { FEC_RS = 1 << 0, FEC_BASER_RS = 1 << 1, FEC_RESERVED = 1 << 2, }; struct port_stats { u64 tx_octets; /* total # of octets in good frames */ u64 tx_frames; /* all good frames */ u64 tx_bcast_frames; /* all broadcast frames */ u64 tx_mcast_frames; /* all multicast frames */ u64 tx_ucast_frames; /* all unicast frames */ u64 tx_error_frames; /* all error frames */ u64 tx_frames_64; /* # of Tx frames in a particular range */ u64 tx_frames_65_127; u64 tx_frames_128_255; u64 tx_frames_256_511; u64 tx_frames_512_1023; u64 tx_frames_1024_1518; u64 tx_frames_1519_max; u64 tx_drop; /* # of dropped Tx frames */ u64 tx_pause; /* # of transmitted pause frames */ u64 tx_ppp0; /* # of transmitted PPP prio 0 frames */ u64 tx_ppp1; /* # of transmitted PPP prio 1 frames */ u64 tx_ppp2; /* # of transmitted PPP prio 2 frames */ u64 tx_ppp3; /* # of transmitted PPP prio 3 frames */ u64 tx_ppp4; /* # of transmitted PPP prio 4 frames */ u64 tx_ppp5; /* # of transmitted PPP prio 5 frames */ u64 tx_ppp6; /* # of transmitted PPP prio 6 frames */ u64 tx_ppp7; /* # of transmitted PPP prio 7 frames */ u64 rx_octets; /* total # of octets in good frames */ u64 rx_frames; /* all good frames */ u64 rx_bcast_frames; /* all broadcast frames */ u64 rx_mcast_frames; /* all multicast frames */ u64 rx_ucast_frames; /* all unicast frames */ u64 rx_too_long; /* # of frames exceeding MTU */ u64 rx_jabber; /* # of jabber frames */ u64 rx_fcs_err; /* # of received frames with bad FCS */ u64 rx_len_err; /* # of received frames with length error */ u64 rx_symbol_err; /* symbol errors */ u64 rx_runt; /* # of short frames */ u64 rx_frames_64; /* # of Rx frames in a particular range */ u64 rx_frames_65_127; u64 rx_frames_128_255; u64 rx_frames_256_511; u64 rx_frames_512_1023; u64 rx_frames_1024_1518; u64 rx_frames_1519_max; u64 rx_pause; /* # of received pause frames */ u64 rx_ppp0; /* # of received PPP prio 0 frames */ u64 rx_ppp1; /* # of received PPP prio 1 frames */ u64 rx_ppp2; /* # of received PPP prio 2 frames */ u64 rx_ppp3; /* # of received PPP prio 3 frames */ u64 rx_ppp4; /* # of received PPP prio 4 frames */ u64 rx_ppp5; /* # of received PPP prio 5 frames */ u64 rx_ppp6; /* # of received PPP prio 6 frames */ u64 rx_ppp7; /* # of received PPP prio 7 frames */ u64 rx_ovflow0; /* drops due to buffer-group 0 overflows */ u64 rx_ovflow1; /* drops due to buffer-group 1 overflows */ u64 rx_ovflow2; /* drops due to buffer-group 2 overflows */ u64 rx_ovflow3; /* drops due to buffer-group 3 overflows */ u64 rx_trunc0; /* buffer-group 0 truncated packets */ u64 rx_trunc1; /* buffer-group 1 truncated packets */ u64 rx_trunc2; /* buffer-group 2 truncated packets */ u64 rx_trunc3; /* buffer-group 3 truncated packets */ }; struct lb_port_stats { u64 octets; u64 frames; u64 bcast_frames; u64 mcast_frames; u64 ucast_frames; u64 error_frames; u64 frames_64; u64 frames_65_127; u64 frames_128_255; u64 frames_256_511; u64 frames_512_1023; u64 frames_1024_1518; u64 frames_1519_max; u64 drop; u64 ovflow0; u64 ovflow1; u64 ovflow2; u64 ovflow3; u64 trunc0; u64 trunc1; u64 trunc2; u64 trunc3; }; struct tp_tcp_stats { u32 tcp_out_rsts; u64 tcp_in_segs; u64 tcp_out_segs; u64 tcp_retrans_segs; }; struct tp_usm_stats { u32 frames; u32 drops; u64 octets; }; struct tp_fcoe_stats { u32 frames_ddp; u32 frames_drop; u64 octets_ddp; }; struct tp_err_stats { u32 mac_in_errs[MAX_NCHAN]; u32 hdr_in_errs[MAX_NCHAN]; u32 tcp_in_errs[MAX_NCHAN]; u32 tnl_cong_drops[MAX_NCHAN]; u32 ofld_chan_drops[MAX_NCHAN]; u32 tnl_tx_drops[MAX_NCHAN]; u32 ofld_vlan_drops[MAX_NCHAN]; u32 tcp6_in_errs[MAX_NCHAN]; u32 ofld_no_neigh; u32 ofld_cong_defer; }; struct tp_proxy_stats { u32 proxy[MAX_NCHAN]; }; struct tp_cpl_stats { u32 req[MAX_NCHAN]; u32 rsp[MAX_NCHAN]; }; struct tp_rdma_stats { u32 rqe_dfr_pkt; u32 rqe_dfr_mod; }; struct sge_params { int timer_val[SGE_NTIMERS]; /* final, scaled values */ int counter_val[SGE_NCOUNTERS]; int fl_starve_threshold; int fl_starve_threshold2; int page_shift; int eq_s_qpp; int iq_s_qpp; int spg_len; int pad_boundary; int pack_boundary; int fl_pktshift; u32 sge_control; u32 sge_fl_buffer_size[SGE_FLBUF_SIZES]; }; struct tp_params { unsigned int tre; /* log2 of core clocks per TP tick */ unsigned int dack_re; /* DACK timer resolution */ unsigned int la_mask; /* what events are recorded by TP LA */ unsigned short tx_modq[MAX_NCHAN]; /* channel to modulation queue map */ uint32_t vlan_pri_map; uint32_t ingress_config; __be16 err_vec_mask; int8_t fcoe_shift; int8_t port_shift; int8_t vnic_shift; int8_t vlan_shift; int8_t tos_shift; int8_t protocol_shift; int8_t ethertype_shift; int8_t macmatch_shift; int8_t matchtype_shift; int8_t frag_shift; }; struct vpd_params { unsigned int cclk; u8 ec[EC_LEN + 1]; u8 sn[SERNUM_LEN + 1]; u8 id[ID_LEN + 1]; u8 pn[PN_LEN + 1]; u8 na[MACADDR_LEN + 1]; }; struct pci_params { unsigned int vpd_cap_addr; unsigned int mps; unsigned short speed; unsigned short width; }; /* * Firmware device log. */ struct devlog_params { u32 memtype; /* which memory (FW_MEMTYPE_* ) */ u32 start; /* start of log in firmware memory */ u32 size; /* size of log */ u32 addr; /* start address in flat addr space */ }; /* Stores chip specific parameters */ struct chip_params { u8 nchan; u8 pm_stats_cnt; u8 cng_ch_bits_log; /* congestion channel map bits width */ u8 nsched_cls; u8 cim_num_obq; u16 mps_rplc_size; u16 vfcount; u32 sge_fl_db; u16 mps_tcam_size; }; /* VF-only parameters. */ /* * Global Receive Side Scaling (RSS) parameters in host-native format. */ struct rss_params { unsigned int mode; /* RSS mode */ union { struct { u_int synmapen:1; /* SYN Map Enable */ u_int syn4tupenipv6:1; /* enable hashing 4-tuple IPv6 SYNs */ u_int syn2tupenipv6:1; /* enable hashing 2-tuple IPv6 SYNs */ u_int syn4tupenipv4:1; /* enable hashing 4-tuple IPv4 SYNs */ u_int syn2tupenipv4:1; /* enable hashing 2-tuple IPv4 SYNs */ u_int ofdmapen:1; /* Offload Map Enable */ u_int tnlmapen:1; /* Tunnel Map Enable */ u_int tnlalllookup:1; /* Tunnel All Lookup */ u_int hashtoeplitz:1; /* use Toeplitz hash */ } basicvirtual; } u; }; /* * Maximum resources provisioned for a PCI VF. */ struct vf_resources { unsigned int nvi; /* N virtual interfaces */ unsigned int neq; /* N egress Qs */ unsigned int nethctrl; /* N egress ETH or CTRL Qs */ unsigned int niqflint; /* N ingress Qs/w free list(s) & intr */ unsigned int niq; /* N ingress Qs */ unsigned int tc; /* PCI-E traffic class */ unsigned int pmask; /* port access rights mask */ unsigned int nexactf; /* N exact MPS filters */ unsigned int r_caps; /* read capabilities */ unsigned int wx_caps; /* write/execute capabilities */ }; struct adapter_params { struct sge_params sge; struct tp_params tp; /* PF-only */ struct vpd_params vpd; struct pci_params pci; struct devlog_params devlog; /* PF-only */ struct rss_params rss; /* VF-only */ struct vf_resources vfres; /* VF-only */ unsigned int sf_size; /* serial flash size in bytes */ unsigned int sf_nsec; /* # of flash sectors */ unsigned int fw_vers; /* firmware version */ unsigned int bs_vers; /* bootstrap version */ unsigned int tp_vers; /* TP microcode version */ unsigned int er_vers; /* expansion ROM version */ unsigned int scfg_vers; /* Serial Configuration version */ unsigned int vpd_vers; /* VPD version */ unsigned short mtus[NMTUS]; unsigned short a_wnd[NCCTRL_WIN]; unsigned short b_wnd[NCCTRL_WIN]; u_int ftid_min; u_int ftid_max; u_int etid_min; u_int netids; unsigned int cim_la_size; uint8_t nports; /* # of ethernet ports */ uint8_t portvec; unsigned int chipid:4; /* chip ID. T4 = 4, T5 = 5, ... */ unsigned int rev:4; /* chip revision */ unsigned int fpga:1; /* this is an FPGA */ unsigned int offload:1; /* hw is TOE capable, fw has divvied up card resources for TOE operation. */ unsigned int bypass:1; /* this is a bypass card */ unsigned int ethoffload:1; unsigned int ofldq_wr_cred; unsigned int eo_wr_cred; unsigned int max_ordird_qp; unsigned int max_ird_adapter; }; #define CHELSIO_T4 0x4 #define CHELSIO_T5 0x5 #define CHELSIO_T6 0x6 /* * State needed to monitor the forward progress of SGE Ingress DMA activities * and possible hangs. */ struct sge_idma_monitor_state { unsigned int idma_1s_thresh; /* 1s threshold in Core Clock ticks */ unsigned int idma_stalled[2]; /* synthesized stalled timers in HZ */ unsigned int idma_state[2]; /* IDMA Hang detect state */ unsigned int idma_qid[2]; /* IDMA Hung Ingress Queue ID */ unsigned int idma_warn[2]; /* time to warning in HZ */ }; struct trace_params { u32 data[TRACE_LEN / 4]; u32 mask[TRACE_LEN / 4]; unsigned short snap_len; unsigned short min_len; unsigned char skip_ofst; unsigned char skip_len; unsigned char invert; unsigned char port; }; struct link_config { /* OS-specific code owns all the requested_* fields */ unsigned char requested_aneg; /* link aneg user has requested */ unsigned char requested_fc; /* flow control user has requested */ unsigned char requested_fec; /* FEC user has requested */ unsigned int requested_speed; /* speed user has requested */ unsigned short supported; /* link capabilities */ unsigned short advertising; /* advertised capabilities */ unsigned short lp_advertising; /* peer advertised capabilities */ unsigned int speed; /* actual link speed */ unsigned char fc; /* actual link flow control */ unsigned char fec; /* actual FEC */ unsigned char link_ok; /* link up? */ unsigned char link_down_rc; /* link down reason */ }; #include "adapter.h" #ifndef PCI_VENDOR_ID_CHELSIO # define PCI_VENDOR_ID_CHELSIO 0x1425 #endif #define for_each_port(adapter, iter) \ for (iter = 0; iter < (adapter)->params.nports; ++iter) static inline int is_ftid(const struct adapter *sc, u_int tid) { return (tid >= sc->params.ftid_min && tid <= sc->params.ftid_max); } static inline int is_etid(const struct adapter *sc, u_int tid) { return (tid >= sc->params.etid_min); } static inline int is_offload(const struct adapter *adap) { return adap->params.offload; } static inline int is_ethoffload(const struct adapter *adap) { return adap->params.ethoffload; } static inline int chip_id(struct adapter *adap) { return adap->params.chipid; } static inline int chip_rev(struct adapter *adap) { return adap->params.rev; } static inline int is_t4(struct adapter *adap) { return adap->params.chipid == CHELSIO_T4; } static inline int is_t5(struct adapter *adap) { return adap->params.chipid == CHELSIO_T5; } static inline int is_t6(struct adapter *adap) { return adap->params.chipid == CHELSIO_T6; } static inline int is_fpga(struct adapter *adap) { return adap->params.fpga; } static inline unsigned int core_ticks_per_usec(const struct adapter *adap) { return adap->params.vpd.cclk / 1000; } static inline unsigned int us_to_core_ticks(const struct adapter *adap, unsigned int us) { return (us * adap->params.vpd.cclk) / 1000; } static inline unsigned int core_ticks_to_us(const struct adapter *adapter, unsigned int ticks) { /* add Core Clock / 2 to round ticks to nearest uS */ return ((ticks * 1000 + adapter->params.vpd.cclk/2) / adapter->params.vpd.cclk); } static inline unsigned int dack_ticks_to_usec(const struct adapter *adap, unsigned int ticks) { return (ticks << adap->params.tp.dack_re) / core_ticks_per_usec(adap); } +static inline u_int ms_to_tcp_ticks(const struct adapter *adap, u_int ms) +{ + u_long l; + + l = (u_long)ms * adap->params.vpd.cclk >> adap->params.tp.tre; + + return (l); +} + void t4_set_reg_field(struct adapter *adap, unsigned int addr, u32 mask, u32 val); int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd, int size, void *rpl, bool sleep_ok, int timeout); int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size, void *rpl, bool sleep_ok); static inline int t4_wr_mbox_timeout(struct adapter *adap, int mbox, const void *cmd, int size, void *rpl, int timeout) { return t4_wr_mbox_meat_timeout(adap, mbox, cmd, size, rpl, true, timeout); } static inline int t4_wr_mbox(struct adapter *adap, int mbox, const void *cmd, int size, void *rpl) { return t4_wr_mbox_meat(adap, mbox, cmd, size, rpl, true); } static inline int t4_wr_mbox_ns(struct adapter *adap, int mbox, const void *cmd, int size, void *rpl) { return t4_wr_mbox_meat(adap, mbox, cmd, size, rpl, false); } void t4_read_indirect(struct adapter *adap, unsigned int addr_reg, unsigned int data_reg, u32 *vals, unsigned int nregs, unsigned int start_idx); void t4_write_indirect(struct adapter *adap, unsigned int addr_reg, unsigned int data_reg, const u32 *vals, unsigned int nregs, unsigned int start_idx); u32 t4_hw_pci_read_cfg4(adapter_t *adapter, int reg); struct fw_filter_wr; void t4_intr_enable(struct adapter *adapter); void t4_intr_disable(struct adapter *adapter); void t4_intr_clear(struct adapter *adapter); int t4_slow_intr_handler(struct adapter *adapter); int t4_hash_mac_addr(const u8 *addr); int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port, struct link_config *lc); int t4_restart_aneg(struct adapter *adap, unsigned int mbox, unsigned int port); int t4_seeprom_read(struct adapter *adapter, u32 addr, u32 *data); int t4_seeprom_write(struct adapter *adapter, u32 addr, u32 data); int t4_eeprom_ptov(unsigned int phys_addr, unsigned int fn, unsigned int sz); int t4_seeprom_wp(struct adapter *adapter, int enable); int t4_read_flash(struct adapter *adapter, unsigned int addr, unsigned int nwords, u32 *data, int byte_oriented); int t4_write_flash(struct adapter *adapter, unsigned int addr, unsigned int n, const u8 *data, int byte_oriented); int t4_load_fw(struct adapter *adapter, const u8 *fw_data, unsigned int size); int t4_fwcache(struct adapter *adap, enum fw_params_param_dev_fwcache op); int t5_fw_init_extern_mem(struct adapter *adap); int t4_load_bootcfg(struct adapter *adapter, const u8 *cfg_data, unsigned int size); int t4_load_boot(struct adapter *adap, u8 *boot_data, unsigned int boot_addr, unsigned int size); int t4_flash_erase_sectors(struct adapter *adapter, int start, int end); int t4_flash_cfg_addr(struct adapter *adapter); int t4_load_cfg(struct adapter *adapter, const u8 *cfg_data, unsigned int size); int t4_get_fw_version(struct adapter *adapter, u32 *vers); int t4_get_bs_version(struct adapter *adapter, u32 *vers); int t4_get_tp_version(struct adapter *adapter, u32 *vers); int t4_get_exprom_version(struct adapter *adapter, u32 *vers); int t4_get_scfg_version(struct adapter *adapter, u32 *vers); int t4_get_vpd_version(struct adapter *adapter, u32 *vers); int t4_get_version_info(struct adapter *adapter); int t4_init_hw(struct adapter *adapter, u32 fw_params); const struct chip_params *t4_get_chip_params(int chipid); int t4_prep_adapter(struct adapter *adapter, u8 *buf); int t4_shutdown_adapter(struct adapter *adapter); int t4_init_devlog_params(struct adapter *adapter, int fw_attach); int t4_init_sge_params(struct adapter *adapter); int t4_init_tp_params(struct adapter *adap); int t4_filter_field_shift(const struct adapter *adap, int filter_sel); int t4_port_init(struct adapter *adap, int mbox, int pf, int vf, int port_id); void t4_fatal_err(struct adapter *adapter); void t4_db_full(struct adapter *adapter); void t4_db_dropped(struct adapter *adapter); int t4_set_trace_filter(struct adapter *adapter, const struct trace_params *tp, int filter_index, int enable); void t4_get_trace_filter(struct adapter *adapter, struct trace_params *tp, int filter_index, int *enabled); int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid, int start, int n, const u16 *rspq, unsigned int nrspq); int t4_config_glbl_rss(struct adapter *adapter, int mbox, unsigned int mode, unsigned int flags); int t4_config_vi_rss(struct adapter *adapter, int mbox, unsigned int viid, unsigned int flags, unsigned int defq, unsigned int skeyidx, unsigned int skey); int t4_read_rss(struct adapter *adapter, u16 *entries); void t4_fw_tp_pio_rw(struct adapter *adap, u32 *vals, unsigned int nregs, unsigned int start_index, unsigned int rw); void t4_read_rss_key(struct adapter *adapter, u32 *key); void t4_write_rss_key(struct adapter *adap, u32 *key, int idx); void t4_read_rss_pf_config(struct adapter *adapter, unsigned int index, u32 *valp); void t4_write_rss_pf_config(struct adapter *adapter, unsigned int index, u32 val); void t4_read_rss_vf_config(struct adapter *adapter, unsigned int index, u32 *vfl, u32 *vfh); void t4_write_rss_vf_config(struct adapter *adapter, unsigned int index, u32 vfl, u32 vfh); u32 t4_read_rss_pf_map(struct adapter *adapter); void t4_write_rss_pf_map(struct adapter *adapter, u32 pfmap); u32 t4_read_rss_pf_mask(struct adapter *adapter); void t4_write_rss_pf_mask(struct adapter *adapter, u32 pfmask); int t4_mps_set_active_ports(struct adapter *adap, unsigned int port_mask); void t4_pmtx_get_stats(struct adapter *adap, u32 cnt[], u64 cycles[]); void t4_pmrx_get_stats(struct adapter *adap, u32 cnt[], u64 cycles[]); void t4_read_cimq_cfg(struct adapter *adap, u16 *base, u16 *size, u16 *thres); int t4_read_cim_ibq(struct adapter *adap, unsigned int qid, u32 *data, size_t n); int t4_read_cim_obq(struct adapter *adap, unsigned int qid, u32 *data, size_t n); int t4_cim_read(struct adapter *adap, unsigned int addr, unsigned int n, unsigned int *valp); int t4_cim_write(struct adapter *adap, unsigned int addr, unsigned int n, const unsigned int *valp); int t4_cim_ctl_read(struct adapter *adap, unsigned int addr, unsigned int n, unsigned int *valp); int t4_cim_read_la(struct adapter *adap, u32 *la_buf, unsigned int *wrptr); void t4_cim_read_pif_la(struct adapter *adap, u32 *pif_req, u32 *pif_rsp, unsigned int *pif_req_wrptr, unsigned int *pif_rsp_wrptr); void t4_cim_read_ma_la(struct adapter *adap, u32 *ma_req, u32 *ma_rsp); int t4_get_flash_params(struct adapter *adapter); u32 t4_read_pcie_cfg4(struct adapter *adap, int reg, int drv_fw_attach); int t4_mc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *parity); int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *parity); int t4_mem_read(struct adapter *adap, int mtype, u32 addr, u32 size, __be32 *data); void t4_idma_monitor_init(struct adapter *adapter, struct sge_idma_monitor_state *idma); void t4_idma_monitor(struct adapter *adapter, struct sge_idma_monitor_state *idma, int hz, int ticks); unsigned int t4_get_regs_len(struct adapter *adapter); void t4_get_regs(struct adapter *adap, u8 *buf, size_t buf_size); const char *t4_get_port_type_description(enum fw_port_type port_type); void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p); void t4_get_port_stats_offset(struct adapter *adap, int idx, struct port_stats *stats, struct port_stats *offset); void t4_get_lb_stats(struct adapter *adap, int idx, struct lb_port_stats *p); void t4_clr_port_stats(struct adapter *adap, int idx); void t4_read_mtu_tbl(struct adapter *adap, u16 *mtus, u8 *mtu_log); void t4_read_cong_tbl(struct adapter *adap, u16 incr[NMTUS][NCCTRL_WIN]); void t4_read_pace_tbl(struct adapter *adap, unsigned int pace_vals[NTX_SCHED]); void t4_get_tx_sched(struct adapter *adap, unsigned int sched, unsigned int *kbps, unsigned int *ipg); void t4_tp_wr_bits_indirect(struct adapter *adap, unsigned int addr, unsigned int mask, unsigned int val); void t4_tp_read_la(struct adapter *adap, u64 *la_buf, unsigned int *wrptr); void t4_tp_get_err_stats(struct adapter *adap, struct tp_err_stats *st); void t4_tp_get_proxy_stats(struct adapter *adap, struct tp_proxy_stats *st); void t4_tp_get_cpl_stats(struct adapter *adap, struct tp_cpl_stats *st); void t4_tp_get_rdma_stats(struct adapter *adap, struct tp_rdma_stats *st); void t4_get_usm_stats(struct adapter *adap, struct tp_usm_stats *st); void t4_tp_get_tcp_stats(struct adapter *adap, struct tp_tcp_stats *v4, struct tp_tcp_stats *v6); void t4_get_fcoe_stats(struct adapter *adap, unsigned int idx, struct tp_fcoe_stats *st); void t4_load_mtus(struct adapter *adap, const unsigned short *mtus, const unsigned short *alpha, const unsigned short *beta); void t4_ulprx_read_la(struct adapter *adap, u32 *la_buf); int t4_set_sched_bps(struct adapter *adap, int sched, unsigned int kbps); int t4_set_sched_ipg(struct adapter *adap, int sched, unsigned int ipg); int t4_set_pace_tbl(struct adapter *adap, const unsigned int *pace_vals, unsigned int start, unsigned int n); void t4_get_chan_txrate(struct adapter *adap, u64 *nic_rate, u64 *ofld_rate); int t4_set_filter_mode(struct adapter *adap, unsigned int mode_map); void t4_mk_filtdelwr(unsigned int ftid, struct fw_filter_wr *wr, int qid); void t4_wol_magic_enable(struct adapter *adap, unsigned int port, const u8 *addr); int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map, u64 mask0, u64 mask1, unsigned int crc, bool enable); int t4_fw_hello(struct adapter *adap, unsigned int mbox, unsigned int evt_mbox, enum dev_master master, enum dev_state *state); int t4_fw_bye(struct adapter *adap, unsigned int mbox); int t4_fw_reset(struct adapter *adap, unsigned int mbox, int reset); int t4_fw_halt(struct adapter *adap, unsigned int mbox, int force); int t4_fw_restart(struct adapter *adap, unsigned int mbox, int reset); int t4_fw_upgrade(struct adapter *adap, unsigned int mbox, const u8 *fw_data, unsigned int size, int force); int t4_fw_forceinstall(struct adapter *adap, const u8 *fw_data, unsigned int size); int t4_fw_initialize(struct adapter *adap, unsigned int mbox); int t4_query_params(struct adapter *adap, unsigned int mbox, unsigned int pf, unsigned int vf, unsigned int nparams, const u32 *params, u32 *val); int t4_query_params_rw(struct adapter *adap, unsigned int mbox, unsigned int pf, unsigned int vf, unsigned int nparams, const u32 *params, u32 *val, int rw); int t4_set_params_timeout(struct adapter *adap, unsigned int mbox, unsigned int pf, unsigned int vf, unsigned int nparams, const u32 *params, const u32 *val, int timeout); int t4_set_params(struct adapter *adap, unsigned int mbox, unsigned int pf, unsigned int vf, unsigned int nparams, const u32 *params, const u32 *val); int t4_cfg_pfvf(struct adapter *adap, unsigned int mbox, unsigned int pf, unsigned int vf, unsigned int txq, unsigned int txq_eth_ctrl, unsigned int rxqi, unsigned int rxq, unsigned int tc, unsigned int vi, unsigned int cmask, unsigned int pmask, unsigned int exactf, unsigned int rcaps, unsigned int wxcaps); int t4_alloc_vi_func(struct adapter *adap, unsigned int mbox, unsigned int port, unsigned int pf, unsigned int vf, unsigned int nmac, u8 *mac, u16 *rss_size, unsigned int portfunc, unsigned int idstype); int t4_alloc_vi(struct adapter *adap, unsigned int mbox, unsigned int port, unsigned int pf, unsigned int vf, unsigned int nmac, u8 *mac, u16 *rss_size); int t4_free_vi(struct adapter *adap, unsigned int mbox, unsigned int pf, unsigned int vf, unsigned int viid); int t4_set_rxmode(struct adapter *adap, unsigned int mbox, unsigned int viid, int mtu, int promisc, int all_multi, int bcast, int vlanex, bool sleep_ok); int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox, unsigned int viid, bool free, unsigned int naddr, const u8 **addr, u16 *idx, u64 *hash, bool sleep_ok); int t4_change_mac(struct adapter *adap, unsigned int mbox, unsigned int viid, int idx, const u8 *addr, bool persist, bool add_smt); int t4_set_addr_hash(struct adapter *adap, unsigned int mbox, unsigned int viid, bool ucast, u64 vec, bool sleep_ok); int t4_enable_vi_params(struct adapter *adap, unsigned int mbox, unsigned int viid, bool rx_en, bool tx_en, bool dcb_en); int t4_enable_vi(struct adapter *adap, unsigned int mbox, unsigned int viid, bool rx_en, bool tx_en); int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid, unsigned int nblinks); int t4_mdio_rd(struct adapter *adap, unsigned int mbox, unsigned int phy_addr, unsigned int mmd, unsigned int reg, unsigned int *valp); int t4_mdio_wr(struct adapter *adap, unsigned int mbox, unsigned int phy_addr, unsigned int mmd, unsigned int reg, unsigned int val); int t4_i2c_rd(struct adapter *adap, unsigned int mbox, int port, unsigned int devid, unsigned int offset, unsigned int len, u8 *buf); int t4_i2c_wr(struct adapter *adap, unsigned int mbox, int port, unsigned int devid, unsigned int offset, unsigned int len, u8 *buf); int t4_iq_stop(struct adapter *adap, unsigned int mbox, unsigned int pf, unsigned int vf, unsigned int iqtype, unsigned int iqid, unsigned int fl0id, unsigned int fl1id); int t4_iq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, unsigned int vf, unsigned int iqtype, unsigned int iqid, unsigned int fl0id, unsigned int fl1id); int t4_eth_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, unsigned int vf, unsigned int eqid); int t4_ctrl_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, unsigned int vf, unsigned int eqid); int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, unsigned int vf, unsigned int eqid); int t4_sge_ctxt_rd(struct adapter *adap, unsigned int mbox, unsigned int cid, enum ctxt_type ctype, u32 *data); int t4_sge_ctxt_rd_bd(struct adapter *adap, unsigned int cid, enum ctxt_type ctype, u32 *data); int t4_sge_ctxt_flush(struct adapter *adap, unsigned int mbox); const char *t4_link_down_rc_str(unsigned char link_down_rc); int t4_update_port_info(struct port_info *pi); int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl); int t4_fwaddrspace_write(struct adapter *adap, unsigned int mbox, u32 addr, u32 val); int t4_sched_config(struct adapter *adapter, int type, int minmaxen, int sleep_ok); int t4_sched_params(struct adapter *adapter, int type, int level, int mode, int rateunit, int ratemode, int channel, int cl, int minrate, int maxrate, int weight, int pktsize, int sleep_ok); int t4_sched_params_ch_rl(struct adapter *adapter, int channel, int ratemode, unsigned int maxrate, int sleep_ok); int t4_sched_params_cl_wrr(struct adapter *adapter, int channel, int cl, int weight, int sleep_ok); int t4_sched_params_cl_rl_kbps(struct adapter *adapter, int channel, int cl, int mode, unsigned int maxrate, int pktsize, int sleep_ok); int t4_config_watchdog(struct adapter *adapter, unsigned int mbox, unsigned int pf, unsigned int vf, unsigned int timeout, unsigned int action); int t4_get_devlog_level(struct adapter *adapter, unsigned int *level); int t4_set_devlog_level(struct adapter *adapter, unsigned int level); void t4_sge_decode_idma_state(struct adapter *adapter, int state); static inline int t4vf_query_params(struct adapter *adapter, unsigned int nparams, const u32 *params, u32 *vals) { return t4_query_params(adapter, 0, 0, 0, nparams, params, vals); } static inline int t4vf_set_params(struct adapter *adapter, unsigned int nparams, const u32 *params, const u32 *vals) { return t4_set_params(adapter, 0, 0, 0, nparams, params, vals); } static inline int t4vf_wr_mbox(struct adapter *adap, const void *cmd, int size, void *rpl) { return t4_wr_mbox(adap, adap->mbox, cmd, size, rpl); } int t4vf_wait_dev_ready(struct adapter *adapter); int t4vf_fw_reset(struct adapter *adapter); int t4vf_get_sge_params(struct adapter *adapter); int t4vf_get_rss_glb_config(struct adapter *adapter); int t4vf_get_vfres(struct adapter *adapter); int t4vf_prep_adapter(struct adapter *adapter); #endif /* __CHELSIO_COMMON_H */ Index: projects/runtime-coverage/sys/dev/cxgbe/t4_main.c =================================================================== --- projects/runtime-coverage/sys/dev/cxgbe/t4_main.c (revision 321457) +++ projects/runtime-coverage/sys/dev/cxgbe/t4_main.c (revision 321458) @@ -1,9964 +1,10078 @@ /*- * Copyright (c) 2011 Chelsio Communications, Inc. * All rights reserved. * Written by: Navdeep Parhar * * 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 __FBSDID("$FreeBSD$"); #include "opt_ddb.h" #include "opt_inet.h" #include "opt_inet6.h" #include "opt_rss.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef RSS #include #endif #if defined(__i386__) || defined(__amd64__) #include #include #endif #ifdef DDB #include #include #endif #include "common/common.h" #include "common/t4_msg.h" #include "common/t4_regs.h" #include "common/t4_regs_values.h" #include "t4_ioctl.h" #include "t4_l2t.h" #include "t4_mp_ring.h" #include "t4_if.h" /* T4 bus driver interface */ static int t4_probe(device_t); static int t4_attach(device_t); static int t4_detach(device_t); static int t4_ready(device_t); static int t4_read_port_device(device_t, int, device_t *); static device_method_t t4_methods[] = { DEVMETHOD(device_probe, t4_probe), DEVMETHOD(device_attach, t4_attach), DEVMETHOD(device_detach, t4_detach), DEVMETHOD(t4_is_main_ready, t4_ready), DEVMETHOD(t4_read_port_device, t4_read_port_device), DEVMETHOD_END }; static driver_t t4_driver = { "t4nex", t4_methods, sizeof(struct adapter) }; /* T4 port (cxgbe) interface */ static int cxgbe_probe(device_t); static int cxgbe_attach(device_t); static int cxgbe_detach(device_t); device_method_t cxgbe_methods[] = { DEVMETHOD(device_probe, cxgbe_probe), DEVMETHOD(device_attach, cxgbe_attach), DEVMETHOD(device_detach, cxgbe_detach), { 0, 0 } }; static driver_t cxgbe_driver = { "cxgbe", cxgbe_methods, sizeof(struct port_info) }; /* T4 VI (vcxgbe) interface */ static int vcxgbe_probe(device_t); static int vcxgbe_attach(device_t); static int vcxgbe_detach(device_t); static device_method_t vcxgbe_methods[] = { DEVMETHOD(device_probe, vcxgbe_probe), DEVMETHOD(device_attach, vcxgbe_attach), DEVMETHOD(device_detach, vcxgbe_detach), { 0, 0 } }; static driver_t vcxgbe_driver = { "vcxgbe", vcxgbe_methods, sizeof(struct vi_info) }; static d_ioctl_t t4_ioctl; static struct cdevsw t4_cdevsw = { .d_version = D_VERSION, .d_ioctl = t4_ioctl, .d_name = "t4nex", }; /* T5 bus driver interface */ static int t5_probe(device_t); static device_method_t t5_methods[] = { DEVMETHOD(device_probe, t5_probe), DEVMETHOD(device_attach, t4_attach), DEVMETHOD(device_detach, t4_detach), DEVMETHOD(t4_is_main_ready, t4_ready), DEVMETHOD(t4_read_port_device, t4_read_port_device), DEVMETHOD_END }; static driver_t t5_driver = { "t5nex", t5_methods, sizeof(struct adapter) }; /* T5 port (cxl) interface */ static driver_t cxl_driver = { "cxl", cxgbe_methods, sizeof(struct port_info) }; /* T5 VI (vcxl) interface */ static driver_t vcxl_driver = { "vcxl", vcxgbe_methods, sizeof(struct vi_info) }; /* T6 bus driver interface */ static int t6_probe(device_t); static device_method_t t6_methods[] = { DEVMETHOD(device_probe, t6_probe), DEVMETHOD(device_attach, t4_attach), DEVMETHOD(device_detach, t4_detach), DEVMETHOD(t4_is_main_ready, t4_ready), DEVMETHOD(t4_read_port_device, t4_read_port_device), DEVMETHOD_END }; static driver_t t6_driver = { "t6nex", t6_methods, sizeof(struct adapter) }; /* T6 port (cc) interface */ static driver_t cc_driver = { "cc", cxgbe_methods, sizeof(struct port_info) }; /* T6 VI (vcc) interface */ static driver_t vcc_driver = { "vcc", vcxgbe_methods, sizeof(struct vi_info) }; /* ifnet + media interface */ static void cxgbe_init(void *); static int cxgbe_ioctl(struct ifnet *, unsigned long, caddr_t); static int cxgbe_transmit(struct ifnet *, struct mbuf *); static void cxgbe_qflush(struct ifnet *); static int cxgbe_media_change(struct ifnet *); static void cxgbe_media_status(struct ifnet *, struct ifmediareq *); MALLOC_DEFINE(M_CXGBE, "cxgbe", "Chelsio T4/T5 Ethernet driver and services"); /* * Correct lock order when you need to acquire multiple locks is t4_list_lock, * then ADAPTER_LOCK, then t4_uld_list_lock. */ static struct sx t4_list_lock; SLIST_HEAD(, adapter) t4_list; #ifdef TCP_OFFLOAD static struct sx t4_uld_list_lock; SLIST_HEAD(, uld_info) t4_uld_list; #endif /* * Tunables. See tweak_tunables() too. * * Each tunable is set to a default value here if it's known at compile-time. * Otherwise it is set to -n as an indication to tweak_tunables() that it should * provide a reasonable default (upto n) when the driver is loaded. * * Tunables applicable to both T4 and T5 are under hw.cxgbe. Those specific to * T5 are under hw.cxl. */ /* * Number of queues for tx and rx, 10G and 1G, NIC and offload. */ #define NTXQ_10G 16 int t4_ntxq10g = -NTXQ_10G; TUNABLE_INT("hw.cxgbe.ntxq10g", &t4_ntxq10g); #define NRXQ_10G 8 int t4_nrxq10g = -NRXQ_10G; TUNABLE_INT("hw.cxgbe.nrxq10g", &t4_nrxq10g); #define NTXQ_1G 4 int t4_ntxq1g = -NTXQ_1G; TUNABLE_INT("hw.cxgbe.ntxq1g", &t4_ntxq1g); #define NRXQ_1G 2 int t4_nrxq1g = -NRXQ_1G; TUNABLE_INT("hw.cxgbe.nrxq1g", &t4_nrxq1g); #define NTXQ_VI 1 static int t4_ntxq_vi = -NTXQ_VI; TUNABLE_INT("hw.cxgbe.ntxq_vi", &t4_ntxq_vi); #define NRXQ_VI 1 static int t4_nrxq_vi = -NRXQ_VI; TUNABLE_INT("hw.cxgbe.nrxq_vi", &t4_nrxq_vi); static int t4_rsrv_noflowq = 0; TUNABLE_INT("hw.cxgbe.rsrv_noflowq", &t4_rsrv_noflowq); #ifdef TCP_OFFLOAD #define NOFLDTXQ_10G 8 static int t4_nofldtxq10g = -NOFLDTXQ_10G; TUNABLE_INT("hw.cxgbe.nofldtxq10g", &t4_nofldtxq10g); #define NOFLDRXQ_10G 2 static int t4_nofldrxq10g = -NOFLDRXQ_10G; TUNABLE_INT("hw.cxgbe.nofldrxq10g", &t4_nofldrxq10g); #define NOFLDTXQ_1G 2 static int t4_nofldtxq1g = -NOFLDTXQ_1G; TUNABLE_INT("hw.cxgbe.nofldtxq1g", &t4_nofldtxq1g); #define NOFLDRXQ_1G 1 static int t4_nofldrxq1g = -NOFLDRXQ_1G; TUNABLE_INT("hw.cxgbe.nofldrxq1g", &t4_nofldrxq1g); #define NOFLDTXQ_VI 1 static int t4_nofldtxq_vi = -NOFLDTXQ_VI; TUNABLE_INT("hw.cxgbe.nofldtxq_vi", &t4_nofldtxq_vi); #define NOFLDRXQ_VI 1 static int t4_nofldrxq_vi = -NOFLDRXQ_VI; TUNABLE_INT("hw.cxgbe.nofldrxq_vi", &t4_nofldrxq_vi); #endif #ifdef DEV_NETMAP #define NNMTXQ_VI 2 static int t4_nnmtxq_vi = -NNMTXQ_VI; TUNABLE_INT("hw.cxgbe.nnmtxq_vi", &t4_nnmtxq_vi); #define NNMRXQ_VI 2 static int t4_nnmrxq_vi = -NNMRXQ_VI; TUNABLE_INT("hw.cxgbe.nnmrxq_vi", &t4_nnmrxq_vi); #endif /* * Holdoff parameters for 10G and 1G ports. */ #define TMR_IDX_10G 1 int t4_tmr_idx_10g = TMR_IDX_10G; TUNABLE_INT("hw.cxgbe.holdoff_timer_idx_10G", &t4_tmr_idx_10g); #define PKTC_IDX_10G (-1) int t4_pktc_idx_10g = PKTC_IDX_10G; TUNABLE_INT("hw.cxgbe.holdoff_pktc_idx_10G", &t4_pktc_idx_10g); #define TMR_IDX_1G 1 int t4_tmr_idx_1g = TMR_IDX_1G; TUNABLE_INT("hw.cxgbe.holdoff_timer_idx_1G", &t4_tmr_idx_1g); #define PKTC_IDX_1G (-1) int t4_pktc_idx_1g = PKTC_IDX_1G; TUNABLE_INT("hw.cxgbe.holdoff_pktc_idx_1G", &t4_pktc_idx_1g); /* * Size (# of entries) of each tx and rx queue. */ unsigned int t4_qsize_txq = TX_EQ_QSIZE; TUNABLE_INT("hw.cxgbe.qsize_txq", &t4_qsize_txq); unsigned int t4_qsize_rxq = RX_IQ_QSIZE; TUNABLE_INT("hw.cxgbe.qsize_rxq", &t4_qsize_rxq); /* * Interrupt types allowed (bits 0, 1, 2 = INTx, MSI, MSI-X respectively). */ int t4_intr_types = INTR_MSIX | INTR_MSI | INTR_INTX; TUNABLE_INT("hw.cxgbe.interrupt_types", &t4_intr_types); /* * Configuration file. */ #define DEFAULT_CF "default" #define FLASH_CF "flash" #define UWIRE_CF "uwire" #define FPGA_CF "fpga" static char t4_cfg_file[32] = DEFAULT_CF; TUNABLE_STR("hw.cxgbe.config_file", t4_cfg_file, sizeof(t4_cfg_file)); /* * PAUSE settings (bit 0, 1 = rx_pause, tx_pause respectively). * rx_pause = 1 to heed incoming PAUSE frames, 0 to ignore them. * tx_pause = 1 to emit PAUSE frames when the rx FIFO reaches its high water * mark or when signalled to do so, 0 to never emit PAUSE. */ static int t4_pause_settings = PAUSE_TX | PAUSE_RX; TUNABLE_INT("hw.cxgbe.pause_settings", &t4_pause_settings); /* * Forward Error Correction settings (bit 0, 1, 2 = FEC_RS, FEC_BASER_RS, * FEC_RESERVED respectively). * -1 to run with the firmware default. * 0 to disable FEC. */ static int t4_fec = -1; TUNABLE_INT("hw.cxgbe.fec", &t4_fec); /* * Link autonegotiation. * -1 to run with the firmware default. * 0 to disable. * 1 to enable. */ static int t4_autoneg = -1; TUNABLE_INT("hw.cxgbe.autoneg", &t4_autoneg); /* * Firmware auto-install by driver during attach (0, 1, 2 = prohibited, allowed, * encouraged respectively). */ static unsigned int t4_fw_install = 1; TUNABLE_INT("hw.cxgbe.fw_install", &t4_fw_install); /* * ASIC features that will be used. Disable the ones you don't want so that the * chip resources aren't wasted on features that will not be used. */ static int t4_nbmcaps_allowed = 0; TUNABLE_INT("hw.cxgbe.nbmcaps_allowed", &t4_nbmcaps_allowed); static int t4_linkcaps_allowed = 0; /* No DCBX, PPP, etc. by default */ TUNABLE_INT("hw.cxgbe.linkcaps_allowed", &t4_linkcaps_allowed); static int t4_switchcaps_allowed = FW_CAPS_CONFIG_SWITCH_INGRESS | FW_CAPS_CONFIG_SWITCH_EGRESS; TUNABLE_INT("hw.cxgbe.switchcaps_allowed", &t4_switchcaps_allowed); static int t4_niccaps_allowed = FW_CAPS_CONFIG_NIC; TUNABLE_INT("hw.cxgbe.niccaps_allowed", &t4_niccaps_allowed); static int t4_toecaps_allowed = -1; TUNABLE_INT("hw.cxgbe.toecaps_allowed", &t4_toecaps_allowed); static int t4_rdmacaps_allowed = -1; TUNABLE_INT("hw.cxgbe.rdmacaps_allowed", &t4_rdmacaps_allowed); static int t4_cryptocaps_allowed = 0; TUNABLE_INT("hw.cxgbe.cryptocaps_allowed", &t4_cryptocaps_allowed); static int t4_iscsicaps_allowed = -1; TUNABLE_INT("hw.cxgbe.iscsicaps_allowed", &t4_iscsicaps_allowed); static int t4_fcoecaps_allowed = 0; TUNABLE_INT("hw.cxgbe.fcoecaps_allowed", &t4_fcoecaps_allowed); static int t5_write_combine = 0; TUNABLE_INT("hw.cxl.write_combine", &t5_write_combine); static int t4_num_vis = 1; TUNABLE_INT("hw.cxgbe.num_vis", &t4_num_vis); /* Functions used by extra VIs to obtain unique MAC addresses for each VI. */ static int vi_mac_funcs[] = { FW_VI_FUNC_OFLD, FW_VI_FUNC_IWARP, FW_VI_FUNC_OPENISCSI, FW_VI_FUNC_OPENFCOE, FW_VI_FUNC_FOISCSI, FW_VI_FUNC_FOFCOE, }; struct intrs_and_queues { uint16_t intr_type; /* INTx, MSI, or MSI-X */ uint16_t nirq; /* Total # of vectors */ uint16_t intr_flags_10g;/* Interrupt flags for each 10G port */ uint16_t intr_flags_1g; /* Interrupt flags for each 1G port */ uint16_t ntxq10g; /* # of NIC txq's for each 10G port */ uint16_t nrxq10g; /* # of NIC rxq's for each 10G port */ uint16_t ntxq1g; /* # of NIC txq's for each 1G port */ uint16_t nrxq1g; /* # of NIC rxq's for each 1G port */ uint16_t rsrv_noflowq; /* Flag whether to reserve queue 0 */ uint16_t nofldtxq10g; /* # of TOE txq's for each 10G port */ uint16_t nofldrxq10g; /* # of TOE rxq's for each 10G port */ uint16_t nofldtxq1g; /* # of TOE txq's for each 1G port */ uint16_t nofldrxq1g; /* # of TOE rxq's for each 1G port */ /* The vcxgbe/vcxl interfaces use these and not the ones above. */ uint16_t ntxq_vi; /* # of NIC txq's */ uint16_t nrxq_vi; /* # of NIC rxq's */ uint16_t nofldtxq_vi; /* # of TOE txq's */ uint16_t nofldrxq_vi; /* # of TOE rxq's */ uint16_t nnmtxq_vi; /* # of netmap txq's */ uint16_t nnmrxq_vi; /* # of netmap rxq's */ }; struct filter_entry { uint32_t valid:1; /* filter allocated and valid */ uint32_t locked:1; /* filter is administratively locked */ uint32_t pending:1; /* filter action is pending firmware reply */ uint32_t smtidx:8; /* Source MAC Table index for smac */ struct l2t_entry *l2t; /* Layer Two Table entry for dmac */ struct t4_filter_specification fs; }; static void setup_memwin(struct adapter *); static void position_memwin(struct adapter *, int, uint32_t); static int rw_via_memwin(struct adapter *, int, uint32_t, uint32_t *, int, int); static inline int read_via_memwin(struct adapter *, int, uint32_t, uint32_t *, int); static inline int write_via_memwin(struct adapter *, int, uint32_t, const uint32_t *, int); static int validate_mem_range(struct adapter *, uint32_t, int); static int fwmtype_to_hwmtype(int); static int validate_mt_off_len(struct adapter *, int, uint32_t, int, uint32_t *); static int fixup_devlog_params(struct adapter *); static int cfg_itype_and_nqueues(struct adapter *, int, int, int, struct intrs_and_queues *); static int prep_firmware(struct adapter *); static int partition_resources(struct adapter *, const struct firmware *, const char *); static int get_params__pre_init(struct adapter *); static int get_params__post_init(struct adapter *); static int set_params__post_init(struct adapter *); static void t4_set_desc(struct adapter *); static void build_medialist(struct port_info *, struct ifmedia *); static void init_l1cfg(struct port_info *); static int cxgbe_init_synchronized(struct vi_info *); static int cxgbe_uninit_synchronized(struct vi_info *); static void quiesce_txq(struct adapter *, struct sge_txq *); static void quiesce_wrq(struct adapter *, struct sge_wrq *); static void quiesce_iq(struct adapter *, struct sge_iq *); static void quiesce_fl(struct adapter *, struct sge_fl *); static int t4_alloc_irq(struct adapter *, struct irq *, int rid, driver_intr_t *, void *, char *); static int t4_free_irq(struct adapter *, struct irq *); static void get_regs(struct adapter *, struct t4_regdump *, uint8_t *); static void vi_refresh_stats(struct adapter *, struct vi_info *); static void cxgbe_refresh_stats(struct adapter *, struct port_info *); static void cxgbe_tick(void *); static void cxgbe_vlan_config(void *, struct ifnet *, uint16_t); static void cxgbe_sysctls(struct port_info *); static int sysctl_int_array(SYSCTL_HANDLER_ARGS); static int sysctl_bitfield(SYSCTL_HANDLER_ARGS); static int sysctl_btphy(SYSCTL_HANDLER_ARGS); static int sysctl_noflowq(SYSCTL_HANDLER_ARGS); static int sysctl_holdoff_tmr_idx(SYSCTL_HANDLER_ARGS); static int sysctl_holdoff_pktc_idx(SYSCTL_HANDLER_ARGS); static int sysctl_qsize_rxq(SYSCTL_HANDLER_ARGS); static int sysctl_qsize_txq(SYSCTL_HANDLER_ARGS); static int sysctl_pause_settings(SYSCTL_HANDLER_ARGS); static int sysctl_fec(SYSCTL_HANDLER_ARGS); static int sysctl_autoneg(SYSCTL_HANDLER_ARGS); static int sysctl_handle_t4_reg64(SYSCTL_HANDLER_ARGS); static int sysctl_temperature(SYSCTL_HANDLER_ARGS); #ifdef SBUF_DRAIN static int sysctl_cctrl(SYSCTL_HANDLER_ARGS); static int sysctl_cim_ibq_obq(SYSCTL_HANDLER_ARGS); static int sysctl_cim_la(SYSCTL_HANDLER_ARGS); static int sysctl_cim_la_t6(SYSCTL_HANDLER_ARGS); static int sysctl_cim_ma_la(SYSCTL_HANDLER_ARGS); static int sysctl_cim_pif_la(SYSCTL_HANDLER_ARGS); static int sysctl_cim_qcfg(SYSCTL_HANDLER_ARGS); static int sysctl_cpl_stats(SYSCTL_HANDLER_ARGS); static int sysctl_ddp_stats(SYSCTL_HANDLER_ARGS); static int sysctl_devlog(SYSCTL_HANDLER_ARGS); static int sysctl_fcoe_stats(SYSCTL_HANDLER_ARGS); static int sysctl_hw_sched(SYSCTL_HANDLER_ARGS); static int sysctl_lb_stats(SYSCTL_HANDLER_ARGS); static int sysctl_linkdnrc(SYSCTL_HANDLER_ARGS); static int sysctl_meminfo(SYSCTL_HANDLER_ARGS); static int sysctl_mps_tcam(SYSCTL_HANDLER_ARGS); static int sysctl_mps_tcam_t6(SYSCTL_HANDLER_ARGS); static int sysctl_path_mtus(SYSCTL_HANDLER_ARGS); static int sysctl_pm_stats(SYSCTL_HANDLER_ARGS); static int sysctl_rdma_stats(SYSCTL_HANDLER_ARGS); static int sysctl_tcp_stats(SYSCTL_HANDLER_ARGS); static int sysctl_tids(SYSCTL_HANDLER_ARGS); static int sysctl_tp_err_stats(SYSCTL_HANDLER_ARGS); static int sysctl_tp_la_mask(SYSCTL_HANDLER_ARGS); static int sysctl_tp_la(SYSCTL_HANDLER_ARGS); static int sysctl_tx_rate(SYSCTL_HANDLER_ARGS); static int sysctl_ulprx_la(SYSCTL_HANDLER_ARGS); static int sysctl_wcwr_stats(SYSCTL_HANDLER_ARGS); static int sysctl_tc_params(SYSCTL_HANDLER_ARGS); #endif #ifdef TCP_OFFLOAD static int sysctl_tp_tick(SYSCTL_HANDLER_ARGS); static int sysctl_tp_dack_timer(SYSCTL_HANDLER_ARGS); static int sysctl_tp_timer(SYSCTL_HANDLER_ARGS); +static int sysctl_tp_shift_cnt(SYSCTL_HANDLER_ARGS); +static int sysctl_tp_backoff(SYSCTL_HANDLER_ARGS); #endif static uint32_t fconf_iconf_to_mode(uint32_t, uint32_t); static uint32_t mode_to_fconf(uint32_t); static uint32_t mode_to_iconf(uint32_t); static int check_fspec_against_fconf_iconf(struct adapter *, struct t4_filter_specification *); static int get_filter_mode(struct adapter *, uint32_t *); static int set_filter_mode(struct adapter *, uint32_t); static inline uint64_t get_filter_hits(struct adapter *, uint32_t); static int get_filter(struct adapter *, struct t4_filter *); static int set_filter(struct adapter *, struct t4_filter *); static int del_filter(struct adapter *, struct t4_filter *); static void clear_filter(struct filter_entry *); static int set_filter_wr(struct adapter *, int); static int del_filter_wr(struct adapter *, int); static int set_tcb_rpl(struct sge_iq *, const struct rss_header *, struct mbuf *); static int get_sge_context(struct adapter *, struct t4_sge_context *); static int load_fw(struct adapter *, struct t4_data *); static int load_cfg(struct adapter *, struct t4_data *); static int load_boot(struct adapter *, struct t4_bootrom *); static int load_bootcfg(struct adapter *, struct t4_data *); static int read_card_mem(struct adapter *, int, struct t4_mem_range *); static int read_i2c(struct adapter *, struct t4_i2c_data *); #ifdef TCP_OFFLOAD static int toe_capability(struct vi_info *, int); #endif static int mod_event(module_t, int, void *); static int notify_siblings(device_t, int); struct { uint16_t device; char *desc; } t4_pciids[] = { {0xa000, "Chelsio Terminator 4 FPGA"}, {0x4400, "Chelsio T440-dbg"}, {0x4401, "Chelsio T420-CR"}, {0x4402, "Chelsio T422-CR"}, {0x4403, "Chelsio T440-CR"}, {0x4404, "Chelsio T420-BCH"}, {0x4405, "Chelsio T440-BCH"}, {0x4406, "Chelsio T440-CH"}, {0x4407, "Chelsio T420-SO"}, {0x4408, "Chelsio T420-CX"}, {0x4409, "Chelsio T420-BT"}, {0x440a, "Chelsio T404-BT"}, {0x440e, "Chelsio T440-LP-CR"}, }, t5_pciids[] = { {0xb000, "Chelsio Terminator 5 FPGA"}, {0x5400, "Chelsio T580-dbg"}, {0x5401, "Chelsio T520-CR"}, /* 2 x 10G */ {0x5402, "Chelsio T522-CR"}, /* 2 x 10G, 2 X 1G */ {0x5403, "Chelsio T540-CR"}, /* 4 x 10G */ {0x5407, "Chelsio T520-SO"}, /* 2 x 10G, nomem */ {0x5409, "Chelsio T520-BT"}, /* 2 x 10GBaseT */ {0x540a, "Chelsio T504-BT"}, /* 4 x 1G */ {0x540d, "Chelsio T580-CR"}, /* 2 x 40G */ {0x540e, "Chelsio T540-LP-CR"}, /* 4 x 10G */ {0x5410, "Chelsio T580-LP-CR"}, /* 2 x 40G */ {0x5411, "Chelsio T520-LL-CR"}, /* 2 x 10G */ {0x5412, "Chelsio T560-CR"}, /* 1 x 40G, 2 x 10G */ {0x5414, "Chelsio T580-LP-SO-CR"}, /* 2 x 40G, nomem */ {0x5415, "Chelsio T502-BT"}, /* 2 x 1G */ #ifdef notyet {0x5404, "Chelsio T520-BCH"}, {0x5405, "Chelsio T540-BCH"}, {0x5406, "Chelsio T540-CH"}, {0x5408, "Chelsio T520-CX"}, {0x540b, "Chelsio B520-SR"}, {0x540c, "Chelsio B504-BT"}, {0x540f, "Chelsio Amsterdam"}, {0x5413, "Chelsio T580-CHR"}, #endif }, t6_pciids[] = { {0xc006, "Chelsio Terminator 6 FPGA"}, /* T6 PE10K6 FPGA (PF0) */ {0x6400, "Chelsio T6-DBG-25"}, /* 2 x 10/25G, debug */ {0x6401, "Chelsio T6225-CR"}, /* 2 x 10/25G */ {0x6402, "Chelsio T6225-SO-CR"}, /* 2 x 10/25G, nomem */ {0x6403, "Chelsio T6425-CR"}, /* 4 x 10/25G */ {0x6404, "Chelsio T6425-SO-CR"}, /* 4 x 10/25G, nomem */ {0x6405, "Chelsio T6225-OCP-SO"}, /* 2 x 10/25G, nomem */ {0x6406, "Chelsio T62100-OCP-SO"}, /* 2 x 40/50/100G, nomem */ {0x6407, "Chelsio T62100-LP-CR"}, /* 2 x 40/50/100G */ {0x6408, "Chelsio T62100-SO-CR"}, /* 2 x 40/50/100G, nomem */ {0x6409, "Chelsio T6210-BT"}, /* 2 x 10GBASE-T */ {0x640d, "Chelsio T62100-CR"}, /* 2 x 40/50/100G */ {0x6410, "Chelsio T6-DBG-100"}, /* 2 x 40/50/100G, debug */ {0x6411, "Chelsio T6225-LL-CR"}, /* 2 x 10/25G */ {0x6414, "Chelsio T61100-OCP-SO"}, /* 1 x 40/50/100G, nomem */ {0x6415, "Chelsio T6201-BT"}, /* 2 x 1000BASE-T */ /* Custom */ {0x6480, "Chelsio T6225 80"}, {0x6481, "Chelsio T62100 81"}, }; #ifdef TCP_OFFLOAD /* * service_iq() has an iq and needs the fl. Offset of fl from the iq should be * exactly the same for both rxq and ofld_rxq. */ CTASSERT(offsetof(struct sge_ofld_rxq, iq) == offsetof(struct sge_rxq, iq)); CTASSERT(offsetof(struct sge_ofld_rxq, fl) == offsetof(struct sge_rxq, fl)); #endif CTASSERT(sizeof(struct cluster_metadata) <= CL_METADATA_SIZE); static int t4_probe(device_t dev) { int i; uint16_t v = pci_get_vendor(dev); uint16_t d = pci_get_device(dev); uint8_t f = pci_get_function(dev); if (v != PCI_VENDOR_ID_CHELSIO) return (ENXIO); /* Attach only to PF0 of the FPGA */ if (d == 0xa000 && f != 0) return (ENXIO); for (i = 0; i < nitems(t4_pciids); i++) { if (d == t4_pciids[i].device) { device_set_desc(dev, t4_pciids[i].desc); return (BUS_PROBE_DEFAULT); } } return (ENXIO); } static int t5_probe(device_t dev) { int i; uint16_t v = pci_get_vendor(dev); uint16_t d = pci_get_device(dev); uint8_t f = pci_get_function(dev); if (v != PCI_VENDOR_ID_CHELSIO) return (ENXIO); /* Attach only to PF0 of the FPGA */ if (d == 0xb000 && f != 0) return (ENXIO); for (i = 0; i < nitems(t5_pciids); i++) { if (d == t5_pciids[i].device) { device_set_desc(dev, t5_pciids[i].desc); return (BUS_PROBE_DEFAULT); } } return (ENXIO); } static int t6_probe(device_t dev) { int i; uint16_t v = pci_get_vendor(dev); uint16_t d = pci_get_device(dev); if (v != PCI_VENDOR_ID_CHELSIO) return (ENXIO); for (i = 0; i < nitems(t6_pciids); i++) { if (d == t6_pciids[i].device) { device_set_desc(dev, t6_pciids[i].desc); return (BUS_PROBE_DEFAULT); } } return (ENXIO); } static void t5_attribute_workaround(device_t dev) { device_t root_port; uint32_t v; /* * The T5 chips do not properly echo the No Snoop and Relaxed * Ordering attributes when replying to a TLP from a Root * Port. As a workaround, find the parent Root Port and * disable No Snoop and Relaxed Ordering. Note that this * affects all devices under this root port. */ root_port = pci_find_pcie_root_port(dev); if (root_port == NULL) { device_printf(dev, "Unable to find parent root port\n"); return; } v = pcie_adjust_config(root_port, PCIER_DEVICE_CTL, PCIEM_CTL_RELAXED_ORD_ENABLE | PCIEM_CTL_NOSNOOP_ENABLE, 0, 2); if ((v & (PCIEM_CTL_RELAXED_ORD_ENABLE | PCIEM_CTL_NOSNOOP_ENABLE)) != 0) device_printf(dev, "Disabled No Snoop/Relaxed Ordering on %s\n", device_get_nameunit(root_port)); } static const struct devnames devnames[] = { { .nexus_name = "t4nex", .ifnet_name = "cxgbe", .vi_ifnet_name = "vcxgbe", .pf03_drv_name = "t4iov", .vf_nexus_name = "t4vf", .vf_ifnet_name = "cxgbev" }, { .nexus_name = "t5nex", .ifnet_name = "cxl", .vi_ifnet_name = "vcxl", .pf03_drv_name = "t5iov", .vf_nexus_name = "t5vf", .vf_ifnet_name = "cxlv" }, { .nexus_name = "t6nex", .ifnet_name = "cc", .vi_ifnet_name = "vcc", .pf03_drv_name = "t6iov", .vf_nexus_name = "t6vf", .vf_ifnet_name = "ccv" } }; void t4_init_devnames(struct adapter *sc) { int id; id = chip_id(sc); if (id >= CHELSIO_T4 && id - CHELSIO_T4 < nitems(devnames)) sc->names = &devnames[id - CHELSIO_T4]; else { device_printf(sc->dev, "chip id %d is not supported.\n", id); sc->names = NULL; } } static int t4_attach(device_t dev) { struct adapter *sc; int rc = 0, i, j, n10g, n1g, rqidx, tqidx; struct make_dev_args mda; struct intrs_and_queues iaq; struct sge *s; uint8_t *buf; #ifdef TCP_OFFLOAD int ofld_rqidx, ofld_tqidx; #endif #ifdef DEV_NETMAP int nm_rqidx, nm_tqidx; #endif int num_vis; sc = device_get_softc(dev); sc->dev = dev; TUNABLE_INT_FETCH("hw.cxgbe.dflags", &sc->debug_flags); if ((pci_get_device(dev) & 0xff00) == 0x5400) t5_attribute_workaround(dev); pci_enable_busmaster(dev); if (pci_find_cap(dev, PCIY_EXPRESS, &i) == 0) { uint32_t v; pci_set_max_read_req(dev, 4096); v = pci_read_config(dev, i + PCIER_DEVICE_CTL, 2); v |= PCIEM_CTL_RELAXED_ORD_ENABLE; pci_write_config(dev, i + PCIER_DEVICE_CTL, v, 2); sc->params.pci.mps = 128 << ((v & PCIEM_CTL_MAX_PAYLOAD) >> 5); } sc->sge_gts_reg = MYPF_REG(A_SGE_PF_GTS); sc->sge_kdoorbell_reg = MYPF_REG(A_SGE_PF_KDOORBELL); sc->traceq = -1; mtx_init(&sc->ifp_lock, sc->ifp_lockname, 0, MTX_DEF); snprintf(sc->ifp_lockname, sizeof(sc->ifp_lockname), "%s tracer", device_get_nameunit(dev)); snprintf(sc->lockname, sizeof(sc->lockname), "%s", device_get_nameunit(dev)); mtx_init(&sc->sc_lock, sc->lockname, 0, MTX_DEF); t4_add_adapter(sc); mtx_init(&sc->sfl_lock, "starving freelists", 0, MTX_DEF); TAILQ_INIT(&sc->sfl); callout_init_mtx(&sc->sfl_callout, &sc->sfl_lock, 0); mtx_init(&sc->reg_lock, "indirect register access", 0, MTX_DEF); rc = t4_map_bars_0_and_4(sc); if (rc != 0) goto done; /* error message displayed already */ memset(sc->chan_map, 0xff, sizeof(sc->chan_map)); /* Prepare the adapter for operation. */ buf = malloc(PAGE_SIZE, M_CXGBE, M_ZERO | M_WAITOK); rc = -t4_prep_adapter(sc, buf); free(buf, M_CXGBE); if (rc != 0) { device_printf(dev, "failed to prepare adapter: %d.\n", rc); goto done; } /* * This is the real PF# to which we're attaching. Works from within PCI * passthrough environments too, where pci_get_function() could return a * different PF# depending on the passthrough configuration. We need to * use the real PF# in all our communication with the firmware. */ j = t4_read_reg(sc, A_PL_WHOAMI); sc->pf = chip_id(sc) <= CHELSIO_T5 ? G_SOURCEPF(j) : G_T6_SOURCEPF(j); sc->mbox = sc->pf; t4_init_devnames(sc); if (sc->names == NULL) { rc = ENOTSUP; goto done; /* error message displayed already */ } /* * Do this really early, with the memory windows set up even before the * character device. The userland tool's register i/o and mem read * will work even in "recovery mode". */ setup_memwin(sc); if (t4_init_devlog_params(sc, 0) == 0) fixup_devlog_params(sc); make_dev_args_init(&mda); mda.mda_devsw = &t4_cdevsw; mda.mda_uid = UID_ROOT; mda.mda_gid = GID_WHEEL; mda.mda_mode = 0600; mda.mda_si_drv1 = sc; rc = make_dev_s(&mda, &sc->cdev, "%s", device_get_nameunit(dev)); if (rc != 0) device_printf(dev, "failed to create nexus char device: %d.\n", rc); /* Go no further if recovery mode has been requested. */ if (TUNABLE_INT_FETCH("hw.cxgbe.sos", &i) && i != 0) { device_printf(dev, "recovery mode.\n"); goto done; } #if defined(__i386__) if ((cpu_feature & CPUID_CX8) == 0) { device_printf(dev, "64 bit atomics not available.\n"); rc = ENOTSUP; goto done; } #endif /* Prepare the firmware for operation */ rc = prep_firmware(sc); if (rc != 0) goto done; /* error message displayed already */ rc = get_params__post_init(sc); if (rc != 0) goto done; /* error message displayed already */ rc = set_params__post_init(sc); if (rc != 0) goto done; /* error message displayed already */ rc = t4_map_bar_2(sc); if (rc != 0) goto done; /* error message displayed already */ rc = t4_create_dma_tag(sc); if (rc != 0) goto done; /* error message displayed already */ /* * Number of VIs to create per-port. The first VI is the "main" regular * VI for the port. The rest are additional virtual interfaces on the * same physical port. Note that the main VI does not have native * netmap support but the extra VIs do. * * Limit the number of VIs per port to the number of available * MAC addresses per port. */ if (t4_num_vis >= 1) num_vis = t4_num_vis; else num_vis = 1; if (num_vis > nitems(vi_mac_funcs)) { num_vis = nitems(vi_mac_funcs); device_printf(dev, "Number of VIs limited to %d\n", num_vis); } /* * First pass over all the ports - allocate VIs and initialize some * basic parameters like mac address, port type, etc. We also figure * out whether a port is 10G or 1G and use that information when * calculating how many interrupts to attempt to allocate. */ n10g = n1g = 0; for_each_port(sc, i) { struct port_info *pi; pi = malloc(sizeof(*pi), M_CXGBE, M_ZERO | M_WAITOK); sc->port[i] = pi; /* These must be set before t4_port_init */ pi->adapter = sc; pi->port_id = i; /* * XXX: vi[0] is special so we can't delay this allocation until * pi->nvi's final value is known. */ pi->vi = malloc(sizeof(struct vi_info) * num_vis, M_CXGBE, M_ZERO | M_WAITOK); /* * Allocate the "main" VI and initialize parameters * like mac addr. */ rc = -t4_port_init(sc, sc->mbox, sc->pf, 0, i); if (rc != 0) { device_printf(dev, "unable to initialize port %d: %d\n", i, rc); free(pi->vi, M_CXGBE); free(pi, M_CXGBE); sc->port[i] = NULL; goto done; } snprintf(pi->lockname, sizeof(pi->lockname), "%sp%d", device_get_nameunit(dev), i); mtx_init(&pi->pi_lock, pi->lockname, 0, MTX_DEF); sc->chan_map[pi->tx_chan] = i; if (port_top_speed(pi) >= 10) { n10g++; } else { n1g++; } pi->dev = device_add_child(dev, sc->names->ifnet_name, -1); if (pi->dev == NULL) { device_printf(dev, "failed to add device for port %d.\n", i); rc = ENXIO; goto done; } pi->vi[0].dev = pi->dev; device_set_softc(pi->dev, pi); } /* * Interrupt type, # of interrupts, # of rx/tx queues, etc. */ rc = cfg_itype_and_nqueues(sc, n10g, n1g, num_vis, &iaq); if (rc != 0) goto done; /* error message displayed already */ if (iaq.nrxq_vi + iaq.nofldrxq_vi + iaq.nnmrxq_vi == 0) num_vis = 1; sc->intr_type = iaq.intr_type; sc->intr_count = iaq.nirq; s = &sc->sge; s->nrxq = n10g * iaq.nrxq10g + n1g * iaq.nrxq1g; s->ntxq = n10g * iaq.ntxq10g + n1g * iaq.ntxq1g; if (num_vis > 1) { s->nrxq += (n10g + n1g) * (num_vis - 1) * iaq.nrxq_vi; s->ntxq += (n10g + n1g) * (num_vis - 1) * iaq.ntxq_vi; } s->neq = s->ntxq + s->nrxq; /* the free list in an rxq is an eq */ s->neq += sc->params.nports + 1;/* ctrl queues: 1 per port + 1 mgmt */ s->niq = s->nrxq + 1; /* 1 extra for firmware event queue */ #ifdef TCP_OFFLOAD if (is_offload(sc)) { s->nofldrxq = n10g * iaq.nofldrxq10g + n1g * iaq.nofldrxq1g; s->nofldtxq = n10g * iaq.nofldtxq10g + n1g * iaq.nofldtxq1g; if (num_vis > 1) { s->nofldrxq += (n10g + n1g) * (num_vis - 1) * iaq.nofldrxq_vi; s->nofldtxq += (n10g + n1g) * (num_vis - 1) * iaq.nofldtxq_vi; } s->neq += s->nofldtxq + s->nofldrxq; s->niq += s->nofldrxq; s->ofld_rxq = malloc(s->nofldrxq * sizeof(struct sge_ofld_rxq), M_CXGBE, M_ZERO | M_WAITOK); s->ofld_txq = malloc(s->nofldtxq * sizeof(struct sge_wrq), M_CXGBE, M_ZERO | M_WAITOK); } #endif #ifdef DEV_NETMAP if (num_vis > 1) { s->nnmrxq = (n10g + n1g) * (num_vis - 1) * iaq.nnmrxq_vi; s->nnmtxq = (n10g + n1g) * (num_vis - 1) * iaq.nnmtxq_vi; } s->neq += s->nnmtxq + s->nnmrxq; s->niq += s->nnmrxq; s->nm_rxq = malloc(s->nnmrxq * sizeof(struct sge_nm_rxq), M_CXGBE, M_ZERO | M_WAITOK); s->nm_txq = malloc(s->nnmtxq * sizeof(struct sge_nm_txq), M_CXGBE, M_ZERO | M_WAITOK); #endif s->ctrlq = malloc(sc->params.nports * sizeof(struct sge_wrq), M_CXGBE, M_ZERO | M_WAITOK); s->rxq = malloc(s->nrxq * sizeof(struct sge_rxq), M_CXGBE, M_ZERO | M_WAITOK); s->txq = malloc(s->ntxq * sizeof(struct sge_txq), M_CXGBE, M_ZERO | M_WAITOK); s->iqmap = malloc(s->niq * sizeof(struct sge_iq *), M_CXGBE, M_ZERO | M_WAITOK); s->eqmap = malloc(s->neq * sizeof(struct sge_eq *), M_CXGBE, M_ZERO | M_WAITOK); sc->irq = malloc(sc->intr_count * sizeof(struct irq), M_CXGBE, M_ZERO | M_WAITOK); t4_init_l2t(sc, M_WAITOK); t4_init_tx_sched(sc); /* * Second pass over the ports. This time we know the number of rx and * tx queues that each port should get. */ rqidx = tqidx = 0; #ifdef TCP_OFFLOAD ofld_rqidx = ofld_tqidx = 0; #endif #ifdef DEV_NETMAP nm_rqidx = nm_tqidx = 0; #endif for_each_port(sc, i) { struct port_info *pi = sc->port[i]; struct vi_info *vi; if (pi == NULL) continue; pi->nvi = num_vis; for_each_vi(pi, j, vi) { vi->pi = pi; vi->qsize_rxq = t4_qsize_rxq; vi->qsize_txq = t4_qsize_txq; vi->first_rxq = rqidx; vi->first_txq = tqidx; if (port_top_speed(pi) >= 10) { vi->tmr_idx = t4_tmr_idx_10g; vi->pktc_idx = t4_pktc_idx_10g; vi->flags |= iaq.intr_flags_10g & INTR_RXQ; vi->nrxq = j == 0 ? iaq.nrxq10g : iaq.nrxq_vi; vi->ntxq = j == 0 ? iaq.ntxq10g : iaq.ntxq_vi; } else { vi->tmr_idx = t4_tmr_idx_1g; vi->pktc_idx = t4_pktc_idx_1g; vi->flags |= iaq.intr_flags_1g & INTR_RXQ; vi->nrxq = j == 0 ? iaq.nrxq1g : iaq.nrxq_vi; vi->ntxq = j == 0 ? iaq.ntxq1g : iaq.ntxq_vi; } rqidx += vi->nrxq; tqidx += vi->ntxq; if (j == 0 && vi->ntxq > 1) vi->rsrv_noflowq = iaq.rsrv_noflowq ? 1 : 0; else vi->rsrv_noflowq = 0; #ifdef TCP_OFFLOAD vi->first_ofld_rxq = ofld_rqidx; vi->first_ofld_txq = ofld_tqidx; if (port_top_speed(pi) >= 10) { vi->flags |= iaq.intr_flags_10g & INTR_OFLD_RXQ; vi->nofldrxq = j == 0 ? iaq.nofldrxq10g : iaq.nofldrxq_vi; vi->nofldtxq = j == 0 ? iaq.nofldtxq10g : iaq.nofldtxq_vi; } else { vi->flags |= iaq.intr_flags_1g & INTR_OFLD_RXQ; vi->nofldrxq = j == 0 ? iaq.nofldrxq1g : iaq.nofldrxq_vi; vi->nofldtxq = j == 0 ? iaq.nofldtxq1g : iaq.nofldtxq_vi; } ofld_rqidx += vi->nofldrxq; ofld_tqidx += vi->nofldtxq; #endif #ifdef DEV_NETMAP if (j > 0) { vi->first_nm_rxq = nm_rqidx; vi->first_nm_txq = nm_tqidx; vi->nnmrxq = iaq.nnmrxq_vi; vi->nnmtxq = iaq.nnmtxq_vi; nm_rqidx += vi->nnmrxq; nm_tqidx += vi->nnmtxq; } #endif } } rc = t4_setup_intr_handlers(sc); if (rc != 0) { device_printf(dev, "failed to setup interrupt handlers: %d\n", rc); goto done; } rc = bus_generic_probe(dev); if (rc != 0) { device_printf(dev, "failed to probe child drivers: %d\n", rc); goto done; } rc = bus_generic_attach(dev); if (rc != 0) { device_printf(dev, "failed to attach all child ports: %d\n", rc); goto done; } device_printf(dev, "PCIe gen%d x%d, %d ports, %d %s interrupt%s, %d eq, %d iq\n", sc->params.pci.speed, sc->params.pci.width, sc->params.nports, sc->intr_count, sc->intr_type == INTR_MSIX ? "MSI-X" : (sc->intr_type == INTR_MSI ? "MSI" : "INTx"), sc->intr_count > 1 ? "s" : "", sc->sge.neq, sc->sge.niq); t4_set_desc(sc); notify_siblings(dev, 0); done: if (rc != 0 && sc->cdev) { /* cdev was created and so cxgbetool works; recover that way. */ device_printf(dev, "error during attach, adapter is now in recovery mode.\n"); rc = 0; } if (rc != 0) t4_detach_common(dev); else t4_sysctls(sc); return (rc); } static int t4_ready(device_t dev) { struct adapter *sc; sc = device_get_softc(dev); if (sc->flags & FW_OK) return (0); return (ENXIO); } static int t4_read_port_device(device_t dev, int port, device_t *child) { struct adapter *sc; struct port_info *pi; sc = device_get_softc(dev); if (port < 0 || port >= MAX_NPORTS) return (EINVAL); pi = sc->port[port]; if (pi == NULL || pi->dev == NULL) return (ENXIO); *child = pi->dev; return (0); } static int notify_siblings(device_t dev, int detaching) { device_t sibling; int error, i; error = 0; for (i = 0; i < PCI_FUNCMAX; i++) { if (i == pci_get_function(dev)) continue; sibling = pci_find_dbsf(pci_get_domain(dev), pci_get_bus(dev), pci_get_slot(dev), i); if (sibling == NULL || !device_is_attached(sibling)) continue; if (detaching) error = T4_DETACH_CHILD(sibling); else (void)T4_ATTACH_CHILD(sibling); if (error) break; } return (error); } /* * Idempotent */ static int t4_detach(device_t dev) { struct adapter *sc; int rc; sc = device_get_softc(dev); rc = notify_siblings(dev, 1); if (rc) { device_printf(dev, "failed to detach sibling devices: %d\n", rc); return (rc); } return (t4_detach_common(dev)); } int t4_detach_common(device_t dev) { struct adapter *sc; struct port_info *pi; int i, rc; sc = device_get_softc(dev); if (sc->flags & FULL_INIT_DONE) { if (!(sc->flags & IS_VF)) t4_intr_disable(sc); } if (sc->cdev) { destroy_dev(sc->cdev); sc->cdev = NULL; } if (device_is_attached(dev)) { rc = bus_generic_detach(dev); if (rc) { device_printf(dev, "failed to detach child devices: %d\n", rc); return (rc); } } for (i = 0; i < sc->intr_count; i++) t4_free_irq(sc, &sc->irq[i]); if ((sc->flags & (IS_VF | FW_OK)) == FW_OK) t4_free_tx_sched(sc); for (i = 0; i < MAX_NPORTS; i++) { pi = sc->port[i]; if (pi) { t4_free_vi(sc, sc->mbox, sc->pf, 0, pi->vi[0].viid); if (pi->dev) device_delete_child(dev, pi->dev); mtx_destroy(&pi->pi_lock); free(pi->vi, M_CXGBE); free(pi, M_CXGBE); } } device_delete_children(dev); if (sc->flags & FULL_INIT_DONE) adapter_full_uninit(sc); if ((sc->flags & (IS_VF | FW_OK)) == FW_OK) t4_fw_bye(sc, sc->mbox); if (sc->intr_type == INTR_MSI || sc->intr_type == INTR_MSIX) pci_release_msi(dev); if (sc->regs_res) bus_release_resource(dev, SYS_RES_MEMORY, sc->regs_rid, sc->regs_res); if (sc->udbs_res) bus_release_resource(dev, SYS_RES_MEMORY, sc->udbs_rid, sc->udbs_res); if (sc->msix_res) bus_release_resource(dev, SYS_RES_MEMORY, sc->msix_rid, sc->msix_res); if (sc->l2t) t4_free_l2t(sc->l2t); #ifdef TCP_OFFLOAD free(sc->sge.ofld_rxq, M_CXGBE); free(sc->sge.ofld_txq, M_CXGBE); #endif #ifdef DEV_NETMAP free(sc->sge.nm_rxq, M_CXGBE); free(sc->sge.nm_txq, M_CXGBE); #endif free(sc->irq, M_CXGBE); free(sc->sge.rxq, M_CXGBE); free(sc->sge.txq, M_CXGBE); free(sc->sge.ctrlq, M_CXGBE); free(sc->sge.iqmap, M_CXGBE); free(sc->sge.eqmap, M_CXGBE); free(sc->tids.ftid_tab, M_CXGBE); t4_destroy_dma_tag(sc); if (mtx_initialized(&sc->sc_lock)) { sx_xlock(&t4_list_lock); SLIST_REMOVE(&t4_list, sc, adapter, link); sx_xunlock(&t4_list_lock); mtx_destroy(&sc->sc_lock); } callout_drain(&sc->sfl_callout); if (mtx_initialized(&sc->tids.ftid_lock)) mtx_destroy(&sc->tids.ftid_lock); if (mtx_initialized(&sc->sfl_lock)) mtx_destroy(&sc->sfl_lock); if (mtx_initialized(&sc->ifp_lock)) mtx_destroy(&sc->ifp_lock); if (mtx_initialized(&sc->reg_lock)) mtx_destroy(&sc->reg_lock); for (i = 0; i < NUM_MEMWIN; i++) { struct memwin *mw = &sc->memwin[i]; if (rw_initialized(&mw->mw_lock)) rw_destroy(&mw->mw_lock); } bzero(sc, sizeof(*sc)); return (0); } static int cxgbe_probe(device_t dev) { char buf[128]; struct port_info *pi = device_get_softc(dev); snprintf(buf, sizeof(buf), "port %d", pi->port_id); device_set_desc_copy(dev, buf); return (BUS_PROBE_DEFAULT); } #define T4_CAP (IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | \ IFCAP_VLAN_HWCSUM | IFCAP_TSO | IFCAP_JUMBO_MTU | IFCAP_LRO | \ IFCAP_VLAN_HWTSO | IFCAP_LINKSTATE | IFCAP_HWCSUM_IPV6 | IFCAP_HWSTATS) #define T4_CAP_ENABLE (T4_CAP) static int cxgbe_vi_attach(device_t dev, struct vi_info *vi) { struct ifnet *ifp; struct sbuf *sb; vi->xact_addr_filt = -1; callout_init(&vi->tick, 1); /* Allocate an ifnet and set it up */ ifp = if_alloc(IFT_ETHER); if (ifp == NULL) { device_printf(dev, "Cannot allocate ifnet\n"); return (ENOMEM); } vi->ifp = ifp; ifp->if_softc = vi; if_initname(ifp, device_get_name(dev), device_get_unit(dev)); ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_init = cxgbe_init; ifp->if_ioctl = cxgbe_ioctl; ifp->if_transmit = cxgbe_transmit; ifp->if_qflush = cxgbe_qflush; ifp->if_get_counter = cxgbe_get_counter; ifp->if_capabilities = T4_CAP; #ifdef TCP_OFFLOAD if (vi->nofldrxq != 0) ifp->if_capabilities |= IFCAP_TOE; #endif #ifdef DEV_NETMAP if (vi->nnmrxq != 0) ifp->if_capabilities |= IFCAP_NETMAP; #endif ifp->if_capenable = T4_CAP_ENABLE; ifp->if_hwassist = CSUM_TCP | CSUM_UDP | CSUM_IP | CSUM_TSO | CSUM_UDP_IPV6 | CSUM_TCP_IPV6; ifp->if_hw_tsomax = 65536 - (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN); ifp->if_hw_tsomaxsegcount = TX_SGL_SEGS; ifp->if_hw_tsomaxsegsize = 65536; /* Initialize ifmedia for this VI */ ifmedia_init(&vi->media, IFM_IMASK, cxgbe_media_change, cxgbe_media_status); vi->vlan_c = EVENTHANDLER_REGISTER(vlan_config, cxgbe_vlan_config, ifp, EVENTHANDLER_PRI_ANY); ether_ifattach(ifp, vi->hw_addr); #ifdef DEV_NETMAP if (ifp->if_capabilities & IFCAP_NETMAP) cxgbe_nm_attach(vi); #endif sb = sbuf_new_auto(); sbuf_printf(sb, "%d txq, %d rxq (NIC)", vi->ntxq, vi->nrxq); #ifdef TCP_OFFLOAD if (ifp->if_capabilities & IFCAP_TOE) sbuf_printf(sb, "; %d txq, %d rxq (TOE)", vi->nofldtxq, vi->nofldrxq); #endif #ifdef DEV_NETMAP if (ifp->if_capabilities & IFCAP_NETMAP) sbuf_printf(sb, "; %d txq, %d rxq (netmap)", vi->nnmtxq, vi->nnmrxq); #endif sbuf_finish(sb); device_printf(dev, "%s\n", sbuf_data(sb)); sbuf_delete(sb); vi_sysctls(vi); return (0); } static int cxgbe_attach(device_t dev) { struct port_info *pi = device_get_softc(dev); struct adapter *sc = pi->adapter; struct vi_info *vi; int i, rc; callout_init_mtx(&pi->tick, &pi->pi_lock, 0); rc = cxgbe_vi_attach(dev, &pi->vi[0]); if (rc) return (rc); for_each_vi(pi, i, vi) { if (i == 0) continue; vi->dev = device_add_child(dev, sc->names->vi_ifnet_name, -1); if (vi->dev == NULL) { device_printf(dev, "failed to add VI %d\n", i); continue; } device_set_softc(vi->dev, vi); } cxgbe_sysctls(pi); bus_generic_attach(dev); return (0); } static void cxgbe_vi_detach(struct vi_info *vi) { struct ifnet *ifp = vi->ifp; ether_ifdetach(ifp); if (vi->vlan_c) EVENTHANDLER_DEREGISTER(vlan_config, vi->vlan_c); /* Let detach proceed even if these fail. */ #ifdef DEV_NETMAP if (ifp->if_capabilities & IFCAP_NETMAP) cxgbe_nm_detach(vi); #endif cxgbe_uninit_synchronized(vi); callout_drain(&vi->tick); vi_full_uninit(vi); ifmedia_removeall(&vi->media); if_free(vi->ifp); vi->ifp = NULL; } static int cxgbe_detach(device_t dev) { struct port_info *pi = device_get_softc(dev); struct adapter *sc = pi->adapter; int rc; /* Detach the extra VIs first. */ rc = bus_generic_detach(dev); if (rc) return (rc); device_delete_children(dev); doom_vi(sc, &pi->vi[0]); if (pi->flags & HAS_TRACEQ) { sc->traceq = -1; /* cloner should not create ifnet */ t4_tracer_port_detach(sc); } cxgbe_vi_detach(&pi->vi[0]); callout_drain(&pi->tick); end_synchronized_op(sc, 0); return (0); } static void cxgbe_init(void *arg) { struct vi_info *vi = arg; struct adapter *sc = vi->pi->adapter; if (begin_synchronized_op(sc, vi, SLEEP_OK | INTR_OK, "t4init") != 0) return; cxgbe_init_synchronized(vi); end_synchronized_op(sc, 0); } static int cxgbe_ioctl(struct ifnet *ifp, unsigned long cmd, caddr_t data) { int rc = 0, mtu, flags, can_sleep; struct vi_info *vi = ifp->if_softc; struct adapter *sc = vi->pi->adapter; struct ifreq *ifr = (struct ifreq *)data; uint32_t mask; switch (cmd) { case SIOCSIFMTU: mtu = ifr->ifr_mtu; if (mtu < ETHERMIN || mtu > MAX_MTU) return (EINVAL); rc = begin_synchronized_op(sc, vi, SLEEP_OK | INTR_OK, "t4mtu"); if (rc) return (rc); ifp->if_mtu = mtu; if (vi->flags & VI_INIT_DONE) { t4_update_fl_bufsize(ifp); if (ifp->if_drv_flags & IFF_DRV_RUNNING) rc = update_mac_settings(ifp, XGMAC_MTU); } end_synchronized_op(sc, 0); break; case SIOCSIFFLAGS: can_sleep = 0; redo_sifflags: rc = begin_synchronized_op(sc, vi, can_sleep ? (SLEEP_OK | INTR_OK) : HOLD_LOCK, "t4flg"); if (rc) return (rc); if (ifp->if_flags & IFF_UP) { if (ifp->if_drv_flags & IFF_DRV_RUNNING) { flags = vi->if_flags; if ((ifp->if_flags ^ flags) & (IFF_PROMISC | IFF_ALLMULTI)) { if (can_sleep == 1) { end_synchronized_op(sc, 0); can_sleep = 0; goto redo_sifflags; } rc = update_mac_settings(ifp, XGMAC_PROMISC | XGMAC_ALLMULTI); } } else { if (can_sleep == 0) { end_synchronized_op(sc, LOCK_HELD); can_sleep = 1; goto redo_sifflags; } rc = cxgbe_init_synchronized(vi); } vi->if_flags = ifp->if_flags; } else if (ifp->if_drv_flags & IFF_DRV_RUNNING) { if (can_sleep == 0) { end_synchronized_op(sc, LOCK_HELD); can_sleep = 1; goto redo_sifflags; } rc = cxgbe_uninit_synchronized(vi); } end_synchronized_op(sc, can_sleep ? 0 : LOCK_HELD); break; case SIOCADDMULTI: case SIOCDELMULTI: /* these two are called with a mutex held :-( */ rc = begin_synchronized_op(sc, vi, HOLD_LOCK, "t4multi"); if (rc) return (rc); if (ifp->if_drv_flags & IFF_DRV_RUNNING) rc = update_mac_settings(ifp, XGMAC_MCADDRS); end_synchronized_op(sc, LOCK_HELD); break; case SIOCSIFCAP: rc = begin_synchronized_op(sc, vi, SLEEP_OK | INTR_OK, "t4cap"); if (rc) return (rc); mask = ifr->ifr_reqcap ^ ifp->if_capenable; if (mask & IFCAP_TXCSUM) { ifp->if_capenable ^= IFCAP_TXCSUM; ifp->if_hwassist ^= (CSUM_TCP | CSUM_UDP | CSUM_IP); if (IFCAP_TSO4 & ifp->if_capenable && !(IFCAP_TXCSUM & ifp->if_capenable)) { ifp->if_capenable &= ~IFCAP_TSO4; if_printf(ifp, "tso4 disabled due to -txcsum.\n"); } } if (mask & IFCAP_TXCSUM_IPV6) { ifp->if_capenable ^= IFCAP_TXCSUM_IPV6; ifp->if_hwassist ^= (CSUM_UDP_IPV6 | CSUM_TCP_IPV6); if (IFCAP_TSO6 & ifp->if_capenable && !(IFCAP_TXCSUM_IPV6 & ifp->if_capenable)) { ifp->if_capenable &= ~IFCAP_TSO6; if_printf(ifp, "tso6 disabled due to -txcsum6.\n"); } } if (mask & IFCAP_RXCSUM) ifp->if_capenable ^= IFCAP_RXCSUM; if (mask & IFCAP_RXCSUM_IPV6) ifp->if_capenable ^= IFCAP_RXCSUM_IPV6; /* * Note that we leave CSUM_TSO alone (it is always set). The * kernel takes both IFCAP_TSOx and CSUM_TSO into account before * sending a TSO request our way, so it's sufficient to toggle * IFCAP_TSOx only. */ if (mask & IFCAP_TSO4) { if (!(IFCAP_TSO4 & ifp->if_capenable) && !(IFCAP_TXCSUM & ifp->if_capenable)) { if_printf(ifp, "enable txcsum first.\n"); rc = EAGAIN; goto fail; } ifp->if_capenable ^= IFCAP_TSO4; } if (mask & IFCAP_TSO6) { if (!(IFCAP_TSO6 & ifp->if_capenable) && !(IFCAP_TXCSUM_IPV6 & ifp->if_capenable)) { if_printf(ifp, "enable txcsum6 first.\n"); rc = EAGAIN; goto fail; } ifp->if_capenable ^= IFCAP_TSO6; } if (mask & IFCAP_LRO) { #if defined(INET) || defined(INET6) int i; struct sge_rxq *rxq; ifp->if_capenable ^= IFCAP_LRO; for_each_rxq(vi, i, rxq) { if (ifp->if_capenable & IFCAP_LRO) rxq->iq.flags |= IQ_LRO_ENABLED; else rxq->iq.flags &= ~IQ_LRO_ENABLED; } #endif } #ifdef TCP_OFFLOAD if (mask & IFCAP_TOE) { int enable = (ifp->if_capenable ^ mask) & IFCAP_TOE; rc = toe_capability(vi, enable); if (rc != 0) goto fail; ifp->if_capenable ^= mask; } #endif if (mask & IFCAP_VLAN_HWTAGGING) { ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING; if (ifp->if_drv_flags & IFF_DRV_RUNNING) rc = update_mac_settings(ifp, XGMAC_VLANEX); } if (mask & IFCAP_VLAN_MTU) { ifp->if_capenable ^= IFCAP_VLAN_MTU; /* Need to find out how to disable auto-mtu-inflation */ } if (mask & IFCAP_VLAN_HWTSO) ifp->if_capenable ^= IFCAP_VLAN_HWTSO; if (mask & IFCAP_VLAN_HWCSUM) ifp->if_capenable ^= IFCAP_VLAN_HWCSUM; #ifdef VLAN_CAPABILITIES VLAN_CAPABILITIES(ifp); #endif fail: end_synchronized_op(sc, 0); break; case SIOCSIFMEDIA: case SIOCGIFMEDIA: case SIOCGIFXMEDIA: ifmedia_ioctl(ifp, ifr, &vi->media, cmd); break; case SIOCGI2C: { struct ifi2creq i2c; rc = copyin(ifr->ifr_data, &i2c, sizeof(i2c)); if (rc != 0) break; if (i2c.dev_addr != 0xA0 && i2c.dev_addr != 0xA2) { rc = EPERM; break; } if (i2c.len > sizeof(i2c.data)) { rc = EINVAL; break; } rc = begin_synchronized_op(sc, vi, SLEEP_OK | INTR_OK, "t4i2c"); if (rc) return (rc); rc = -t4_i2c_rd(sc, sc->mbox, vi->pi->port_id, i2c.dev_addr, i2c.offset, i2c.len, &i2c.data[0]); end_synchronized_op(sc, 0); if (rc == 0) rc = copyout(&i2c, ifr->ifr_data, sizeof(i2c)); break; } default: rc = ether_ioctl(ifp, cmd, data); } return (rc); } static int cxgbe_transmit(struct ifnet *ifp, struct mbuf *m) { struct vi_info *vi = ifp->if_softc; struct port_info *pi = vi->pi; struct adapter *sc = pi->adapter; struct sge_txq *txq; void *items[1]; int rc; M_ASSERTPKTHDR(m); MPASS(m->m_nextpkt == NULL); /* not quite ready for this yet */ if (__predict_false(pi->link_cfg.link_ok == 0)) { m_freem(m); return (ENETDOWN); } rc = parse_pkt(sc, &m); if (__predict_false(rc != 0)) { MPASS(m == NULL); /* was freed already */ atomic_add_int(&pi->tx_parse_error, 1); /* rare, atomic is ok */ return (rc); } /* Select a txq. */ txq = &sc->sge.txq[vi->first_txq]; if (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE) txq += ((m->m_pkthdr.flowid % (vi->ntxq - vi->rsrv_noflowq)) + vi->rsrv_noflowq); items[0] = m; rc = mp_ring_enqueue(txq->r, items, 1, 4096); if (__predict_false(rc != 0)) m_freem(m); return (rc); } static void cxgbe_qflush(struct ifnet *ifp) { struct vi_info *vi = ifp->if_softc; struct sge_txq *txq; int i; /* queues do not exist if !VI_INIT_DONE. */ if (vi->flags & VI_INIT_DONE) { for_each_txq(vi, i, txq) { TXQ_LOCK(txq); txq->eq.flags |= EQ_QFLUSH; TXQ_UNLOCK(txq); while (!mp_ring_is_idle(txq->r)) { mp_ring_check_drainage(txq->r, 0); pause("qflush", 1); } TXQ_LOCK(txq); txq->eq.flags &= ~EQ_QFLUSH; TXQ_UNLOCK(txq); } } if_qflush(ifp); } static uint64_t vi_get_counter(struct ifnet *ifp, ift_counter c) { struct vi_info *vi = ifp->if_softc; struct fw_vi_stats_vf *s = &vi->stats; vi_refresh_stats(vi->pi->adapter, vi); switch (c) { case IFCOUNTER_IPACKETS: return (s->rx_bcast_frames + s->rx_mcast_frames + s->rx_ucast_frames); case IFCOUNTER_IERRORS: return (s->rx_err_frames); case IFCOUNTER_OPACKETS: return (s->tx_bcast_frames + s->tx_mcast_frames + s->tx_ucast_frames + s->tx_offload_frames); case IFCOUNTER_OERRORS: return (s->tx_drop_frames); case IFCOUNTER_IBYTES: return (s->rx_bcast_bytes + s->rx_mcast_bytes + s->rx_ucast_bytes); case IFCOUNTER_OBYTES: return (s->tx_bcast_bytes + s->tx_mcast_bytes + s->tx_ucast_bytes + s->tx_offload_bytes); case IFCOUNTER_IMCASTS: return (s->rx_mcast_frames); case IFCOUNTER_OMCASTS: return (s->tx_mcast_frames); case IFCOUNTER_OQDROPS: { uint64_t drops; drops = 0; if (vi->flags & VI_INIT_DONE) { int i; struct sge_txq *txq; for_each_txq(vi, i, txq) drops += counter_u64_fetch(txq->r->drops); } return (drops); } default: return (if_get_counter_default(ifp, c)); } } uint64_t cxgbe_get_counter(struct ifnet *ifp, ift_counter c) { struct vi_info *vi = ifp->if_softc; struct port_info *pi = vi->pi; struct adapter *sc = pi->adapter; struct port_stats *s = &pi->stats; if (pi->nvi > 1 || sc->flags & IS_VF) return (vi_get_counter(ifp, c)); cxgbe_refresh_stats(sc, pi); switch (c) { case IFCOUNTER_IPACKETS: return (s->rx_frames); case IFCOUNTER_IERRORS: return (s->rx_jabber + s->rx_runt + s->rx_too_long + s->rx_fcs_err + s->rx_len_err); case IFCOUNTER_OPACKETS: return (s->tx_frames); case IFCOUNTER_OERRORS: return (s->tx_error_frames); case IFCOUNTER_IBYTES: return (s->rx_octets); case IFCOUNTER_OBYTES: return (s->tx_octets); case IFCOUNTER_IMCASTS: return (s->rx_mcast_frames); case IFCOUNTER_OMCASTS: return (s->tx_mcast_frames); case IFCOUNTER_IQDROPS: return (s->rx_ovflow0 + s->rx_ovflow1 + s->rx_ovflow2 + s->rx_ovflow3 + s->rx_trunc0 + s->rx_trunc1 + s->rx_trunc2 + s->rx_trunc3 + pi->tnl_cong_drops); case IFCOUNTER_OQDROPS: { uint64_t drops; drops = s->tx_drop; if (vi->flags & VI_INIT_DONE) { int i; struct sge_txq *txq; for_each_txq(vi, i, txq) drops += counter_u64_fetch(txq->r->drops); } return (drops); } default: return (if_get_counter_default(ifp, c)); } } static int cxgbe_media_change(struct ifnet *ifp) { struct vi_info *vi = ifp->if_softc; device_printf(vi->dev, "%s unimplemented.\n", __func__); return (EOPNOTSUPP); } static void cxgbe_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) { struct vi_info *vi = ifp->if_softc; struct port_info *pi = vi->pi; struct ifmedia_entry *cur; struct link_config *lc = &pi->link_cfg; /* * If all the interfaces are administratively down the firmware does not * report transceiver changes. Refresh port info here so that ifconfig * displays accurate information at all times. */ if (begin_synchronized_op(pi->adapter, NULL, SLEEP_OK | INTR_OK, "t4med") == 0) { PORT_LOCK(pi); if (pi->up_vis == 0) { t4_update_port_info(pi); build_medialist(pi, &vi->media); } PORT_UNLOCK(pi); end_synchronized_op(pi->adapter, 0); } cur = vi->media.ifm_cur; ifmr->ifm_status = IFM_AVALID; if (lc->link_ok == 0) return; ifmr->ifm_status |= IFM_ACTIVE; ifmr->ifm_active &= ~(IFM_ETH_TXPAUSE | IFM_ETH_RXPAUSE); if (lc->fc & PAUSE_RX) ifmr->ifm_active |= IFM_ETH_RXPAUSE; if (lc->fc & PAUSE_TX) ifmr->ifm_active |= IFM_ETH_TXPAUSE; /* active and current will differ iff current media is autoselect. */ if (IFM_SUBTYPE(cur->ifm_media) != IFM_AUTO) return; ifmr->ifm_active = IFM_ETHER | IFM_FDX; if (lc->fc & PAUSE_RX) ifmr->ifm_active |= IFM_ETH_RXPAUSE; if (lc->fc & PAUSE_TX) ifmr->ifm_active |= IFM_ETH_TXPAUSE; switch (lc->speed) { case 10000: ifmr->ifm_active |= IFM_10G_T; break; case 1000: ifmr->ifm_active |= IFM_1000_T; break; case 100: ifmr->ifm_active |= IFM_100_TX; break; case 10: ifmr->ifm_active |= IFM_10_T; break; default: device_printf(vi->dev, "link up but speed unknown (%u)\n", lc->speed); } } static int vcxgbe_probe(device_t dev) { char buf[128]; struct vi_info *vi = device_get_softc(dev); snprintf(buf, sizeof(buf), "port %d vi %td", vi->pi->port_id, vi - vi->pi->vi); device_set_desc_copy(dev, buf); return (BUS_PROBE_DEFAULT); } static int vcxgbe_attach(device_t dev) { struct vi_info *vi; struct port_info *pi; struct adapter *sc; int func, index, rc; u32 param, val; vi = device_get_softc(dev); pi = vi->pi; sc = pi->adapter; index = vi - pi->vi; KASSERT(index < nitems(vi_mac_funcs), ("%s: VI %s doesn't have a MAC func", __func__, device_get_nameunit(dev))); func = vi_mac_funcs[index]; rc = t4_alloc_vi_func(sc, sc->mbox, pi->tx_chan, sc->pf, 0, 1, vi->hw_addr, &vi->rss_size, func, 0); if (rc < 0) { device_printf(dev, "Failed to allocate virtual interface " "for port %d: %d\n", pi->port_id, -rc); return (-rc); } vi->viid = rc; if (chip_id(sc) <= CHELSIO_T5) vi->smt_idx = (rc & 0x7f) << 1; else vi->smt_idx = (rc & 0x7f); param = V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_RSSINFO) | V_FW_PARAMS_PARAM_YZ(vi->viid); rc = t4_query_params(sc, sc->mbox, sc->pf, 0, 1, ¶m, &val); if (rc) vi->rss_base = 0xffff; else { /* MPASS((val >> 16) == rss_size); */ vi->rss_base = val & 0xffff; } rc = cxgbe_vi_attach(dev, vi); if (rc) { t4_free_vi(sc, sc->mbox, sc->pf, 0, vi->viid); return (rc); } return (0); } static int vcxgbe_detach(device_t dev) { struct vi_info *vi; struct adapter *sc; vi = device_get_softc(dev); sc = vi->pi->adapter; doom_vi(sc, vi); cxgbe_vi_detach(vi); t4_free_vi(sc, sc->mbox, sc->pf, 0, vi->viid); end_synchronized_op(sc, 0); return (0); } void t4_fatal_err(struct adapter *sc) { t4_set_reg_field(sc, A_SGE_CONTROL, F_GLOBALENABLE, 0); t4_intr_disable(sc); log(LOG_EMERG, "%s: encountered fatal error, adapter stopped.\n", device_get_nameunit(sc->dev)); } void t4_add_adapter(struct adapter *sc) { sx_xlock(&t4_list_lock); SLIST_INSERT_HEAD(&t4_list, sc, link); sx_xunlock(&t4_list_lock); } int t4_map_bars_0_and_4(struct adapter *sc) { sc->regs_rid = PCIR_BAR(0); sc->regs_res = bus_alloc_resource_any(sc->dev, SYS_RES_MEMORY, &sc->regs_rid, RF_ACTIVE); if (sc->regs_res == NULL) { device_printf(sc->dev, "cannot map registers.\n"); return (ENXIO); } sc->bt = rman_get_bustag(sc->regs_res); sc->bh = rman_get_bushandle(sc->regs_res); sc->mmio_len = rman_get_size(sc->regs_res); setbit(&sc->doorbells, DOORBELL_KDB); sc->msix_rid = PCIR_BAR(4); sc->msix_res = bus_alloc_resource_any(sc->dev, SYS_RES_MEMORY, &sc->msix_rid, RF_ACTIVE); if (sc->msix_res == NULL) { device_printf(sc->dev, "cannot map MSI-X BAR.\n"); return (ENXIO); } return (0); } int t4_map_bar_2(struct adapter *sc) { /* * T4: only iWARP driver uses the userspace doorbells. There is no need * to map it if RDMA is disabled. */ if (is_t4(sc) && sc->rdmacaps == 0) return (0); sc->udbs_rid = PCIR_BAR(2); sc->udbs_res = bus_alloc_resource_any(sc->dev, SYS_RES_MEMORY, &sc->udbs_rid, RF_ACTIVE); if (sc->udbs_res == NULL) { device_printf(sc->dev, "cannot map doorbell BAR.\n"); return (ENXIO); } sc->udbs_base = rman_get_virtual(sc->udbs_res); if (chip_id(sc) >= CHELSIO_T5) { setbit(&sc->doorbells, DOORBELL_UDB); #if defined(__i386__) || defined(__amd64__) if (t5_write_combine) { int rc, mode; /* * Enable write combining on BAR2. This is the * userspace doorbell BAR and is split into 128B * (UDBS_SEG_SIZE) doorbell regions, each associated * with an egress queue. The first 64B has the doorbell * and the second 64B can be used to submit a tx work * request with an implicit doorbell. */ rc = pmap_change_attr((vm_offset_t)sc->udbs_base, rman_get_size(sc->udbs_res), PAT_WRITE_COMBINING); if (rc == 0) { clrbit(&sc->doorbells, DOORBELL_UDB); setbit(&sc->doorbells, DOORBELL_WCWR); setbit(&sc->doorbells, DOORBELL_UDBWC); } else { device_printf(sc->dev, "couldn't enable write combining: %d\n", rc); } mode = is_t5(sc) ? V_STATMODE(0) : V_T6_STATMODE(0); t4_write_reg(sc, A_SGE_STAT_CFG, V_STATSOURCE_T5(7) | mode); } #endif } return (0); } struct memwin_init { uint32_t base; uint32_t aperture; }; static const struct memwin_init t4_memwin[NUM_MEMWIN] = { { MEMWIN0_BASE, MEMWIN0_APERTURE }, { MEMWIN1_BASE, MEMWIN1_APERTURE }, { MEMWIN2_BASE_T4, MEMWIN2_APERTURE_T4 } }; static const struct memwin_init t5_memwin[NUM_MEMWIN] = { { MEMWIN0_BASE, MEMWIN0_APERTURE }, { MEMWIN1_BASE, MEMWIN1_APERTURE }, { MEMWIN2_BASE_T5, MEMWIN2_APERTURE_T5 }, }; static void setup_memwin(struct adapter *sc) { const struct memwin_init *mw_init; struct memwin *mw; int i; uint32_t bar0; if (is_t4(sc)) { /* * Read low 32b of bar0 indirectly via the hardware backdoor * mechanism. Works from within PCI passthrough environments * too, where rman_get_start() can return a different value. We * need to program the T4 memory window decoders with the actual * addresses that will be coming across the PCIe link. */ bar0 = t4_hw_pci_read_cfg4(sc, PCIR_BAR(0)); bar0 &= (uint32_t) PCIM_BAR_MEM_BASE; mw_init = &t4_memwin[0]; } else { /* T5+ use the relative offset inside the PCIe BAR */ bar0 = 0; mw_init = &t5_memwin[0]; } for (i = 0, mw = &sc->memwin[0]; i < NUM_MEMWIN; i++, mw_init++, mw++) { rw_init(&mw->mw_lock, "memory window access"); mw->mw_base = mw_init->base; mw->mw_aperture = mw_init->aperture; mw->mw_curpos = 0; t4_write_reg(sc, PCIE_MEM_ACCESS_REG(A_PCIE_MEM_ACCESS_BASE_WIN, i), (mw->mw_base + bar0) | V_BIR(0) | V_WINDOW(ilog2(mw->mw_aperture) - 10)); rw_wlock(&mw->mw_lock); position_memwin(sc, i, 0); rw_wunlock(&mw->mw_lock); } /* flush */ t4_read_reg(sc, PCIE_MEM_ACCESS_REG(A_PCIE_MEM_ACCESS_BASE_WIN, 2)); } /* * Positions the memory window at the given address in the card's address space. * There are some alignment requirements and the actual position may be at an * address prior to the requested address. mw->mw_curpos always has the actual * position of the window. */ static void position_memwin(struct adapter *sc, int idx, uint32_t addr) { struct memwin *mw; uint32_t pf; uint32_t reg; MPASS(idx >= 0 && idx < NUM_MEMWIN); mw = &sc->memwin[idx]; rw_assert(&mw->mw_lock, RA_WLOCKED); if (is_t4(sc)) { pf = 0; mw->mw_curpos = addr & ~0xf; /* start must be 16B aligned */ } else { pf = V_PFNUM(sc->pf); mw->mw_curpos = addr & ~0x7f; /* start must be 128B aligned */ } reg = PCIE_MEM_ACCESS_REG(A_PCIE_MEM_ACCESS_OFFSET, idx); t4_write_reg(sc, reg, mw->mw_curpos | pf); t4_read_reg(sc, reg); /* flush */ } static int rw_via_memwin(struct adapter *sc, int idx, uint32_t addr, uint32_t *val, int len, int rw) { struct memwin *mw; uint32_t mw_end, v; MPASS(idx >= 0 && idx < NUM_MEMWIN); /* Memory can only be accessed in naturally aligned 4 byte units */ if (addr & 3 || len & 3 || len <= 0) return (EINVAL); mw = &sc->memwin[idx]; while (len > 0) { rw_rlock(&mw->mw_lock); mw_end = mw->mw_curpos + mw->mw_aperture; if (addr >= mw_end || addr < mw->mw_curpos) { /* Will need to reposition the window */ if (!rw_try_upgrade(&mw->mw_lock)) { rw_runlock(&mw->mw_lock); rw_wlock(&mw->mw_lock); } rw_assert(&mw->mw_lock, RA_WLOCKED); position_memwin(sc, idx, addr); rw_downgrade(&mw->mw_lock); mw_end = mw->mw_curpos + mw->mw_aperture; } rw_assert(&mw->mw_lock, RA_RLOCKED); while (addr < mw_end && len > 0) { if (rw == 0) { v = t4_read_reg(sc, mw->mw_base + addr - mw->mw_curpos); *val++ = le32toh(v); } else { v = *val++; t4_write_reg(sc, mw->mw_base + addr - mw->mw_curpos, htole32(v)); } addr += 4; len -= 4; } rw_runlock(&mw->mw_lock); } return (0); } static inline int read_via_memwin(struct adapter *sc, int idx, uint32_t addr, uint32_t *val, int len) { return (rw_via_memwin(sc, idx, addr, val, len, 0)); } static inline int write_via_memwin(struct adapter *sc, int idx, uint32_t addr, const uint32_t *val, int len) { return (rw_via_memwin(sc, idx, addr, (void *)(uintptr_t)val, len, 1)); } static int t4_range_cmp(const void *a, const void *b) { return ((const struct t4_range *)a)->start - ((const struct t4_range *)b)->start; } /* * Verify that the memory range specified by the addr/len pair is valid within * the card's address space. */ static int validate_mem_range(struct adapter *sc, uint32_t addr, int len) { struct t4_range mem_ranges[4], *r, *next; uint32_t em, addr_len; int i, n, remaining; /* Memory can only be accessed in naturally aligned 4 byte units */ if (addr & 3 || len & 3 || len <= 0) return (EINVAL); /* Enabled memories */ em = t4_read_reg(sc, A_MA_TARGET_MEM_ENABLE); r = &mem_ranges[0]; n = 0; bzero(r, sizeof(mem_ranges)); if (em & F_EDRAM0_ENABLE) { addr_len = t4_read_reg(sc, A_MA_EDRAM0_BAR); r->size = G_EDRAM0_SIZE(addr_len) << 20; if (r->size > 0) { r->start = G_EDRAM0_BASE(addr_len) << 20; if (addr >= r->start && addr + len <= r->start + r->size) return (0); r++; n++; } } if (em & F_EDRAM1_ENABLE) { addr_len = t4_read_reg(sc, A_MA_EDRAM1_BAR); r->size = G_EDRAM1_SIZE(addr_len) << 20; if (r->size > 0) { r->start = G_EDRAM1_BASE(addr_len) << 20; if (addr >= r->start && addr + len <= r->start + r->size) return (0); r++; n++; } } if (em & F_EXT_MEM_ENABLE) { addr_len = t4_read_reg(sc, A_MA_EXT_MEMORY_BAR); r->size = G_EXT_MEM_SIZE(addr_len) << 20; if (r->size > 0) { r->start = G_EXT_MEM_BASE(addr_len) << 20; if (addr >= r->start && addr + len <= r->start + r->size) return (0); r++; n++; } } if (is_t5(sc) && em & F_EXT_MEM1_ENABLE) { addr_len = t4_read_reg(sc, A_MA_EXT_MEMORY1_BAR); r->size = G_EXT_MEM1_SIZE(addr_len) << 20; if (r->size > 0) { r->start = G_EXT_MEM1_BASE(addr_len) << 20; if (addr >= r->start && addr + len <= r->start + r->size) return (0); r++; n++; } } MPASS(n <= nitems(mem_ranges)); if (n > 1) { /* Sort and merge the ranges. */ qsort(mem_ranges, n, sizeof(struct t4_range), t4_range_cmp); /* Start from index 0 and examine the next n - 1 entries. */ r = &mem_ranges[0]; for (remaining = n - 1; remaining > 0; remaining--, r++) { MPASS(r->size > 0); /* r is a valid entry. */ next = r + 1; MPASS(next->size > 0); /* and so is the next one. */ while (r->start + r->size >= next->start) { /* Merge the next one into the current entry. */ r->size = max(r->start + r->size, next->start + next->size) - r->start; n--; /* One fewer entry in total. */ if (--remaining == 0) goto done; /* short circuit */ next++; } if (next != r + 1) { /* * Some entries were merged into r and next * points to the first valid entry that couldn't * be merged. */ MPASS(next->size > 0); /* must be valid */ memcpy(r + 1, next, remaining * sizeof(*r)); #ifdef INVARIANTS /* * This so that the foo->size assertion in the * next iteration of the loop do the right * thing for entries that were pulled up and are * no longer valid. */ MPASS(n < nitems(mem_ranges)); bzero(&mem_ranges[n], (nitems(mem_ranges) - n) * sizeof(struct t4_range)); #endif } } done: /* Done merging the ranges. */ MPASS(n > 0); r = &mem_ranges[0]; for (i = 0; i < n; i++, r++) { if (addr >= r->start && addr + len <= r->start + r->size) return (0); } } return (EFAULT); } static int fwmtype_to_hwmtype(int mtype) { switch (mtype) { case FW_MEMTYPE_EDC0: return (MEM_EDC0); case FW_MEMTYPE_EDC1: return (MEM_EDC1); case FW_MEMTYPE_EXTMEM: return (MEM_MC0); case FW_MEMTYPE_EXTMEM1: return (MEM_MC1); default: panic("%s: cannot translate fw mtype %d.", __func__, mtype); } } /* * Verify that the memory range specified by the memtype/offset/len pair is * valid and lies entirely within the memtype specified. The global address of * the start of the range is returned in addr. */ static int validate_mt_off_len(struct adapter *sc, int mtype, uint32_t off, int len, uint32_t *addr) { uint32_t em, addr_len, maddr; /* Memory can only be accessed in naturally aligned 4 byte units */ if (off & 3 || len & 3 || len == 0) return (EINVAL); em = t4_read_reg(sc, A_MA_TARGET_MEM_ENABLE); switch (fwmtype_to_hwmtype(mtype)) { case MEM_EDC0: if (!(em & F_EDRAM0_ENABLE)) return (EINVAL); addr_len = t4_read_reg(sc, A_MA_EDRAM0_BAR); maddr = G_EDRAM0_BASE(addr_len) << 20; break; case MEM_EDC1: if (!(em & F_EDRAM1_ENABLE)) return (EINVAL); addr_len = t4_read_reg(sc, A_MA_EDRAM1_BAR); maddr = G_EDRAM1_BASE(addr_len) << 20; break; case MEM_MC: if (!(em & F_EXT_MEM_ENABLE)) return (EINVAL); addr_len = t4_read_reg(sc, A_MA_EXT_MEMORY_BAR); maddr = G_EXT_MEM_BASE(addr_len) << 20; break; case MEM_MC1: if (!is_t5(sc) || !(em & F_EXT_MEM1_ENABLE)) return (EINVAL); addr_len = t4_read_reg(sc, A_MA_EXT_MEMORY1_BAR); maddr = G_EXT_MEM1_BASE(addr_len) << 20; break; default: return (EINVAL); } *addr = maddr + off; /* global address */ return (validate_mem_range(sc, *addr, len)); } static int fixup_devlog_params(struct adapter *sc) { struct devlog_params *dparams = &sc->params.devlog; int rc; rc = validate_mt_off_len(sc, dparams->memtype, dparams->start, dparams->size, &dparams->addr); return (rc); } static int cfg_itype_and_nqueues(struct adapter *sc, int n10g, int n1g, int num_vis, struct intrs_and_queues *iaq) { int rc, itype, navail, nrxq10g, nrxq1g, n; int nofldrxq10g = 0, nofldrxq1g = 0; bzero(iaq, sizeof(*iaq)); iaq->ntxq10g = t4_ntxq10g; iaq->ntxq1g = t4_ntxq1g; iaq->ntxq_vi = t4_ntxq_vi; iaq->nrxq10g = nrxq10g = t4_nrxq10g; iaq->nrxq1g = nrxq1g = t4_nrxq1g; iaq->nrxq_vi = t4_nrxq_vi; iaq->rsrv_noflowq = t4_rsrv_noflowq; #ifdef TCP_OFFLOAD if (is_offload(sc)) { iaq->nofldtxq10g = t4_nofldtxq10g; iaq->nofldtxq1g = t4_nofldtxq1g; iaq->nofldtxq_vi = t4_nofldtxq_vi; iaq->nofldrxq10g = nofldrxq10g = t4_nofldrxq10g; iaq->nofldrxq1g = nofldrxq1g = t4_nofldrxq1g; iaq->nofldrxq_vi = t4_nofldrxq_vi; } #endif #ifdef DEV_NETMAP iaq->nnmtxq_vi = t4_nnmtxq_vi; iaq->nnmrxq_vi = t4_nnmrxq_vi; #endif for (itype = INTR_MSIX; itype; itype >>= 1) { if ((itype & t4_intr_types) == 0) continue; /* not allowed */ if (itype == INTR_MSIX) navail = pci_msix_count(sc->dev); else if (itype == INTR_MSI) navail = pci_msi_count(sc->dev); else navail = 1; restart: if (navail == 0) continue; iaq->intr_type = itype; iaq->intr_flags_10g = 0; iaq->intr_flags_1g = 0; /* * Best option: an interrupt vector for errors, one for the * firmware event queue, and one for every rxq (NIC and TOE) of * every VI. The VIs that support netmap use the same * interrupts for the NIC rx queues and the netmap rx queues * because only one set of queues is active at a time. */ iaq->nirq = T4_EXTRA_INTR; iaq->nirq += n10g * (nrxq10g + nofldrxq10g); iaq->nirq += n1g * (nrxq1g + nofldrxq1g); iaq->nirq += (n10g + n1g) * (num_vis - 1) * max(iaq->nrxq_vi, iaq->nnmrxq_vi); /* See comment above. */ iaq->nirq += (n10g + n1g) * (num_vis - 1) * iaq->nofldrxq_vi; if (iaq->nirq <= navail && (itype != INTR_MSI || powerof2(iaq->nirq))) { iaq->intr_flags_10g = INTR_ALL; iaq->intr_flags_1g = INTR_ALL; goto allocate; } /* Disable the VIs (and netmap) if there aren't enough intrs */ if (num_vis > 1) { device_printf(sc->dev, "virtual interfaces disabled " "because num_vis=%u with current settings " "(nrxq10g=%u, nrxq1g=%u, nofldrxq10g=%u, " "nofldrxq1g=%u, nrxq_vi=%u nofldrxq_vi=%u, " "nnmrxq_vi=%u) would need %u interrupts but " "only %u are available.\n", num_vis, nrxq10g, nrxq1g, nofldrxq10g, nofldrxq1g, iaq->nrxq_vi, iaq->nofldrxq_vi, iaq->nnmrxq_vi, iaq->nirq, navail); num_vis = 1; iaq->ntxq_vi = iaq->nrxq_vi = 0; iaq->nofldtxq_vi = iaq->nofldrxq_vi = 0; iaq->nnmtxq_vi = iaq->nnmrxq_vi = 0; goto restart; } /* * Second best option: a vector for errors, one for the firmware * event queue, and vectors for either all the NIC rx queues or * all the TOE rx queues. The queues that don't get vectors * will forward their interrupts to those that do. */ iaq->nirq = T4_EXTRA_INTR; if (nrxq10g >= nofldrxq10g) { iaq->intr_flags_10g = INTR_RXQ; iaq->nirq += n10g * nrxq10g; } else { iaq->intr_flags_10g = INTR_OFLD_RXQ; iaq->nirq += n10g * nofldrxq10g; } if (nrxq1g >= nofldrxq1g) { iaq->intr_flags_1g = INTR_RXQ; iaq->nirq += n1g * nrxq1g; } else { iaq->intr_flags_1g = INTR_OFLD_RXQ; iaq->nirq += n1g * nofldrxq1g; } if (iaq->nirq <= navail && (itype != INTR_MSI || powerof2(iaq->nirq))) goto allocate; /* * Next best option: an interrupt vector for errors, one for the * firmware event queue, and at least one per main-VI. At this * point we know we'll have to downsize nrxq and/or nofldrxq to * fit what's available to us. */ iaq->nirq = T4_EXTRA_INTR; iaq->nirq += n10g + n1g; if (iaq->nirq <= navail) { int leftover = navail - iaq->nirq; if (n10g > 0) { int target = max(nrxq10g, nofldrxq10g); iaq->intr_flags_10g = nrxq10g >= nofldrxq10g ? INTR_RXQ : INTR_OFLD_RXQ; n = 1; while (n < target && leftover >= n10g) { leftover -= n10g; iaq->nirq += n10g; n++; } iaq->nrxq10g = min(n, nrxq10g); #ifdef TCP_OFFLOAD iaq->nofldrxq10g = min(n, nofldrxq10g); #endif } if (n1g > 0) { int target = max(nrxq1g, nofldrxq1g); iaq->intr_flags_1g = nrxq1g >= nofldrxq1g ? INTR_RXQ : INTR_OFLD_RXQ; n = 1; while (n < target && leftover >= n1g) { leftover -= n1g; iaq->nirq += n1g; n++; } iaq->nrxq1g = min(n, nrxq1g); #ifdef TCP_OFFLOAD iaq->nofldrxq1g = min(n, nofldrxq1g); #endif } if (itype != INTR_MSI || powerof2(iaq->nirq)) goto allocate; } /* * Least desirable option: one interrupt vector for everything. */ iaq->nirq = iaq->nrxq10g = iaq->nrxq1g = 1; iaq->intr_flags_10g = iaq->intr_flags_1g = 0; #ifdef TCP_OFFLOAD if (is_offload(sc)) iaq->nofldrxq10g = iaq->nofldrxq1g = 1; #endif allocate: navail = iaq->nirq; rc = 0; if (itype == INTR_MSIX) rc = pci_alloc_msix(sc->dev, &navail); else if (itype == INTR_MSI) rc = pci_alloc_msi(sc->dev, &navail); if (rc == 0) { if (navail == iaq->nirq) return (0); /* * Didn't get the number requested. Use whatever number * the kernel is willing to allocate (it's in navail). */ device_printf(sc->dev, "fewer vectors than requested, " "type=%d, req=%d, rcvd=%d; will downshift req.\n", itype, iaq->nirq, navail); pci_release_msi(sc->dev); goto restart; } device_printf(sc->dev, "failed to allocate vectors:%d, type=%d, req=%d, rcvd=%d\n", itype, rc, iaq->nirq, navail); } device_printf(sc->dev, "failed to find a usable interrupt type. " "allowed=%d, msi-x=%d, msi=%d, intx=1", t4_intr_types, pci_msix_count(sc->dev), pci_msi_count(sc->dev)); return (ENXIO); } #define FW_VERSION(chip) ( \ V_FW_HDR_FW_VER_MAJOR(chip##FW_VERSION_MAJOR) | \ V_FW_HDR_FW_VER_MINOR(chip##FW_VERSION_MINOR) | \ V_FW_HDR_FW_VER_MICRO(chip##FW_VERSION_MICRO) | \ V_FW_HDR_FW_VER_BUILD(chip##FW_VERSION_BUILD)) #define FW_INTFVER(chip, intf) (chip##FW_HDR_INTFVER_##intf) struct fw_info { uint8_t chip; char *kld_name; char *fw_mod_name; struct fw_hdr fw_hdr; /* XXX: waste of space, need a sparse struct */ } fw_info[] = { { .chip = CHELSIO_T4, .kld_name = "t4fw_cfg", .fw_mod_name = "t4fw", .fw_hdr = { .chip = FW_HDR_CHIP_T4, .fw_ver = htobe32_const(FW_VERSION(T4)), .intfver_nic = FW_INTFVER(T4, NIC), .intfver_vnic = FW_INTFVER(T4, VNIC), .intfver_ofld = FW_INTFVER(T4, OFLD), .intfver_ri = FW_INTFVER(T4, RI), .intfver_iscsipdu = FW_INTFVER(T4, ISCSIPDU), .intfver_iscsi = FW_INTFVER(T4, ISCSI), .intfver_fcoepdu = FW_INTFVER(T4, FCOEPDU), .intfver_fcoe = FW_INTFVER(T4, FCOE), }, }, { .chip = CHELSIO_T5, .kld_name = "t5fw_cfg", .fw_mod_name = "t5fw", .fw_hdr = { .chip = FW_HDR_CHIP_T5, .fw_ver = htobe32_const(FW_VERSION(T5)), .intfver_nic = FW_INTFVER(T5, NIC), .intfver_vnic = FW_INTFVER(T5, VNIC), .intfver_ofld = FW_INTFVER(T5, OFLD), .intfver_ri = FW_INTFVER(T5, RI), .intfver_iscsipdu = FW_INTFVER(T5, ISCSIPDU), .intfver_iscsi = FW_INTFVER(T5, ISCSI), .intfver_fcoepdu = FW_INTFVER(T5, FCOEPDU), .intfver_fcoe = FW_INTFVER(T5, FCOE), }, }, { .chip = CHELSIO_T6, .kld_name = "t6fw_cfg", .fw_mod_name = "t6fw", .fw_hdr = { .chip = FW_HDR_CHIP_T6, .fw_ver = htobe32_const(FW_VERSION(T6)), .intfver_nic = FW_INTFVER(T6, NIC), .intfver_vnic = FW_INTFVER(T6, VNIC), .intfver_ofld = FW_INTFVER(T6, OFLD), .intfver_ri = FW_INTFVER(T6, RI), .intfver_iscsipdu = FW_INTFVER(T6, ISCSIPDU), .intfver_iscsi = FW_INTFVER(T6, ISCSI), .intfver_fcoepdu = FW_INTFVER(T6, FCOEPDU), .intfver_fcoe = FW_INTFVER(T6, FCOE), }, } }; static struct fw_info * find_fw_info(int chip) { int i; for (i = 0; i < nitems(fw_info); i++) { if (fw_info[i].chip == chip) return (&fw_info[i]); } return (NULL); } /* * Is the given firmware API compatible with the one the driver was compiled * with? */ static int fw_compatible(const struct fw_hdr *hdr1, const struct fw_hdr *hdr2) { /* short circuit if it's the exact same firmware version */ if (hdr1->chip == hdr2->chip && hdr1->fw_ver == hdr2->fw_ver) return (1); /* * XXX: Is this too conservative? Perhaps I should limit this to the * features that are supported in the driver. */ #define SAME_INTF(x) (hdr1->intfver_##x == hdr2->intfver_##x) if (hdr1->chip == hdr2->chip && SAME_INTF(nic) && SAME_INTF(vnic) && SAME_INTF(ofld) && SAME_INTF(ri) && SAME_INTF(iscsipdu) && SAME_INTF(iscsi) && SAME_INTF(fcoepdu) && SAME_INTF(fcoe)) return (1); #undef SAME_INTF return (0); } /* * The firmware in the KLD is usable, but should it be installed? This routine * explains itself in detail if it indicates the KLD firmware should be * installed. */ static int should_install_kld_fw(struct adapter *sc, int card_fw_usable, int k, int c) { const char *reason; if (!card_fw_usable) { reason = "incompatible or unusable"; goto install; } if (k > c) { reason = "older than the version bundled with this driver"; goto install; } if (t4_fw_install == 2 && k != c) { reason = "different than the version bundled with this driver"; goto install; } return (0); install: if (t4_fw_install == 0) { device_printf(sc->dev, "firmware on card (%u.%u.%u.%u) is %s, " "but the driver is prohibited from installing a different " "firmware on the card.\n", G_FW_HDR_FW_VER_MAJOR(c), G_FW_HDR_FW_VER_MINOR(c), G_FW_HDR_FW_VER_MICRO(c), G_FW_HDR_FW_VER_BUILD(c), reason); return (0); } device_printf(sc->dev, "firmware on card (%u.%u.%u.%u) is %s, " "installing firmware %u.%u.%u.%u on card.\n", G_FW_HDR_FW_VER_MAJOR(c), G_FW_HDR_FW_VER_MINOR(c), G_FW_HDR_FW_VER_MICRO(c), G_FW_HDR_FW_VER_BUILD(c), reason, G_FW_HDR_FW_VER_MAJOR(k), G_FW_HDR_FW_VER_MINOR(k), G_FW_HDR_FW_VER_MICRO(k), G_FW_HDR_FW_VER_BUILD(k)); return (1); } /* * Establish contact with the firmware and determine if we are the master driver * or not, and whether we are responsible for chip initialization. */ static int prep_firmware(struct adapter *sc) { const struct firmware *fw = NULL, *default_cfg; int rc, pf, card_fw_usable, kld_fw_usable, need_fw_reset = 1; enum dev_state state; struct fw_info *fw_info; struct fw_hdr *card_fw; /* fw on the card */ const struct fw_hdr *kld_fw; /* fw in the KLD */ const struct fw_hdr *drv_fw; /* fw header the driver was compiled against */ /* This is the firmware whose headers the driver was compiled against */ fw_info = find_fw_info(chip_id(sc)); if (fw_info == NULL) { device_printf(sc->dev, "unable to look up firmware information for chip %d.\n", chip_id(sc)); return (EINVAL); } drv_fw = &fw_info->fw_hdr; /* * The firmware KLD contains many modules. The KLD name is also the * name of the module that contains the default config file. */ default_cfg = firmware_get(fw_info->kld_name); /* This is the firmware in the KLD */ fw = firmware_get(fw_info->fw_mod_name); if (fw != NULL) { kld_fw = (const void *)fw->data; kld_fw_usable = fw_compatible(drv_fw, kld_fw); } else { kld_fw = NULL; kld_fw_usable = 0; } /* Read the header of the firmware on the card */ card_fw = malloc(sizeof(*card_fw), M_CXGBE, M_ZERO | M_WAITOK); rc = -t4_read_flash(sc, FLASH_FW_START, sizeof (*card_fw) / sizeof (uint32_t), (uint32_t *)card_fw, 1); if (rc == 0) { card_fw_usable = fw_compatible(drv_fw, (const void*)card_fw); if (card_fw->fw_ver == be32toh(0xffffffff)) { uint32_t d = be32toh(kld_fw->fw_ver); if (!kld_fw_usable) { device_printf(sc->dev, "no firmware on the card and no usable " "firmware bundled with the driver.\n"); rc = EIO; goto done; } else if (t4_fw_install == 0) { device_printf(sc->dev, "no firmware on the card and the driver " "is prohibited from installing new " "firmware.\n"); rc = EIO; goto done; } device_printf(sc->dev, "no firmware on the card, " "installing firmware %d.%d.%d.%d\n", G_FW_HDR_FW_VER_MAJOR(d), G_FW_HDR_FW_VER_MINOR(d), G_FW_HDR_FW_VER_MICRO(d), G_FW_HDR_FW_VER_BUILD(d)); rc = t4_fw_forceinstall(sc, fw->data, fw->datasize); if (rc < 0) { rc = -rc; device_printf(sc->dev, "firmware install failed: %d.\n", rc); goto done; } memcpy(card_fw, kld_fw, sizeof(*card_fw)); card_fw_usable = 1; need_fw_reset = 0; } } else { device_printf(sc->dev, "Unable to read card's firmware header: %d\n", rc); card_fw_usable = 0; } /* Contact firmware. */ rc = t4_fw_hello(sc, sc->mbox, sc->mbox, MASTER_MAY, &state); if (rc < 0 || state == DEV_STATE_ERR) { rc = -rc; device_printf(sc->dev, "failed to connect to the firmware: %d, %d.\n", rc, state); goto done; } pf = rc; if (pf == sc->mbox) sc->flags |= MASTER_PF; else if (state == DEV_STATE_UNINIT) { /* * We didn't get to be the master so we definitely won't be * configuring the chip. It's a bug if someone else hasn't * configured it already. */ device_printf(sc->dev, "couldn't be master(%d), " "device not already initialized either(%d).\n", rc, state); rc = EPROTO; goto done; } if (card_fw_usable && card_fw->fw_ver == drv_fw->fw_ver && (!kld_fw_usable || kld_fw->fw_ver == drv_fw->fw_ver)) { /* * Common case: the firmware on the card is an exact match and * the KLD is an exact match too, or the KLD is * absent/incompatible. Note that t4_fw_install = 2 is ignored * here -- use cxgbetool loadfw if you want to reinstall the * same firmware as the one on the card. */ } else if (kld_fw_usable && state == DEV_STATE_UNINIT && should_install_kld_fw(sc, card_fw_usable, be32toh(kld_fw->fw_ver), be32toh(card_fw->fw_ver))) { rc = -t4_fw_upgrade(sc, sc->mbox, fw->data, fw->datasize, 0); if (rc != 0) { device_printf(sc->dev, "failed to install firmware: %d\n", rc); goto done; } /* Installed successfully, update the cached header too. */ memcpy(card_fw, kld_fw, sizeof(*card_fw)); card_fw_usable = 1; need_fw_reset = 0; /* already reset as part of load_fw */ } if (!card_fw_usable) { uint32_t d, c, k; d = ntohl(drv_fw->fw_ver); c = ntohl(card_fw->fw_ver); k = kld_fw ? ntohl(kld_fw->fw_ver) : 0; device_printf(sc->dev, "Cannot find a usable firmware: " "fw_install %d, chip state %d, " "driver compiled with %d.%d.%d.%d, " "card has %d.%d.%d.%d, KLD has %d.%d.%d.%d\n", t4_fw_install, state, G_FW_HDR_FW_VER_MAJOR(d), G_FW_HDR_FW_VER_MINOR(d), G_FW_HDR_FW_VER_MICRO(d), G_FW_HDR_FW_VER_BUILD(d), G_FW_HDR_FW_VER_MAJOR(c), G_FW_HDR_FW_VER_MINOR(c), G_FW_HDR_FW_VER_MICRO(c), G_FW_HDR_FW_VER_BUILD(c), G_FW_HDR_FW_VER_MAJOR(k), G_FW_HDR_FW_VER_MINOR(k), G_FW_HDR_FW_VER_MICRO(k), G_FW_HDR_FW_VER_BUILD(k)); rc = EINVAL; goto done; } /* Reset device */ if (need_fw_reset && (rc = -t4_fw_reset(sc, sc->mbox, F_PIORSTMODE | F_PIORST)) != 0) { device_printf(sc->dev, "firmware reset failed: %d.\n", rc); if (rc != ETIMEDOUT && rc != EIO) t4_fw_bye(sc, sc->mbox); goto done; } sc->flags |= FW_OK; rc = get_params__pre_init(sc); if (rc != 0) goto done; /* error message displayed already */ /* Partition adapter resources as specified in the config file. */ if (state == DEV_STATE_UNINIT) { KASSERT(sc->flags & MASTER_PF, ("%s: trying to change chip settings when not master.", __func__)); rc = partition_resources(sc, default_cfg, fw_info->kld_name); if (rc != 0) goto done; /* error message displayed already */ t4_tweak_chip_settings(sc); /* get basic stuff going */ rc = -t4_fw_initialize(sc, sc->mbox); if (rc != 0) { device_printf(sc->dev, "fw init failed: %d.\n", rc); goto done; } } else { snprintf(sc->cfg_file, sizeof(sc->cfg_file), "pf%d", pf); sc->cfcsum = 0; } done: free(card_fw, M_CXGBE); if (fw != NULL) firmware_put(fw, FIRMWARE_UNLOAD); if (default_cfg != NULL) firmware_put(default_cfg, FIRMWARE_UNLOAD); return (rc); } #define FW_PARAM_DEV(param) \ (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | \ V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_##param)) #define FW_PARAM_PFVF(param) \ (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_PFVF) | \ V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_PFVF_##param)) /* * Partition chip resources for use between various PFs, VFs, etc. */ static int partition_resources(struct adapter *sc, const struct firmware *default_cfg, const char *name_prefix) { const struct firmware *cfg = NULL; int rc = 0; struct fw_caps_config_cmd caps; uint32_t mtype, moff, finicsum, cfcsum; /* * Figure out what configuration file to use. Pick the default config * file for the card if the user hasn't specified one explicitly. */ snprintf(sc->cfg_file, sizeof(sc->cfg_file), "%s", t4_cfg_file); if (strncmp(t4_cfg_file, DEFAULT_CF, sizeof(t4_cfg_file)) == 0) { /* Card specific overrides go here. */ if (pci_get_device(sc->dev) == 0x440a) snprintf(sc->cfg_file, sizeof(sc->cfg_file), UWIRE_CF); if (is_fpga(sc)) snprintf(sc->cfg_file, sizeof(sc->cfg_file), FPGA_CF); } /* * We need to load another module if the profile is anything except * "default" or "flash". */ if (strncmp(sc->cfg_file, DEFAULT_CF, sizeof(sc->cfg_file)) != 0 && strncmp(sc->cfg_file, FLASH_CF, sizeof(sc->cfg_file)) != 0) { char s[32]; snprintf(s, sizeof(s), "%s_%s", name_prefix, sc->cfg_file); cfg = firmware_get(s); if (cfg == NULL) { if (default_cfg != NULL) { device_printf(sc->dev, "unable to load module \"%s\" for " "configuration profile \"%s\", will use " "the default config file instead.\n", s, sc->cfg_file); snprintf(sc->cfg_file, sizeof(sc->cfg_file), "%s", DEFAULT_CF); } else { device_printf(sc->dev, "unable to load module \"%s\" for " "configuration profile \"%s\", will use " "the config file on the card's flash " "instead.\n", s, sc->cfg_file); snprintf(sc->cfg_file, sizeof(sc->cfg_file), "%s", FLASH_CF); } } } if (strncmp(sc->cfg_file, DEFAULT_CF, sizeof(sc->cfg_file)) == 0 && default_cfg == NULL) { device_printf(sc->dev, "default config file not available, will use the config " "file on the card's flash instead.\n"); snprintf(sc->cfg_file, sizeof(sc->cfg_file), "%s", FLASH_CF); } if (strncmp(sc->cfg_file, FLASH_CF, sizeof(sc->cfg_file)) != 0) { u_int cflen; const uint32_t *cfdata; uint32_t param, val, addr; KASSERT(cfg != NULL || default_cfg != NULL, ("%s: no config to upload", __func__)); /* * Ask the firmware where it wants us to upload the config file. */ param = FW_PARAM_DEV(CF); rc = -t4_query_params(sc, sc->mbox, sc->pf, 0, 1, ¶m, &val); if (rc != 0) { /* No support for config file? Shouldn't happen. */ device_printf(sc->dev, "failed to query config file location: %d.\n", rc); goto done; } mtype = G_FW_PARAMS_PARAM_Y(val); moff = G_FW_PARAMS_PARAM_Z(val) << 16; /* * XXX: sheer laziness. We deliberately added 4 bytes of * useless stuffing/comments at the end of the config file so * it's ok to simply throw away the last remaining bytes when * the config file is not an exact multiple of 4. This also * helps with the validate_mt_off_len check. */ if (cfg != NULL) { cflen = cfg->datasize & ~3; cfdata = cfg->data; } else { cflen = default_cfg->datasize & ~3; cfdata = default_cfg->data; } if (cflen > FLASH_CFG_MAX_SIZE) { device_printf(sc->dev, "config file too long (%d, max allowed is %d). " "Will try to use the config on the card, if any.\n", cflen, FLASH_CFG_MAX_SIZE); goto use_config_on_flash; } rc = validate_mt_off_len(sc, mtype, moff, cflen, &addr); if (rc != 0) { device_printf(sc->dev, "%s: addr (%d/0x%x) or len %d is not valid: %d. " "Will try to use the config on the card, if any.\n", __func__, mtype, moff, cflen, rc); goto use_config_on_flash; } write_via_memwin(sc, 2, addr, cfdata, cflen); } else { use_config_on_flash: mtype = FW_MEMTYPE_FLASH; moff = t4_flash_cfg_addr(sc); } bzero(&caps, sizeof(caps)); caps.op_to_write = htobe32(V_FW_CMD_OP(FW_CAPS_CONFIG_CMD) | F_FW_CMD_REQUEST | F_FW_CMD_READ); caps.cfvalid_to_len16 = htobe32(F_FW_CAPS_CONFIG_CMD_CFVALID | V_FW_CAPS_CONFIG_CMD_MEMTYPE_CF(mtype) | V_FW_CAPS_CONFIG_CMD_MEMADDR64K_CF(moff >> 16) | FW_LEN16(caps)); rc = -t4_wr_mbox(sc, sc->mbox, &caps, sizeof(caps), &caps); if (rc != 0) { device_printf(sc->dev, "failed to pre-process config file: %d " "(mtype %d, moff 0x%x).\n", rc, mtype, moff); goto done; } finicsum = be32toh(caps.finicsum); cfcsum = be32toh(caps.cfcsum); if (finicsum != cfcsum) { device_printf(sc->dev, "WARNING: config file checksum mismatch: %08x %08x\n", finicsum, cfcsum); } sc->cfcsum = cfcsum; #define LIMIT_CAPS(x) do { \ caps.x &= htobe16(t4_##x##_allowed); \ } while (0) /* * Let the firmware know what features will (not) be used so it can tune * things accordingly. */ LIMIT_CAPS(nbmcaps); LIMIT_CAPS(linkcaps); LIMIT_CAPS(switchcaps); LIMIT_CAPS(niccaps); LIMIT_CAPS(toecaps); LIMIT_CAPS(rdmacaps); LIMIT_CAPS(cryptocaps); LIMIT_CAPS(iscsicaps); LIMIT_CAPS(fcoecaps); #undef LIMIT_CAPS caps.op_to_write = htobe32(V_FW_CMD_OP(FW_CAPS_CONFIG_CMD) | F_FW_CMD_REQUEST | F_FW_CMD_WRITE); caps.cfvalid_to_len16 = htobe32(FW_LEN16(caps)); rc = -t4_wr_mbox(sc, sc->mbox, &caps, sizeof(caps), NULL); if (rc != 0) { device_printf(sc->dev, "failed to process config file: %d.\n", rc); } done: if (cfg != NULL) firmware_put(cfg, FIRMWARE_UNLOAD); return (rc); } /* * Retrieve parameters that are needed (or nice to have) very early. */ static int get_params__pre_init(struct adapter *sc) { int rc; uint32_t param[2], val[2]; t4_get_version_info(sc); snprintf(sc->fw_version, sizeof(sc->fw_version), "%u.%u.%u.%u", G_FW_HDR_FW_VER_MAJOR(sc->params.fw_vers), G_FW_HDR_FW_VER_MINOR(sc->params.fw_vers), G_FW_HDR_FW_VER_MICRO(sc->params.fw_vers), G_FW_HDR_FW_VER_BUILD(sc->params.fw_vers)); snprintf(sc->bs_version, sizeof(sc->bs_version), "%u.%u.%u.%u", G_FW_HDR_FW_VER_MAJOR(sc->params.bs_vers), G_FW_HDR_FW_VER_MINOR(sc->params.bs_vers), G_FW_HDR_FW_VER_MICRO(sc->params.bs_vers), G_FW_HDR_FW_VER_BUILD(sc->params.bs_vers)); snprintf(sc->tp_version, sizeof(sc->tp_version), "%u.%u.%u.%u", G_FW_HDR_FW_VER_MAJOR(sc->params.tp_vers), G_FW_HDR_FW_VER_MINOR(sc->params.tp_vers), G_FW_HDR_FW_VER_MICRO(sc->params.tp_vers), G_FW_HDR_FW_VER_BUILD(sc->params.tp_vers)); snprintf(sc->er_version, sizeof(sc->er_version), "%u.%u.%u.%u", G_FW_HDR_FW_VER_MAJOR(sc->params.er_vers), G_FW_HDR_FW_VER_MINOR(sc->params.er_vers), G_FW_HDR_FW_VER_MICRO(sc->params.er_vers), G_FW_HDR_FW_VER_BUILD(sc->params.er_vers)); param[0] = FW_PARAM_DEV(PORTVEC); param[1] = FW_PARAM_DEV(CCLK); rc = -t4_query_params(sc, sc->mbox, sc->pf, 0, 2, param, val); if (rc != 0) { device_printf(sc->dev, "failed to query parameters (pre_init): %d.\n", rc); return (rc); } sc->params.portvec = val[0]; sc->params.nports = bitcount32(val[0]); sc->params.vpd.cclk = val[1]; /* Read device log parameters. */ rc = -t4_init_devlog_params(sc, 1); if (rc == 0) fixup_devlog_params(sc); else { device_printf(sc->dev, "failed to get devlog parameters: %d.\n", rc); rc = 0; /* devlog isn't critical for device operation */ } return (rc); } /* * Retrieve various parameters that are of interest to the driver. The device * has been initialized by the firmware at this point. */ static int get_params__post_init(struct adapter *sc) { int rc; uint32_t param[7], val[7]; struct fw_caps_config_cmd caps; param[0] = FW_PARAM_PFVF(IQFLINT_START); param[1] = FW_PARAM_PFVF(EQ_START); param[2] = FW_PARAM_PFVF(FILTER_START); param[3] = FW_PARAM_PFVF(FILTER_END); param[4] = FW_PARAM_PFVF(L2T_START); param[5] = FW_PARAM_PFVF(L2T_END); rc = -t4_query_params(sc, sc->mbox, sc->pf, 0, 6, param, val); if (rc != 0) { device_printf(sc->dev, "failed to query parameters (post_init): %d.\n", rc); return (rc); } sc->sge.iq_start = val[0]; sc->sge.eq_start = val[1]; sc->tids.ftid_base = val[2]; sc->tids.nftids = val[3] - val[2] + 1; sc->params.ftid_min = val[2]; sc->params.ftid_max = val[3]; sc->vres.l2t.start = val[4]; sc->vres.l2t.size = val[5] - val[4] + 1; KASSERT(sc->vres.l2t.size <= L2T_SIZE, ("%s: L2 table size (%u) larger than expected (%u)", __func__, sc->vres.l2t.size, L2T_SIZE)); /* get capabilites */ bzero(&caps, sizeof(caps)); caps.op_to_write = htobe32(V_FW_CMD_OP(FW_CAPS_CONFIG_CMD) | F_FW_CMD_REQUEST | F_FW_CMD_READ); caps.cfvalid_to_len16 = htobe32(FW_LEN16(caps)); rc = -t4_wr_mbox(sc, sc->mbox, &caps, sizeof(caps), &caps); if (rc != 0) { device_printf(sc->dev, "failed to get card capabilities: %d.\n", rc); return (rc); } #define READ_CAPS(x) do { \ sc->x = htobe16(caps.x); \ } while (0) READ_CAPS(nbmcaps); READ_CAPS(linkcaps); READ_CAPS(switchcaps); READ_CAPS(niccaps); READ_CAPS(toecaps); READ_CAPS(rdmacaps); READ_CAPS(cryptocaps); READ_CAPS(iscsicaps); READ_CAPS(fcoecaps); if (sc->niccaps & FW_CAPS_CONFIG_NIC_ETHOFLD) { param[0] = FW_PARAM_PFVF(ETHOFLD_START); param[1] = FW_PARAM_PFVF(ETHOFLD_END); param[2] = FW_PARAM_DEV(FLOWC_BUFFIFO_SZ); rc = -t4_query_params(sc, sc->mbox, sc->pf, 0, 3, param, val); if (rc != 0) { device_printf(sc->dev, "failed to query NIC parameters: %d.\n", rc); return (rc); } sc->tids.etid_base = val[0]; sc->params.etid_min = val[0]; sc->tids.netids = val[1] - val[0] + 1; sc->params.netids = sc->tids.netids; sc->params.eo_wr_cred = val[2]; sc->params.ethoffload = 1; } if (sc->toecaps) { /* query offload-related parameters */ param[0] = FW_PARAM_DEV(NTID); param[1] = FW_PARAM_PFVF(SERVER_START); param[2] = FW_PARAM_PFVF(SERVER_END); param[3] = FW_PARAM_PFVF(TDDP_START); param[4] = FW_PARAM_PFVF(TDDP_END); param[5] = FW_PARAM_DEV(FLOWC_BUFFIFO_SZ); rc = -t4_query_params(sc, sc->mbox, sc->pf, 0, 6, param, val); if (rc != 0) { device_printf(sc->dev, "failed to query TOE parameters: %d.\n", rc); return (rc); } sc->tids.ntids = val[0]; sc->tids.natids = min(sc->tids.ntids / 2, MAX_ATIDS); sc->tids.stid_base = val[1]; sc->tids.nstids = val[2] - val[1] + 1; sc->vres.ddp.start = val[3]; sc->vres.ddp.size = val[4] - val[3] + 1; sc->params.ofldq_wr_cred = val[5]; sc->params.offload = 1; } if (sc->rdmacaps) { param[0] = FW_PARAM_PFVF(STAG_START); param[1] = FW_PARAM_PFVF(STAG_END); param[2] = FW_PARAM_PFVF(RQ_START); param[3] = FW_PARAM_PFVF(RQ_END); param[4] = FW_PARAM_PFVF(PBL_START); param[5] = FW_PARAM_PFVF(PBL_END); rc = -t4_query_params(sc, sc->mbox, sc->pf, 0, 6, param, val); if (rc != 0) { device_printf(sc->dev, "failed to query RDMA parameters(1): %d.\n", rc); return (rc); } sc->vres.stag.start = val[0]; sc->vres.stag.size = val[1] - val[0] + 1; sc->vres.rq.start = val[2]; sc->vres.rq.size = val[3] - val[2] + 1; sc->vres.pbl.start = val[4]; sc->vres.pbl.size = val[5] - val[4] + 1; param[0] = FW_PARAM_PFVF(SQRQ_START); param[1] = FW_PARAM_PFVF(SQRQ_END); param[2] = FW_PARAM_PFVF(CQ_START); param[3] = FW_PARAM_PFVF(CQ_END); param[4] = FW_PARAM_PFVF(OCQ_START); param[5] = FW_PARAM_PFVF(OCQ_END); rc = -t4_query_params(sc, sc->mbox, sc->pf, 0, 6, param, val); if (rc != 0) { device_printf(sc->dev, "failed to query RDMA parameters(2): %d.\n", rc); return (rc); } sc->vres.qp.start = val[0]; sc->vres.qp.size = val[1] - val[0] + 1; sc->vres.cq.start = val[2]; sc->vres.cq.size = val[3] - val[2] + 1; sc->vres.ocq.start = val[4]; sc->vres.ocq.size = val[5] - val[4] + 1; param[0] = FW_PARAM_PFVF(SRQ_START); param[1] = FW_PARAM_PFVF(SRQ_END); param[2] = FW_PARAM_DEV(MAXORDIRD_QP); param[3] = FW_PARAM_DEV(MAXIRD_ADAPTER); rc = -t4_query_params(sc, sc->mbox, sc->pf, 0, 4, param, val); if (rc != 0) { device_printf(sc->dev, "failed to query RDMA parameters(3): %d.\n", rc); return (rc); } sc->vres.srq.start = val[0]; sc->vres.srq.size = val[1] - val[0] + 1; sc->params.max_ordird_qp = val[2]; sc->params.max_ird_adapter = val[3]; } if (sc->iscsicaps) { param[0] = FW_PARAM_PFVF(ISCSI_START); param[1] = FW_PARAM_PFVF(ISCSI_END); rc = -t4_query_params(sc, sc->mbox, sc->pf, 0, 2, param, val); if (rc != 0) { device_printf(sc->dev, "failed to query iSCSI parameters: %d.\n", rc); return (rc); } sc->vres.iscsi.start = val[0]; sc->vres.iscsi.size = val[1] - val[0] + 1; } t4_init_sge_params(sc); /* * We've got the params we wanted to query via the firmware. Now grab * some others directly from the chip. */ rc = t4_read_chip_settings(sc); return (rc); } static int set_params__post_init(struct adapter *sc) { uint32_t param, val; + int i, v, shift; + char s[32]; /* ask for encapsulated CPLs */ param = FW_PARAM_PFVF(CPLFW4MSG_ENCAP); val = 1; (void)t4_set_params(sc, sc->mbox, sc->pf, 0, 1, ¶m, &val); + /* + * Override the TOE timers with user provided tunables. This is not the + * recommended way to change the timers (the firmware config file is) so + * these tunables are not documented. + * + * All the timer tunables are in milliseconds. + */ + if (TUNABLE_INT_FETCH("hw.cxgbe.toe.keepalive_idle", &v)) { + t4_set_reg_field(sc, A_TP_KEEP_IDLE, + V_KEEPALIVEIDLE(M_KEEPALIVEIDLE), + V_KEEPALIVEIDLE(ms_to_tcp_ticks(sc, v))); + } + if (TUNABLE_INT_FETCH("hw.cxgbe.toe.keepalive_interval", &v)) { + t4_set_reg_field(sc, A_TP_KEEP_INTVL, + V_KEEPALIVEINTVL(M_KEEPALIVEINTVL), + V_KEEPALIVEINTVL(ms_to_tcp_ticks(sc, v))); + } + if (TUNABLE_INT_FETCH("hw.cxgbe.toe.keepalive_count", &v)) { + v &= M_KEEPALIVEMAXR1; + t4_set_reg_field(sc, A_TP_SHIFT_CNT, + V_KEEPALIVEMAXR1(M_KEEPALIVEMAXR1) | + V_KEEPALIVEMAXR2(M_KEEPALIVEMAXR2), + V_KEEPALIVEMAXR1(1) | V_KEEPALIVEMAXR2(v)); + } + if (TUNABLE_INT_FETCH("hw.cxgbe.toe.rexmt_min", &v)) { + t4_set_reg_field(sc, A_TP_RXT_MIN, + V_RXTMIN(M_RXTMIN), V_RXTMIN(ms_to_tcp_ticks(sc, v))); + } + if (TUNABLE_INT_FETCH("hw.cxgbe.toe.rexmt_max", &v)) { + t4_set_reg_field(sc, A_TP_RXT_MAX, + V_RXTMAX(M_RXTMAX), V_RXTMAX(ms_to_tcp_ticks(sc, v))); + } + if (TUNABLE_INT_FETCH("hw.cxgbe.toe.rexmt_count", &v)) { + v &= M_RXTSHIFTMAXR1; + t4_set_reg_field(sc, A_TP_SHIFT_CNT, + V_RXTSHIFTMAXR1(M_RXTSHIFTMAXR1) | + V_RXTSHIFTMAXR2(M_RXTSHIFTMAXR2), + V_RXTSHIFTMAXR1(1) | V_RXTSHIFTMAXR2(v)); + } + for (i = 0; i < 16; i++) { + snprintf(s, sizeof(s), "hw.cxgbe.toe.rexmt_backoff.%d", i); + if (TUNABLE_INT_FETCH(s, &v)) { + v &= M_TIMERBACKOFFINDEX0; + shift = (i & 3) << 3; + t4_set_reg_field(sc, A_TP_TCP_BACKOFF_REG0 + (i & ~3), + M_TIMERBACKOFFINDEX0 << shift, v << shift); + } + } return (0); } #undef FW_PARAM_PFVF #undef FW_PARAM_DEV static void t4_set_desc(struct adapter *sc) { char buf[128]; struct adapter_params *p = &sc->params; snprintf(buf, sizeof(buf), "Chelsio %s", p->vpd.id); device_set_desc_copy(sc->dev, buf); } static void build_medialist(struct port_info *pi, struct ifmedia *media) { int m; PORT_LOCK_ASSERT_OWNED(pi); ifmedia_removeall(media); /* * XXX: Would it be better to ifmedia_add all 4 combinations of pause * settings for every speed instead of just txpause|rxpause? ifconfig * media display looks much better if autoselect is the only case where * ifm_current is different from ifm_active. If the user picks anything * except txpause|rxpause the display is ugly. */ m = IFM_ETHER | IFM_FDX | IFM_ETH_TXPAUSE | IFM_ETH_RXPAUSE; switch(pi->port_type) { case FW_PORT_TYPE_BT_XFI: case FW_PORT_TYPE_BT_XAUI: ifmedia_add(media, m | IFM_10G_T, 0, NULL); /* fall through */ case FW_PORT_TYPE_BT_SGMII: 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, 0, NULL); ifmedia_set(media, m | IFM_10G_CX4); break; case FW_PORT_TYPE_QSFP_10G: case FW_PORT_TYPE_SFP: case FW_PORT_TYPE_FIBER_XFI: case FW_PORT_TYPE_FIBER_XAUI: switch (pi->mod_type) { case FW_PORT_MOD_TYPE_LR: 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, 0, NULL); ifmedia_set(media, m | IFM_10G_SR); break; case FW_PORT_MOD_TYPE_LRM: 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, 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, 0, NULL); ifmedia_set(media, m | IFM_NONE); break; case FW_PORT_MOD_TYPE_NA: case FW_PORT_MOD_TYPE_ER: default: device_printf(pi->dev, "unknown port_type (%d), mod_type (%d)\n", pi->port_type, pi->mod_type); ifmedia_add(media, m | IFM_UNKNOWN, 0, NULL); ifmedia_set(media, m | IFM_UNKNOWN); break; } break; case FW_PORT_TYPE_CR_QSFP: case FW_PORT_TYPE_SFP28: case FW_PORT_TYPE_KR_SFP28: switch (pi->mod_type) { case FW_PORT_MOD_TYPE_SR: ifmedia_add(media, m | IFM_25G_SR, 0, NULL); ifmedia_set(media, m | IFM_25G_SR); break; case FW_PORT_MOD_TYPE_TWINAX_PASSIVE: case FW_PORT_MOD_TYPE_TWINAX_ACTIVE: ifmedia_add(media, m | IFM_25G_CR, 0, NULL); ifmedia_set(media, m | IFM_25G_CR); break; case FW_PORT_MOD_TYPE_NONE: m &= ~IFM_FDX; ifmedia_add(media, m | IFM_NONE, 0, NULL); ifmedia_set(media, m | IFM_NONE); break; default: device_printf(pi->dev, "unknown port_type (%d), mod_type (%d)\n", pi->port_type, pi->mod_type); ifmedia_add(media, m | IFM_UNKNOWN, 0, NULL); ifmedia_set(media, m | IFM_UNKNOWN); break; } break; case FW_PORT_TYPE_QSFP: switch (pi->mod_type) { case FW_PORT_MOD_TYPE_LR: 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, 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, 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, 0, NULL); ifmedia_set(media, m | IFM_NONE); break; default: device_printf(pi->dev, "unknown port_type (%d), mod_type (%d)\n", pi->port_type, pi->mod_type); ifmedia_add(media, m | IFM_UNKNOWN, 0, NULL); ifmedia_set(media, m | IFM_UNKNOWN); break; } break; case FW_PORT_TYPE_KR4_100G: case FW_PORT_TYPE_CR4_QSFP: switch (pi->mod_type) { case FW_PORT_MOD_TYPE_LR: ifmedia_add(media, m | IFM_100G_LR4, 0, NULL); ifmedia_set(media, m | IFM_100G_LR4); break; case FW_PORT_MOD_TYPE_SR: ifmedia_add(media, m | IFM_100G_SR4, 0, NULL); ifmedia_set(media, m | IFM_100G_SR4); break; case FW_PORT_MOD_TYPE_TWINAX_PASSIVE: case FW_PORT_MOD_TYPE_TWINAX_ACTIVE: ifmedia_add(media, m | IFM_100G_CR4, 0, NULL); ifmedia_set(media, m | IFM_100G_CR4); break; case FW_PORT_MOD_TYPE_NONE: m &= ~IFM_FDX; ifmedia_add(media, m | IFM_NONE, 0, NULL); ifmedia_set(media, m | IFM_NONE); break; default: device_printf(pi->dev, "unknown port_type (%d), mod_type (%d)\n", pi->port_type, pi->mod_type); ifmedia_add(media, m | IFM_UNKNOWN, 0, NULL); ifmedia_set(media, m | IFM_UNKNOWN); break; } break; default: device_printf(pi->dev, "unknown port_type (%d), mod_type (%d)\n", pi->port_type, pi->mod_type); ifmedia_add(media, m | IFM_UNKNOWN, 0, NULL); ifmedia_set(media, m | IFM_UNKNOWN); break; } } /* * Update all the requested_* fields in the link config and then send a mailbox * command to apply the settings. */ static void init_l1cfg(struct port_info *pi) { struct adapter *sc = pi->adapter; struct link_config *lc = &pi->link_cfg; int rc; ASSERT_SYNCHRONIZED_OP(sc); if (t4_autoneg != 0 && lc->supported & FW_PORT_CAP_ANEG) { lc->requested_aneg = AUTONEG_ENABLE; lc->requested_speed = 0; } else { lc->requested_aneg = AUTONEG_DISABLE; lc->requested_speed = port_top_speed(pi); /* in Gbps */ } lc->requested_fc = t4_pause_settings & (PAUSE_TX | PAUSE_RX); if (t4_fec != -1) { lc->requested_fec = t4_fec & (FEC_RS | FEC_BASER_RS | FEC_RESERVED); } else { /* Use the suggested value provided by the firmware in acaps */ if (lc->advertising & FW_PORT_CAP_FEC_RS) lc->requested_fec = FEC_RS; else if (lc->advertising & FW_PORT_CAP_FEC_BASER_RS) lc->requested_fec = FEC_BASER_RS; else if (lc->advertising & FW_PORT_CAP_FEC_RESERVED) lc->requested_fec = FEC_RESERVED; else lc->requested_fec = 0; } rc = -t4_link_l1cfg(sc, sc->mbox, pi->tx_chan, lc); if (rc != 0) { device_printf(pi->dev, "l1cfg failed: %d\n", rc); } else { lc->fc = lc->requested_fc; lc->fec = lc->requested_fec; } } #define FW_MAC_EXACT_CHUNK 7 /* * Program the port's XGMAC based on parameters in ifnet. The caller also * indicates which parameters should be programmed (the rest are left alone). */ int update_mac_settings(struct ifnet *ifp, int flags) { int rc = 0; struct vi_info *vi = ifp->if_softc; struct port_info *pi = vi->pi; struct adapter *sc = pi->adapter; int mtu = -1, promisc = -1, allmulti = -1, vlanex = -1; ASSERT_SYNCHRONIZED_OP(sc); KASSERT(flags, ("%s: not told what to update.", __func__)); if (flags & XGMAC_MTU) mtu = ifp->if_mtu; if (flags & XGMAC_PROMISC) promisc = ifp->if_flags & IFF_PROMISC ? 1 : 0; if (flags & XGMAC_ALLMULTI) allmulti = ifp->if_flags & IFF_ALLMULTI ? 1 : 0; if (flags & XGMAC_VLANEX) vlanex = ifp->if_capenable & IFCAP_VLAN_HWTAGGING ? 1 : 0; if (flags & (XGMAC_MTU|XGMAC_PROMISC|XGMAC_ALLMULTI|XGMAC_VLANEX)) { rc = -t4_set_rxmode(sc, sc->mbox, vi->viid, mtu, promisc, allmulti, 1, vlanex, false); if (rc) { if_printf(ifp, "set_rxmode (%x) failed: %d\n", flags, rc); return (rc); } } if (flags & XGMAC_UCADDR) { uint8_t ucaddr[ETHER_ADDR_LEN]; bcopy(IF_LLADDR(ifp), ucaddr, sizeof(ucaddr)); rc = t4_change_mac(sc, sc->mbox, vi->viid, vi->xact_addr_filt, ucaddr, true, true); if (rc < 0) { rc = -rc; if_printf(ifp, "change_mac failed: %d\n", rc); return (rc); } else { vi->xact_addr_filt = rc; rc = 0; } } if (flags & XGMAC_MCADDRS) { const uint8_t *mcaddr[FW_MAC_EXACT_CHUNK]; int del = 1; uint64_t hash = 0; struct ifmultiaddr *ifma; int i = 0, j; if_maddr_rlock(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; mcaddr[i] = LLADDR((struct sockaddr_dl *)ifma->ifma_addr); MPASS(ETHER_IS_MULTICAST(mcaddr[i])); i++; if (i == FW_MAC_EXACT_CHUNK) { rc = t4_alloc_mac_filt(sc, sc->mbox, vi->viid, del, i, mcaddr, NULL, &hash, 0); if (rc < 0) { rc = -rc; for (j = 0; j < i; j++) { if_printf(ifp, "failed to add mc address" " %02x:%02x:%02x:" "%02x:%02x:%02x rc=%d\n", mcaddr[j][0], mcaddr[j][1], mcaddr[j][2], mcaddr[j][3], mcaddr[j][4], mcaddr[j][5], rc); } goto mcfail; } del = 0; i = 0; } } if (i > 0) { rc = t4_alloc_mac_filt(sc, sc->mbox, vi->viid, del, i, mcaddr, NULL, &hash, 0); if (rc < 0) { rc = -rc; for (j = 0; j < i; j++) { if_printf(ifp, "failed to add mc address" " %02x:%02x:%02x:" "%02x:%02x:%02x rc=%d\n", mcaddr[j][0], mcaddr[j][1], mcaddr[j][2], mcaddr[j][3], mcaddr[j][4], mcaddr[j][5], rc); } goto mcfail; } } rc = -t4_set_addr_hash(sc, sc->mbox, vi->viid, 0, hash, 0); if (rc != 0) if_printf(ifp, "failed to set mc address hash: %d", rc); mcfail: if_maddr_runlock(ifp); } return (rc); } /* * {begin|end}_synchronized_op must be called from the same thread. */ int begin_synchronized_op(struct adapter *sc, struct vi_info *vi, int flags, char *wmesg) { int rc, pri; #ifdef WITNESS /* the caller thinks it's ok to sleep, but is it really? */ if (flags & SLEEP_OK) WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, "begin_synchronized_op"); #endif if (INTR_OK) pri = PCATCH; else pri = 0; ADAPTER_LOCK(sc); for (;;) { if (vi && IS_DOOMED(vi)) { rc = ENXIO; goto done; } if (!IS_BUSY(sc)) { rc = 0; break; } if (!(flags & SLEEP_OK)) { rc = EBUSY; goto done; } if (mtx_sleep(&sc->flags, &sc->sc_lock, pri, wmesg, 0)) { rc = EINTR; goto done; } } KASSERT(!IS_BUSY(sc), ("%s: controller busy.", __func__)); SET_BUSY(sc); #ifdef INVARIANTS sc->last_op = wmesg; sc->last_op_thr = curthread; sc->last_op_flags = flags; #endif done: if (!(flags & HOLD_LOCK) || rc) ADAPTER_UNLOCK(sc); return (rc); } /* * Tell if_ioctl and if_init that the VI is going away. This is * special variant of begin_synchronized_op and must be paired with a * call to end_synchronized_op. */ void doom_vi(struct adapter *sc, struct vi_info *vi) { ADAPTER_LOCK(sc); SET_DOOMED(vi); wakeup(&sc->flags); while (IS_BUSY(sc)) mtx_sleep(&sc->flags, &sc->sc_lock, 0, "t4detach", 0); SET_BUSY(sc); #ifdef INVARIANTS sc->last_op = "t4detach"; sc->last_op_thr = curthread; sc->last_op_flags = 0; #endif ADAPTER_UNLOCK(sc); } /* * {begin|end}_synchronized_op must be called from the same thread. */ void end_synchronized_op(struct adapter *sc, int flags) { if (flags & LOCK_HELD) ADAPTER_LOCK_ASSERT_OWNED(sc); else ADAPTER_LOCK(sc); KASSERT(IS_BUSY(sc), ("%s: controller not busy.", __func__)); CLR_BUSY(sc); wakeup(&sc->flags); ADAPTER_UNLOCK(sc); } static int cxgbe_init_synchronized(struct vi_info *vi) { struct port_info *pi = vi->pi; struct adapter *sc = pi->adapter; struct ifnet *ifp = vi->ifp; int rc = 0, i; struct sge_txq *txq; ASSERT_SYNCHRONIZED_OP(sc); if (ifp->if_drv_flags & IFF_DRV_RUNNING) return (0); /* already running */ if (!(sc->flags & FULL_INIT_DONE) && ((rc = adapter_full_init(sc)) != 0)) return (rc); /* error message displayed already */ if (!(vi->flags & VI_INIT_DONE) && ((rc = vi_full_init(vi)) != 0)) return (rc); /* error message displayed already */ rc = update_mac_settings(ifp, XGMAC_ALL); if (rc) goto done; /* error message displayed already */ rc = -t4_enable_vi(sc, sc->mbox, vi->viid, true, true); if (rc != 0) { if_printf(ifp, "enable_vi failed: %d\n", rc); goto done; } /* * Can't fail from this point onwards. Review cxgbe_uninit_synchronized * if this changes. */ for_each_txq(vi, i, txq) { TXQ_LOCK(txq); txq->eq.flags |= EQ_ENABLED; TXQ_UNLOCK(txq); } /* * The first iq of the first port to come up is used for tracing. */ if (sc->traceq < 0 && IS_MAIN_VI(vi)) { sc->traceq = sc->sge.rxq[vi->first_rxq].iq.abs_id; t4_write_reg(sc, is_t4(sc) ? A_MPS_TRC_RSS_CONTROL : A_MPS_T5_TRC_RSS_CONTROL, V_RSSCONTROL(pi->tx_chan) | V_QUEUENUMBER(sc->traceq)); pi->flags |= HAS_TRACEQ; } /* all ok */ PORT_LOCK(pi); if (pi->up_vis++ == 0) { t4_update_port_info(pi); build_medialist(vi->pi, &vi->media); init_l1cfg(pi); } ifp->if_drv_flags |= IFF_DRV_RUNNING; if (pi->nvi > 1 || sc->flags & IS_VF) callout_reset(&vi->tick, hz, vi_tick, vi); else callout_reset(&pi->tick, hz, cxgbe_tick, pi); PORT_UNLOCK(pi); done: if (rc != 0) cxgbe_uninit_synchronized(vi); return (rc); } /* * Idempotent. */ static int cxgbe_uninit_synchronized(struct vi_info *vi) { struct port_info *pi = vi->pi; struct adapter *sc = pi->adapter; struct ifnet *ifp = vi->ifp; int rc, i; struct sge_txq *txq; ASSERT_SYNCHRONIZED_OP(sc); if (!(vi->flags & VI_INIT_DONE)) { KASSERT(!(ifp->if_drv_flags & IFF_DRV_RUNNING), ("uninited VI is running")); return (0); } /* * Disable the VI so that all its data in either direction is discarded * by the MPS. Leave everything else (the queues, interrupts, and 1Hz * tick) intact as the TP can deliver negative advice or data that it's * holding in its RAM (for an offloaded connection) even after the VI is * disabled. */ rc = -t4_enable_vi(sc, sc->mbox, vi->viid, false, false); if (rc) { if_printf(ifp, "disable_vi failed: %d\n", rc); return (rc); } for_each_txq(vi, i, txq) { TXQ_LOCK(txq); txq->eq.flags &= ~EQ_ENABLED; TXQ_UNLOCK(txq); } PORT_LOCK(pi); if (pi->nvi > 1 || sc->flags & IS_VF) callout_stop(&vi->tick); else callout_stop(&pi->tick); if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { PORT_UNLOCK(pi); return (0); } ifp->if_drv_flags &= ~IFF_DRV_RUNNING; pi->up_vis--; if (pi->up_vis > 0) { PORT_UNLOCK(pi); return (0); } PORT_UNLOCK(pi); pi->link_cfg.link_ok = 0; pi->link_cfg.speed = 0; pi->link_cfg.link_down_rc = 255; t4_os_link_changed(pi, NULL); return (0); } /* * It is ok for this function to fail midway and return right away. t4_detach * will walk the entire sc->irq list and clean up whatever is valid. */ int t4_setup_intr_handlers(struct adapter *sc) { int rc, rid, p, q, v; char s[8]; struct irq *irq; struct port_info *pi; struct vi_info *vi; struct sge *sge = &sc->sge; struct sge_rxq *rxq; #ifdef TCP_OFFLOAD struct sge_ofld_rxq *ofld_rxq; #endif #ifdef DEV_NETMAP struct sge_nm_rxq *nm_rxq; #endif #ifdef RSS int nbuckets = rss_getnumbuckets(); #endif /* * Setup interrupts. */ irq = &sc->irq[0]; rid = sc->intr_type == INTR_INTX ? 0 : 1; if (sc->intr_count == 1) return (t4_alloc_irq(sc, irq, rid, t4_intr_all, sc, "all")); /* Multiple interrupts. */ if (sc->flags & IS_VF) KASSERT(sc->intr_count >= T4VF_EXTRA_INTR + sc->params.nports, ("%s: too few intr.", __func__)); else KASSERT(sc->intr_count >= T4_EXTRA_INTR + sc->params.nports, ("%s: too few intr.", __func__)); /* The first one is always error intr on PFs */ if (!(sc->flags & IS_VF)) { rc = t4_alloc_irq(sc, irq, rid, t4_intr_err, sc, "err"); if (rc != 0) return (rc); irq++; rid++; } /* The second one is always the firmware event queue (first on VFs) */ rc = t4_alloc_irq(sc, irq, rid, t4_intr_evt, &sge->fwq, "evt"); if (rc != 0) return (rc); irq++; rid++; for_each_port(sc, p) { pi = sc->port[p]; for_each_vi(pi, v, vi) { vi->first_intr = rid - 1; if (vi->nnmrxq > 0) { int n = max(vi->nrxq, vi->nnmrxq); MPASS(vi->flags & INTR_RXQ); rxq = &sge->rxq[vi->first_rxq]; #ifdef DEV_NETMAP nm_rxq = &sge->nm_rxq[vi->first_nm_rxq]; #endif for (q = 0; q < n; q++) { snprintf(s, sizeof(s), "%x%c%x", p, 'a' + v, q); if (q < vi->nrxq) irq->rxq = rxq++; #ifdef DEV_NETMAP if (q < vi->nnmrxq) irq->nm_rxq = nm_rxq++; #endif rc = t4_alloc_irq(sc, irq, rid, t4_vi_intr, irq, s); if (rc != 0) return (rc); irq++; rid++; vi->nintr++; } } else if (vi->flags & INTR_RXQ) { for_each_rxq(vi, q, rxq) { snprintf(s, sizeof(s), "%x%c%x", p, 'a' + v, q); rc = t4_alloc_irq(sc, irq, rid, t4_intr, rxq, s); if (rc != 0) return (rc); #ifdef RSS bus_bind_intr(sc->dev, irq->res, rss_getcpu(q % nbuckets)); #endif irq++; rid++; vi->nintr++; } } #ifdef TCP_OFFLOAD if (vi->flags & INTR_OFLD_RXQ) { for_each_ofld_rxq(vi, q, ofld_rxq) { snprintf(s, sizeof(s), "%x%c%x", p, 'A' + v, q); rc = t4_alloc_irq(sc, irq, rid, t4_intr, ofld_rxq, s); if (rc != 0) return (rc); irq++; rid++; vi->nintr++; } } #endif } } MPASS(irq == &sc->irq[sc->intr_count]); return (0); } int adapter_full_init(struct adapter *sc) { int rc, i; #ifdef RSS uint32_t raw_rss_key[RSS_KEYSIZE / sizeof(uint32_t)]; uint32_t rss_key[RSS_KEYSIZE / sizeof(uint32_t)]; #endif ASSERT_SYNCHRONIZED_OP(sc); ADAPTER_LOCK_ASSERT_NOTOWNED(sc); KASSERT((sc->flags & FULL_INIT_DONE) == 0, ("%s: FULL_INIT_DONE already", __func__)); /* * queues that belong to the adapter (not any particular port). */ rc = t4_setup_adapter_queues(sc); if (rc != 0) goto done; for (i = 0; i < nitems(sc->tq); i++) { sc->tq[i] = taskqueue_create("t4 taskq", M_NOWAIT, taskqueue_thread_enqueue, &sc->tq[i]); if (sc->tq[i] == NULL) { device_printf(sc->dev, "failed to allocate task queue %d\n", i); rc = ENOMEM; goto done; } taskqueue_start_threads(&sc->tq[i], 1, PI_NET, "%s tq%d", device_get_nameunit(sc->dev), i); } #ifdef RSS MPASS(RSS_KEYSIZE == 40); rss_getkey((void *)&raw_rss_key[0]); for (i = 0; i < nitems(rss_key); i++) { rss_key[i] = htobe32(raw_rss_key[nitems(rss_key) - 1 - i]); } t4_write_rss_key(sc, &rss_key[0], -1); #endif if (!(sc->flags & IS_VF)) t4_intr_enable(sc); sc->flags |= FULL_INIT_DONE; done: if (rc != 0) adapter_full_uninit(sc); return (rc); } int adapter_full_uninit(struct adapter *sc) { int i; ADAPTER_LOCK_ASSERT_NOTOWNED(sc); t4_teardown_adapter_queues(sc); for (i = 0; i < nitems(sc->tq) && sc->tq[i]; i++) { taskqueue_free(sc->tq[i]); sc->tq[i] = NULL; } sc->flags &= ~FULL_INIT_DONE; return (0); } #ifdef RSS #define SUPPORTED_RSS_HASHTYPES (RSS_HASHTYPE_RSS_IPV4 | \ RSS_HASHTYPE_RSS_TCP_IPV4 | RSS_HASHTYPE_RSS_IPV6 | \ RSS_HASHTYPE_RSS_TCP_IPV6 | RSS_HASHTYPE_RSS_UDP_IPV4 | \ RSS_HASHTYPE_RSS_UDP_IPV6) /* Translates kernel hash types to hardware. */ static int hashconfig_to_hashen(int hashconfig) { int hashen = 0; if (hashconfig & RSS_HASHTYPE_RSS_IPV4) hashen |= F_FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN; if (hashconfig & RSS_HASHTYPE_RSS_IPV6) hashen |= F_FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN; if (hashconfig & RSS_HASHTYPE_RSS_UDP_IPV4) { hashen |= F_FW_RSS_VI_CONFIG_CMD_UDPEN | F_FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN; } if (hashconfig & RSS_HASHTYPE_RSS_UDP_IPV6) { hashen |= F_FW_RSS_VI_CONFIG_CMD_UDPEN | F_FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN; } if (hashconfig & RSS_HASHTYPE_RSS_TCP_IPV4) hashen |= F_FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN; if (hashconfig & RSS_HASHTYPE_RSS_TCP_IPV6) hashen |= F_FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN; return (hashen); } /* Translates hardware hash types to kernel. */ static int hashen_to_hashconfig(int hashen) { int hashconfig = 0; if (hashen & F_FW_RSS_VI_CONFIG_CMD_UDPEN) { /* * If UDP hashing was enabled it must have been enabled for * either IPv4 or IPv6 (inclusive or). Enabling UDP without * enabling any 4-tuple hash is nonsense configuration. */ MPASS(hashen & (F_FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN | F_FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN)); if (hashen & F_FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN) hashconfig |= RSS_HASHTYPE_RSS_UDP_IPV4; if (hashen & F_FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN) hashconfig |= RSS_HASHTYPE_RSS_UDP_IPV6; } if (hashen & F_FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN) hashconfig |= RSS_HASHTYPE_RSS_TCP_IPV4; if (hashen & F_FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN) hashconfig |= RSS_HASHTYPE_RSS_TCP_IPV6; if (hashen & F_FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN) hashconfig |= RSS_HASHTYPE_RSS_IPV4; if (hashen & F_FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN) hashconfig |= RSS_HASHTYPE_RSS_IPV6; return (hashconfig); } #endif int vi_full_init(struct vi_info *vi) { struct adapter *sc = vi->pi->adapter; struct ifnet *ifp = vi->ifp; uint16_t *rss; struct sge_rxq *rxq; int rc, i, j, hashen; #ifdef RSS int nbuckets = rss_getnumbuckets(); int hashconfig = rss_gethashconfig(); int extra; #endif ASSERT_SYNCHRONIZED_OP(sc); KASSERT((vi->flags & VI_INIT_DONE) == 0, ("%s: VI_INIT_DONE already", __func__)); sysctl_ctx_init(&vi->ctx); vi->flags |= VI_SYSCTL_CTX; /* * Allocate tx/rx/fl queues for this VI. */ rc = t4_setup_vi_queues(vi); if (rc != 0) goto done; /* error message displayed already */ /* * Setup RSS for this VI. Save a copy of the RSS table for later use. */ if (vi->nrxq > vi->rss_size) { if_printf(ifp, "nrxq (%d) > hw RSS table size (%d); " "some queues will never receive traffic.\n", vi->nrxq, vi->rss_size); } else if (vi->rss_size % vi->nrxq) { if_printf(ifp, "nrxq (%d), hw RSS table size (%d); " "expect uneven traffic distribution.\n", vi->nrxq, vi->rss_size); } #ifdef RSS if (vi->nrxq != nbuckets) { if_printf(ifp, "nrxq (%d) != kernel RSS buckets (%d);" "performance will be impacted.\n", vi->nrxq, nbuckets); } #endif rss = malloc(vi->rss_size * sizeof (*rss), M_CXGBE, M_ZERO | M_WAITOK); for (i = 0; i < vi->rss_size;) { #ifdef RSS j = rss_get_indirection_to_bucket(i); j %= vi->nrxq; rxq = &sc->sge.rxq[vi->first_rxq + j]; rss[i++] = rxq->iq.abs_id; #else for_each_rxq(vi, j, rxq) { rss[i++] = rxq->iq.abs_id; if (i == vi->rss_size) break; } #endif } rc = -t4_config_rss_range(sc, sc->mbox, vi->viid, 0, vi->rss_size, rss, vi->rss_size); if (rc != 0) { if_printf(ifp, "rss_config failed: %d\n", rc); goto done; } #ifdef RSS hashen = hashconfig_to_hashen(hashconfig); /* * We may have had to enable some hashes even though the global config * wants them disabled. This is a potential problem that must be * reported to the user. */ extra = hashen_to_hashconfig(hashen) ^ hashconfig; /* * If we consider only the supported hash types, then the enabled hashes * are a superset of the requested hashes. In other words, there cannot * be any supported hash that was requested but not enabled, but there * can be hashes that were not requested but had to be enabled. */ extra &= SUPPORTED_RSS_HASHTYPES; MPASS((extra & hashconfig) == 0); if (extra) { if_printf(ifp, "global RSS config (0x%x) cannot be accommodated.\n", hashconfig); } if (extra & RSS_HASHTYPE_RSS_IPV4) if_printf(ifp, "IPv4 2-tuple hashing forced on.\n"); if (extra & RSS_HASHTYPE_RSS_TCP_IPV4) if_printf(ifp, "TCP/IPv4 4-tuple hashing forced on.\n"); if (extra & RSS_HASHTYPE_RSS_IPV6) if_printf(ifp, "IPv6 2-tuple hashing forced on.\n"); if (extra & RSS_HASHTYPE_RSS_TCP_IPV6) if_printf(ifp, "TCP/IPv6 4-tuple hashing forced on.\n"); if (extra & RSS_HASHTYPE_RSS_UDP_IPV4) if_printf(ifp, "UDP/IPv4 4-tuple hashing forced on.\n"); if (extra & RSS_HASHTYPE_RSS_UDP_IPV6) if_printf(ifp, "UDP/IPv6 4-tuple hashing forced on.\n"); #else hashen = F_FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN | F_FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN | F_FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN | F_FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN | F_FW_RSS_VI_CONFIG_CMD_UDPEN; #endif rc = -t4_config_vi_rss(sc, sc->mbox, vi->viid, hashen, rss[0], 0, 0); if (rc != 0) { if_printf(ifp, "rss hash/defaultq config failed: %d\n", rc); goto done; } vi->rss = rss; vi->flags |= VI_INIT_DONE; done: if (rc != 0) vi_full_uninit(vi); return (rc); } /* * Idempotent. */ int vi_full_uninit(struct vi_info *vi) { struct port_info *pi = vi->pi; struct adapter *sc = pi->adapter; int i; struct sge_rxq *rxq; struct sge_txq *txq; #ifdef TCP_OFFLOAD struct sge_ofld_rxq *ofld_rxq; struct sge_wrq *ofld_txq; #endif if (vi->flags & VI_INIT_DONE) { /* Need to quiesce queues. */ /* XXX: Only for the first VI? */ if (IS_MAIN_VI(vi) && !(sc->flags & IS_VF)) quiesce_wrq(sc, &sc->sge.ctrlq[pi->port_id]); for_each_txq(vi, i, txq) { quiesce_txq(sc, txq); } #ifdef TCP_OFFLOAD for_each_ofld_txq(vi, i, ofld_txq) { quiesce_wrq(sc, ofld_txq); } #endif for_each_rxq(vi, i, rxq) { quiesce_iq(sc, &rxq->iq); quiesce_fl(sc, &rxq->fl); } #ifdef TCP_OFFLOAD for_each_ofld_rxq(vi, i, ofld_rxq) { quiesce_iq(sc, &ofld_rxq->iq); quiesce_fl(sc, &ofld_rxq->fl); } #endif free(vi->rss, M_CXGBE); free(vi->nm_rss, M_CXGBE); } t4_teardown_vi_queues(vi); vi->flags &= ~VI_INIT_DONE; return (0); } static void quiesce_txq(struct adapter *sc, struct sge_txq *txq) { struct sge_eq *eq = &txq->eq; struct sge_qstat *spg = (void *)&eq->desc[eq->sidx]; (void) sc; /* unused */ #ifdef INVARIANTS TXQ_LOCK(txq); MPASS((eq->flags & EQ_ENABLED) == 0); TXQ_UNLOCK(txq); #endif /* Wait for the mp_ring to empty. */ while (!mp_ring_is_idle(txq->r)) { mp_ring_check_drainage(txq->r, 0); pause("rquiesce", 1); } /* Then wait for the hardware to finish. */ while (spg->cidx != htobe16(eq->pidx)) pause("equiesce", 1); /* Finally, wait for the driver to reclaim all descriptors. */ while (eq->cidx != eq->pidx) pause("dquiesce", 1); } static void quiesce_wrq(struct adapter *sc, struct sge_wrq *wrq) { /* XXXTX */ } static void quiesce_iq(struct adapter *sc, struct sge_iq *iq) { (void) sc; /* unused */ /* Synchronize with the interrupt handler */ while (!atomic_cmpset_int(&iq->state, IQS_IDLE, IQS_DISABLED)) pause("iqfree", 1); } static void quiesce_fl(struct adapter *sc, struct sge_fl *fl) { mtx_lock(&sc->sfl_lock); FL_LOCK(fl); fl->flags |= FL_DOOMED; FL_UNLOCK(fl); callout_stop(&sc->sfl_callout); mtx_unlock(&sc->sfl_lock); KASSERT((fl->flags & FL_STARVING) == 0, ("%s: still starving", __func__)); } static int t4_alloc_irq(struct adapter *sc, struct irq *irq, int rid, driver_intr_t *handler, void *arg, char *name) { int rc; irq->rid = rid; irq->res = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ, &irq->rid, RF_SHAREABLE | RF_ACTIVE); if (irq->res == NULL) { device_printf(sc->dev, "failed to allocate IRQ for rid %d, name %s.\n", rid, name); return (ENOMEM); } rc = bus_setup_intr(sc->dev, irq->res, INTR_MPSAFE | INTR_TYPE_NET, NULL, handler, arg, &irq->tag); if (rc != 0) { device_printf(sc->dev, "failed to setup interrupt for rid %d, name %s: %d\n", rid, name, rc); } else if (name) bus_describe_intr(sc->dev, irq->res, irq->tag, "%s", name); return (rc); } static int t4_free_irq(struct adapter *sc, struct irq *irq) { if (irq->tag) bus_teardown_intr(sc->dev, irq->res, irq->tag); if (irq->res) bus_release_resource(sc->dev, SYS_RES_IRQ, irq->rid, irq->res); bzero(irq, sizeof(*irq)); return (0); } static void get_regs(struct adapter *sc, struct t4_regdump *regs, uint8_t *buf) { regs->version = chip_id(sc) | chip_rev(sc) << 10; t4_get_regs(sc, buf, regs->len); } #define A_PL_INDIR_CMD 0x1f8 #define S_PL_AUTOINC 31 #define M_PL_AUTOINC 0x1U #define V_PL_AUTOINC(x) ((x) << S_PL_AUTOINC) #define G_PL_AUTOINC(x) (((x) >> S_PL_AUTOINC) & M_PL_AUTOINC) #define S_PL_VFID 20 #define M_PL_VFID 0xffU #define V_PL_VFID(x) ((x) << S_PL_VFID) #define G_PL_VFID(x) (((x) >> S_PL_VFID) & M_PL_VFID) #define S_PL_ADDR 0 #define M_PL_ADDR 0xfffffU #define V_PL_ADDR(x) ((x) << S_PL_ADDR) #define G_PL_ADDR(x) (((x) >> S_PL_ADDR) & M_PL_ADDR) #define A_PL_INDIR_DATA 0x1fc static uint64_t read_vf_stat(struct adapter *sc, unsigned int viid, int reg) { u32 stats[2]; mtx_assert(&sc->reg_lock, MA_OWNED); if (sc->flags & IS_VF) { stats[0] = t4_read_reg(sc, VF_MPS_REG(reg)); stats[1] = t4_read_reg(sc, VF_MPS_REG(reg + 4)); } else { t4_write_reg(sc, A_PL_INDIR_CMD, V_PL_AUTOINC(1) | V_PL_VFID(G_FW_VIID_VIN(viid)) | V_PL_ADDR(VF_MPS_REG(reg))); stats[0] = t4_read_reg(sc, A_PL_INDIR_DATA); stats[1] = t4_read_reg(sc, A_PL_INDIR_DATA); } return (((uint64_t)stats[1]) << 32 | stats[0]); } static void t4_get_vi_stats(struct adapter *sc, unsigned int viid, struct fw_vi_stats_vf *stats) { #define GET_STAT(name) \ read_vf_stat(sc, viid, A_MPS_VF_STAT_##name##_L) stats->tx_bcast_bytes = GET_STAT(TX_VF_BCAST_BYTES); stats->tx_bcast_frames = GET_STAT(TX_VF_BCAST_FRAMES); stats->tx_mcast_bytes = GET_STAT(TX_VF_MCAST_BYTES); stats->tx_mcast_frames = GET_STAT(TX_VF_MCAST_FRAMES); stats->tx_ucast_bytes = GET_STAT(TX_VF_UCAST_BYTES); stats->tx_ucast_frames = GET_STAT(TX_VF_UCAST_FRAMES); stats->tx_drop_frames = GET_STAT(TX_VF_DROP_FRAMES); stats->tx_offload_bytes = GET_STAT(TX_VF_OFFLOAD_BYTES); stats->tx_offload_frames = GET_STAT(TX_VF_OFFLOAD_FRAMES); stats->rx_bcast_bytes = GET_STAT(RX_VF_BCAST_BYTES); stats->rx_bcast_frames = GET_STAT(RX_VF_BCAST_FRAMES); stats->rx_mcast_bytes = GET_STAT(RX_VF_MCAST_BYTES); stats->rx_mcast_frames = GET_STAT(RX_VF_MCAST_FRAMES); stats->rx_ucast_bytes = GET_STAT(RX_VF_UCAST_BYTES); stats->rx_ucast_frames = GET_STAT(RX_VF_UCAST_FRAMES); stats->rx_err_frames = GET_STAT(RX_VF_ERR_FRAMES); #undef GET_STAT } static void t4_clr_vi_stats(struct adapter *sc, unsigned int viid) { int reg; t4_write_reg(sc, A_PL_INDIR_CMD, V_PL_AUTOINC(1) | V_PL_VFID(G_FW_VIID_VIN(viid)) | V_PL_ADDR(VF_MPS_REG(A_MPS_VF_STAT_TX_VF_BCAST_BYTES_L))); for (reg = A_MPS_VF_STAT_TX_VF_BCAST_BYTES_L; reg <= A_MPS_VF_STAT_RX_VF_ERR_FRAMES_H; reg += 4) t4_write_reg(sc, A_PL_INDIR_DATA, 0); } static void vi_refresh_stats(struct adapter *sc, struct vi_info *vi) { struct timeval tv; const struct timeval interval = {0, 250000}; /* 250ms */ if (!(vi->flags & VI_INIT_DONE)) return; getmicrotime(&tv); timevalsub(&tv, &interval); if (timevalcmp(&tv, &vi->last_refreshed, <)) return; mtx_lock(&sc->reg_lock); t4_get_vi_stats(sc, vi->viid, &vi->stats); getmicrotime(&vi->last_refreshed); mtx_unlock(&sc->reg_lock); } static void cxgbe_refresh_stats(struct adapter *sc, struct port_info *pi) { int i; u_int v, tnl_cong_drops; struct timeval tv; const struct timeval interval = {0, 250000}; /* 250ms */ getmicrotime(&tv); timevalsub(&tv, &interval); if (timevalcmp(&tv, &pi->last_refreshed, <)) return; tnl_cong_drops = 0; t4_get_port_stats(sc, pi->tx_chan, &pi->stats); for (i = 0; i < sc->chip_params->nchan; i++) { if (pi->rx_chan_map & (1 << i)) { mtx_lock(&sc->reg_lock); t4_read_indirect(sc, A_TP_MIB_INDEX, A_TP_MIB_DATA, &v, 1, A_TP_MIB_TNL_CNG_DROP_0 + i); mtx_unlock(&sc->reg_lock); tnl_cong_drops += v; } } pi->tnl_cong_drops = tnl_cong_drops; getmicrotime(&pi->last_refreshed); } static void cxgbe_tick(void *arg) { struct port_info *pi = arg; struct adapter *sc = pi->adapter; PORT_LOCK_ASSERT_OWNED(pi); cxgbe_refresh_stats(sc, pi); callout_schedule(&pi->tick, hz); } void vi_tick(void *arg) { struct vi_info *vi = arg; struct adapter *sc = vi->pi->adapter; vi_refresh_stats(sc, vi); callout_schedule(&vi->tick, hz); } static void cxgbe_vlan_config(void *arg, struct ifnet *ifp, uint16_t vid) { struct ifnet *vlan; if (arg != ifp || ifp->if_type != IFT_ETHER) return; vlan = VLAN_DEVAT(ifp, vid); VLAN_SETCOOKIE(vlan, ifp); } /* * Should match fw_caps_config_ enums in t4fw_interface.h */ static char *caps_decoder[] = { "\20\001IPMI\002NCSI", /* 0: NBM */ "\20\001PPP\002QFC\003DCBX", /* 1: link */ "\20\001INGRESS\002EGRESS", /* 2: switch */ "\20\001NIC\002VM\003IDS\004UM\005UM_ISGL" /* 3: NIC */ "\006HASHFILTER\007ETHOFLD", "\20\001TOE", /* 4: TOE */ "\20\001RDDP\002RDMAC", /* 5: RDMA */ "\20\001INITIATOR_PDU\002TARGET_PDU" /* 6: iSCSI */ "\003INITIATOR_CNXOFLD\004TARGET_CNXOFLD" "\005INITIATOR_SSNOFLD\006TARGET_SSNOFLD" "\007T10DIF" "\010INITIATOR_CMDOFLD\011TARGET_CMDOFLD", "\20\001LOOKASIDE\002TLSKEYS", /* 7: Crypto */ "\20\001INITIATOR\002TARGET\003CTRL_OFLD" /* 8: FCoE */ "\004PO_INITIATOR\005PO_TARGET", }; void t4_sysctls(struct adapter *sc) { struct sysctl_ctx_list *ctx; struct sysctl_oid *oid; struct sysctl_oid_list *children, *c0; static char *doorbells = {"\20\1UDB\2WCWR\3UDBWC\4KDB"}; ctx = device_get_sysctl_ctx(sc->dev); /* * dev.t4nex.X. */ oid = device_get_sysctl_tree(sc->dev); c0 = children = SYSCTL_CHILDREN(oid); sc->sc_do_rxcopy = 1; SYSCTL_ADD_INT(ctx, children, OID_AUTO, "do_rx_copy", CTLFLAG_RW, &sc->sc_do_rxcopy, 1, "Do RX copy of small frames"); SYSCTL_ADD_INT(ctx, children, OID_AUTO, "nports", CTLFLAG_RD, NULL, sc->params.nports, "# of ports"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "doorbells", CTLTYPE_STRING | CTLFLAG_RD, doorbells, sc->doorbells, sysctl_bitfield, "A", "available doorbells"); SYSCTL_ADD_INT(ctx, children, OID_AUTO, "core_clock", CTLFLAG_RD, NULL, sc->params.vpd.cclk, "core clock frequency (in KHz)"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "holdoff_timers", CTLTYPE_STRING | CTLFLAG_RD, sc->params.sge.timer_val, sizeof(sc->params.sge.timer_val), sysctl_int_array, "A", "interrupt holdoff timer values (us)"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "holdoff_pkt_counts", CTLTYPE_STRING | CTLFLAG_RD, sc->params.sge.counter_val, sizeof(sc->params.sge.counter_val), sysctl_int_array, "A", "interrupt holdoff packet counter values"); t4_sge_sysctls(sc, ctx, children); sc->lro_timeout = 100; SYSCTL_ADD_INT(ctx, children, OID_AUTO, "lro_timeout", CTLFLAG_RW, &sc->lro_timeout, 0, "lro inactive-flush timeout (in us)"); SYSCTL_ADD_INT(ctx, children, OID_AUTO, "dflags", CTLFLAG_RW, &sc->debug_flags, 0, "flags to enable runtime debugging"); SYSCTL_ADD_STRING(ctx, children, OID_AUTO, "tp_version", CTLFLAG_RD, sc->tp_version, 0, "TP microcode version"); SYSCTL_ADD_STRING(ctx, children, OID_AUTO, "firmware_version", CTLFLAG_RD, sc->fw_version, 0, "firmware version"); if (sc->flags & IS_VF) return; SYSCTL_ADD_INT(ctx, children, OID_AUTO, "hw_revision", CTLFLAG_RD, NULL, chip_rev(sc), "chip hardware revision"); SYSCTL_ADD_STRING(ctx, children, OID_AUTO, "sn", CTLFLAG_RD, sc->params.vpd.sn, 0, "serial number"); SYSCTL_ADD_STRING(ctx, children, OID_AUTO, "pn", CTLFLAG_RD, sc->params.vpd.pn, 0, "part number"); SYSCTL_ADD_STRING(ctx, children, OID_AUTO, "ec", CTLFLAG_RD, sc->params.vpd.ec, 0, "engineering change"); SYSCTL_ADD_STRING(ctx, children, OID_AUTO, "na", CTLFLAG_RD, sc->params.vpd.na, 0, "network address"); SYSCTL_ADD_STRING(ctx, children, OID_AUTO, "er_version", CTLFLAG_RD, sc->er_version, 0, "expansion ROM version"); SYSCTL_ADD_STRING(ctx, children, OID_AUTO, "bs_version", CTLFLAG_RD, sc->bs_version, 0, "bootstrap firmware version"); SYSCTL_ADD_UINT(ctx, children, OID_AUTO, "scfg_version", CTLFLAG_RD, NULL, sc->params.scfg_vers, "serial config version"); SYSCTL_ADD_UINT(ctx, children, OID_AUTO, "vpd_version", CTLFLAG_RD, NULL, sc->params.vpd_vers, "VPD version"); SYSCTL_ADD_STRING(ctx, children, OID_AUTO, "cf", CTLFLAG_RD, sc->cfg_file, 0, "configuration file"); SYSCTL_ADD_UINT(ctx, children, OID_AUTO, "cfcsum", CTLFLAG_RD, NULL, sc->cfcsum, "config file checksum"); #define SYSCTL_CAP(name, n, text) \ SYSCTL_ADD_PROC(ctx, children, OID_AUTO, #name, \ CTLTYPE_STRING | CTLFLAG_RD, caps_decoder[n], sc->name, \ sysctl_bitfield, "A", "available " text " capabilities") SYSCTL_CAP(nbmcaps, 0, "NBM"); SYSCTL_CAP(linkcaps, 1, "link"); SYSCTL_CAP(switchcaps, 2, "switch"); SYSCTL_CAP(niccaps, 3, "NIC"); SYSCTL_CAP(toecaps, 4, "TCP offload"); SYSCTL_CAP(rdmacaps, 5, "RDMA"); SYSCTL_CAP(iscsicaps, 6, "iSCSI"); SYSCTL_CAP(cryptocaps, 7, "crypto"); SYSCTL_CAP(fcoecaps, 8, "FCoE"); #undef SYSCTL_CAP SYSCTL_ADD_INT(ctx, children, OID_AUTO, "nfilters", CTLFLAG_RD, NULL, sc->tids.nftids, "number of filters"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "temperature", CTLTYPE_INT | CTLFLAG_RD, sc, 0, sysctl_temperature, "I", "chip temperature (in Celsius)"); #ifdef SBUF_DRAIN /* * dev.t4nex.X.misc. Marked CTLFLAG_SKIP to avoid information overload. */ oid = SYSCTL_ADD_NODE(ctx, c0, OID_AUTO, "misc", CTLFLAG_RD | CTLFLAG_SKIP, NULL, "logs and miscellaneous information"); children = SYSCTL_CHILDREN(oid); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "cctrl", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, sysctl_cctrl, "A", "congestion control"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "cim_ibq_tp0", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, sysctl_cim_ibq_obq, "A", "CIM IBQ 0 (TP0)"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "cim_ibq_tp1", CTLTYPE_STRING | CTLFLAG_RD, sc, 1, sysctl_cim_ibq_obq, "A", "CIM IBQ 1 (TP1)"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "cim_ibq_ulp", CTLTYPE_STRING | CTLFLAG_RD, sc, 2, sysctl_cim_ibq_obq, "A", "CIM IBQ 2 (ULP)"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "cim_ibq_sge0", CTLTYPE_STRING | CTLFLAG_RD, sc, 3, sysctl_cim_ibq_obq, "A", "CIM IBQ 3 (SGE0)"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "cim_ibq_sge1", CTLTYPE_STRING | CTLFLAG_RD, sc, 4, sysctl_cim_ibq_obq, "A", "CIM IBQ 4 (SGE1)"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "cim_ibq_ncsi", CTLTYPE_STRING | CTLFLAG_RD, sc, 5, sysctl_cim_ibq_obq, "A", "CIM IBQ 5 (NCSI)"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "cim_la", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, chip_id(sc) <= CHELSIO_T5 ? sysctl_cim_la : sysctl_cim_la_t6, "A", "CIM logic analyzer"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "cim_ma_la", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, sysctl_cim_ma_la, "A", "CIM MA logic analyzer"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "cim_obq_ulp0", CTLTYPE_STRING | CTLFLAG_RD, sc, 0 + CIM_NUM_IBQ, sysctl_cim_ibq_obq, "A", "CIM OBQ 0 (ULP0)"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "cim_obq_ulp1", CTLTYPE_STRING | CTLFLAG_RD, sc, 1 + CIM_NUM_IBQ, sysctl_cim_ibq_obq, "A", "CIM OBQ 1 (ULP1)"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "cim_obq_ulp2", CTLTYPE_STRING | CTLFLAG_RD, sc, 2 + CIM_NUM_IBQ, sysctl_cim_ibq_obq, "A", "CIM OBQ 2 (ULP2)"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "cim_obq_ulp3", CTLTYPE_STRING | CTLFLAG_RD, sc, 3 + CIM_NUM_IBQ, sysctl_cim_ibq_obq, "A", "CIM OBQ 3 (ULP3)"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "cim_obq_sge", CTLTYPE_STRING | CTLFLAG_RD, sc, 4 + CIM_NUM_IBQ, sysctl_cim_ibq_obq, "A", "CIM OBQ 4 (SGE)"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "cim_obq_ncsi", CTLTYPE_STRING | CTLFLAG_RD, sc, 5 + CIM_NUM_IBQ, sysctl_cim_ibq_obq, "A", "CIM OBQ 5 (NCSI)"); if (chip_id(sc) > CHELSIO_T4) { SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "cim_obq_sge0_rx", CTLTYPE_STRING | CTLFLAG_RD, sc, 6 + CIM_NUM_IBQ, sysctl_cim_ibq_obq, "A", "CIM OBQ 6 (SGE0-RX)"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "cim_obq_sge1_rx", CTLTYPE_STRING | CTLFLAG_RD, sc, 7 + CIM_NUM_IBQ, sysctl_cim_ibq_obq, "A", "CIM OBQ 7 (SGE1-RX)"); } SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "cim_pif_la", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, sysctl_cim_pif_la, "A", "CIM PIF logic analyzer"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "cim_qcfg", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, sysctl_cim_qcfg, "A", "CIM queue configuration"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "cpl_stats", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, sysctl_cpl_stats, "A", "CPL statistics"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "ddp_stats", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, sysctl_ddp_stats, "A", "non-TCP DDP statistics"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "devlog", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, sysctl_devlog, "A", "firmware's device log"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "fcoe_stats", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, sysctl_fcoe_stats, "A", "FCoE statistics"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "hw_sched", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, sysctl_hw_sched, "A", "hardware scheduler "); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "l2t", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, sysctl_l2t, "A", "hardware L2 table"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "lb_stats", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, sysctl_lb_stats, "A", "loopback statistics"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "meminfo", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, sysctl_meminfo, "A", "memory regions"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "mps_tcam", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, chip_id(sc) <= CHELSIO_T5 ? sysctl_mps_tcam : sysctl_mps_tcam_t6, "A", "MPS TCAM entries"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "path_mtus", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, sysctl_path_mtus, "A", "path MTUs"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "pm_stats", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, sysctl_pm_stats, "A", "PM statistics"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "rdma_stats", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, sysctl_rdma_stats, "A", "RDMA statistics"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "tcp_stats", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, sysctl_tcp_stats, "A", "TCP statistics"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "tids", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, sysctl_tids, "A", "TID information"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "tp_err_stats", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, sysctl_tp_err_stats, "A", "TP error statistics"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "tp_la_mask", CTLTYPE_INT | CTLFLAG_RW, sc, 0, sysctl_tp_la_mask, "I", "TP logic analyzer event capture mask"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "tp_la", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, sysctl_tp_la, "A", "TP logic analyzer"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "tx_rate", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, sysctl_tx_rate, "A", "Tx rate"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "ulprx_la", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, sysctl_ulprx_la, "A", "ULPRX logic analyzer"); if (chip_id(sc) >= CHELSIO_T5) { SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "wcwr_stats", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, sysctl_wcwr_stats, "A", "write combined work requests"); } #endif #ifdef TCP_OFFLOAD if (is_offload(sc)) { + int i; + char s[4]; + /* * dev.t4nex.X.toe. */ oid = SYSCTL_ADD_NODE(ctx, c0, OID_AUTO, "toe", CTLFLAG_RD, NULL, "TOE parameters"); children = SYSCTL_CHILDREN(oid); sc->tt.sndbuf = 256 * 1024; SYSCTL_ADD_INT(ctx, children, OID_AUTO, "sndbuf", CTLFLAG_RW, &sc->tt.sndbuf, 0, "max hardware send buffer size"); sc->tt.ddp = 0; SYSCTL_ADD_INT(ctx, children, OID_AUTO, "ddp", CTLFLAG_RW, &sc->tt.ddp, 0, "DDP allowed"); sc->tt.rx_coalesce = 1; SYSCTL_ADD_INT(ctx, children, OID_AUTO, "rx_coalesce", CTLFLAG_RW, &sc->tt.rx_coalesce, 0, "receive coalescing"); sc->tt.tx_align = 1; SYSCTL_ADD_INT(ctx, children, OID_AUTO, "tx_align", CTLFLAG_RW, &sc->tt.tx_align, 0, "chop and align payload"); sc->tt.tx_zcopy = 0; SYSCTL_ADD_INT(ctx, children, OID_AUTO, "tx_zcopy", CTLFLAG_RW, &sc->tt.tx_zcopy, 0, "Enable zero-copy aio_write(2)"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "timer_tick", CTLTYPE_STRING | CTLFLAG_RD, sc, 0, sysctl_tp_tick, "A", "TP timer tick (us)"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "timestamp_tick", CTLTYPE_STRING | CTLFLAG_RD, sc, 1, sysctl_tp_tick, "A", "TCP timestamp tick (us)"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "dack_tick", CTLTYPE_STRING | CTLFLAG_RD, sc, 2, sysctl_tp_tick, "A", "DACK tick (us)"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "dack_timer", CTLTYPE_UINT | CTLFLAG_RD, sc, 0, sysctl_tp_dack_timer, "IU", "DACK timer (us)"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "rexmt_min", CTLTYPE_ULONG | CTLFLAG_RD, sc, A_TP_RXT_MIN, - sysctl_tp_timer, "LU", "Retransmit min (us)"); + sysctl_tp_timer, "LU", "Minimum retransmit interval (us)"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "rexmt_max", CTLTYPE_ULONG | CTLFLAG_RD, sc, A_TP_RXT_MAX, - sysctl_tp_timer, "LU", "Retransmit max (us)"); + sysctl_tp_timer, "LU", "Maximum retransmit interval (us)"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "persist_min", CTLTYPE_ULONG | CTLFLAG_RD, sc, A_TP_PERS_MIN, sysctl_tp_timer, "LU", "Persist timer min (us)"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "persist_max", CTLTYPE_ULONG | CTLFLAG_RD, sc, A_TP_PERS_MAX, sysctl_tp_timer, "LU", "Persist timer max (us)"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "keepalive_idle", CTLTYPE_ULONG | CTLFLAG_RD, sc, A_TP_KEEP_IDLE, - sysctl_tp_timer, "LU", "Keepidle idle timer (us)"); + sysctl_tp_timer, "LU", "Keepalive idle timer (us)"); - SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "keepalive_intvl", + SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "keepalive_interval", CTLTYPE_ULONG | CTLFLAG_RD, sc, A_TP_KEEP_INTVL, - sysctl_tp_timer, "LU", "Keepidle interval (us)"); + sysctl_tp_timer, "LU", "Keepalive interval timer (us)"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "initial_srtt", CTLTYPE_ULONG | CTLFLAG_RD, sc, A_TP_INIT_SRTT, sysctl_tp_timer, "LU", "Initial SRTT (us)"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "finwait2_timer", CTLTYPE_ULONG | CTLFLAG_RD, sc, A_TP_FINWAIT2_TIMER, sysctl_tp_timer, "LU", "FINWAIT2 timer (us)"); + + SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "syn_rexmt_count", + CTLTYPE_UINT | CTLFLAG_RD, sc, S_SYNSHIFTMAX, + sysctl_tp_shift_cnt, "IU", + "Number of SYN retransmissions before abort"); + + SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "rexmt_count", + CTLTYPE_UINT | CTLFLAG_RD, sc, S_RXTSHIFTMAXR2, + sysctl_tp_shift_cnt, "IU", + "Number of retransmissions before abort"); + + SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "keepalive_count", + CTLTYPE_UINT | CTLFLAG_RD, sc, S_KEEPALIVEMAXR2, + sysctl_tp_shift_cnt, "IU", + "Number of keepalive probes before abort"); + + oid = SYSCTL_ADD_NODE(ctx, children, OID_AUTO, "rexmt_backoff", + CTLFLAG_RD, NULL, "TOE retransmit backoffs"); + children = SYSCTL_CHILDREN(oid); + for (i = 0; i < 16; i++) { + snprintf(s, sizeof(s), "%u", i); + SYSCTL_ADD_PROC(ctx, children, OID_AUTO, s, + CTLTYPE_UINT | CTLFLAG_RD, sc, i, sysctl_tp_backoff, + "IU", "TOE retransmit backoff"); + } } #endif } void vi_sysctls(struct vi_info *vi) { struct sysctl_ctx_list *ctx; struct sysctl_oid *oid; struct sysctl_oid_list *children; ctx = device_get_sysctl_ctx(vi->dev); /* * dev.v?(cxgbe|cxl).X. */ oid = device_get_sysctl_tree(vi->dev); children = SYSCTL_CHILDREN(oid); SYSCTL_ADD_UINT(ctx, children, OID_AUTO, "viid", CTLFLAG_RD, NULL, vi->viid, "VI identifer"); SYSCTL_ADD_INT(ctx, children, OID_AUTO, "nrxq", CTLFLAG_RD, &vi->nrxq, 0, "# of rx queues"); SYSCTL_ADD_INT(ctx, children, OID_AUTO, "ntxq", CTLFLAG_RD, &vi->ntxq, 0, "# of tx queues"); SYSCTL_ADD_INT(ctx, children, OID_AUTO, "first_rxq", CTLFLAG_RD, &vi->first_rxq, 0, "index of first rx queue"); SYSCTL_ADD_INT(ctx, children, OID_AUTO, "first_txq", CTLFLAG_RD, &vi->first_txq, 0, "index of first tx queue"); SYSCTL_ADD_UINT(ctx, children, OID_AUTO, "rss_size", CTLFLAG_RD, NULL, vi->rss_size, "size of RSS indirection table"); if (IS_MAIN_VI(vi)) { SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "rsrv_noflowq", CTLTYPE_INT | CTLFLAG_RW, vi, 0, sysctl_noflowq, "IU", "Reserve queue 0 for non-flowid packets"); } #ifdef TCP_OFFLOAD if (vi->nofldrxq != 0) { SYSCTL_ADD_INT(ctx, children, OID_AUTO, "nofldrxq", CTLFLAG_RD, &vi->nofldrxq, 0, "# of rx queues for offloaded TCP connections"); SYSCTL_ADD_INT(ctx, children, OID_AUTO, "nofldtxq", CTLFLAG_RD, &vi->nofldtxq, 0, "# of tx queues for offloaded TCP connections"); SYSCTL_ADD_INT(ctx, children, OID_AUTO, "first_ofld_rxq", CTLFLAG_RD, &vi->first_ofld_rxq, 0, "index of first TOE rx queue"); SYSCTL_ADD_INT(ctx, children, OID_AUTO, "first_ofld_txq", CTLFLAG_RD, &vi->first_ofld_txq, 0, "index of first TOE tx queue"); } #endif #ifdef DEV_NETMAP if (vi->nnmrxq != 0) { SYSCTL_ADD_INT(ctx, children, OID_AUTO, "nnmrxq", CTLFLAG_RD, &vi->nnmrxq, 0, "# of netmap rx queues"); SYSCTL_ADD_INT(ctx, children, OID_AUTO, "nnmtxq", CTLFLAG_RD, &vi->nnmtxq, 0, "# of netmap tx queues"); SYSCTL_ADD_INT(ctx, children, OID_AUTO, "first_nm_rxq", CTLFLAG_RD, &vi->first_nm_rxq, 0, "index of first netmap rx queue"); SYSCTL_ADD_INT(ctx, children, OID_AUTO, "first_nm_txq", CTLFLAG_RD, &vi->first_nm_txq, 0, "index of first netmap tx queue"); } #endif SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "holdoff_tmr_idx", CTLTYPE_INT | CTLFLAG_RW, vi, 0, sysctl_holdoff_tmr_idx, "I", "holdoff timer index"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "holdoff_pktc_idx", CTLTYPE_INT | CTLFLAG_RW, vi, 0, sysctl_holdoff_pktc_idx, "I", "holdoff packet counter index"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "qsize_rxq", CTLTYPE_INT | CTLFLAG_RW, vi, 0, sysctl_qsize_rxq, "I", "rx queue size"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "qsize_txq", CTLTYPE_INT | CTLFLAG_RW, vi, 0, sysctl_qsize_txq, "I", "tx queue size"); } static void cxgbe_sysctls(struct port_info *pi) { struct sysctl_ctx_list *ctx; struct sysctl_oid *oid; struct sysctl_oid_list *children, *children2; struct adapter *sc = pi->adapter; int i; char name[16]; ctx = device_get_sysctl_ctx(pi->dev); /* * dev.cxgbe.X. */ oid = device_get_sysctl_tree(pi->dev); children = SYSCTL_CHILDREN(oid); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "linkdnrc", CTLTYPE_STRING | CTLFLAG_RD, pi, 0, sysctl_linkdnrc, "A", "reason why link is down"); if (pi->port_type == FW_PORT_TYPE_BT_XAUI) { SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "temperature", CTLTYPE_INT | CTLFLAG_RD, pi, 0, sysctl_btphy, "I", "PHY temperature (in Celsius)"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "fw_version", CTLTYPE_INT | CTLFLAG_RD, pi, 1, sysctl_btphy, "I", "PHY firmware version"); } SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "pause_settings", CTLTYPE_STRING | CTLFLAG_RW, pi, 0, sysctl_pause_settings, "A", "PAUSE settings (bit 0 = rx_pause, bit 1 = tx_pause)"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "fec", CTLTYPE_STRING | CTLFLAG_RW, pi, 0, sysctl_fec, "A", "Forward Error Correction (bit 0 = RS, bit 1 = BASER_RS)"); SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "autoneg", CTLTYPE_INT | CTLFLAG_RW, pi, 0, sysctl_autoneg, "I", "autonegotiation (-1 = not supported)"); SYSCTL_ADD_INT(ctx, children, OID_AUTO, "max_speed", CTLFLAG_RD, NULL, port_top_speed(pi), "max speed (in Gbps)"); if (sc->flags & IS_VF) return; /* * dev.(cxgbe|cxl).X.tc. */ oid = SYSCTL_ADD_NODE(ctx, children, OID_AUTO, "tc", CTLFLAG_RD, NULL, "Tx scheduler traffic classes (cl_rl)"); for (i = 0; i < sc->chip_params->nsched_cls; i++) { struct tx_cl_rl_params *tc = &pi->sched_params->cl_rl[i]; snprintf(name, sizeof(name), "%d", i); children2 = SYSCTL_CHILDREN(SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(oid), OID_AUTO, name, CTLFLAG_RD, NULL, "traffic class")); SYSCTL_ADD_UINT(ctx, children2, OID_AUTO, "flags", CTLFLAG_RD, &tc->flags, 0, "flags"); SYSCTL_ADD_UINT(ctx, children2, OID_AUTO, "refcount", CTLFLAG_RD, &tc->refcount, 0, "references to this class"); #ifdef SBUF_DRAIN SYSCTL_ADD_PROC(ctx, children2, OID_AUTO, "params", CTLTYPE_STRING | CTLFLAG_RD, sc, (pi->port_id << 16) | i, sysctl_tc_params, "A", "traffic class parameters"); #endif } /* * dev.cxgbe.X.stats. */ oid = SYSCTL_ADD_NODE(ctx, children, OID_AUTO, "stats", CTLFLAG_RD, NULL, "port statistics"); children = SYSCTL_CHILDREN(oid); SYSCTL_ADD_UINT(ctx, children, OID_AUTO, "tx_parse_error", CTLFLAG_RD, &pi->tx_parse_error, 0, "# of tx packets with invalid length or # of segments"); #define SYSCTL_ADD_T4_REG64(pi, name, desc, reg) \ SYSCTL_ADD_OID(ctx, children, OID_AUTO, name, \ CTLTYPE_U64 | CTLFLAG_RD, sc, reg, \ sysctl_handle_t4_reg64, "QU", desc) SYSCTL_ADD_T4_REG64(pi, "tx_octets", "# of octets in good frames", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_TX_PORT_BYTES_L)); SYSCTL_ADD_T4_REG64(pi, "tx_frames", "total # of good frames", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_TX_PORT_FRAMES_L)); SYSCTL_ADD_T4_REG64(pi, "tx_bcast_frames", "# of broadcast frames", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_TX_PORT_BCAST_L)); SYSCTL_ADD_T4_REG64(pi, "tx_mcast_frames", "# of multicast frames", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_TX_PORT_MCAST_L)); SYSCTL_ADD_T4_REG64(pi, "tx_ucast_frames", "# of unicast frames", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_TX_PORT_UCAST_L)); SYSCTL_ADD_T4_REG64(pi, "tx_error_frames", "# of error frames", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_TX_PORT_ERROR_L)); SYSCTL_ADD_T4_REG64(pi, "tx_frames_64", "# of tx frames in this range", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_TX_PORT_64B_L)); SYSCTL_ADD_T4_REG64(pi, "tx_frames_65_127", "# of tx frames in this range", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_TX_PORT_65B_127B_L)); SYSCTL_ADD_T4_REG64(pi, "tx_frames_128_255", "# of tx frames in this range", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_TX_PORT_128B_255B_L)); SYSCTL_ADD_T4_REG64(pi, "tx_frames_256_511", "# of tx frames in this range", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_TX_PORT_256B_511B_L)); SYSCTL_ADD_T4_REG64(pi, "tx_frames_512_1023", "# of tx frames in this range", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_TX_PORT_512B_1023B_L)); SYSCTL_ADD_T4_REG64(pi, "tx_frames_1024_1518", "# of tx frames in this range", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_TX_PORT_1024B_1518B_L)); SYSCTL_ADD_T4_REG64(pi, "tx_frames_1519_max", "# of tx frames in this range", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_TX_PORT_1519B_MAX_L)); SYSCTL_ADD_T4_REG64(pi, "tx_drop", "# of dropped tx frames", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_TX_PORT_DROP_L)); SYSCTL_ADD_T4_REG64(pi, "tx_pause", "# of pause frames transmitted", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_TX_PORT_PAUSE_L)); SYSCTL_ADD_T4_REG64(pi, "tx_ppp0", "# of PPP prio 0 frames transmitted", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_TX_PORT_PPP0_L)); SYSCTL_ADD_T4_REG64(pi, "tx_ppp1", "# of PPP prio 1 frames transmitted", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_TX_PORT_PPP1_L)); SYSCTL_ADD_T4_REG64(pi, "tx_ppp2", "# of PPP prio 2 frames transmitted", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_TX_PORT_PPP2_L)); SYSCTL_ADD_T4_REG64(pi, "tx_ppp3", "# of PPP prio 3 frames transmitted", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_TX_PORT_PPP3_L)); SYSCTL_ADD_T4_REG64(pi, "tx_ppp4", "# of PPP prio 4 frames transmitted", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_TX_PORT_PPP4_L)); SYSCTL_ADD_T4_REG64(pi, "tx_ppp5", "# of PPP prio 5 frames transmitted", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_TX_PORT_PPP5_L)); SYSCTL_ADD_T4_REG64(pi, "tx_ppp6", "# of PPP prio 6 frames transmitted", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_TX_PORT_PPP6_L)); SYSCTL_ADD_T4_REG64(pi, "tx_ppp7", "# of PPP prio 7 frames transmitted", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_TX_PORT_PPP7_L)); SYSCTL_ADD_T4_REG64(pi, "rx_octets", "# of octets in good frames", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_RX_PORT_BYTES_L)); SYSCTL_ADD_T4_REG64(pi, "rx_frames", "total # of good frames", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_RX_PORT_FRAMES_L)); SYSCTL_ADD_T4_REG64(pi, "rx_bcast_frames", "# of broadcast frames", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_RX_PORT_BCAST_L)); SYSCTL_ADD_T4_REG64(pi, "rx_mcast_frames", "# of multicast frames", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_RX_PORT_MCAST_L)); SYSCTL_ADD_T4_REG64(pi, "rx_ucast_frames", "# of unicast frames", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_RX_PORT_UCAST_L)); SYSCTL_ADD_T4_REG64(pi, "rx_too_long", "# of frames exceeding MTU", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_RX_PORT_MTU_ERROR_L)); SYSCTL_ADD_T4_REG64(pi, "rx_jabber", "# of jabber frames", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_RX_PORT_MTU_CRC_ERROR_L)); SYSCTL_ADD_T4_REG64(pi, "rx_fcs_err", "# of frames received with bad FCS", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_RX_PORT_CRC_ERROR_L)); SYSCTL_ADD_T4_REG64(pi, "rx_len_err", "# of frames received with length error", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_RX_PORT_LEN_ERROR_L)); SYSCTL_ADD_T4_REG64(pi, "rx_symbol_err", "symbol errors", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_RX_PORT_SYM_ERROR_L)); SYSCTL_ADD_T4_REG64(pi, "rx_runt", "# of short frames received", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_RX_PORT_LESS_64B_L)); SYSCTL_ADD_T4_REG64(pi, "rx_frames_64", "# of rx frames in this range", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_RX_PORT_64B_L)); SYSCTL_ADD_T4_REG64(pi, "rx_frames_65_127", "# of rx frames in this range", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_RX_PORT_65B_127B_L)); SYSCTL_ADD_T4_REG64(pi, "rx_frames_128_255", "# of rx frames in this range", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_RX_PORT_128B_255B_L)); SYSCTL_ADD_T4_REG64(pi, "rx_frames_256_511", "# of rx frames in this range", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_RX_PORT_256B_511B_L)); SYSCTL_ADD_T4_REG64(pi, "rx_frames_512_1023", "# of rx frames in this range", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_RX_PORT_512B_1023B_L)); SYSCTL_ADD_T4_REG64(pi, "rx_frames_1024_1518", "# of rx frames in this range", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_RX_PORT_1024B_1518B_L)); SYSCTL_ADD_T4_REG64(pi, "rx_frames_1519_max", "# of rx frames in this range", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_RX_PORT_1519B_MAX_L)); SYSCTL_ADD_T4_REG64(pi, "rx_pause", "# of pause frames received", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_RX_PORT_PAUSE_L)); SYSCTL_ADD_T4_REG64(pi, "rx_ppp0", "# of PPP prio 0 frames received", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_RX_PORT_PPP0_L)); SYSCTL_ADD_T4_REG64(pi, "rx_ppp1", "# of PPP prio 1 frames received", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_RX_PORT_PPP1_L)); SYSCTL_ADD_T4_REG64(pi, "rx_ppp2", "# of PPP prio 2 frames received", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_RX_PORT_PPP2_L)); SYSCTL_ADD_T4_REG64(pi, "rx_ppp3", "# of PPP prio 3 frames received", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_RX_PORT_PPP3_L)); SYSCTL_ADD_T4_REG64(pi, "rx_ppp4", "# of PPP prio 4 frames received", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_RX_PORT_PPP4_L)); SYSCTL_ADD_T4_REG64(pi, "rx_ppp5", "# of PPP prio 5 frames received", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_RX_PORT_PPP5_L)); SYSCTL_ADD_T4_REG64(pi, "rx_ppp6", "# of PPP prio 6 frames received", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_RX_PORT_PPP6_L)); SYSCTL_ADD_T4_REG64(pi, "rx_ppp7", "# of PPP prio 7 frames received", PORT_REG(pi->tx_chan, A_MPS_PORT_STAT_RX_PORT_PPP7_L)); #undef SYSCTL_ADD_T4_REG64 #define SYSCTL_ADD_T4_PORTSTAT(name, desc) \ SYSCTL_ADD_UQUAD(ctx, children, OID_AUTO, #name, CTLFLAG_RD, \ &pi->stats.name, desc) /* We get these from port_stats and they may be stale by up to 1s */ SYSCTL_ADD_T4_PORTSTAT(rx_ovflow0, "# drops due to buffer-group 0 overflows"); SYSCTL_ADD_T4_PORTSTAT(rx_ovflow1, "# drops due to buffer-group 1 overflows"); SYSCTL_ADD_T4_PORTSTAT(rx_ovflow2, "# drops due to buffer-group 2 overflows"); SYSCTL_ADD_T4_PORTSTAT(rx_ovflow3, "# drops due to buffer-group 3 overflows"); SYSCTL_ADD_T4_PORTSTAT(rx_trunc0, "# of buffer-group 0 truncated packets"); SYSCTL_ADD_T4_PORTSTAT(rx_trunc1, "# of buffer-group 1 truncated packets"); SYSCTL_ADD_T4_PORTSTAT(rx_trunc2, "# of buffer-group 2 truncated packets"); SYSCTL_ADD_T4_PORTSTAT(rx_trunc3, "# of buffer-group 3 truncated packets"); #undef SYSCTL_ADD_T4_PORTSTAT } static int sysctl_int_array(SYSCTL_HANDLER_ARGS) { int rc, *i, space = 0; struct sbuf sb; sbuf_new_for_sysctl(&sb, NULL, 64, req); for (i = arg1; arg2; arg2 -= sizeof(int), i++) { if (space) sbuf_printf(&sb, " "); sbuf_printf(&sb, "%d", *i); space = 1; } rc = sbuf_finish(&sb); sbuf_delete(&sb); return (rc); } static int sysctl_bitfield(SYSCTL_HANDLER_ARGS) { int rc; struct sbuf *sb; rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) return(rc); sb = sbuf_new_for_sysctl(NULL, NULL, 128, req); if (sb == NULL) return (ENOMEM); sbuf_printf(sb, "%b", (int)arg2, (char *)arg1); rc = sbuf_finish(sb); sbuf_delete(sb); return (rc); } static int sysctl_btphy(SYSCTL_HANDLER_ARGS) { struct port_info *pi = arg1; int op = arg2; struct adapter *sc = pi->adapter; u_int v; int rc; rc = begin_synchronized_op(sc, &pi->vi[0], SLEEP_OK | INTR_OK, "t4btt"); if (rc) return (rc); /* XXX: magic numbers */ rc = -t4_mdio_rd(sc, sc->mbox, pi->mdio_addr, 0x1e, op ? 0x20 : 0xc820, &v); end_synchronized_op(sc, 0); if (rc) return (rc); if (op == 0) v /= 256; rc = sysctl_handle_int(oidp, &v, 0, req); return (rc); } static int sysctl_noflowq(SYSCTL_HANDLER_ARGS) { struct vi_info *vi = arg1; int rc, val; val = vi->rsrv_noflowq; rc = sysctl_handle_int(oidp, &val, 0, req); if (rc != 0 || req->newptr == NULL) return (rc); if ((val >= 1) && (vi->ntxq > 1)) vi->rsrv_noflowq = 1; else vi->rsrv_noflowq = 0; return (rc); } static int sysctl_holdoff_tmr_idx(SYSCTL_HANDLER_ARGS) { struct vi_info *vi = arg1; struct adapter *sc = vi->pi->adapter; int idx, rc, i; struct sge_rxq *rxq; #ifdef TCP_OFFLOAD struct sge_ofld_rxq *ofld_rxq; #endif uint8_t v; idx = vi->tmr_idx; rc = sysctl_handle_int(oidp, &idx, 0, req); if (rc != 0 || req->newptr == NULL) return (rc); if (idx < 0 || idx >= SGE_NTIMERS) return (EINVAL); rc = begin_synchronized_op(sc, vi, HOLD_LOCK | SLEEP_OK | INTR_OK, "t4tmr"); if (rc) return (rc); v = V_QINTR_TIMER_IDX(idx) | V_QINTR_CNT_EN(vi->pktc_idx != -1); for_each_rxq(vi, i, rxq) { #ifdef atomic_store_rel_8 atomic_store_rel_8(&rxq->iq.intr_params, v); #else rxq->iq.intr_params = v; #endif } #ifdef TCP_OFFLOAD for_each_ofld_rxq(vi, i, ofld_rxq) { #ifdef atomic_store_rel_8 atomic_store_rel_8(&ofld_rxq->iq.intr_params, v); #else ofld_rxq->iq.intr_params = v; #endif } #endif vi->tmr_idx = idx; end_synchronized_op(sc, LOCK_HELD); return (0); } static int sysctl_holdoff_pktc_idx(SYSCTL_HANDLER_ARGS) { struct vi_info *vi = arg1; struct adapter *sc = vi->pi->adapter; int idx, rc; idx = vi->pktc_idx; rc = sysctl_handle_int(oidp, &idx, 0, req); if (rc != 0 || req->newptr == NULL) return (rc); if (idx < -1 || idx >= SGE_NCOUNTERS) return (EINVAL); rc = begin_synchronized_op(sc, vi, HOLD_LOCK | SLEEP_OK | INTR_OK, "t4pktc"); if (rc) return (rc); if (vi->flags & VI_INIT_DONE) rc = EBUSY; /* cannot be changed once the queues are created */ else vi->pktc_idx = idx; end_synchronized_op(sc, LOCK_HELD); return (rc); } static int sysctl_qsize_rxq(SYSCTL_HANDLER_ARGS) { struct vi_info *vi = arg1; struct adapter *sc = vi->pi->adapter; int qsize, rc; qsize = vi->qsize_rxq; rc = sysctl_handle_int(oidp, &qsize, 0, req); if (rc != 0 || req->newptr == NULL) return (rc); if (qsize < 128 || (qsize & 7)) return (EINVAL); rc = begin_synchronized_op(sc, vi, HOLD_LOCK | SLEEP_OK | INTR_OK, "t4rxqs"); if (rc) return (rc); if (vi->flags & VI_INIT_DONE) rc = EBUSY; /* cannot be changed once the queues are created */ else vi->qsize_rxq = qsize; end_synchronized_op(sc, LOCK_HELD); return (rc); } static int sysctl_qsize_txq(SYSCTL_HANDLER_ARGS) { struct vi_info *vi = arg1; struct adapter *sc = vi->pi->adapter; int qsize, rc; qsize = vi->qsize_txq; rc = sysctl_handle_int(oidp, &qsize, 0, req); if (rc != 0 || req->newptr == NULL) return (rc); if (qsize < 128 || qsize > 65536) return (EINVAL); rc = begin_synchronized_op(sc, vi, HOLD_LOCK | SLEEP_OK | INTR_OK, "t4txqs"); if (rc) return (rc); if (vi->flags & VI_INIT_DONE) rc = EBUSY; /* cannot be changed once the queues are created */ else vi->qsize_txq = qsize; end_synchronized_op(sc, LOCK_HELD); return (rc); } static int sysctl_pause_settings(SYSCTL_HANDLER_ARGS) { struct port_info *pi = arg1; struct adapter *sc = pi->adapter; struct link_config *lc = &pi->link_cfg; int rc; if (req->newptr == NULL) { struct sbuf *sb; static char *bits = "\20\1PAUSE_RX\2PAUSE_TX"; rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) return(rc); sb = sbuf_new_for_sysctl(NULL, NULL, 128, req); if (sb == NULL) return (ENOMEM); sbuf_printf(sb, "%b", lc->fc & (PAUSE_TX | PAUSE_RX), bits); rc = sbuf_finish(sb); sbuf_delete(sb); } else { char s[2]; int n; s[0] = '0' + (lc->requested_fc & (PAUSE_TX | PAUSE_RX)); s[1] = 0; rc = sysctl_handle_string(oidp, s, sizeof(s), req); if (rc != 0) return(rc); if (s[1] != 0) return (EINVAL); if (s[0] < '0' || s[0] > '9') return (EINVAL); /* not a number */ n = s[0] - '0'; if (n & ~(PAUSE_TX | PAUSE_RX)) return (EINVAL); /* some other bit is set too */ rc = begin_synchronized_op(sc, &pi->vi[0], SLEEP_OK | INTR_OK, "t4PAUSE"); if (rc) return (rc); if ((lc->requested_fc & (PAUSE_TX | PAUSE_RX)) != n) { lc->requested_fc &= ~(PAUSE_TX | PAUSE_RX); lc->requested_fc |= n; rc = -t4_link_l1cfg(sc, sc->mbox, pi->tx_chan, lc); if (rc == 0) { lc->fc = lc->requested_fc; } } end_synchronized_op(sc, 0); } return (rc); } static int sysctl_fec(SYSCTL_HANDLER_ARGS) { struct port_info *pi = arg1; struct adapter *sc = pi->adapter; struct link_config *lc = &pi->link_cfg; int rc; if (req->newptr == NULL) { struct sbuf *sb; static char *bits = "\20\1RS\2BASER_RS\3RESERVED"; rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) return(rc); sb = sbuf_new_for_sysctl(NULL, NULL, 128, req); if (sb == NULL) return (ENOMEM); sbuf_printf(sb, "%b", lc->fec & M_FW_PORT_CAP_FEC, bits); rc = sbuf_finish(sb); sbuf_delete(sb); } else { char s[2]; int n; s[0] = '0' + (lc->requested_fec & M_FW_PORT_CAP_FEC); s[1] = 0; rc = sysctl_handle_string(oidp, s, sizeof(s), req); if (rc != 0) return(rc); if (s[1] != 0) return (EINVAL); if (s[0] < '0' || s[0] > '9') return (EINVAL); /* not a number */ n = s[0] - '0'; if (n & ~M_FW_PORT_CAP_FEC) return (EINVAL); /* some other bit is set too */ rc = begin_synchronized_op(sc, &pi->vi[0], SLEEP_OK | INTR_OK, "t4fec"); if (rc) return (rc); if ((lc->requested_fec & M_FW_PORT_CAP_FEC) != n) { lc->requested_fec = n & G_FW_PORT_CAP_FEC(lc->supported); rc = -t4_link_l1cfg(sc, sc->mbox, pi->tx_chan, lc); if (rc == 0) { lc->fec = lc->requested_fec; } } end_synchronized_op(sc, 0); } return (rc); } static int sysctl_autoneg(SYSCTL_HANDLER_ARGS) { struct port_info *pi = arg1; struct adapter *sc = pi->adapter; struct link_config *lc = &pi->link_cfg; int rc, val, old; if (lc->supported & FW_PORT_CAP_ANEG) val = lc->requested_aneg == AUTONEG_ENABLE ? 1 : 0; else val = -1; rc = sysctl_handle_int(oidp, &val, 0, req); if (rc != 0 || req->newptr == NULL) return (rc); if ((lc->supported & FW_PORT_CAP_ANEG) == 0) return (ENOTSUP); if (val == 0) val = AUTONEG_DISABLE; else if (val == 1) val = AUTONEG_ENABLE; else return (EINVAL); if (lc->requested_aneg == val) return (0); /* no change */ rc = begin_synchronized_op(sc, &pi->vi[0], SLEEP_OK | INTR_OK, "t4aneg"); if (rc) return (rc); old = lc->requested_aneg; lc->requested_aneg = val; rc = -t4_link_l1cfg(sc, sc->mbox, pi->tx_chan, lc); if (rc != 0) lc->requested_aneg = old; end_synchronized_op(sc, 0); return (rc); } static int sysctl_handle_t4_reg64(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; int reg = arg2; uint64_t val; val = t4_read_reg64(sc, reg); return (sysctl_handle_64(oidp, &val, 0, req)); } static int sysctl_temperature(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; int rc, t; uint32_t param, val; rc = begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t4temp"); if (rc) return (rc); param = V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_DIAG) | V_FW_PARAMS_PARAM_Y(FW_PARAM_DEV_DIAG_TMP); rc = -t4_query_params(sc, sc->mbox, sc->pf, 0, 1, ¶m, &val); end_synchronized_op(sc, 0); if (rc) return (rc); /* unknown is returned as 0 but we display -1 in that case */ t = val == 0 ? -1 : val; rc = sysctl_handle_int(oidp, &t, 0, req); return (rc); } #ifdef SBUF_DRAIN static int sysctl_cctrl(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; struct sbuf *sb; int rc, i; uint16_t incr[NMTUS][NCCTRL_WIN]; static const char *dec_fac[] = { "0.5", "0.5625", "0.625", "0.6875", "0.75", "0.8125", "0.875", "0.9375" }; rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) return (rc); sb = sbuf_new_for_sysctl(NULL, NULL, 4096, req); if (sb == NULL) return (ENOMEM); t4_read_cong_tbl(sc, incr); for (i = 0; i < NCCTRL_WIN; ++i) { sbuf_printf(sb, "%2d: %4u %4u %4u %4u %4u %4u %4u %4u\n", i, incr[0][i], incr[1][i], incr[2][i], incr[3][i], incr[4][i], incr[5][i], incr[6][i], incr[7][i]); sbuf_printf(sb, "%8u %4u %4u %4u %4u %4u %4u %4u %5u %s\n", incr[8][i], incr[9][i], incr[10][i], incr[11][i], incr[12][i], incr[13][i], incr[14][i], incr[15][i], sc->params.a_wnd[i], dec_fac[sc->params.b_wnd[i]]); } rc = sbuf_finish(sb); sbuf_delete(sb); return (rc); } static const char *qname[CIM_NUM_IBQ + CIM_NUM_OBQ_T5] = { "TP0", "TP1", "ULP", "SGE0", "SGE1", "NC-SI", /* ibq's */ "ULP0", "ULP1", "ULP2", "ULP3", "SGE", "NC-SI", /* obq's */ "SGE0-RX", "SGE1-RX" /* additional obq's (T5 onwards) */ }; static int sysctl_cim_ibq_obq(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; struct sbuf *sb; int rc, i, n, qid = arg2; uint32_t *buf, *p; char *qtype; u_int cim_num_obq = sc->chip_params->cim_num_obq; KASSERT(qid >= 0 && qid < CIM_NUM_IBQ + cim_num_obq, ("%s: bad qid %d\n", __func__, qid)); if (qid < CIM_NUM_IBQ) { /* inbound queue */ qtype = "IBQ"; n = 4 * CIM_IBQ_SIZE; buf = malloc(n * sizeof(uint32_t), M_CXGBE, M_ZERO | M_WAITOK); rc = t4_read_cim_ibq(sc, qid, buf, n); } else { /* outbound queue */ qtype = "OBQ"; qid -= CIM_NUM_IBQ; n = 4 * cim_num_obq * CIM_OBQ_SIZE; buf = malloc(n * sizeof(uint32_t), M_CXGBE, M_ZERO | M_WAITOK); rc = t4_read_cim_obq(sc, qid, buf, n); } if (rc < 0) { rc = -rc; goto done; } n = rc * sizeof(uint32_t); /* rc has # of words actually read */ rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) goto done; sb = sbuf_new_for_sysctl(NULL, NULL, PAGE_SIZE, req); if (sb == NULL) { rc = ENOMEM; goto done; } sbuf_printf(sb, "%s%d %s", qtype , qid, qname[arg2]); for (i = 0, p = buf; i < n; i += 16, p += 4) sbuf_printf(sb, "\n%#06x: %08x %08x %08x %08x", i, p[0], p[1], p[2], p[3]); rc = sbuf_finish(sb); sbuf_delete(sb); done: free(buf, M_CXGBE); return (rc); } static int sysctl_cim_la(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; u_int cfg; struct sbuf *sb; uint32_t *buf, *p; int rc; MPASS(chip_id(sc) <= CHELSIO_T5); rc = -t4_cim_read(sc, A_UP_UP_DBG_LA_CFG, 1, &cfg); if (rc != 0) return (rc); rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) return (rc); sb = sbuf_new_for_sysctl(NULL, NULL, 4096, req); if (sb == NULL) return (ENOMEM); buf = malloc(sc->params.cim_la_size * sizeof(uint32_t), M_CXGBE, M_ZERO | M_WAITOK); rc = -t4_cim_read_la(sc, buf, NULL); if (rc != 0) goto done; sbuf_printf(sb, "Status Data PC%s", cfg & F_UPDBGLACAPTPCONLY ? "" : " LS0Stat LS0Addr LS0Data"); for (p = buf; p <= &buf[sc->params.cim_la_size - 8]; p += 8) { if (cfg & F_UPDBGLACAPTPCONLY) { sbuf_printf(sb, "\n %02x %08x %08x", p[5] & 0xff, p[6], p[7]); sbuf_printf(sb, "\n %02x %02x%06x %02x%06x", (p[3] >> 8) & 0xff, p[3] & 0xff, p[4] >> 8, p[4] & 0xff, p[5] >> 8); sbuf_printf(sb, "\n %02x %x%07x %x%07x", (p[0] >> 4) & 0xff, p[0] & 0xf, p[1] >> 4, p[1] & 0xf, p[2] >> 4); } else { sbuf_printf(sb, "\n %02x %x%07x %x%07x %08x %08x " "%08x%08x%08x%08x", (p[0] >> 4) & 0xff, p[0] & 0xf, p[1] >> 4, p[1] & 0xf, p[2] >> 4, p[2] & 0xf, p[3], p[4], p[5], p[6], p[7]); } } rc = sbuf_finish(sb); sbuf_delete(sb); done: free(buf, M_CXGBE); return (rc); } static int sysctl_cim_la_t6(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; u_int cfg; struct sbuf *sb; uint32_t *buf, *p; int rc; MPASS(chip_id(sc) > CHELSIO_T5); rc = -t4_cim_read(sc, A_UP_UP_DBG_LA_CFG, 1, &cfg); if (rc != 0) return (rc); rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) return (rc); sb = sbuf_new_for_sysctl(NULL, NULL, 4096, req); if (sb == NULL) return (ENOMEM); buf = malloc(sc->params.cim_la_size * sizeof(uint32_t), M_CXGBE, M_ZERO | M_WAITOK); rc = -t4_cim_read_la(sc, buf, NULL); if (rc != 0) goto done; sbuf_printf(sb, "Status Inst Data PC%s", cfg & F_UPDBGLACAPTPCONLY ? "" : " LS0Stat LS0Addr LS0Data LS1Stat LS1Addr LS1Data"); for (p = buf; p <= &buf[sc->params.cim_la_size - 10]; p += 10) { if (cfg & F_UPDBGLACAPTPCONLY) { sbuf_printf(sb, "\n %02x %08x %08x %08x", p[3] & 0xff, p[2], p[1], p[0]); sbuf_printf(sb, "\n %02x %02x%06x %02x%06x %02x%06x", (p[6] >> 8) & 0xff, p[6] & 0xff, p[5] >> 8, p[5] & 0xff, p[4] >> 8, p[4] & 0xff, p[3] >> 8); sbuf_printf(sb, "\n %02x %04x%04x %04x%04x %04x%04x", (p[9] >> 16) & 0xff, p[9] & 0xffff, p[8] >> 16, p[8] & 0xffff, p[7] >> 16, p[7] & 0xffff, p[6] >> 16); } else { sbuf_printf(sb, "\n %02x %04x%04x %04x%04x %04x%04x " "%08x %08x %08x %08x %08x %08x", (p[9] >> 16) & 0xff, p[9] & 0xffff, p[8] >> 16, p[8] & 0xffff, p[7] >> 16, p[7] & 0xffff, p[6] >> 16, p[2], p[1], p[0], p[5], p[4], p[3]); } } rc = sbuf_finish(sb); sbuf_delete(sb); done: free(buf, M_CXGBE); return (rc); } static int sysctl_cim_ma_la(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; u_int i; struct sbuf *sb; uint32_t *buf, *p; int rc; rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) return (rc); sb = sbuf_new_for_sysctl(NULL, NULL, 4096, req); if (sb == NULL) return (ENOMEM); buf = malloc(2 * CIM_MALA_SIZE * 5 * sizeof(uint32_t), M_CXGBE, M_ZERO | M_WAITOK); t4_cim_read_ma_la(sc, buf, buf + 5 * CIM_MALA_SIZE); p = buf; for (i = 0; i < CIM_MALA_SIZE; i++, p += 5) { sbuf_printf(sb, "\n%02x%08x%08x%08x%08x", p[4], p[3], p[2], p[1], p[0]); } sbuf_printf(sb, "\n\nCnt ID Tag UE Data RDY VLD"); for (i = 0; i < CIM_MALA_SIZE; i++, p += 5) { sbuf_printf(sb, "\n%3u %2u %x %u %08x%08x %u %u", (p[2] >> 10) & 0xff, (p[2] >> 7) & 7, (p[2] >> 3) & 0xf, (p[2] >> 2) & 1, (p[1] >> 2) | ((p[2] & 3) << 30), (p[0] >> 2) | ((p[1] & 3) << 30), (p[0] >> 1) & 1, p[0] & 1); } rc = sbuf_finish(sb); sbuf_delete(sb); free(buf, M_CXGBE); return (rc); } static int sysctl_cim_pif_la(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; u_int i; struct sbuf *sb; uint32_t *buf, *p; int rc; rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) return (rc); sb = sbuf_new_for_sysctl(NULL, NULL, 4096, req); if (sb == NULL) return (ENOMEM); buf = malloc(2 * CIM_PIFLA_SIZE * 6 * sizeof(uint32_t), M_CXGBE, M_ZERO | M_WAITOK); t4_cim_read_pif_la(sc, buf, buf + 6 * CIM_PIFLA_SIZE, NULL, NULL); p = buf; sbuf_printf(sb, "Cntl ID DataBE Addr Data"); for (i = 0; i < CIM_PIFLA_SIZE; i++, p += 6) { sbuf_printf(sb, "\n %02x %02x %04x %08x %08x%08x%08x%08x", (p[5] >> 22) & 0xff, (p[5] >> 16) & 0x3f, p[5] & 0xffff, p[4], p[3], p[2], p[1], p[0]); } sbuf_printf(sb, "\n\nCntl ID Data"); for (i = 0; i < CIM_PIFLA_SIZE; i++, p += 6) { sbuf_printf(sb, "\n %02x %02x %08x%08x%08x%08x", (p[4] >> 6) & 0xff, p[4] & 0x3f, p[3], p[2], p[1], p[0]); } rc = sbuf_finish(sb); sbuf_delete(sb); free(buf, M_CXGBE); return (rc); } static int sysctl_cim_qcfg(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; struct sbuf *sb; int rc, i; uint16_t base[CIM_NUM_IBQ + CIM_NUM_OBQ_T5]; uint16_t size[CIM_NUM_IBQ + CIM_NUM_OBQ_T5]; uint16_t thres[CIM_NUM_IBQ]; uint32_t obq_wr[2 * CIM_NUM_OBQ_T5], *wr = obq_wr; uint32_t stat[4 * (CIM_NUM_IBQ + CIM_NUM_OBQ_T5)], *p = stat; u_int cim_num_obq, ibq_rdaddr, obq_rdaddr, nq; cim_num_obq = sc->chip_params->cim_num_obq; if (is_t4(sc)) { ibq_rdaddr = A_UP_IBQ_0_RDADDR; obq_rdaddr = A_UP_OBQ_0_REALADDR; } else { ibq_rdaddr = A_UP_IBQ_0_SHADOW_RDADDR; obq_rdaddr = A_UP_OBQ_0_SHADOW_REALADDR; } nq = CIM_NUM_IBQ + cim_num_obq; rc = -t4_cim_read(sc, ibq_rdaddr, 4 * nq, stat); if (rc == 0) rc = -t4_cim_read(sc, obq_rdaddr, 2 * cim_num_obq, obq_wr); if (rc != 0) return (rc); t4_read_cimq_cfg(sc, base, size, thres); rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) return (rc); sb = sbuf_new_for_sysctl(NULL, NULL, PAGE_SIZE, req); if (sb == NULL) return (ENOMEM); sbuf_printf(sb, " Queue Base Size Thres RdPtr WrPtr SOP EOP Avail"); for (i = 0; i < CIM_NUM_IBQ; i++, p += 4) sbuf_printf(sb, "\n%7s %5x %5u %5u %6x %4x %4u %4u %5u", qname[i], base[i], size[i], thres[i], G_IBQRDADDR(p[0]), G_IBQWRADDR(p[1]), G_QUESOPCNT(p[3]), G_QUEEOPCNT(p[3]), G_QUEREMFLITS(p[2]) * 16); for ( ; i < nq; i++, p += 4, wr += 2) sbuf_printf(sb, "\n%7s %5x %5u %12x %4x %4u %4u %5u", qname[i], base[i], size[i], G_QUERDADDR(p[0]) & 0x3fff, wr[0] - base[i], G_QUESOPCNT(p[3]), G_QUEEOPCNT(p[3]), G_QUEREMFLITS(p[2]) * 16); rc = sbuf_finish(sb); sbuf_delete(sb); return (rc); } static int sysctl_cpl_stats(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; struct sbuf *sb; int rc; struct tp_cpl_stats stats; rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) return (rc); sb = sbuf_new_for_sysctl(NULL, NULL, 256, req); if (sb == NULL) return (ENOMEM); mtx_lock(&sc->reg_lock); t4_tp_get_cpl_stats(sc, &stats); mtx_unlock(&sc->reg_lock); if (sc->chip_params->nchan > 2) { sbuf_printf(sb, " channel 0 channel 1" " channel 2 channel 3"); sbuf_printf(sb, "\nCPL requests: %10u %10u %10u %10u", stats.req[0], stats.req[1], stats.req[2], stats.req[3]); sbuf_printf(sb, "\nCPL responses: %10u %10u %10u %10u", stats.rsp[0], stats.rsp[1], stats.rsp[2], stats.rsp[3]); } else { sbuf_printf(sb, " channel 0 channel 1"); sbuf_printf(sb, "\nCPL requests: %10u %10u", stats.req[0], stats.req[1]); sbuf_printf(sb, "\nCPL responses: %10u %10u", stats.rsp[0], stats.rsp[1]); } rc = sbuf_finish(sb); sbuf_delete(sb); return (rc); } static int sysctl_ddp_stats(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; struct sbuf *sb; int rc; struct tp_usm_stats stats; rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) return(rc); sb = sbuf_new_for_sysctl(NULL, NULL, 256, req); if (sb == NULL) return (ENOMEM); t4_get_usm_stats(sc, &stats); sbuf_printf(sb, "Frames: %u\n", stats.frames); sbuf_printf(sb, "Octets: %ju\n", stats.octets); sbuf_printf(sb, "Drops: %u", stats.drops); rc = sbuf_finish(sb); sbuf_delete(sb); return (rc); } static const char * const devlog_level_strings[] = { [FW_DEVLOG_LEVEL_EMERG] = "EMERG", [FW_DEVLOG_LEVEL_CRIT] = "CRIT", [FW_DEVLOG_LEVEL_ERR] = "ERR", [FW_DEVLOG_LEVEL_NOTICE] = "NOTICE", [FW_DEVLOG_LEVEL_INFO] = "INFO", [FW_DEVLOG_LEVEL_DEBUG] = "DEBUG" }; static const char * const devlog_facility_strings[] = { [FW_DEVLOG_FACILITY_CORE] = "CORE", [FW_DEVLOG_FACILITY_CF] = "CF", [FW_DEVLOG_FACILITY_SCHED] = "SCHED", [FW_DEVLOG_FACILITY_TIMER] = "TIMER", [FW_DEVLOG_FACILITY_RES] = "RES", [FW_DEVLOG_FACILITY_HW] = "HW", [FW_DEVLOG_FACILITY_FLR] = "FLR", [FW_DEVLOG_FACILITY_DMAQ] = "DMAQ", [FW_DEVLOG_FACILITY_PHY] = "PHY", [FW_DEVLOG_FACILITY_MAC] = "MAC", [FW_DEVLOG_FACILITY_PORT] = "PORT", [FW_DEVLOG_FACILITY_VI] = "VI", [FW_DEVLOG_FACILITY_FILTER] = "FILTER", [FW_DEVLOG_FACILITY_ACL] = "ACL", [FW_DEVLOG_FACILITY_TM] = "TM", [FW_DEVLOG_FACILITY_QFC] = "QFC", [FW_DEVLOG_FACILITY_DCB] = "DCB", [FW_DEVLOG_FACILITY_ETH] = "ETH", [FW_DEVLOG_FACILITY_OFLD] = "OFLD", [FW_DEVLOG_FACILITY_RI] = "RI", [FW_DEVLOG_FACILITY_ISCSI] = "ISCSI", [FW_DEVLOG_FACILITY_FCOE] = "FCOE", [FW_DEVLOG_FACILITY_FOISCSI] = "FOISCSI", [FW_DEVLOG_FACILITY_FOFCOE] = "FOFCOE", [FW_DEVLOG_FACILITY_CHNET] = "CHNET", }; static int sysctl_devlog(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; struct devlog_params *dparams = &sc->params.devlog; struct fw_devlog_e *buf, *e; int i, j, rc, nentries, first = 0; struct sbuf *sb; uint64_t ftstamp = UINT64_MAX; if (dparams->addr == 0) return (ENXIO); buf = malloc(dparams->size, M_CXGBE, M_NOWAIT); if (buf == NULL) return (ENOMEM); rc = read_via_memwin(sc, 1, dparams->addr, (void *)buf, dparams->size); if (rc != 0) goto done; nentries = dparams->size / sizeof(struct fw_devlog_e); for (i = 0; i < nentries; i++) { e = &buf[i]; if (e->timestamp == 0) break; /* end */ e->timestamp = be64toh(e->timestamp); e->seqno = be32toh(e->seqno); for (j = 0; j < 8; j++) e->params[j] = be32toh(e->params[j]); if (e->timestamp < ftstamp) { ftstamp = e->timestamp; first = i; } } if (buf[first].timestamp == 0) goto done; /* nothing in the log */ rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) goto done; sb = sbuf_new_for_sysctl(NULL, NULL, 4096, req); if (sb == NULL) { rc = ENOMEM; goto done; } sbuf_printf(sb, "%10s %15s %8s %8s %s\n", "Seq#", "Tstamp", "Level", "Facility", "Message"); i = first; do { e = &buf[i]; if (e->timestamp == 0) break; /* end */ sbuf_printf(sb, "%10d %15ju %8s %8s ", e->seqno, e->timestamp, (e->level < nitems(devlog_level_strings) ? devlog_level_strings[e->level] : "UNKNOWN"), (e->facility < nitems(devlog_facility_strings) ? devlog_facility_strings[e->facility] : "UNKNOWN")); sbuf_printf(sb, e->fmt, e->params[0], e->params[1], e->params[2], e->params[3], e->params[4], e->params[5], e->params[6], e->params[7]); if (++i == nentries) i = 0; } while (i != first); rc = sbuf_finish(sb); sbuf_delete(sb); done: free(buf, M_CXGBE); return (rc); } static int sysctl_fcoe_stats(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; struct sbuf *sb; int rc; struct tp_fcoe_stats stats[MAX_NCHAN]; int i, nchan = sc->chip_params->nchan; rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) return (rc); sb = sbuf_new_for_sysctl(NULL, NULL, 256, req); if (sb == NULL) return (ENOMEM); for (i = 0; i < nchan; i++) t4_get_fcoe_stats(sc, i, &stats[i]); if (nchan > 2) { sbuf_printf(sb, " channel 0 channel 1" " channel 2 channel 3"); sbuf_printf(sb, "\noctetsDDP: %16ju %16ju %16ju %16ju", stats[0].octets_ddp, stats[1].octets_ddp, stats[2].octets_ddp, stats[3].octets_ddp); sbuf_printf(sb, "\nframesDDP: %16u %16u %16u %16u", stats[0].frames_ddp, stats[1].frames_ddp, stats[2].frames_ddp, stats[3].frames_ddp); sbuf_printf(sb, "\nframesDrop: %16u %16u %16u %16u", stats[0].frames_drop, stats[1].frames_drop, stats[2].frames_drop, stats[3].frames_drop); } else { sbuf_printf(sb, " channel 0 channel 1"); sbuf_printf(sb, "\noctetsDDP: %16ju %16ju", stats[0].octets_ddp, stats[1].octets_ddp); sbuf_printf(sb, "\nframesDDP: %16u %16u", stats[0].frames_ddp, stats[1].frames_ddp); sbuf_printf(sb, "\nframesDrop: %16u %16u", stats[0].frames_drop, stats[1].frames_drop); } rc = sbuf_finish(sb); sbuf_delete(sb); return (rc); } static int sysctl_hw_sched(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; struct sbuf *sb; int rc, i; unsigned int map, kbps, ipg, mode; unsigned int pace_tab[NTX_SCHED]; rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) return (rc); sb = sbuf_new_for_sysctl(NULL, NULL, 256, req); if (sb == NULL) return (ENOMEM); map = t4_read_reg(sc, A_TP_TX_MOD_QUEUE_REQ_MAP); mode = G_TIMERMODE(t4_read_reg(sc, A_TP_MOD_CONFIG)); t4_read_pace_tbl(sc, pace_tab); sbuf_printf(sb, "Scheduler Mode Channel Rate (Kbps) " "Class IPG (0.1 ns) Flow IPG (us)"); for (i = 0; i < NTX_SCHED; ++i, map >>= 2) { t4_get_tx_sched(sc, i, &kbps, &ipg); sbuf_printf(sb, "\n %u %-5s %u ", i, (mode & (1 << i)) ? "flow" : "class", map & 3); if (kbps) sbuf_printf(sb, "%9u ", kbps); else sbuf_printf(sb, " disabled "); if (ipg) sbuf_printf(sb, "%13u ", ipg); else sbuf_printf(sb, " disabled "); if (pace_tab[i]) sbuf_printf(sb, "%10u", pace_tab[i]); else sbuf_printf(sb, " disabled"); } rc = sbuf_finish(sb); sbuf_delete(sb); return (rc); } static int sysctl_lb_stats(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; struct sbuf *sb; int rc, i, j; uint64_t *p0, *p1; struct lb_port_stats s[2]; static const char *stat_name[] = { "OctetsOK:", "FramesOK:", "BcastFrames:", "McastFrames:", "UcastFrames:", "ErrorFrames:", "Frames64:", "Frames65To127:", "Frames128To255:", "Frames256To511:", "Frames512To1023:", "Frames1024To1518:", "Frames1519ToMax:", "FramesDropped:", "BG0FramesDropped:", "BG1FramesDropped:", "BG2FramesDropped:", "BG3FramesDropped:", "BG0FramesTrunc:", "BG1FramesTrunc:", "BG2FramesTrunc:", "BG3FramesTrunc:" }; rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) return (rc); sb = sbuf_new_for_sysctl(NULL, NULL, 4096, req); if (sb == NULL) return (ENOMEM); memset(s, 0, sizeof(s)); for (i = 0; i < sc->chip_params->nchan; i += 2) { t4_get_lb_stats(sc, i, &s[0]); t4_get_lb_stats(sc, i + 1, &s[1]); p0 = &s[0].octets; p1 = &s[1].octets; sbuf_printf(sb, "%s Loopback %u" " Loopback %u", i == 0 ? "" : "\n", i, i + 1); for (j = 0; j < nitems(stat_name); j++) sbuf_printf(sb, "\n%-17s %20ju %20ju", stat_name[j], *p0++, *p1++); } rc = sbuf_finish(sb); sbuf_delete(sb); return (rc); } static int sysctl_linkdnrc(SYSCTL_HANDLER_ARGS) { int rc = 0; struct port_info *pi = arg1; struct link_config *lc = &pi->link_cfg; struct sbuf *sb; rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) return(rc); sb = sbuf_new_for_sysctl(NULL, NULL, 64, req); if (sb == NULL) return (ENOMEM); if (lc->link_ok || lc->link_down_rc == 255) sbuf_printf(sb, "n/a"); else sbuf_printf(sb, "%s", t4_link_down_rc_str(lc->link_down_rc)); rc = sbuf_finish(sb); sbuf_delete(sb); return (rc); } struct mem_desc { unsigned int base; unsigned int limit; unsigned int idx; }; static int mem_desc_cmp(const void *a, const void *b) { return ((const struct mem_desc *)a)->base - ((const struct mem_desc *)b)->base; } static void mem_region_show(struct sbuf *sb, const char *name, unsigned int from, unsigned int to) { unsigned int size; if (from == to) return; size = to - from + 1; if (size == 0) return; /* XXX: need humanize_number(3) in libkern for a more readable 'size' */ sbuf_printf(sb, "%-15s %#x-%#x [%u]\n", name, from, to, size); } static int sysctl_meminfo(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; struct sbuf *sb; int rc, i, n; uint32_t lo, hi, used, alloc; static const char *memory[] = {"EDC0:", "EDC1:", "MC:", "MC0:", "MC1:"}; static const char *region[] = { "DBQ contexts:", "IMSG contexts:", "FLM cache:", "TCBs:", "Pstructs:", "Timers:", "Rx FL:", "Tx FL:", "Pstruct FL:", "Tx payload:", "Rx payload:", "LE hash:", "iSCSI region:", "TDDP region:", "TPT region:", "STAG region:", "RQ region:", "RQUDP region:", "PBL region:", "TXPBL region:", "DBVFIFO region:", "ULPRX state:", "ULPTX state:", "On-chip queues:" }; struct mem_desc avail[4]; struct mem_desc mem[nitems(region) + 3]; /* up to 3 holes */ struct mem_desc *md = mem; rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) return (rc); sb = sbuf_new_for_sysctl(NULL, NULL, 4096, req); if (sb == NULL) return (ENOMEM); for (i = 0; i < nitems(mem); i++) { mem[i].limit = 0; mem[i].idx = i; } /* Find and sort the populated memory ranges */ i = 0; lo = t4_read_reg(sc, A_MA_TARGET_MEM_ENABLE); if (lo & F_EDRAM0_ENABLE) { hi = t4_read_reg(sc, A_MA_EDRAM0_BAR); avail[i].base = G_EDRAM0_BASE(hi) << 20; avail[i].limit = avail[i].base + (G_EDRAM0_SIZE(hi) << 20); avail[i].idx = 0; i++; } if (lo & F_EDRAM1_ENABLE) { hi = t4_read_reg(sc, A_MA_EDRAM1_BAR); avail[i].base = G_EDRAM1_BASE(hi) << 20; avail[i].limit = avail[i].base + (G_EDRAM1_SIZE(hi) << 20); avail[i].idx = 1; i++; } if (lo & F_EXT_MEM_ENABLE) { hi = t4_read_reg(sc, A_MA_EXT_MEMORY_BAR); avail[i].base = G_EXT_MEM_BASE(hi) << 20; avail[i].limit = avail[i].base + (G_EXT_MEM_SIZE(hi) << 20); avail[i].idx = is_t5(sc) ? 3 : 2; /* Call it MC0 for T5 */ i++; } if (is_t5(sc) && lo & F_EXT_MEM1_ENABLE) { hi = t4_read_reg(sc, A_MA_EXT_MEMORY1_BAR); avail[i].base = G_EXT_MEM1_BASE(hi) << 20; avail[i].limit = avail[i].base + (G_EXT_MEM1_SIZE(hi) << 20); avail[i].idx = 4; i++; } if (!i) /* no memory available */ return 0; qsort(avail, i, sizeof(struct mem_desc), mem_desc_cmp); (md++)->base = t4_read_reg(sc, A_SGE_DBQ_CTXT_BADDR); (md++)->base = t4_read_reg(sc, A_SGE_IMSG_CTXT_BADDR); (md++)->base = t4_read_reg(sc, A_SGE_FLM_CACHE_BADDR); (md++)->base = t4_read_reg(sc, A_TP_CMM_TCB_BASE); (md++)->base = t4_read_reg(sc, A_TP_CMM_MM_BASE); (md++)->base = t4_read_reg(sc, A_TP_CMM_TIMER_BASE); (md++)->base = t4_read_reg(sc, A_TP_CMM_MM_RX_FLST_BASE); (md++)->base = t4_read_reg(sc, A_TP_CMM_MM_TX_FLST_BASE); (md++)->base = t4_read_reg(sc, A_TP_CMM_MM_PS_FLST_BASE); /* the next few have explicit upper bounds */ md->base = t4_read_reg(sc, A_TP_PMM_TX_BASE); md->limit = md->base - 1 + t4_read_reg(sc, A_TP_PMM_TX_PAGE_SIZE) * G_PMTXMAXPAGE(t4_read_reg(sc, A_TP_PMM_TX_MAX_PAGE)); md++; md->base = t4_read_reg(sc, A_TP_PMM_RX_BASE); md->limit = md->base - 1 + t4_read_reg(sc, A_TP_PMM_RX_PAGE_SIZE) * G_PMRXMAXPAGE(t4_read_reg(sc, A_TP_PMM_RX_MAX_PAGE)); md++; if (t4_read_reg(sc, A_LE_DB_CONFIG) & F_HASHEN) { if (chip_id(sc) <= CHELSIO_T5) md->base = t4_read_reg(sc, A_LE_DB_HASH_TID_BASE); else md->base = t4_read_reg(sc, A_LE_DB_HASH_TBL_BASE_ADDR); md->limit = 0; } else { md->base = 0; md->idx = nitems(region); /* hide it */ } md++; #define ulp_region(reg) \ md->base = t4_read_reg(sc, A_ULP_ ## reg ## _LLIMIT);\ (md++)->limit = t4_read_reg(sc, A_ULP_ ## reg ## _ULIMIT) ulp_region(RX_ISCSI); ulp_region(RX_TDDP); ulp_region(TX_TPT); ulp_region(RX_STAG); ulp_region(RX_RQ); ulp_region(RX_RQUDP); ulp_region(RX_PBL); ulp_region(TX_PBL); #undef ulp_region md->base = 0; md->idx = nitems(region); if (!is_t4(sc)) { uint32_t size = 0; uint32_t sge_ctrl = t4_read_reg(sc, A_SGE_CONTROL2); uint32_t fifo_size = t4_read_reg(sc, A_SGE_DBVFIFO_SIZE); if (is_t5(sc)) { if (sge_ctrl & F_VFIFO_ENABLE) size = G_DBVFIFO_SIZE(fifo_size); } else size = G_T6_DBVFIFO_SIZE(fifo_size); if (size) { md->base = G_BASEADDR(t4_read_reg(sc, A_SGE_DBVFIFO_BADDR)); md->limit = md->base + (size << 2) - 1; } } md++; md->base = t4_read_reg(sc, A_ULP_RX_CTX_BASE); md->limit = 0; md++; md->base = t4_read_reg(sc, A_ULP_TX_ERR_TABLE_BASE); md->limit = 0; md++; md->base = sc->vres.ocq.start; if (sc->vres.ocq.size) md->limit = md->base + sc->vres.ocq.size - 1; else md->idx = nitems(region); /* hide it */ md++; /* add any address-space holes, there can be up to 3 */ for (n = 0; n < i - 1; n++) if (avail[n].limit < avail[n + 1].base) (md++)->base = avail[n].limit; if (avail[n].limit) (md++)->base = avail[n].limit; n = md - mem; qsort(mem, n, sizeof(struct mem_desc), mem_desc_cmp); for (lo = 0; lo < i; lo++) mem_region_show(sb, memory[avail[lo].idx], avail[lo].base, avail[lo].limit - 1); sbuf_printf(sb, "\n"); for (i = 0; i < n; i++) { if (mem[i].idx >= nitems(region)) continue; /* skip holes */ if (!mem[i].limit) mem[i].limit = i < n - 1 ? mem[i + 1].base - 1 : ~0; mem_region_show(sb, region[mem[i].idx], mem[i].base, mem[i].limit); } sbuf_printf(sb, "\n"); lo = t4_read_reg(sc, A_CIM_SDRAM_BASE_ADDR); hi = t4_read_reg(sc, A_CIM_SDRAM_ADDR_SIZE) + lo - 1; mem_region_show(sb, "uP RAM:", lo, hi); lo = t4_read_reg(sc, A_CIM_EXTMEM2_BASE_ADDR); hi = t4_read_reg(sc, A_CIM_EXTMEM2_ADDR_SIZE) + lo - 1; mem_region_show(sb, "uP Extmem2:", lo, hi); lo = t4_read_reg(sc, A_TP_PMM_RX_MAX_PAGE); sbuf_printf(sb, "\n%u Rx pages of size %uKiB for %u channels\n", G_PMRXMAXPAGE(lo), t4_read_reg(sc, A_TP_PMM_RX_PAGE_SIZE) >> 10, (lo & F_PMRXNUMCHN) ? 2 : 1); lo = t4_read_reg(sc, A_TP_PMM_TX_MAX_PAGE); hi = t4_read_reg(sc, A_TP_PMM_TX_PAGE_SIZE); sbuf_printf(sb, "%u Tx pages of size %u%ciB for %u channels\n", G_PMTXMAXPAGE(lo), hi >= (1 << 20) ? (hi >> 20) : (hi >> 10), hi >= (1 << 20) ? 'M' : 'K', 1 << G_PMTXNUMCHN(lo)); sbuf_printf(sb, "%u p-structs\n", t4_read_reg(sc, A_TP_CMM_MM_MAX_PSTRUCT)); for (i = 0; i < 4; i++) { if (chip_id(sc) > CHELSIO_T5) lo = t4_read_reg(sc, A_MPS_RX_MAC_BG_PG_CNT0 + i * 4); else lo = t4_read_reg(sc, A_MPS_RX_PG_RSV0 + i * 4); if (is_t5(sc)) { used = G_T5_USED(lo); alloc = G_T5_ALLOC(lo); } else { used = G_USED(lo); alloc = G_ALLOC(lo); } /* For T6 these are MAC buffer groups */ sbuf_printf(sb, "\nPort %d using %u pages out of %u allocated", i, used, alloc); } for (i = 0; i < sc->chip_params->nchan; i++) { if (chip_id(sc) > CHELSIO_T5) lo = t4_read_reg(sc, A_MPS_RX_LPBK_BG_PG_CNT0 + i * 4); else lo = t4_read_reg(sc, A_MPS_RX_PG_RSV4 + i * 4); if (is_t5(sc)) { used = G_T5_USED(lo); alloc = G_T5_ALLOC(lo); } else { used = G_USED(lo); alloc = G_ALLOC(lo); } /* For T6 these are MAC buffer groups */ sbuf_printf(sb, "\nLoopback %d using %u pages out of %u allocated", i, used, alloc); } rc = sbuf_finish(sb); sbuf_delete(sb); return (rc); } static inline void tcamxy2valmask(uint64_t x, uint64_t y, uint8_t *addr, uint64_t *mask) { *mask = x | y; y = htobe64(y); memcpy(addr, (char *)&y + 2, ETHER_ADDR_LEN); } static int sysctl_mps_tcam(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; struct sbuf *sb; int rc, i; MPASS(chip_id(sc) <= CHELSIO_T5); rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) return (rc); sb = sbuf_new_for_sysctl(NULL, NULL, 4096, req); if (sb == NULL) return (ENOMEM); sbuf_printf(sb, "Idx Ethernet address Mask Vld Ports PF" " VF Replication P0 P1 P2 P3 ML"); for (i = 0; i < sc->chip_params->mps_tcam_size; i++) { uint64_t tcamx, tcamy, mask; uint32_t cls_lo, cls_hi; uint8_t addr[ETHER_ADDR_LEN]; tcamy = t4_read_reg64(sc, MPS_CLS_TCAM_Y_L(i)); tcamx = t4_read_reg64(sc, MPS_CLS_TCAM_X_L(i)); if (tcamx & tcamy) continue; tcamxy2valmask(tcamx, tcamy, addr, &mask); cls_lo = t4_read_reg(sc, MPS_CLS_SRAM_L(i)); cls_hi = t4_read_reg(sc, MPS_CLS_SRAM_H(i)); sbuf_printf(sb, "\n%3u %02x:%02x:%02x:%02x:%02x:%02x %012jx" " %c %#x%4u%4d", i, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], (uintmax_t)mask, (cls_lo & F_SRAM_VLD) ? 'Y' : 'N', G_PORTMAP(cls_hi), G_PF(cls_lo), (cls_lo & F_VF_VALID) ? G_VF(cls_lo) : -1); if (cls_lo & F_REPLICATE) { struct fw_ldst_cmd ldst_cmd; memset(&ldst_cmd, 0, sizeof(ldst_cmd)); ldst_cmd.op_to_addrspace = htobe32(V_FW_CMD_OP(FW_LDST_CMD) | F_FW_CMD_REQUEST | F_FW_CMD_READ | V_FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_MPS)); ldst_cmd.cycles_to_len16 = htobe32(FW_LEN16(ldst_cmd)); ldst_cmd.u.mps.rplc.fid_idx = htobe16(V_FW_LDST_CMD_FID(FW_LDST_MPS_RPLC) | V_FW_LDST_CMD_IDX(i)); rc = begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t4mps"); if (rc) break; rc = -t4_wr_mbox(sc, sc->mbox, &ldst_cmd, sizeof(ldst_cmd), &ldst_cmd); end_synchronized_op(sc, 0); if (rc != 0) { sbuf_printf(sb, "%36d", rc); rc = 0; } else { sbuf_printf(sb, " %08x %08x %08x %08x", be32toh(ldst_cmd.u.mps.rplc.rplc127_96), be32toh(ldst_cmd.u.mps.rplc.rplc95_64), be32toh(ldst_cmd.u.mps.rplc.rplc63_32), be32toh(ldst_cmd.u.mps.rplc.rplc31_0)); } } else sbuf_printf(sb, "%36s", ""); sbuf_printf(sb, "%4u%3u%3u%3u %#3x", G_SRAM_PRIO0(cls_lo), G_SRAM_PRIO1(cls_lo), G_SRAM_PRIO2(cls_lo), G_SRAM_PRIO3(cls_lo), (cls_lo >> S_MULTILISTEN0) & 0xf); } if (rc) (void) sbuf_finish(sb); else rc = sbuf_finish(sb); sbuf_delete(sb); return (rc); } static int sysctl_mps_tcam_t6(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; struct sbuf *sb; int rc, i; MPASS(chip_id(sc) > CHELSIO_T5); rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) return (rc); sb = sbuf_new_for_sysctl(NULL, NULL, 4096, req); if (sb == NULL) return (ENOMEM); sbuf_printf(sb, "Idx Ethernet address Mask VNI Mask" " IVLAN Vld DIP_Hit Lookup Port Vld Ports PF VF" " Replication" " P0 P1 P2 P3 ML\n"); for (i = 0; i < sc->chip_params->mps_tcam_size; i++) { uint8_t dip_hit, vlan_vld, lookup_type, port_num; uint16_t ivlan; uint64_t tcamx, tcamy, val, mask; uint32_t cls_lo, cls_hi, ctl, data2, vnix, vniy; uint8_t addr[ETHER_ADDR_LEN]; ctl = V_CTLREQID(1) | V_CTLCMDTYPE(0) | V_CTLXYBITSEL(0); if (i < 256) ctl |= V_CTLTCAMINDEX(i) | V_CTLTCAMSEL(0); else ctl |= V_CTLTCAMINDEX(i - 256) | V_CTLTCAMSEL(1); t4_write_reg(sc, A_MPS_CLS_TCAM_DATA2_CTL, ctl); val = t4_read_reg(sc, A_MPS_CLS_TCAM_RDATA1_REQ_ID1); tcamy = G_DMACH(val) << 32; tcamy |= t4_read_reg(sc, A_MPS_CLS_TCAM_RDATA0_REQ_ID1); data2 = t4_read_reg(sc, A_MPS_CLS_TCAM_RDATA2_REQ_ID1); lookup_type = G_DATALKPTYPE(data2); port_num = G_DATAPORTNUM(data2); if (lookup_type && lookup_type != M_DATALKPTYPE) { /* Inner header VNI */ vniy = ((data2 & F_DATAVIDH2) << 23) | (G_DATAVIDH1(data2) << 16) | G_VIDL(val); dip_hit = data2 & F_DATADIPHIT; vlan_vld = 0; } else { vniy = 0; dip_hit = 0; vlan_vld = data2 & F_DATAVIDH2; ivlan = G_VIDL(val); } ctl |= V_CTLXYBITSEL(1); t4_write_reg(sc, A_MPS_CLS_TCAM_DATA2_CTL, ctl); val = t4_read_reg(sc, A_MPS_CLS_TCAM_RDATA1_REQ_ID1); tcamx = G_DMACH(val) << 32; tcamx |= t4_read_reg(sc, A_MPS_CLS_TCAM_RDATA0_REQ_ID1); data2 = t4_read_reg(sc, A_MPS_CLS_TCAM_RDATA2_REQ_ID1); if (lookup_type && lookup_type != M_DATALKPTYPE) { /* Inner header VNI mask */ vnix = ((data2 & F_DATAVIDH2) << 23) | (G_DATAVIDH1(data2) << 16) | G_VIDL(val); } else vnix = 0; if (tcamx & tcamy) continue; tcamxy2valmask(tcamx, tcamy, addr, &mask); cls_lo = t4_read_reg(sc, MPS_CLS_SRAM_L(i)); cls_hi = t4_read_reg(sc, MPS_CLS_SRAM_H(i)); if (lookup_type && lookup_type != M_DATALKPTYPE) { sbuf_printf(sb, "\n%3u %02x:%02x:%02x:%02x:%02x:%02x " "%012jx %06x %06x - - %3c" " 'I' %4x %3c %#x%4u%4d", i, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], (uintmax_t)mask, vniy, vnix, dip_hit ? 'Y' : 'N', port_num, cls_lo & F_T6_SRAM_VLD ? 'Y' : 'N', G_PORTMAP(cls_hi), G_T6_PF(cls_lo), cls_lo & F_T6_VF_VALID ? G_T6_VF(cls_lo) : -1); } else { sbuf_printf(sb, "\n%3u %02x:%02x:%02x:%02x:%02x:%02x " "%012jx - - ", i, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], (uintmax_t)mask); if (vlan_vld) sbuf_printf(sb, "%4u Y ", ivlan); else sbuf_printf(sb, " - N "); sbuf_printf(sb, "- %3c %4x %3c %#x%4u%4d", lookup_type ? 'I' : 'O', port_num, cls_lo & F_T6_SRAM_VLD ? 'Y' : 'N', G_PORTMAP(cls_hi), G_T6_PF(cls_lo), cls_lo & F_T6_VF_VALID ? G_T6_VF(cls_lo) : -1); } if (cls_lo & F_T6_REPLICATE) { struct fw_ldst_cmd ldst_cmd; memset(&ldst_cmd, 0, sizeof(ldst_cmd)); ldst_cmd.op_to_addrspace = htobe32(V_FW_CMD_OP(FW_LDST_CMD) | F_FW_CMD_REQUEST | F_FW_CMD_READ | V_FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_MPS)); ldst_cmd.cycles_to_len16 = htobe32(FW_LEN16(ldst_cmd)); ldst_cmd.u.mps.rplc.fid_idx = htobe16(V_FW_LDST_CMD_FID(FW_LDST_MPS_RPLC) | V_FW_LDST_CMD_IDX(i)); rc = begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t6mps"); if (rc) break; rc = -t4_wr_mbox(sc, sc->mbox, &ldst_cmd, sizeof(ldst_cmd), &ldst_cmd); end_synchronized_op(sc, 0); if (rc != 0) { sbuf_printf(sb, "%72d", rc); rc = 0; } else { sbuf_printf(sb, " %08x %08x %08x %08x" " %08x %08x %08x %08x", be32toh(ldst_cmd.u.mps.rplc.rplc255_224), be32toh(ldst_cmd.u.mps.rplc.rplc223_192), be32toh(ldst_cmd.u.mps.rplc.rplc191_160), be32toh(ldst_cmd.u.mps.rplc.rplc159_128), be32toh(ldst_cmd.u.mps.rplc.rplc127_96), be32toh(ldst_cmd.u.mps.rplc.rplc95_64), be32toh(ldst_cmd.u.mps.rplc.rplc63_32), be32toh(ldst_cmd.u.mps.rplc.rplc31_0)); } } else sbuf_printf(sb, "%72s", ""); sbuf_printf(sb, "%4u%3u%3u%3u %#x", G_T6_SRAM_PRIO0(cls_lo), G_T6_SRAM_PRIO1(cls_lo), G_T6_SRAM_PRIO2(cls_lo), G_T6_SRAM_PRIO3(cls_lo), (cls_lo >> S_T6_MULTILISTEN0) & 0xf); } if (rc) (void) sbuf_finish(sb); else rc = sbuf_finish(sb); sbuf_delete(sb); return (rc); } static int sysctl_path_mtus(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; struct sbuf *sb; int rc; uint16_t mtus[NMTUS]; rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) return (rc); sb = sbuf_new_for_sysctl(NULL, NULL, 256, req); if (sb == NULL) return (ENOMEM); t4_read_mtu_tbl(sc, mtus, NULL); sbuf_printf(sb, "%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u", mtus[0], mtus[1], mtus[2], mtus[3], mtus[4], mtus[5], mtus[6], mtus[7], mtus[8], mtus[9], mtus[10], mtus[11], mtus[12], mtus[13], mtus[14], mtus[15]); rc = sbuf_finish(sb); sbuf_delete(sb); return (rc); } static int sysctl_pm_stats(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; struct sbuf *sb; int rc, i; uint32_t tx_cnt[MAX_PM_NSTATS], rx_cnt[MAX_PM_NSTATS]; uint64_t tx_cyc[MAX_PM_NSTATS], rx_cyc[MAX_PM_NSTATS]; static const char *tx_stats[MAX_PM_NSTATS] = { "Read:", "Write bypass:", "Write mem:", "Bypass + mem:", "Tx FIFO wait", NULL, "Tx latency" }; static const char *rx_stats[MAX_PM_NSTATS] = { "Read:", "Write bypass:", "Write mem:", "Flush:", "Rx FIFO wait", NULL, "Rx latency" }; rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) return (rc); sb = sbuf_new_for_sysctl(NULL, NULL, 256, req); if (sb == NULL) return (ENOMEM); t4_pmtx_get_stats(sc, tx_cnt, tx_cyc); t4_pmrx_get_stats(sc, rx_cnt, rx_cyc); sbuf_printf(sb, " Tx pcmds Tx bytes"); for (i = 0; i < 4; i++) { sbuf_printf(sb, "\n%-13s %10u %20ju", tx_stats[i], tx_cnt[i], tx_cyc[i]); } sbuf_printf(sb, "\n Rx pcmds Rx bytes"); for (i = 0; i < 4; i++) { sbuf_printf(sb, "\n%-13s %10u %20ju", rx_stats[i], rx_cnt[i], rx_cyc[i]); } if (chip_id(sc) > CHELSIO_T5) { sbuf_printf(sb, "\n Total wait Total occupancy"); sbuf_printf(sb, "\n%-13s %10u %20ju", tx_stats[i], tx_cnt[i], tx_cyc[i]); sbuf_printf(sb, "\n%-13s %10u %20ju", rx_stats[i], rx_cnt[i], rx_cyc[i]); i += 2; MPASS(i < nitems(tx_stats)); sbuf_printf(sb, "\n Reads Total wait"); sbuf_printf(sb, "\n%-13s %10u %20ju", tx_stats[i], tx_cnt[i], tx_cyc[i]); sbuf_printf(sb, "\n%-13s %10u %20ju", rx_stats[i], rx_cnt[i], rx_cyc[i]); } rc = sbuf_finish(sb); sbuf_delete(sb); return (rc); } static int sysctl_rdma_stats(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; struct sbuf *sb; int rc; struct tp_rdma_stats stats; rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) return (rc); sb = sbuf_new_for_sysctl(NULL, NULL, 256, req); if (sb == NULL) return (ENOMEM); mtx_lock(&sc->reg_lock); t4_tp_get_rdma_stats(sc, &stats); mtx_unlock(&sc->reg_lock); sbuf_printf(sb, "NoRQEModDefferals: %u\n", stats.rqe_dfr_mod); sbuf_printf(sb, "NoRQEPktDefferals: %u", stats.rqe_dfr_pkt); rc = sbuf_finish(sb); sbuf_delete(sb); return (rc); } static int sysctl_tcp_stats(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; struct sbuf *sb; int rc; struct tp_tcp_stats v4, v6; rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) return (rc); sb = sbuf_new_for_sysctl(NULL, NULL, 256, req); if (sb == NULL) return (ENOMEM); mtx_lock(&sc->reg_lock); t4_tp_get_tcp_stats(sc, &v4, &v6); mtx_unlock(&sc->reg_lock); sbuf_printf(sb, " IP IPv6\n"); sbuf_printf(sb, "OutRsts: %20u %20u\n", v4.tcp_out_rsts, v6.tcp_out_rsts); sbuf_printf(sb, "InSegs: %20ju %20ju\n", v4.tcp_in_segs, v6.tcp_in_segs); sbuf_printf(sb, "OutSegs: %20ju %20ju\n", v4.tcp_out_segs, v6.tcp_out_segs); sbuf_printf(sb, "RetransSegs: %20ju %20ju", v4.tcp_retrans_segs, v6.tcp_retrans_segs); rc = sbuf_finish(sb); sbuf_delete(sb); return (rc); } static int sysctl_tids(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; struct sbuf *sb; int rc; struct tid_info *t = &sc->tids; rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) return (rc); sb = sbuf_new_for_sysctl(NULL, NULL, 256, req); if (sb == NULL) return (ENOMEM); if (t->natids) { sbuf_printf(sb, "ATID range: 0-%u, in use: %u\n", t->natids - 1, t->atids_in_use); } if (t->ntids) { sbuf_printf(sb, "TID range: "); if (t4_read_reg(sc, A_LE_DB_CONFIG) & F_HASHEN) { uint32_t b, hb; if (chip_id(sc) <= CHELSIO_T5) { b = t4_read_reg(sc, A_LE_DB_SERVER_INDEX) / 4; hb = t4_read_reg(sc, A_LE_DB_TID_HASHBASE) / 4; } else { b = t4_read_reg(sc, A_LE_DB_SRVR_START_INDEX); hb = t4_read_reg(sc, A_T6_LE_DB_HASH_TID_BASE); } if (b) sbuf_printf(sb, "0-%u, ", b - 1); sbuf_printf(sb, "%u-%u", hb, t->ntids - 1); } else sbuf_printf(sb, "0-%u", t->ntids - 1); sbuf_printf(sb, ", in use: %u\n", atomic_load_acq_int(&t->tids_in_use)); } if (t->nstids) { sbuf_printf(sb, "STID range: %u-%u, in use: %u\n", t->stid_base, t->stid_base + t->nstids - 1, t->stids_in_use); } if (t->nftids) { sbuf_printf(sb, "FTID range: %u-%u\n", t->ftid_base, t->ftid_base + t->nftids - 1); } if (t->netids) { sbuf_printf(sb, "ETID range: %u-%u\n", t->etid_base, t->etid_base + t->netids - 1); } sbuf_printf(sb, "HW TID usage: %u IP users, %u IPv6 users", t4_read_reg(sc, A_LE_DB_ACT_CNT_IPV4), t4_read_reg(sc, A_LE_DB_ACT_CNT_IPV6)); rc = sbuf_finish(sb); sbuf_delete(sb); return (rc); } static int sysctl_tp_err_stats(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; struct sbuf *sb; int rc; struct tp_err_stats stats; rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) return (rc); sb = sbuf_new_for_sysctl(NULL, NULL, 256, req); if (sb == NULL) return (ENOMEM); mtx_lock(&sc->reg_lock); t4_tp_get_err_stats(sc, &stats); mtx_unlock(&sc->reg_lock); if (sc->chip_params->nchan > 2) { sbuf_printf(sb, " channel 0 channel 1" " channel 2 channel 3\n"); sbuf_printf(sb, "macInErrs: %10u %10u %10u %10u\n", stats.mac_in_errs[0], stats.mac_in_errs[1], stats.mac_in_errs[2], stats.mac_in_errs[3]); sbuf_printf(sb, "hdrInErrs: %10u %10u %10u %10u\n", stats.hdr_in_errs[0], stats.hdr_in_errs[1], stats.hdr_in_errs[2], stats.hdr_in_errs[3]); sbuf_printf(sb, "tcpInErrs: %10u %10u %10u %10u\n", stats.tcp_in_errs[0], stats.tcp_in_errs[1], stats.tcp_in_errs[2], stats.tcp_in_errs[3]); sbuf_printf(sb, "tcp6InErrs: %10u %10u %10u %10u\n", stats.tcp6_in_errs[0], stats.tcp6_in_errs[1], stats.tcp6_in_errs[2], stats.tcp6_in_errs[3]); sbuf_printf(sb, "tnlCongDrops: %10u %10u %10u %10u\n", stats.tnl_cong_drops[0], stats.tnl_cong_drops[1], stats.tnl_cong_drops[2], stats.tnl_cong_drops[3]); sbuf_printf(sb, "tnlTxDrops: %10u %10u %10u %10u\n", stats.tnl_tx_drops[0], stats.tnl_tx_drops[1], stats.tnl_tx_drops[2], stats.tnl_tx_drops[3]); sbuf_printf(sb, "ofldVlanDrops: %10u %10u %10u %10u\n", stats.ofld_vlan_drops[0], stats.ofld_vlan_drops[1], stats.ofld_vlan_drops[2], stats.ofld_vlan_drops[3]); sbuf_printf(sb, "ofldChanDrops: %10u %10u %10u %10u\n\n", stats.ofld_chan_drops[0], stats.ofld_chan_drops[1], stats.ofld_chan_drops[2], stats.ofld_chan_drops[3]); } else { sbuf_printf(sb, " channel 0 channel 1\n"); sbuf_printf(sb, "macInErrs: %10u %10u\n", stats.mac_in_errs[0], stats.mac_in_errs[1]); sbuf_printf(sb, "hdrInErrs: %10u %10u\n", stats.hdr_in_errs[0], stats.hdr_in_errs[1]); sbuf_printf(sb, "tcpInErrs: %10u %10u\n", stats.tcp_in_errs[0], stats.tcp_in_errs[1]); sbuf_printf(sb, "tcp6InErrs: %10u %10u\n", stats.tcp6_in_errs[0], stats.tcp6_in_errs[1]); sbuf_printf(sb, "tnlCongDrops: %10u %10u\n", stats.tnl_cong_drops[0], stats.tnl_cong_drops[1]); sbuf_printf(sb, "tnlTxDrops: %10u %10u\n", stats.tnl_tx_drops[0], stats.tnl_tx_drops[1]); sbuf_printf(sb, "ofldVlanDrops: %10u %10u\n", stats.ofld_vlan_drops[0], stats.ofld_vlan_drops[1]); sbuf_printf(sb, "ofldChanDrops: %10u %10u\n\n", stats.ofld_chan_drops[0], stats.ofld_chan_drops[1]); } sbuf_printf(sb, "ofldNoNeigh: %u\nofldCongDefer: %u", stats.ofld_no_neigh, stats.ofld_cong_defer); rc = sbuf_finish(sb); sbuf_delete(sb); return (rc); } static int sysctl_tp_la_mask(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; struct tp_params *tpp = &sc->params.tp; u_int mask; int rc; mask = tpp->la_mask >> 16; rc = sysctl_handle_int(oidp, &mask, 0, req); if (rc != 0 || req->newptr == NULL) return (rc); if (mask > 0xffff) return (EINVAL); tpp->la_mask = mask << 16; t4_set_reg_field(sc, A_TP_DBG_LA_CONFIG, 0xffff0000U, tpp->la_mask); return (0); } struct field_desc { const char *name; u_int start; u_int width; }; static void field_desc_show(struct sbuf *sb, uint64_t v, const struct field_desc *f) { char buf[32]; int line_size = 0; while (f->name) { uint64_t mask = (1ULL << f->width) - 1; int len = snprintf(buf, sizeof(buf), "%s: %ju", f->name, ((uintmax_t)v >> f->start) & mask); if (line_size + len >= 79) { line_size = 8; sbuf_printf(sb, "\n "); } sbuf_printf(sb, "%s ", buf); line_size += len + 1; f++; } sbuf_printf(sb, "\n"); } static const struct field_desc tp_la0[] = { { "RcfOpCodeOut", 60, 4 }, { "State", 56, 4 }, { "WcfState", 52, 4 }, { "RcfOpcSrcOut", 50, 2 }, { "CRxError", 49, 1 }, { "ERxError", 48, 1 }, { "SanityFailed", 47, 1 }, { "SpuriousMsg", 46, 1 }, { "FlushInputMsg", 45, 1 }, { "FlushInputCpl", 44, 1 }, { "RssUpBit", 43, 1 }, { "RssFilterHit", 42, 1 }, { "Tid", 32, 10 }, { "InitTcb", 31, 1 }, { "LineNumber", 24, 7 }, { "Emsg", 23, 1 }, { "EdataOut", 22, 1 }, { "Cmsg", 21, 1 }, { "CdataOut", 20, 1 }, { "EreadPdu", 19, 1 }, { "CreadPdu", 18, 1 }, { "TunnelPkt", 17, 1 }, { "RcfPeerFin", 16, 1 }, { "RcfReasonOut", 12, 4 }, { "TxCchannel", 10, 2 }, { "RcfTxChannel", 8, 2 }, { "RxEchannel", 6, 2 }, { "RcfRxChannel", 5, 1 }, { "RcfDataOutSrdy", 4, 1 }, { "RxDvld", 3, 1 }, { "RxOoDvld", 2, 1 }, { "RxCongestion", 1, 1 }, { "TxCongestion", 0, 1 }, { NULL } }; static const struct field_desc tp_la1[] = { { "CplCmdIn", 56, 8 }, { "CplCmdOut", 48, 8 }, { "ESynOut", 47, 1 }, { "EAckOut", 46, 1 }, { "EFinOut", 45, 1 }, { "ERstOut", 44, 1 }, { "SynIn", 43, 1 }, { "AckIn", 42, 1 }, { "FinIn", 41, 1 }, { "RstIn", 40, 1 }, { "DataIn", 39, 1 }, { "DataInVld", 38, 1 }, { "PadIn", 37, 1 }, { "RxBufEmpty", 36, 1 }, { "RxDdp", 35, 1 }, { "RxFbCongestion", 34, 1 }, { "TxFbCongestion", 33, 1 }, { "TxPktSumSrdy", 32, 1 }, { "RcfUlpType", 28, 4 }, { "Eread", 27, 1 }, { "Ebypass", 26, 1 }, { "Esave", 25, 1 }, { "Static0", 24, 1 }, { "Cread", 23, 1 }, { "Cbypass", 22, 1 }, { "Csave", 21, 1 }, { "CPktOut", 20, 1 }, { "RxPagePoolFull", 18, 2 }, { "RxLpbkPkt", 17, 1 }, { "TxLpbkPkt", 16, 1 }, { "RxVfValid", 15, 1 }, { "SynLearned", 14, 1 }, { "SetDelEntry", 13, 1 }, { "SetInvEntry", 12, 1 }, { "CpcmdDvld", 11, 1 }, { "CpcmdSave", 10, 1 }, { "RxPstructsFull", 8, 2 }, { "EpcmdDvld", 7, 1 }, { "EpcmdFlush", 6, 1 }, { "EpcmdTrimPrefix", 5, 1 }, { "EpcmdTrimPostfix", 4, 1 }, { "ERssIp4Pkt", 3, 1 }, { "ERssIp6Pkt", 2, 1 }, { "ERssTcpUdpPkt", 1, 1 }, { "ERssFceFipPkt", 0, 1 }, { NULL } }; static const struct field_desc tp_la2[] = { { "CplCmdIn", 56, 8 }, { "MpsVfVld", 55, 1 }, { "MpsPf", 52, 3 }, { "MpsVf", 44, 8 }, { "SynIn", 43, 1 }, { "AckIn", 42, 1 }, { "FinIn", 41, 1 }, { "RstIn", 40, 1 }, { "DataIn", 39, 1 }, { "DataInVld", 38, 1 }, { "PadIn", 37, 1 }, { "RxBufEmpty", 36, 1 }, { "RxDdp", 35, 1 }, { "RxFbCongestion", 34, 1 }, { "TxFbCongestion", 33, 1 }, { "TxPktSumSrdy", 32, 1 }, { "RcfUlpType", 28, 4 }, { "Eread", 27, 1 }, { "Ebypass", 26, 1 }, { "Esave", 25, 1 }, { "Static0", 24, 1 }, { "Cread", 23, 1 }, { "Cbypass", 22, 1 }, { "Csave", 21, 1 }, { "CPktOut", 20, 1 }, { "RxPagePoolFull", 18, 2 }, { "RxLpbkPkt", 17, 1 }, { "TxLpbkPkt", 16, 1 }, { "RxVfValid", 15, 1 }, { "SynLearned", 14, 1 }, { "SetDelEntry", 13, 1 }, { "SetInvEntry", 12, 1 }, { "CpcmdDvld", 11, 1 }, { "CpcmdSave", 10, 1 }, { "RxPstructsFull", 8, 2 }, { "EpcmdDvld", 7, 1 }, { "EpcmdFlush", 6, 1 }, { "EpcmdTrimPrefix", 5, 1 }, { "EpcmdTrimPostfix", 4, 1 }, { "ERssIp4Pkt", 3, 1 }, { "ERssIp6Pkt", 2, 1 }, { "ERssTcpUdpPkt", 1, 1 }, { "ERssFceFipPkt", 0, 1 }, { NULL } }; static void tp_la_show(struct sbuf *sb, uint64_t *p, int idx) { field_desc_show(sb, *p, tp_la0); } static void tp_la_show2(struct sbuf *sb, uint64_t *p, int idx) { if (idx) sbuf_printf(sb, "\n"); field_desc_show(sb, p[0], tp_la0); if (idx < (TPLA_SIZE / 2 - 1) || p[1] != ~0ULL) field_desc_show(sb, p[1], tp_la0); } static void tp_la_show3(struct sbuf *sb, uint64_t *p, int idx) { if (idx) sbuf_printf(sb, "\n"); field_desc_show(sb, p[0], tp_la0); if (idx < (TPLA_SIZE / 2 - 1) || p[1] != ~0ULL) field_desc_show(sb, p[1], (p[0] & (1 << 17)) ? tp_la2 : tp_la1); } static int sysctl_tp_la(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; struct sbuf *sb; uint64_t *buf, *p; int rc; u_int i, inc; void (*show_func)(struct sbuf *, uint64_t *, int); rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) return (rc); sb = sbuf_new_for_sysctl(NULL, NULL, 4096, req); if (sb == NULL) return (ENOMEM); buf = malloc(TPLA_SIZE * sizeof(uint64_t), M_CXGBE, M_ZERO | M_WAITOK); t4_tp_read_la(sc, buf, NULL); p = buf; switch (G_DBGLAMODE(t4_read_reg(sc, A_TP_DBG_LA_CONFIG))) { case 2: inc = 2; show_func = tp_la_show2; break; case 3: inc = 2; show_func = tp_la_show3; break; default: inc = 1; show_func = tp_la_show; } for (i = 0; i < TPLA_SIZE / inc; i++, p += inc) (*show_func)(sb, p, i); rc = sbuf_finish(sb); sbuf_delete(sb); free(buf, M_CXGBE); return (rc); } static int sysctl_tx_rate(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; struct sbuf *sb; int rc; u64 nrate[MAX_NCHAN], orate[MAX_NCHAN]; rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) return (rc); sb = sbuf_new_for_sysctl(NULL, NULL, 256, req); if (sb == NULL) return (ENOMEM); t4_get_chan_txrate(sc, nrate, orate); if (sc->chip_params->nchan > 2) { sbuf_printf(sb, " channel 0 channel 1" " channel 2 channel 3\n"); sbuf_printf(sb, "NIC B/s: %10ju %10ju %10ju %10ju\n", nrate[0], nrate[1], nrate[2], nrate[3]); sbuf_printf(sb, "Offload B/s: %10ju %10ju %10ju %10ju", orate[0], orate[1], orate[2], orate[3]); } else { sbuf_printf(sb, " channel 0 channel 1\n"); sbuf_printf(sb, "NIC B/s: %10ju %10ju\n", nrate[0], nrate[1]); sbuf_printf(sb, "Offload B/s: %10ju %10ju", orate[0], orate[1]); } rc = sbuf_finish(sb); sbuf_delete(sb); return (rc); } static int sysctl_ulprx_la(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; struct sbuf *sb; uint32_t *buf, *p; int rc, i; rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) return (rc); sb = sbuf_new_for_sysctl(NULL, NULL, 4096, req); if (sb == NULL) return (ENOMEM); buf = malloc(ULPRX_LA_SIZE * 8 * sizeof(uint32_t), M_CXGBE, M_ZERO | M_WAITOK); t4_ulprx_read_la(sc, buf); p = buf; sbuf_printf(sb, " Pcmd Type Message" " Data"); for (i = 0; i < ULPRX_LA_SIZE; i++, p += 8) { sbuf_printf(sb, "\n%08x%08x %4x %08x %08x%08x%08x%08x", p[1], p[0], p[2], p[3], p[7], p[6], p[5], p[4]); } rc = sbuf_finish(sb); sbuf_delete(sb); free(buf, M_CXGBE); return (rc); } static int sysctl_wcwr_stats(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; struct sbuf *sb; int rc, v; MPASS(chip_id(sc) >= CHELSIO_T5); rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) return (rc); sb = sbuf_new_for_sysctl(NULL, NULL, 4096, req); if (sb == NULL) return (ENOMEM); v = t4_read_reg(sc, A_SGE_STAT_CFG); if (G_STATSOURCE_T5(v) == 7) { int mode; mode = is_t5(sc) ? G_STATMODE(v) : G_T6_STATMODE(v); if (mode == 0) { sbuf_printf(sb, "total %d, incomplete %d", t4_read_reg(sc, A_SGE_STAT_TOTAL), t4_read_reg(sc, A_SGE_STAT_MATCH)); } else if (mode == 1) { sbuf_printf(sb, "total %d, data overflow %d", t4_read_reg(sc, A_SGE_STAT_TOTAL), t4_read_reg(sc, A_SGE_STAT_MATCH)); } else { sbuf_printf(sb, "unknown mode %d", mode); } } rc = sbuf_finish(sb); sbuf_delete(sb); return (rc); } static int sysctl_tc_params(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; struct tx_cl_rl_params tc; struct sbuf *sb; int i, rc, port_id, mbps, gbps; rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) return (rc); sb = sbuf_new_for_sysctl(NULL, NULL, 4096, req); if (sb == NULL) return (ENOMEM); port_id = arg2 >> 16; MPASS(port_id < sc->params.nports); MPASS(sc->port[port_id] != NULL); i = arg2 & 0xffff; MPASS(i < sc->chip_params->nsched_cls); mtx_lock(&sc->tc_lock); tc = sc->port[port_id]->sched_params->cl_rl[i]; mtx_unlock(&sc->tc_lock); if (tc.flags & TX_CLRL_ERROR) { sbuf_printf(sb, "error"); goto done; } if (tc.ratemode == SCHED_CLASS_RATEMODE_REL) { /* XXX: top speed or actual link speed? */ gbps = port_top_speed(sc->port[port_id]); sbuf_printf(sb, " %u%% of %uGbps", tc.maxrate, gbps); } else if (tc.ratemode == SCHED_CLASS_RATEMODE_ABS) { switch (tc.rateunit) { case SCHED_CLASS_RATEUNIT_BITS: mbps = tc.maxrate / 1000; gbps = tc.maxrate / 1000000; if (tc.maxrate == gbps * 1000000) sbuf_printf(sb, " %uGbps", gbps); else if (tc.maxrate == mbps * 1000) sbuf_printf(sb, " %uMbps", mbps); else sbuf_printf(sb, " %uKbps", tc.maxrate); break; case SCHED_CLASS_RATEUNIT_PKTS: sbuf_printf(sb, " %upps", tc.maxrate); break; default: rc = ENXIO; goto done; } } switch (tc.mode) { case SCHED_CLASS_MODE_CLASS: sbuf_printf(sb, " aggregate"); break; case SCHED_CLASS_MODE_FLOW: sbuf_printf(sb, " per-flow"); break; default: rc = ENXIO; goto done; } done: if (rc == 0) rc = sbuf_finish(sb); sbuf_delete(sb); return (rc); } #endif #ifdef TCP_OFFLOAD static void unit_conv(char *buf, size_t len, u_int val, u_int factor) { u_int rem = val % factor; if (rem == 0) snprintf(buf, len, "%u", val / factor); else { while (rem % 10 == 0) rem /= 10; snprintf(buf, len, "%u.%u", val / factor, rem); } } static int sysctl_tp_tick(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; char buf[16]; u_int res, re; u_int cclk_ps = 1000000000 / sc->params.vpd.cclk; res = t4_read_reg(sc, A_TP_TIMER_RESOLUTION); switch (arg2) { case 0: /* timer_tick */ re = G_TIMERRESOLUTION(res); break; case 1: /* TCP timestamp tick */ re = G_TIMESTAMPRESOLUTION(res); break; case 2: /* DACK tick */ re = G_DELAYEDACKRESOLUTION(res); break; default: return (EDOOFUS); } unit_conv(buf, sizeof(buf), (cclk_ps << re), 1000000); return (sysctl_handle_string(oidp, buf, sizeof(buf), req)); } static int sysctl_tp_dack_timer(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; u_int res, dack_re, v; u_int cclk_ps = 1000000000 / sc->params.vpd.cclk; res = t4_read_reg(sc, A_TP_TIMER_RESOLUTION); dack_re = G_DELAYEDACKRESOLUTION(res); v = ((cclk_ps << dack_re) / 1000000) * t4_read_reg(sc, A_TP_DACK_TIMER); return (sysctl_handle_int(oidp, &v, 0, req)); } static int sysctl_tp_timer(SYSCTL_HANDLER_ARGS) { struct adapter *sc = arg1; int reg = arg2; u_int tre; u_long tp_tick_us, v; u_int cclk_ps = 1000000000 / sc->params.vpd.cclk; MPASS(reg == A_TP_RXT_MIN || reg == A_TP_RXT_MAX || reg == A_TP_PERS_MIN || reg == A_TP_PERS_MAX || reg == A_TP_KEEP_IDLE || reg == A_TP_KEEP_INTVL || reg == A_TP_INIT_SRTT || reg == A_TP_FINWAIT2_TIMER); tre = G_TIMERRESOLUTION(t4_read_reg(sc, A_TP_TIMER_RESOLUTION)); tp_tick_us = (cclk_ps << tre) / 1000000; if (reg == A_TP_INIT_SRTT) v = tp_tick_us * G_INITSRTT(t4_read_reg(sc, reg)); else v = tp_tick_us * t4_read_reg(sc, reg); return (sysctl_handle_long(oidp, &v, 0, req)); +} + +/* + * All fields in TP_SHIFT_CNT are 4b and the starting location of the field is + * passed to this function. + */ +static int +sysctl_tp_shift_cnt(SYSCTL_HANDLER_ARGS) +{ + struct adapter *sc = arg1; + int idx = arg2; + u_int v; + + MPASS(idx >= 0 && idx <= 24); + + v = (t4_read_reg(sc, A_TP_SHIFT_CNT) >> idx) & 0xf; + + return (sysctl_handle_int(oidp, &v, 0, req)); +} + +static int +sysctl_tp_backoff(SYSCTL_HANDLER_ARGS) +{ + struct adapter *sc = arg1; + int idx = arg2; + u_int shift, v, r; + + MPASS(idx >= 0 && idx < 16); + + r = A_TP_TCP_BACKOFF_REG0 + (idx & ~3); + shift = (idx & 3) << 3; + v = (t4_read_reg(sc, r) >> shift) & M_TIMERBACKOFFINDEX0; + + return (sysctl_handle_int(oidp, &v, 0, req)); } #endif static uint32_t fconf_iconf_to_mode(uint32_t fconf, uint32_t iconf) { uint32_t mode; mode = T4_FILTER_IPv4 | T4_FILTER_IPv6 | T4_FILTER_IP_SADDR | T4_FILTER_IP_DADDR | T4_FILTER_IP_SPORT | T4_FILTER_IP_DPORT; if (fconf & F_FRAGMENTATION) mode |= T4_FILTER_IP_FRAGMENT; if (fconf & F_MPSHITTYPE) mode |= T4_FILTER_MPS_HIT_TYPE; if (fconf & F_MACMATCH) mode |= T4_FILTER_MAC_IDX; if (fconf & F_ETHERTYPE) mode |= T4_FILTER_ETH_TYPE; if (fconf & F_PROTOCOL) mode |= T4_FILTER_IP_PROTO; if (fconf & F_TOS) mode |= T4_FILTER_IP_TOS; if (fconf & F_VLAN) mode |= T4_FILTER_VLAN; if (fconf & F_VNIC_ID) { mode |= T4_FILTER_VNIC; if (iconf & F_VNIC) mode |= T4_FILTER_IC_VNIC; } if (fconf & F_PORT) mode |= T4_FILTER_PORT; if (fconf & F_FCOE) mode |= T4_FILTER_FCoE; return (mode); } static uint32_t mode_to_fconf(uint32_t mode) { uint32_t fconf = 0; if (mode & T4_FILTER_IP_FRAGMENT) fconf |= F_FRAGMENTATION; if (mode & T4_FILTER_MPS_HIT_TYPE) fconf |= F_MPSHITTYPE; if (mode & T4_FILTER_MAC_IDX) fconf |= F_MACMATCH; if (mode & T4_FILTER_ETH_TYPE) fconf |= F_ETHERTYPE; if (mode & T4_FILTER_IP_PROTO) fconf |= F_PROTOCOL; if (mode & T4_FILTER_IP_TOS) fconf |= F_TOS; if (mode & T4_FILTER_VLAN) fconf |= F_VLAN; if (mode & T4_FILTER_VNIC) fconf |= F_VNIC_ID; if (mode & T4_FILTER_PORT) fconf |= F_PORT; if (mode & T4_FILTER_FCoE) fconf |= F_FCOE; return (fconf); } static uint32_t mode_to_iconf(uint32_t mode) { if (mode & T4_FILTER_IC_VNIC) return (F_VNIC); return (0); } static int check_fspec_against_fconf_iconf(struct adapter *sc, struct t4_filter_specification *fs) { struct tp_params *tpp = &sc->params.tp; uint32_t fconf = 0; if (fs->val.frag || fs->mask.frag) fconf |= F_FRAGMENTATION; if (fs->val.matchtype || fs->mask.matchtype) fconf |= F_MPSHITTYPE; if (fs->val.macidx || fs->mask.macidx) fconf |= F_MACMATCH; if (fs->val.ethtype || fs->mask.ethtype) fconf |= F_ETHERTYPE; if (fs->val.proto || fs->mask.proto) fconf |= F_PROTOCOL; if (fs->val.tos || fs->mask.tos) fconf |= F_TOS; if (fs->val.vlan_vld || fs->mask.vlan_vld) fconf |= F_VLAN; if (fs->val.ovlan_vld || fs->mask.ovlan_vld) { fconf |= F_VNIC_ID; if (tpp->ingress_config & F_VNIC) return (EINVAL); } if (fs->val.pfvf_vld || fs->mask.pfvf_vld) { fconf |= F_VNIC_ID; if ((tpp->ingress_config & F_VNIC) == 0) return (EINVAL); } if (fs->val.iport || fs->mask.iport) fconf |= F_PORT; if (fs->val.fcoe || fs->mask.fcoe) fconf |= F_FCOE; if ((tpp->vlan_pri_map | fconf) != tpp->vlan_pri_map) return (E2BIG); return (0); } static int get_filter_mode(struct adapter *sc, uint32_t *mode) { struct tp_params *tpp = &sc->params.tp; /* * We trust the cached values of the relevant TP registers. This means * things work reliably only if writes to those registers are always via * t4_set_filter_mode. */ *mode = fconf_iconf_to_mode(tpp->vlan_pri_map, tpp->ingress_config); return (0); } static int set_filter_mode(struct adapter *sc, uint32_t mode) { struct tp_params *tpp = &sc->params.tp; uint32_t fconf, iconf; int rc; iconf = mode_to_iconf(mode); if ((iconf ^ tpp->ingress_config) & F_VNIC) { /* * For now we just complain if A_TP_INGRESS_CONFIG is not * already set to the correct value for the requested filter * mode. It's not clear if it's safe to write to this register * on the fly. (And we trust the cached value of the register). */ return (EBUSY); } fconf = mode_to_fconf(mode); rc = begin_synchronized_op(sc, NULL, HOLD_LOCK | SLEEP_OK | INTR_OK, "t4setfm"); if (rc) return (rc); if (sc->tids.ftids_in_use > 0) { rc = EBUSY; goto done; } #ifdef TCP_OFFLOAD if (uld_active(sc, ULD_TOM)) { rc = EBUSY; goto done; } #endif rc = -t4_set_filter_mode(sc, fconf); done: end_synchronized_op(sc, LOCK_HELD); return (rc); } static inline uint64_t get_filter_hits(struct adapter *sc, uint32_t fid) { uint32_t tcb_addr; tcb_addr = t4_read_reg(sc, A_TP_CMM_TCB_BASE) + (fid + sc->tids.ftid_base) * TCB_SIZE; if (is_t4(sc)) { uint64_t hits; read_via_memwin(sc, 0, tcb_addr + 16, (uint32_t *)&hits, 8); return (be64toh(hits)); } else { uint32_t hits; read_via_memwin(sc, 0, tcb_addr + 24, &hits, 4); return (be32toh(hits)); } } static int get_filter(struct adapter *sc, struct t4_filter *t) { int i, rc, nfilters = sc->tids.nftids; struct filter_entry *f; rc = begin_synchronized_op(sc, NULL, HOLD_LOCK | SLEEP_OK | INTR_OK, "t4getf"); if (rc) return (rc); if (sc->tids.ftids_in_use == 0 || sc->tids.ftid_tab == NULL || t->idx >= nfilters) { t->idx = 0xffffffff; goto done; } f = &sc->tids.ftid_tab[t->idx]; for (i = t->idx; i < nfilters; i++, f++) { if (f->valid) { t->idx = i; t->l2tidx = f->l2t ? f->l2t->idx : 0; t->smtidx = f->smtidx; if (f->fs.hitcnts) t->hits = get_filter_hits(sc, t->idx); else t->hits = UINT64_MAX; t->fs = f->fs; goto done; } } t->idx = 0xffffffff; done: end_synchronized_op(sc, LOCK_HELD); return (0); } static int set_filter(struct adapter *sc, struct t4_filter *t) { unsigned int nfilters, nports; struct filter_entry *f; int i, rc; rc = begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t4setf"); if (rc) return (rc); nfilters = sc->tids.nftids; nports = sc->params.nports; if (nfilters == 0) { rc = ENOTSUP; goto done; } if (t->idx >= nfilters) { rc = EINVAL; goto done; } /* Validate against the global filter mode and ingress config */ rc = check_fspec_against_fconf_iconf(sc, &t->fs); if (rc != 0) goto done; if (t->fs.action == FILTER_SWITCH && t->fs.eport >= nports) { rc = EINVAL; goto done; } if (t->fs.val.iport >= nports) { rc = EINVAL; goto done; } /* Can't specify an iq if not steering to it */ if (!t->fs.dirsteer && t->fs.iq) { rc = EINVAL; goto done; } /* IPv6 filter idx must be 4 aligned */ if (t->fs.type == 1 && ((t->idx & 0x3) || t->idx + 4 >= nfilters)) { rc = EINVAL; goto done; } if (!(sc->flags & FULL_INIT_DONE) && ((rc = adapter_full_init(sc)) != 0)) goto done; if (sc->tids.ftid_tab == NULL) { KASSERT(sc->tids.ftids_in_use == 0, ("%s: no memory allocated but filters_in_use > 0", __func__)); sc->tids.ftid_tab = malloc(sizeof (struct filter_entry) * nfilters, M_CXGBE, M_NOWAIT | M_ZERO); if (sc->tids.ftid_tab == NULL) { rc = ENOMEM; goto done; } mtx_init(&sc->tids.ftid_lock, "T4 filters", 0, MTX_DEF); } for (i = 0; i < 4; i++) { f = &sc->tids.ftid_tab[t->idx + i]; if (f->pending || f->valid) { rc = EBUSY; goto done; } if (f->locked) { rc = EPERM; goto done; } if (t->fs.type == 0) break; } f = &sc->tids.ftid_tab[t->idx]; f->fs = t->fs; rc = set_filter_wr(sc, t->idx); done: end_synchronized_op(sc, 0); if (rc == 0) { mtx_lock(&sc->tids.ftid_lock); for (;;) { if (f->pending == 0) { rc = f->valid ? 0 : EIO; break; } if (mtx_sleep(&sc->tids.ftid_tab, &sc->tids.ftid_lock, PCATCH, "t4setfw", 0)) { rc = EINPROGRESS; break; } } mtx_unlock(&sc->tids.ftid_lock); } return (rc); } static int del_filter(struct adapter *sc, struct t4_filter *t) { unsigned int nfilters; struct filter_entry *f; int rc; rc = begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t4delf"); if (rc) return (rc); nfilters = sc->tids.nftids; if (nfilters == 0) { rc = ENOTSUP; goto done; } if (sc->tids.ftid_tab == NULL || sc->tids.ftids_in_use == 0 || t->idx >= nfilters) { rc = EINVAL; goto done; } if (!(sc->flags & FULL_INIT_DONE)) { rc = EAGAIN; goto done; } f = &sc->tids.ftid_tab[t->idx]; if (f->pending) { rc = EBUSY; goto done; } if (f->locked) { rc = EPERM; goto done; } if (f->valid) { t->fs = f->fs; /* extra info for the caller */ rc = del_filter_wr(sc, t->idx); } done: end_synchronized_op(sc, 0); if (rc == 0) { mtx_lock(&sc->tids.ftid_lock); for (;;) { if (f->pending == 0) { rc = f->valid ? EIO : 0; break; } if (mtx_sleep(&sc->tids.ftid_tab, &sc->tids.ftid_lock, PCATCH, "t4delfw", 0)) { rc = EINPROGRESS; break; } } mtx_unlock(&sc->tids.ftid_lock); } return (rc); } static void clear_filter(struct filter_entry *f) { if (f->l2t) t4_l2t_release(f->l2t); bzero(f, sizeof (*f)); } static int set_filter_wr(struct adapter *sc, int fidx) { struct filter_entry *f = &sc->tids.ftid_tab[fidx]; struct fw_filter_wr *fwr; unsigned int ftid, vnic_vld, vnic_vld_mask; struct wrq_cookie cookie; ASSERT_SYNCHRONIZED_OP(sc); if (f->fs.newdmac || f->fs.newvlan) { /* This filter needs an L2T entry; allocate one. */ f->l2t = t4_l2t_alloc_switching(sc->l2t); if (f->l2t == NULL) return (EAGAIN); if (t4_l2t_set_switching(sc, f->l2t, f->fs.vlan, f->fs.eport, f->fs.dmac)) { t4_l2t_release(f->l2t); f->l2t = NULL; return (ENOMEM); } } /* Already validated against fconf, iconf */ MPASS((f->fs.val.pfvf_vld & f->fs.val.ovlan_vld) == 0); MPASS((f->fs.mask.pfvf_vld & f->fs.mask.ovlan_vld) == 0); if (f->fs.val.pfvf_vld || f->fs.val.ovlan_vld) vnic_vld = 1; else vnic_vld = 0; if (f->fs.mask.pfvf_vld || f->fs.mask.ovlan_vld) vnic_vld_mask = 1; else vnic_vld_mask = 0; ftid = sc->tids.ftid_base + fidx; fwr = start_wrq_wr(&sc->sge.mgmtq, howmany(sizeof(*fwr), 16), &cookie); if (fwr == NULL) return (ENOMEM); bzero(fwr, sizeof(*fwr)); fwr->op_pkd = htobe32(V_FW_WR_OP(FW_FILTER_WR)); fwr->len16_pkd = htobe32(FW_LEN16(*fwr)); fwr->tid_to_iq = htobe32(V_FW_FILTER_WR_TID(ftid) | V_FW_FILTER_WR_RQTYPE(f->fs.type) | V_FW_FILTER_WR_NOREPLY(0) | V_FW_FILTER_WR_IQ(f->fs.iq)); fwr->del_filter_to_l2tix = htobe32(V_FW_FILTER_WR_RPTTID(f->fs.rpttid) | V_FW_FILTER_WR_DROP(f->fs.action == FILTER_DROP) | V_FW_FILTER_WR_DIRSTEER(f->fs.dirsteer) | V_FW_FILTER_WR_MASKHASH(f->fs.maskhash) | V_FW_FILTER_WR_DIRSTEERHASH(f->fs.dirsteerhash) | V_FW_FILTER_WR_LPBK(f->fs.action == FILTER_SWITCH) | V_FW_FILTER_WR_DMAC(f->fs.newdmac) | V_FW_FILTER_WR_SMAC(f->fs.newsmac) | V_FW_FILTER_WR_INSVLAN(f->fs.newvlan == VLAN_INSERT || f->fs.newvlan == VLAN_REWRITE) | V_FW_FILTER_WR_RMVLAN(f->fs.newvlan == VLAN_REMOVE || f->fs.newvlan == VLAN_REWRITE) | V_FW_FILTER_WR_HITCNTS(f->fs.hitcnts) | V_FW_FILTER_WR_TXCHAN(f->fs.eport) | V_FW_FILTER_WR_PRIO(f->fs.prio) | V_FW_FILTER_WR_L2TIX(f->l2t ? f->l2t->idx : 0)); fwr->ethtype = htobe16(f->fs.val.ethtype); fwr->ethtypem = htobe16(f->fs.mask.ethtype); fwr->frag_to_ovlan_vldm = (V_FW_FILTER_WR_FRAG(f->fs.val.frag) | V_FW_FILTER_WR_FRAGM(f->fs.mask.frag) | V_FW_FILTER_WR_IVLAN_VLD(f->fs.val.vlan_vld) | V_FW_FILTER_WR_OVLAN_VLD(vnic_vld) | V_FW_FILTER_WR_IVLAN_VLDM(f->fs.mask.vlan_vld) | V_FW_FILTER_WR_OVLAN_VLDM(vnic_vld_mask)); fwr->smac_sel = 0; fwr->rx_chan_rx_rpl_iq = htobe16(V_FW_FILTER_WR_RX_CHAN(0) | V_FW_FILTER_WR_RX_RPL_IQ(sc->sge.fwq.abs_id)); fwr->maci_to_matchtypem = htobe32(V_FW_FILTER_WR_MACI(f->fs.val.macidx) | V_FW_FILTER_WR_MACIM(f->fs.mask.macidx) | V_FW_FILTER_WR_FCOE(f->fs.val.fcoe) | V_FW_FILTER_WR_FCOEM(f->fs.mask.fcoe) | V_FW_FILTER_WR_PORT(f->fs.val.iport) | V_FW_FILTER_WR_PORTM(f->fs.mask.iport) | V_FW_FILTER_WR_MATCHTYPE(f->fs.val.matchtype) | V_FW_FILTER_WR_MATCHTYPEM(f->fs.mask.matchtype)); fwr->ptcl = f->fs.val.proto; fwr->ptclm = f->fs.mask.proto; fwr->ttyp = f->fs.val.tos; fwr->ttypm = f->fs.mask.tos; fwr->ivlan = htobe16(f->fs.val.vlan); fwr->ivlanm = htobe16(f->fs.mask.vlan); fwr->ovlan = htobe16(f->fs.val.vnic); fwr->ovlanm = htobe16(f->fs.mask.vnic); bcopy(f->fs.val.dip, fwr->lip, sizeof (fwr->lip)); bcopy(f->fs.mask.dip, fwr->lipm, sizeof (fwr->lipm)); bcopy(f->fs.val.sip, fwr->fip, sizeof (fwr->fip)); bcopy(f->fs.mask.sip, fwr->fipm, sizeof (fwr->fipm)); fwr->lp = htobe16(f->fs.val.dport); fwr->lpm = htobe16(f->fs.mask.dport); fwr->fp = htobe16(f->fs.val.sport); fwr->fpm = htobe16(f->fs.mask.sport); if (f->fs.newsmac) bcopy(f->fs.smac, fwr->sma, sizeof (fwr->sma)); f->pending = 1; sc->tids.ftids_in_use++; commit_wrq_wr(&sc->sge.mgmtq, fwr, &cookie); return (0); } static int del_filter_wr(struct adapter *sc, int fidx) { struct filter_entry *f = &sc->tids.ftid_tab[fidx]; struct fw_filter_wr *fwr; unsigned int ftid; struct wrq_cookie cookie; ftid = sc->tids.ftid_base + fidx; fwr = start_wrq_wr(&sc->sge.mgmtq, howmany(sizeof(*fwr), 16), &cookie); if (fwr == NULL) return (ENOMEM); bzero(fwr, sizeof (*fwr)); t4_mk_filtdelwr(ftid, fwr, sc->sge.fwq.abs_id); f->pending = 1; commit_wrq_wr(&sc->sge.mgmtq, fwr, &cookie); return (0); } int t4_filter_rpl(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) { struct adapter *sc = iq->adapter; const struct cpl_set_tcb_rpl *rpl = (const void *)(rss + 1); unsigned int idx = GET_TID(rpl); unsigned int rc; struct filter_entry *f; KASSERT(m == NULL, ("%s: payload with opcode %02x", __func__, rss->opcode)); MPASS(iq == &sc->sge.fwq); MPASS(is_ftid(sc, idx)); idx -= sc->tids.ftid_base; f = &sc->tids.ftid_tab[idx]; rc = G_COOKIE(rpl->cookie); mtx_lock(&sc->tids.ftid_lock); if (rc == FW_FILTER_WR_FLT_ADDED) { KASSERT(f->pending, ("%s: filter[%u] isn't pending.", __func__, idx)); f->smtidx = (be64toh(rpl->oldval) >> 24) & 0xff; f->pending = 0; /* asynchronous setup completed */ f->valid = 1; } else { if (rc != FW_FILTER_WR_FLT_DELETED) { /* Add or delete failed, display an error */ log(LOG_ERR, "filter %u setup failed with error %u\n", idx, rc); } clear_filter(f); sc->tids.ftids_in_use--; } wakeup(&sc->tids.ftid_tab); mtx_unlock(&sc->tids.ftid_lock); return (0); } static int set_tcb_rpl(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) { MPASS(iq->set_tcb_rpl != NULL); return (iq->set_tcb_rpl(iq, rss, m)); } static int l2t_write_rpl(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) { MPASS(iq->l2t_write_rpl != NULL); return (iq->l2t_write_rpl(iq, rss, m)); } static int get_sge_context(struct adapter *sc, struct t4_sge_context *cntxt) { int rc; if (cntxt->cid > M_CTXTQID) return (EINVAL); if (cntxt->mem_id != CTXT_EGRESS && cntxt->mem_id != CTXT_INGRESS && cntxt->mem_id != CTXT_FLM && cntxt->mem_id != CTXT_CNM) return (EINVAL); rc = begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t4ctxt"); if (rc) return (rc); if (sc->flags & FW_OK) { rc = -t4_sge_ctxt_rd(sc, sc->mbox, cntxt->cid, cntxt->mem_id, &cntxt->data[0]); if (rc == 0) goto done; } /* * Read via firmware failed or wasn't even attempted. Read directly via * the backdoor. */ rc = -t4_sge_ctxt_rd_bd(sc, cntxt->cid, cntxt->mem_id, &cntxt->data[0]); done: end_synchronized_op(sc, 0); return (rc); } static int load_fw(struct adapter *sc, struct t4_data *fw) { int rc; uint8_t *fw_data; rc = begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t4ldfw"); if (rc) return (rc); if (sc->flags & FULL_INIT_DONE) { rc = EBUSY; goto done; } fw_data = malloc(fw->len, M_CXGBE, M_WAITOK); if (fw_data == NULL) { rc = ENOMEM; goto done; } rc = copyin(fw->data, fw_data, fw->len); if (rc == 0) rc = -t4_load_fw(sc, fw_data, fw->len); free(fw_data, M_CXGBE); done: end_synchronized_op(sc, 0); return (rc); } static int load_cfg(struct adapter *sc, struct t4_data *cfg) { int rc; uint8_t *cfg_data = NULL; rc = begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t4ldcf"); if (rc) return (rc); if (cfg->len == 0) { /* clear */ rc = -t4_load_cfg(sc, NULL, 0); goto done; } cfg_data = malloc(cfg->len, M_CXGBE, M_WAITOK); if (cfg_data == NULL) { rc = ENOMEM; goto done; } rc = copyin(cfg->data, cfg_data, cfg->len); if (rc == 0) rc = -t4_load_cfg(sc, cfg_data, cfg->len); free(cfg_data, M_CXGBE); done: end_synchronized_op(sc, 0); return (rc); } static int load_boot(struct adapter *sc, struct t4_bootrom *br) { int rc; uint8_t *br_data = NULL; u_int offset; if (br->len > 1024 * 1024) return (EFBIG); if (br->pf_offset == 0) { /* pfidx */ if (br->pfidx_addr > 7) return (EINVAL); offset = G_OFFSET(t4_read_reg(sc, PF_REG(br->pfidx_addr, A_PCIE_PF_EXPROM_OFST))); } else if (br->pf_offset == 1) { /* offset */ offset = G_OFFSET(br->pfidx_addr); } else { return (EINVAL); } rc = begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t4ldbr"); if (rc) return (rc); if (br->len == 0) { /* clear */ rc = -t4_load_boot(sc, NULL, offset, 0); goto done; } br_data = malloc(br->len, M_CXGBE, M_WAITOK); if (br_data == NULL) { rc = ENOMEM; goto done; } rc = copyin(br->data, br_data, br->len); if (rc == 0) rc = -t4_load_boot(sc, br_data, offset, br->len); free(br_data, M_CXGBE); done: end_synchronized_op(sc, 0); return (rc); } static int load_bootcfg(struct adapter *sc, struct t4_data *bc) { int rc; uint8_t *bc_data = NULL; rc = begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t4ldcf"); if (rc) return (rc); if (bc->len == 0) { /* clear */ rc = -t4_load_bootcfg(sc, NULL, 0); goto done; } bc_data = malloc(bc->len, M_CXGBE, M_WAITOK); if (bc_data == NULL) { rc = ENOMEM; goto done; } rc = copyin(bc->data, bc_data, bc->len); if (rc == 0) rc = -t4_load_bootcfg(sc, bc_data, bc->len); free(bc_data, M_CXGBE); done: end_synchronized_op(sc, 0); return (rc); } #define MAX_READ_BUF_SIZE (128 * 1024) static int read_card_mem(struct adapter *sc, int win, struct t4_mem_range *mr) { uint32_t addr, remaining, n; uint32_t *buf; int rc; uint8_t *dst; rc = validate_mem_range(sc, mr->addr, mr->len); if (rc != 0) return (rc); buf = malloc(min(mr->len, MAX_READ_BUF_SIZE), M_CXGBE, M_WAITOK); addr = mr->addr; remaining = mr->len; dst = (void *)mr->data; while (remaining) { n = min(remaining, MAX_READ_BUF_SIZE); read_via_memwin(sc, 2, addr, buf, n); rc = copyout(buf, dst, n); if (rc != 0) break; dst += n; remaining -= n; addr += n; } free(buf, M_CXGBE); return (rc); } #undef MAX_READ_BUF_SIZE static int read_i2c(struct adapter *sc, struct t4_i2c_data *i2cd) { int rc; if (i2cd->len == 0 || i2cd->port_id >= sc->params.nports) return (EINVAL); if (i2cd->len > sizeof(i2cd->data)) return (EFBIG); rc = begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t4i2crd"); if (rc) return (rc); rc = -t4_i2c_rd(sc, sc->mbox, i2cd->port_id, i2cd->dev_addr, i2cd->offset, i2cd->len, &i2cd->data[0]); end_synchronized_op(sc, 0); return (rc); } int t4_os_find_pci_capability(struct adapter *sc, int cap) { int i; return (pci_find_cap(sc->dev, cap, &i) == 0 ? i : 0); } int t4_os_pci_save_state(struct adapter *sc) { device_t dev; struct pci_devinfo *dinfo; dev = sc->dev; dinfo = device_get_ivars(dev); pci_cfg_save(dev, dinfo, 0); return (0); } int t4_os_pci_restore_state(struct adapter *sc) { device_t dev; struct pci_devinfo *dinfo; dev = sc->dev; dinfo = device_get_ivars(dev); pci_cfg_restore(dev, dinfo); return (0); } void t4_os_portmod_changed(struct port_info *pi, int old_ptype, int old_mtype, struct link_config *old_lc) { struct vi_info *vi; struct ifnet *ifp; int v; static const char *mod_str[] = { NULL, "LR", "SR", "ER", "TWINAX", "active TWINAX", "LRM" }; PORT_LOCK(pi); for_each_vi(pi, v, vi) { build_medialist(pi, &vi->media); } PORT_UNLOCK(pi); if (begin_synchronized_op(pi->adapter, vi, HOLD_LOCK, "t4mod") == 0) { init_l1cfg(pi); end_synchronized_op(pi->adapter, LOCK_HELD); } ifp = pi->vi[0].ifp; if (pi->mod_type == FW_PORT_MOD_TYPE_NONE) if_printf(ifp, "transceiver unplugged.\n"); else if (pi->mod_type == FW_PORT_MOD_TYPE_UNKNOWN) if_printf(ifp, "unknown transceiver inserted.\n"); else if (pi->mod_type == FW_PORT_MOD_TYPE_NOTSUPPORTED) if_printf(ifp, "unsupported transceiver inserted.\n"); else if (pi->mod_type > 0 && pi->mod_type < nitems(mod_str)) { if_printf(ifp, "%dGbps %s transceiver inserted.\n", port_top_speed(pi), mod_str[pi->mod_type]); } else { if_printf(ifp, "transceiver (type %d) inserted.\n", pi->mod_type); } } void t4_os_link_changed(struct port_info *pi, struct link_config *old_lc) { struct vi_info *vi; struct ifnet *ifp; struct link_config *lc; int v; for_each_vi(pi, v, vi) { ifp = vi->ifp; if (ifp == NULL) continue; lc = &pi->link_cfg; if (lc->link_ok) { ifp->if_baudrate = IF_Mbps(lc->speed); if_link_state_change(ifp, LINK_STATE_UP); } else { if_link_state_change(ifp, LINK_STATE_DOWN); } } } void t4_iterate(void (*func)(struct adapter *, void *), void *arg) { struct adapter *sc; sx_slock(&t4_list_lock); SLIST_FOREACH(sc, &t4_list, link) { /* * func should not make any assumptions about what state sc is * in - the only guarantee is that sc->sc_lock is a valid lock. */ func(sc, arg); } sx_sunlock(&t4_list_lock); } static int t4_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data, int fflag, struct thread *td) { int rc; struct adapter *sc = dev->si_drv1; rc = priv_check(td, PRIV_DRIVER); if (rc != 0) return (rc); switch (cmd) { case CHELSIO_T4_GETREG: { struct t4_reg *edata = (struct t4_reg *)data; if ((edata->addr & 0x3) != 0 || edata->addr >= sc->mmio_len) return (EFAULT); if (edata->size == 4) edata->val = t4_read_reg(sc, edata->addr); else if (edata->size == 8) edata->val = t4_read_reg64(sc, edata->addr); else return (EINVAL); break; } case CHELSIO_T4_SETREG: { struct t4_reg *edata = (struct t4_reg *)data; if ((edata->addr & 0x3) != 0 || edata->addr >= sc->mmio_len) return (EFAULT); if (edata->size == 4) { if (edata->val & 0xffffffff00000000) return (EINVAL); t4_write_reg(sc, edata->addr, (uint32_t) edata->val); } else if (edata->size == 8) t4_write_reg64(sc, edata->addr, edata->val); else return (EINVAL); break; } case CHELSIO_T4_REGDUMP: { struct t4_regdump *regs = (struct t4_regdump *)data; int reglen = t4_get_regs_len(sc); uint8_t *buf; if (regs->len < reglen) { regs->len = reglen; /* hint to the caller */ return (ENOBUFS); } regs->len = reglen; buf = malloc(reglen, M_CXGBE, M_WAITOK | M_ZERO); get_regs(sc, regs, buf); rc = copyout(buf, regs->data, reglen); free(buf, M_CXGBE); break; } case CHELSIO_T4_GET_FILTER_MODE: rc = get_filter_mode(sc, (uint32_t *)data); break; case CHELSIO_T4_SET_FILTER_MODE: rc = set_filter_mode(sc, *(uint32_t *)data); break; case CHELSIO_T4_GET_FILTER: rc = get_filter(sc, (struct t4_filter *)data); break; case CHELSIO_T4_SET_FILTER: rc = set_filter(sc, (struct t4_filter *)data); break; case CHELSIO_T4_DEL_FILTER: rc = del_filter(sc, (struct t4_filter *)data); break; case CHELSIO_T4_GET_SGE_CONTEXT: rc = get_sge_context(sc, (struct t4_sge_context *)data); break; case CHELSIO_T4_LOAD_FW: rc = load_fw(sc, (struct t4_data *)data); break; case CHELSIO_T4_GET_MEM: rc = read_card_mem(sc, 2, (struct t4_mem_range *)data); break; case CHELSIO_T4_GET_I2C: rc = read_i2c(sc, (struct t4_i2c_data *)data); break; case CHELSIO_T4_CLEAR_STATS: { int i, v; u_int port_id = *(uint32_t *)data; struct port_info *pi; struct vi_info *vi; if (port_id >= sc->params.nports) return (EINVAL); pi = sc->port[port_id]; if (pi == NULL) return (EIO); /* MAC stats */ t4_clr_port_stats(sc, pi->tx_chan); pi->tx_parse_error = 0; mtx_lock(&sc->reg_lock); for_each_vi(pi, v, vi) { if (vi->flags & VI_INIT_DONE) t4_clr_vi_stats(sc, vi->viid); } mtx_unlock(&sc->reg_lock); /* * Since this command accepts a port, clear stats for * all VIs on this port. */ for_each_vi(pi, v, vi) { if (vi->flags & VI_INIT_DONE) { struct sge_rxq *rxq; struct sge_txq *txq; struct sge_wrq *wrq; for_each_rxq(vi, i, rxq) { #if defined(INET) || defined(INET6) rxq->lro.lro_queued = 0; rxq->lro.lro_flushed = 0; #endif rxq->rxcsum = 0; rxq->vlan_extraction = 0; } for_each_txq(vi, i, txq) { txq->txcsum = 0; txq->tso_wrs = 0; txq->vlan_insertion = 0; txq->imm_wrs = 0; txq->sgl_wrs = 0; txq->txpkt_wrs = 0; txq->txpkts0_wrs = 0; txq->txpkts1_wrs = 0; txq->txpkts0_pkts = 0; txq->txpkts1_pkts = 0; mp_ring_reset_stats(txq->r); } #ifdef TCP_OFFLOAD /* nothing to clear for each ofld_rxq */ for_each_ofld_txq(vi, i, wrq) { wrq->tx_wrs_direct = 0; wrq->tx_wrs_copied = 0; } #endif if (IS_MAIN_VI(vi)) { wrq = &sc->sge.ctrlq[pi->port_id]; wrq->tx_wrs_direct = 0; wrq->tx_wrs_copied = 0; } } } break; } case CHELSIO_T4_SCHED_CLASS: rc = t4_set_sched_class(sc, (struct t4_sched_params *)data); break; case CHELSIO_T4_SCHED_QUEUE: rc = t4_set_sched_queue(sc, (struct t4_sched_queue *)data); break; case CHELSIO_T4_GET_TRACER: rc = t4_get_tracer(sc, (struct t4_tracer *)data); break; case CHELSIO_T4_SET_TRACER: rc = t4_set_tracer(sc, (struct t4_tracer *)data); break; case CHELSIO_T4_LOAD_CFG: rc = load_cfg(sc, (struct t4_data *)data); break; case CHELSIO_T4_LOAD_BOOT: rc = load_boot(sc, (struct t4_bootrom *)data); break; case CHELSIO_T4_LOAD_BOOTCFG: rc = load_bootcfg(sc, (struct t4_data *)data); break; default: rc = ENOTTY; } return (rc); } void t4_db_full(struct adapter *sc) { CXGBE_UNIMPLEMENTED(__func__); } void t4_db_dropped(struct adapter *sc) { CXGBE_UNIMPLEMENTED(__func__); } #ifdef TCP_OFFLOAD static int toe_capability(struct vi_info *vi, int enable) { int rc; struct port_info *pi = vi->pi; struct adapter *sc = pi->adapter; ASSERT_SYNCHRONIZED_OP(sc); if (!is_offload(sc)) return (ENODEV); if (enable) { if ((vi->ifp->if_capenable & IFCAP_TOE) != 0) { /* TOE is already enabled. */ return (0); } /* * We need the port's queues around so that we're able to send * and receive CPLs to/from the TOE even if the ifnet for this * port has never been UP'd administratively. */ if (!(vi->flags & VI_INIT_DONE)) { rc = vi_full_init(vi); if (rc) return (rc); } if (!(pi->vi[0].flags & VI_INIT_DONE)) { rc = vi_full_init(&pi->vi[0]); if (rc) return (rc); } if (isset(&sc->offload_map, pi->port_id)) { /* TOE is enabled on another VI of this port. */ pi->uld_vis++; return (0); } if (!uld_active(sc, ULD_TOM)) { rc = t4_activate_uld(sc, ULD_TOM); if (rc == EAGAIN) { log(LOG_WARNING, "You must kldload t4_tom.ko before trying " "to enable TOE on a cxgbe interface.\n"); } if (rc != 0) return (rc); KASSERT(sc->tom_softc != NULL, ("%s: TOM activated but softc NULL", __func__)); KASSERT(uld_active(sc, ULD_TOM), ("%s: TOM activated but flag not set", __func__)); } /* Activate iWARP and iSCSI too, if the modules are loaded. */ if (!uld_active(sc, ULD_IWARP)) (void) t4_activate_uld(sc, ULD_IWARP); if (!uld_active(sc, ULD_ISCSI)) (void) t4_activate_uld(sc, ULD_ISCSI); pi->uld_vis++; setbit(&sc->offload_map, pi->port_id); } else { pi->uld_vis--; if (!isset(&sc->offload_map, pi->port_id) || pi->uld_vis > 0) return (0); KASSERT(uld_active(sc, ULD_TOM), ("%s: TOM never initialized?", __func__)); clrbit(&sc->offload_map, pi->port_id); } return (0); } /* * Add an upper layer driver to the global list. */ int t4_register_uld(struct uld_info *ui) { int rc = 0; struct uld_info *u; sx_xlock(&t4_uld_list_lock); SLIST_FOREACH(u, &t4_uld_list, link) { if (u->uld_id == ui->uld_id) { rc = EEXIST; goto done; } } SLIST_INSERT_HEAD(&t4_uld_list, ui, link); ui->refcount = 0; done: sx_xunlock(&t4_uld_list_lock); return (rc); } int t4_unregister_uld(struct uld_info *ui) { int rc = EINVAL; struct uld_info *u; sx_xlock(&t4_uld_list_lock); SLIST_FOREACH(u, &t4_uld_list, link) { if (u == ui) { if (ui->refcount > 0) { rc = EBUSY; goto done; } SLIST_REMOVE(&t4_uld_list, ui, uld_info, link); rc = 0; goto done; } } done: sx_xunlock(&t4_uld_list_lock); return (rc); } int t4_activate_uld(struct adapter *sc, int id) { int rc; struct uld_info *ui; ASSERT_SYNCHRONIZED_OP(sc); if (id < 0 || id > ULD_MAX) return (EINVAL); rc = EAGAIN; /* kldoad the module with this ULD and try again. */ sx_slock(&t4_uld_list_lock); SLIST_FOREACH(ui, &t4_uld_list, link) { if (ui->uld_id == id) { if (!(sc->flags & FULL_INIT_DONE)) { rc = adapter_full_init(sc); if (rc != 0) break; } rc = ui->activate(sc); if (rc == 0) { setbit(&sc->active_ulds, id); ui->refcount++; } break; } } sx_sunlock(&t4_uld_list_lock); return (rc); } int t4_deactivate_uld(struct adapter *sc, int id) { int rc; struct uld_info *ui; ASSERT_SYNCHRONIZED_OP(sc); if (id < 0 || id > ULD_MAX) return (EINVAL); rc = ENXIO; sx_slock(&t4_uld_list_lock); SLIST_FOREACH(ui, &t4_uld_list, link) { if (ui->uld_id == id) { rc = ui->deactivate(sc); if (rc == 0) { clrbit(&sc->active_ulds, id); ui->refcount--; } break; } } sx_sunlock(&t4_uld_list_lock); return (rc); } int uld_active(struct adapter *sc, int uld_id) { MPASS(uld_id >= 0 && uld_id <= ULD_MAX); return (isset(&sc->active_ulds, uld_id)); } #endif /* * t = ptr to tunable. * nc = number of CPUs. * c = compiled in default for that tunable. */ static void calculate_nqueues(int *t, int nc, const int c) { int nq; if (*t > 0) return; nq = *t < 0 ? -*t : c; *t = min(nc, nq); } /* * Come up with reasonable defaults for some of the tunables, provided they're * not set by the user (in which case we'll use the values as is). */ static void tweak_tunables(void) { int nc = mp_ncpus; /* our snapshot of the number of CPUs */ if (t4_ntxq10g < 1) { #ifdef RSS t4_ntxq10g = rss_getnumbuckets(); #else calculate_nqueues(&t4_ntxq10g, nc, NTXQ_10G); #endif } if (t4_ntxq1g < 1) { #ifdef RSS /* XXX: way too many for 1GbE? */ t4_ntxq1g = rss_getnumbuckets(); #else calculate_nqueues(&t4_ntxq1g, nc, NTXQ_1G); #endif } calculate_nqueues(&t4_ntxq_vi, nc, NTXQ_VI); if (t4_nrxq10g < 1) { #ifdef RSS t4_nrxq10g = rss_getnumbuckets(); #else calculate_nqueues(&t4_nrxq10g, nc, NRXQ_10G); #endif } if (t4_nrxq1g < 1) { #ifdef RSS /* XXX: way too many for 1GbE? */ t4_nrxq1g = rss_getnumbuckets(); #else calculate_nqueues(&t4_nrxq1g, nc, NRXQ_1G); #endif } calculate_nqueues(&t4_nrxq_vi, nc, NRXQ_VI); #ifdef TCP_OFFLOAD calculate_nqueues(&t4_nofldtxq10g, nc, NOFLDTXQ_10G); calculate_nqueues(&t4_nofldtxq1g, nc, NOFLDTXQ_1G); calculate_nqueues(&t4_nofldtxq_vi, nc, NOFLDTXQ_VI); calculate_nqueues(&t4_nofldrxq10g, nc, NOFLDRXQ_10G); calculate_nqueues(&t4_nofldrxq1g, nc, NOFLDRXQ_1G); calculate_nqueues(&t4_nofldrxq_vi, nc, NOFLDRXQ_VI); if (t4_toecaps_allowed == -1) t4_toecaps_allowed = FW_CAPS_CONFIG_TOE; if (t4_rdmacaps_allowed == -1) { t4_rdmacaps_allowed = FW_CAPS_CONFIG_RDMA_RDDP | FW_CAPS_CONFIG_RDMA_RDMAC; } if (t4_iscsicaps_allowed == -1) { t4_iscsicaps_allowed = FW_CAPS_CONFIG_ISCSI_INITIATOR_PDU | FW_CAPS_CONFIG_ISCSI_TARGET_PDU | FW_CAPS_CONFIG_ISCSI_T10DIF; } #else if (t4_toecaps_allowed == -1) t4_toecaps_allowed = 0; if (t4_rdmacaps_allowed == -1) t4_rdmacaps_allowed = 0; if (t4_iscsicaps_allowed == -1) t4_iscsicaps_allowed = 0; #endif #ifdef DEV_NETMAP calculate_nqueues(&t4_nnmtxq_vi, nc, NNMTXQ_VI); calculate_nqueues(&t4_nnmrxq_vi, nc, NNMRXQ_VI); #endif if (t4_tmr_idx_10g < 0 || t4_tmr_idx_10g >= SGE_NTIMERS) t4_tmr_idx_10g = TMR_IDX_10G; if (t4_pktc_idx_10g < -1 || t4_pktc_idx_10g >= SGE_NCOUNTERS) t4_pktc_idx_10g = PKTC_IDX_10G; if (t4_tmr_idx_1g < 0 || t4_tmr_idx_1g >= SGE_NTIMERS) t4_tmr_idx_1g = TMR_IDX_1G; if (t4_pktc_idx_1g < -1 || t4_pktc_idx_1g >= SGE_NCOUNTERS) t4_pktc_idx_1g = PKTC_IDX_1G; if (t4_qsize_txq < 128) t4_qsize_txq = 128; if (t4_qsize_rxq < 128) t4_qsize_rxq = 128; while (t4_qsize_rxq & 7) t4_qsize_rxq++; t4_intr_types &= INTR_MSIX | INTR_MSI | INTR_INTX; } #ifdef DDB static void t4_dump_tcb(struct adapter *sc, int tid) { uint32_t base, i, j, off, pf, reg, save, tcb_addr, win_pos; reg = PCIE_MEM_ACCESS_REG(A_PCIE_MEM_ACCESS_OFFSET, 2); save = t4_read_reg(sc, reg); base = sc->memwin[2].mw_base; /* Dump TCB for the tid */ tcb_addr = t4_read_reg(sc, A_TP_CMM_TCB_BASE); tcb_addr += tid * TCB_SIZE; if (is_t4(sc)) { pf = 0; win_pos = tcb_addr & ~0xf; /* start must be 16B aligned */ } else { pf = V_PFNUM(sc->pf); win_pos = tcb_addr & ~0x7f; /* start must be 128B aligned */ } t4_write_reg(sc, reg, win_pos | pf); t4_read_reg(sc, reg); off = tcb_addr - win_pos; for (i = 0; i < 4; i++) { uint32_t buf[8]; for (j = 0; j < 8; j++, off += 4) buf[j] = htonl(t4_read_reg(sc, base + off)); db_printf("%08x %08x %08x %08x %08x %08x %08x %08x\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); } t4_write_reg(sc, reg, save); t4_read_reg(sc, reg); } static void t4_dump_devlog(struct adapter *sc) { struct devlog_params *dparams = &sc->params.devlog; struct fw_devlog_e e; int i, first, j, m, nentries, rc; uint64_t ftstamp = UINT64_MAX; if (dparams->start == 0) { db_printf("devlog params not valid\n"); return; } nentries = dparams->size / sizeof(struct fw_devlog_e); m = fwmtype_to_hwmtype(dparams->memtype); /* Find the first entry. */ first = -1; for (i = 0; i < nentries && !db_pager_quit; i++) { rc = -t4_mem_read(sc, m, dparams->start + i * sizeof(e), sizeof(e), (void *)&e); if (rc != 0) break; if (e.timestamp == 0) break; e.timestamp = be64toh(e.timestamp); if (e.timestamp < ftstamp) { ftstamp = e.timestamp; first = i; } } if (first == -1) return; i = first; do { rc = -t4_mem_read(sc, m, dparams->start + i * sizeof(e), sizeof(e), (void *)&e); if (rc != 0) return; if (e.timestamp == 0) return; e.timestamp = be64toh(e.timestamp); e.seqno = be32toh(e.seqno); for (j = 0; j < 8; j++) e.params[j] = be32toh(e.params[j]); db_printf("%10d %15ju %8s %8s ", e.seqno, e.timestamp, (e.level < nitems(devlog_level_strings) ? devlog_level_strings[e.level] : "UNKNOWN"), (e.facility < nitems(devlog_facility_strings) ? devlog_facility_strings[e.facility] : "UNKNOWN")); db_printf(e.fmt, e.params[0], e.params[1], e.params[2], e.params[3], e.params[4], e.params[5], e.params[6], e.params[7]); if (++i == nentries) i = 0; } while (i != first && !db_pager_quit); } static struct command_table db_t4_table = LIST_HEAD_INITIALIZER(db_t4_table); _DB_SET(_show, t4, NULL, db_show_table, 0, &db_t4_table); DB_FUNC(devlog, db_show_devlog, db_t4_table, CS_OWN, NULL) { device_t dev; int t; bool valid; valid = false; t = db_read_token(); if (t == tIDENT) { dev = device_lookup_by_name(db_tok_string); valid = true; } db_skip_to_eol(); if (!valid) { db_printf("usage: show t4 devlog \n"); return; } if (dev == NULL) { db_printf("device not found\n"); return; } t4_dump_devlog(device_get_softc(dev)); } DB_FUNC(tcb, db_show_t4tcb, db_t4_table, CS_OWN, NULL) { device_t dev; int radix, tid, t; bool valid; valid = false; radix = db_radix; db_radix = 10; t = db_read_token(); if (t == tIDENT) { dev = device_lookup_by_name(db_tok_string); t = db_read_token(); if (t == tNUMBER) { tid = db_tok_number; valid = true; } } db_radix = radix; db_skip_to_eol(); if (!valid) { db_printf("usage: show t4 tcb \n"); return; } if (dev == NULL) { db_printf("device not found\n"); return; } if (tid < 0) { db_printf("invalid tid\n"); return; } t4_dump_tcb(device_get_softc(dev), tid); } #endif static struct sx mlu; /* mod load unload */ SX_SYSINIT(cxgbe_mlu, &mlu, "cxgbe mod load/unload"); static int mod_event(module_t mod, int cmd, void *arg) { int rc = 0; static int loaded = 0; switch (cmd) { case MOD_LOAD: sx_xlock(&mlu); if (loaded++ == 0) { t4_sge_modload(); t4_register_cpl_handler(CPL_SET_TCB_RPL, set_tcb_rpl); t4_register_cpl_handler(CPL_L2T_WRITE_RPL, l2t_write_rpl); t4_register_cpl_handler(CPL_TRACE_PKT, t4_trace_pkt); t4_register_cpl_handler(CPL_T5_TRACE_PKT, t5_trace_pkt); sx_init(&t4_list_lock, "T4/T5 adapters"); SLIST_INIT(&t4_list); #ifdef TCP_OFFLOAD sx_init(&t4_uld_list_lock, "T4/T5 ULDs"); SLIST_INIT(&t4_uld_list); #endif t4_tracer_modload(); tweak_tunables(); } sx_xunlock(&mlu); break; case MOD_UNLOAD: sx_xlock(&mlu); if (--loaded == 0) { int tries; sx_slock(&t4_list_lock); if (!SLIST_EMPTY(&t4_list)) { rc = EBUSY; sx_sunlock(&t4_list_lock); goto done_unload; } #ifdef TCP_OFFLOAD sx_slock(&t4_uld_list_lock); if (!SLIST_EMPTY(&t4_uld_list)) { rc = EBUSY; sx_sunlock(&t4_uld_list_lock); sx_sunlock(&t4_list_lock); goto done_unload; } #endif tries = 0; while (tries++ < 5 && t4_sge_extfree_refs() != 0) { uprintf("%ju clusters with custom free routine " "still is use.\n", t4_sge_extfree_refs()); pause("t4unload", 2 * hz); } #ifdef TCP_OFFLOAD sx_sunlock(&t4_uld_list_lock); #endif sx_sunlock(&t4_list_lock); if (t4_sge_extfree_refs() == 0) { t4_tracer_modunload(); #ifdef TCP_OFFLOAD sx_destroy(&t4_uld_list_lock); #endif sx_destroy(&t4_list_lock); t4_sge_modunload(); loaded = 0; } else { rc = EBUSY; loaded++; /* undo earlier decrement */ } } done_unload: sx_xunlock(&mlu); break; } return (rc); } static devclass_t t4_devclass, t5_devclass, t6_devclass; static devclass_t cxgbe_devclass, cxl_devclass, cc_devclass; static devclass_t vcxgbe_devclass, vcxl_devclass, vcc_devclass; DRIVER_MODULE(t4nex, pci, t4_driver, t4_devclass, mod_event, 0); MODULE_VERSION(t4nex, 1); MODULE_DEPEND(t4nex, firmware, 1, 1, 1); #ifdef DEV_NETMAP MODULE_DEPEND(t4nex, netmap, 1, 1, 1); #endif /* DEV_NETMAP */ DRIVER_MODULE(t5nex, pci, t5_driver, t5_devclass, mod_event, 0); MODULE_VERSION(t5nex, 1); MODULE_DEPEND(t5nex, firmware, 1, 1, 1); #ifdef DEV_NETMAP MODULE_DEPEND(t5nex, netmap, 1, 1, 1); #endif /* DEV_NETMAP */ DRIVER_MODULE(t6nex, pci, t6_driver, t6_devclass, mod_event, 0); MODULE_VERSION(t6nex, 1); MODULE_DEPEND(t6nex, firmware, 1, 1, 1); #ifdef DEV_NETMAP MODULE_DEPEND(t6nex, netmap, 1, 1, 1); #endif /* DEV_NETMAP */ DRIVER_MODULE(cxgbe, t4nex, cxgbe_driver, cxgbe_devclass, 0, 0); MODULE_VERSION(cxgbe, 1); DRIVER_MODULE(cxl, t5nex, cxl_driver, cxl_devclass, 0, 0); MODULE_VERSION(cxl, 1); DRIVER_MODULE(cc, t6nex, cc_driver, cc_devclass, 0, 0); MODULE_VERSION(cc, 1); DRIVER_MODULE(vcxgbe, cxgbe, vcxgbe_driver, vcxgbe_devclass, 0, 0); MODULE_VERSION(vcxgbe, 1); DRIVER_MODULE(vcxl, cxl, vcxl_driver, vcxl_devclass, 0, 0); MODULE_VERSION(vcxl, 1); DRIVER_MODULE(vcc, cc, vcc_driver, vcc_devclass, 0, 0); MODULE_VERSION(vcc, 1); Index: projects/runtime-coverage/usr.bin/ar/write.c =================================================================== --- projects/runtime-coverage/usr.bin/ar/write.c (revision 321457) +++ projects/runtime-coverage/usr.bin/ar/write.c (revision 321458) @@ -1,912 +1,919 @@ /*- * Copyright (c) 2007 Kai Wang * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer * in this position and unchanged. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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 __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ar.h" #define _ARMAG_LEN 8 /* length of ar magic string */ #define _ARHDR_LEN 60 /* length of ar header */ #define _INIT_AS_CAP 128 /* initial archive string table size */ #define _INIT_SYMOFF_CAP (256*(sizeof(uint32_t))) /* initial so table size */ #define _INIT_SYMNAME_CAP 1024 /* initial sn table size */ #define _MAXNAMELEN_SVR4 15 /* max member name length in svr4 variant */ #define _TRUNCATE_LEN 15 /* number of bytes to keep for member name */ static void add_to_ar_str_table(struct bsdar *bsdar, const char *name); static void add_to_ar_sym_table(struct bsdar *bsdar, const char *name); static struct ar_obj *create_obj_from_file(struct bsdar *bsdar, const char *name, time_t mtime); static void create_symtab_entry(struct bsdar *bsdar, void *maddr, size_t size); static void free_obj(struct bsdar *bsdar, struct ar_obj *obj); static void insert_obj(struct bsdar *bsdar, struct ar_obj *obj, struct ar_obj *pos); static void prefault_buffer(const char *buf, size_t s); static void read_objs(struct bsdar *bsdar, const char *archive, int checkargv); static void write_archive(struct bsdar *bsdar, char mode); static void write_cleanup(struct bsdar *bsdar); static void write_data(struct bsdar *bsdar, struct archive *a, const void *buf, size_t s); static void write_objs(struct bsdar *bsdar); void ar_mode_d(struct bsdar *bsdar) { write_archive(bsdar, 'd'); } void ar_mode_m(struct bsdar *bsdar) { write_archive(bsdar, 'm'); } void ar_mode_q(struct bsdar *bsdar) { write_archive(bsdar, 'q'); } void ar_mode_r(struct bsdar *bsdar) { write_archive(bsdar, 'r'); } void ar_mode_s(struct bsdar *bsdar) { write_archive(bsdar, 's'); } void ar_mode_A(struct bsdar *bsdar) { write_archive(bsdar, 'A'); } /* * Create object from file, return created obj upon success, or NULL * when an error occurs or the member is not newer than existing * one while -u is specified. */ static struct ar_obj * create_obj_from_file(struct bsdar *bsdar, const char *name, time_t mtime) { struct ar_obj *obj; struct stat sb; const char *bname; char *tmpname; if (name == NULL) return (NULL); obj = malloc(sizeof(struct ar_obj)); if (obj == NULL) bsdar_errc(bsdar, EX_SOFTWARE, errno, "malloc failed"); if ((obj->fd = open(name, O_RDONLY, 0)) < 0) { bsdar_warnc(bsdar, errno, "can't open file: %s", name); free(obj); return (NULL); } tmpname = strdup(name); if (tmpname == NULL) bsdar_errc(bsdar, EX_SOFTWARE, errno, "strdup failed"); if ((bname = basename(tmpname)) == NULL) bsdar_errc(bsdar, EX_SOFTWARE, errno, "basename failed"); if (bsdar->options & AR_TR && strlen(bname) > _TRUNCATE_LEN) { if ((obj->name = malloc(_TRUNCATE_LEN + 1)) == NULL) bsdar_errc(bsdar, EX_SOFTWARE, errno, "malloc failed"); (void)strncpy(obj->name, bname, _TRUNCATE_LEN); obj->name[_TRUNCATE_LEN] = '\0'; } else if ((obj->name = strdup(bname)) == NULL) bsdar_errc(bsdar, EX_SOFTWARE, errno, "strdup failed"); free(tmpname); if (fstat(obj->fd, &sb) < 0) { bsdar_warnc(bsdar, errno, "can't fstat file: %s", obj->name); goto giveup; } if (!S_ISREG(sb.st_mode)) { bsdar_warnc(bsdar, 0, "%s is not an ordinary file", obj->name); goto giveup; } /* * When option '-u' is specified and member is not newer than the * existing one, the replace will not happen. While if mtime == 0, * which indicates that this is to "replace a none exist member", * the replace will proceed regardless of '-u'. */ if (mtime != 0 && bsdar->options & AR_U && sb.st_mtime <= mtime) goto giveup; /* * When option '-D' is specified, mtime and UID / GID from the file * will be replaced with 0, and file mode with 644. This ensures that * checksums will match for two archives containing the exact same * files. */ if (bsdar->options & AR_D) { obj->uid = 0; obj->gid = 0; obj->mtime = 0; obj->md = S_IFREG | 0644; } else { obj->uid = sb.st_uid; obj->gid = sb.st_gid; obj->mtime = sb.st_mtime; obj->md = sb.st_mode; } obj->size = sb.st_size; obj->dev = sb.st_dev; obj->ino = sb.st_ino; if (obj->size == 0) { obj->maddr = NULL; return (obj); } if ((obj->maddr = mmap(NULL, obj->size, PROT_READ, MAP_PRIVATE, obj->fd, (off_t)0)) == MAP_FAILED) { bsdar_warnc(bsdar, errno, "can't mmap file: %s", obj->name); goto giveup; } if (close(obj->fd) < 0) bsdar_errc(bsdar, EX_SOFTWARE, errno, "close failed: %s", obj->name); return (obj); giveup: if (close(obj->fd) < 0) bsdar_errc(bsdar, EX_SOFTWARE, errno, "close failed: %s", obj->name); free(obj->name); free(obj); return (NULL); } /* * Free object itself and its associated allocations. */ static void free_obj(struct bsdar *bsdar, struct ar_obj *obj) { if (obj->fd == -1) free(obj->maddr); else if (obj->maddr != NULL && munmap(obj->maddr, obj->size)) bsdar_warnc(bsdar, errno, "can't munmap file: %s", obj->name); free(obj->name); free(obj); } /* * Insert obj to the tail, or before/after the pos obj. */ static void insert_obj(struct bsdar *bsdar, struct ar_obj *obj, struct ar_obj *pos) { if (obj == NULL) bsdar_errc(bsdar, EX_SOFTWARE, 0, "try to insert a null obj"); if (pos == NULL || obj == pos) /* * If the object to move happens to be the position obj, * or if there is not a pos obj, move it to tail. */ goto tail; if (bsdar->options & AR_B) { TAILQ_INSERT_BEFORE(pos, obj, objs); return; } if (bsdar->options & AR_A) { TAILQ_INSERT_AFTER(&bsdar->v_obj, pos, obj, objs); return; } tail: TAILQ_INSERT_TAIL(&bsdar->v_obj, obj, objs); } /* * Read objects from archive into v_obj list. Note that checkargv is * set when read_objs is used to read objects from the target of * ADDLIB command (ar script mode), in this case argv array possibly * specifies the members ADDLIB want. */ static void read_objs(struct bsdar *bsdar, const char *archive, int checkargv) { struct archive *a; struct archive_entry *entry; struct ar_obj *obj; const char *name; const char *bname; char *buff; char **av; size_t size; int i, r, find; if ((a = archive_read_new()) == NULL) bsdar_errc(bsdar, EX_SOFTWARE, 0, "archive_read_new failed"); archive_read_support_format_ar(a); AC(archive_read_open_filename(a, archive, DEF_BLKSZ)); for (;;) { r = archive_read_next_header(a, &entry); if (r == ARCHIVE_FATAL) bsdar_errc(bsdar, EX_DATAERR, 0, "%s", archive_error_string(a)); if (r == ARCHIVE_EOF) break; if (r == ARCHIVE_WARN || r == ARCHIVE_RETRY) bsdar_warnc(bsdar, 0, "%s", archive_error_string(a)); if (r == ARCHIVE_RETRY) { bsdar_warnc(bsdar, 0, "Retrying..."); continue; } name = archive_entry_pathname(entry); /* * skip pseudo members. */ if (strcmp(name, "/") == 0 || strcmp(name, "//") == 0) continue; /* * If checkargv is set, only read those members specified * in argv. */ if (checkargv && bsdar->argc > 0) { find = 0; for(i = 0; i < bsdar->argc; i++) { av = &bsdar->argv[i]; if (*av == NULL) continue; if ((bname = basename(*av)) == NULL) bsdar_errc(bsdar, EX_SOFTWARE, errno, "basename failed"); if (strcmp(bname, name) != 0) continue; *av = NULL; find = 1; break; } if (!find) continue; } size = archive_entry_size(entry); if (size > 0) { if ((buff = malloc(size)) == NULL) bsdar_errc(bsdar, EX_SOFTWARE, errno, "malloc failed"); if (archive_read_data(a, buff, size) != (ssize_t)size) { bsdar_warnc(bsdar, 0, "%s", archive_error_string(a)); free(buff); continue; } } else buff = NULL; obj = malloc(sizeof(struct ar_obj)); if (obj == NULL) bsdar_errc(bsdar, EX_SOFTWARE, errno, "malloc failed"); obj->maddr = buff; if ((obj->name = strdup(name)) == NULL) bsdar_errc(bsdar, EX_SOFTWARE, errno, "strdup failed"); obj->size = size; obj->uid = archive_entry_uid(entry); obj->gid = archive_entry_gid(entry); obj->md = archive_entry_mode(entry); obj->mtime = archive_entry_mtime(entry); obj->dev = 0; obj->ino = 0; /* * Objects from archive have obj->fd set to -1, * for the ease of cleaning up. */ obj->fd = -1; TAILQ_INSERT_TAIL(&bsdar->v_obj, obj, objs); } AC(archive_read_close(a)); AC(archive_read_free(a)); } /* * Determine the constitution of resulting archive. */ static void write_archive(struct bsdar *bsdar, char mode) { struct ar_obj *nobj, *obj, *obj_temp, *pos; struct stat sb; const char *bname; char **av; int i; TAILQ_INIT(&bsdar->v_obj); nobj = NULL; pos = NULL; memset(&sb, 0, sizeof(sb)); /* * Test if the specified archive exists, to figure out * whether we are creating one here. */ if (stat(bsdar->filename, &sb) != 0) { if (errno != ENOENT) { bsdar_warnc(bsdar, 0, "stat %s failed", bsdar->filename); return; } /* We do not create archive in mode 'd', 'm' and 's'. */ if (mode != 'r' && mode != 'q') { bsdar_warnc(bsdar, 0, "%s: no such file", bsdar->filename); return; } /* Issue a warning if -c is not specified when creating. */ if (!(bsdar->options & AR_C)) bsdar_warnc(bsdar, 0, "creating %s", bsdar->filename); goto new_archive; } /* * First read members from existing archive. */ read_objs(bsdar, bsdar->filename, 0); /* * For mode 's', no member will be moved, deleted or replaced. */ if (mode == 's') goto write_objs; /* * For mode 'q', we don't need to adjust existing members either. * Also, -a, -b and -i are ignored in this mode. New members are * always inserted at tail. */ if (mode == 'q') goto new_archive; /* * Mode 'A' adds the contents of another archive to the tail of * current archive. Note that mode 'A' is a special mode for the * ADDLIB command of the ar script mode. Currently there is no * access to this function from the ar command line mode. */ if (mode == 'A') { /* * Read objects from the target archive of ADDLIB command. * If there are members specified in argv, read those members * only, otherwise the entire archive will be read. */ read_objs(bsdar, bsdar->addlib, 1); goto write_objs; } /* * Try to find the position member specified by user. */ if (bsdar->options & AR_A || bsdar->options & AR_B) { TAILQ_FOREACH(obj, &bsdar->v_obj, objs) { if (strcmp(obj->name, bsdar->posarg) == 0) { pos = obj; break; } } /* * If can't find `pos' specified by user, * silently insert objects at tail. */ if (pos == NULL) bsdar->options &= ~(AR_A | AR_B); } for (i = 0; i < bsdar->argc; i++) { av = &bsdar->argv[i]; TAILQ_FOREACH_SAFE(obj, &bsdar->v_obj, objs, obj_temp) { if ((bname = basename(*av)) == NULL) bsdar_errc(bsdar, EX_SOFTWARE, errno, "basename failed"); if (bsdar->options & AR_TR) { if (strncmp(bname, obj->name, _TRUNCATE_LEN)) continue; } else if (strcmp(bname, obj->name) != 0) continue; if (mode == 'r') { /* * if the new member is not qualified * to replace the old one, skip it. */ nobj = create_obj_from_file(bsdar, *av, obj->mtime); if (nobj == NULL) goto skip_obj; } if (bsdar->options & AR_V) (void)fprintf(stdout, "%c - %s\n", mode, *av); TAILQ_REMOVE(&bsdar->v_obj, obj, objs); if (mode == 'd' || mode == 'r') free_obj(bsdar, obj); if (mode == 'm') insert_obj(bsdar, obj, pos); if (mode == 'r') insert_obj(bsdar, nobj, pos); skip_obj: *av = NULL; break; } } new_archive: /* * When operating in mode 'r', directly add those user specified * objects which do not exist in current archive. When operating * in mode 'q', all objects specified in command line args are * appended to the archive, without comparing with existing ones. */ for (i = 0; i < bsdar->argc; i++) { av = &bsdar->argv[i]; if (*av != NULL && (mode == 'r' || mode == 'q')) { nobj = create_obj_from_file(bsdar, *av, 0); if (nobj != NULL) insert_obj(bsdar, nobj, pos); if (bsdar->options & AR_V && nobj != NULL) (void)fprintf(stdout, "a - %s\n", *av); *av = NULL; } } write_objs: write_objs(bsdar); write_cleanup(bsdar); } /* * Memory cleaning up. */ static void write_cleanup(struct bsdar *bsdar) { struct ar_obj *obj, *obj_temp; TAILQ_FOREACH_SAFE(obj, &bsdar->v_obj, objs, obj_temp) { TAILQ_REMOVE(&bsdar->v_obj, obj, objs); free_obj(bsdar, obj); } free(bsdar->as); free(bsdar->s_so); free(bsdar->s_sn); bsdar->as = NULL; bsdar->s_so = NULL; bsdar->s_sn = NULL; } /* * Fault in the buffer prior to writing as a workaround for poor performance * due to interaction with kernel fs deadlock avoidance code. See the comment * above vn_io_fault_doio() in sys/kern/vfs_vnops.c for details of the issue. */ static void prefault_buffer(const char *buf, size_t s) { volatile const char *p; size_t page_size; if (s == 0) return; page_size = sysconf(_SC_PAGESIZE); for (p = buf; p < buf + s; p += page_size) *p; /* * Ensure we touch the last page as well, in case the buffer is not * page-aligned. */ *(volatile const char *)(buf + s - 1); } /* * Wrapper for archive_write_data(). */ static void write_data(struct bsdar *bsdar, struct archive *a, const void *buf, size_t s) { + ssize_t written; + prefault_buffer(buf, s); - if (archive_write_data(a, buf, s) != (ssize_t)s) - bsdar_errc(bsdar, EX_SOFTWARE, 0, "%s", - archive_error_string(a)); + while (s > 0) { + written = archive_write_data(a, buf, s); + if (written < 0) + bsdar_errc(bsdar, EX_SOFTWARE, 0, "%s", + archive_error_string(a)); + buf = (const char *)buf + written; + s -= written; + } } /* * Write the resulting archive members. */ static void write_objs(struct bsdar *bsdar) { struct ar_obj *obj; struct archive *a; struct archive_entry *entry; size_t s_sz; /* size of archive symbol table. */ size_t pm_sz; /* size of pseudo members */ int i, nr; if (elf_version(EV_CURRENT) == EV_NONE) bsdar_errc(bsdar, EX_SOFTWARE, 0, "ELF library initialization failed: %s", elf_errmsg(-1)); bsdar->rela_off = 0; /* Create archive symbol table and archive string table, if need. */ TAILQ_FOREACH(obj, &bsdar->v_obj, objs) { if (!(bsdar->options & AR_SS) && obj->maddr != NULL) create_symtab_entry(bsdar, obj->maddr, obj->size); if (strlen(obj->name) > _MAXNAMELEN_SVR4) add_to_ar_str_table(bsdar, obj->name); bsdar->rela_off += _ARHDR_LEN + obj->size + obj->size % 2; } /* * Pad the symbol name string table. It is treated specially because * symbol name table should be padded by a '\0', not the common '\n' * for other members. The size of sn table includes the pad bit. */ if (bsdar->s_cnt != 0 && bsdar->s_sn_sz % 2 != 0) bsdar->s_sn[bsdar->s_sn_sz++] = '\0'; /* * Archive string table is padded by a "\n" as the normal members. * The difference is that the size of archive string table counts * in the pad bit, while normal members' size fileds do not. */ if (bsdar->as != NULL && bsdar->as_sz % 2 != 0) bsdar->as[bsdar->as_sz++] = '\n'; /* * If there is a symbol table, calculate the size of pseudo members, * convert previously stored relative offsets to absolute ones, and * then make them Big Endian. * * absolute_offset = htobe32(relative_offset + size_of_pseudo_members) */ if (bsdar->s_cnt != 0) { s_sz = (bsdar->s_cnt + 1) * sizeof(uint32_t) + bsdar->s_sn_sz; pm_sz = _ARMAG_LEN + (_ARHDR_LEN + s_sz); if (bsdar->as != NULL) pm_sz += _ARHDR_LEN + bsdar->as_sz; for (i = 0; (size_t)i < bsdar->s_cnt; i++) *(bsdar->s_so + i) = htobe32(*(bsdar->s_so + i) + pm_sz); } if ((a = archive_write_new()) == NULL) bsdar_errc(bsdar, EX_SOFTWARE, 0, "archive_write_new failed"); archive_write_set_format_ar_svr4(a); AC(archive_write_open_filename(a, bsdar->filename)); /* * write the archive symbol table, if there is one. * If options -s is explicitly specified or we are invoked * as ranlib, write the symbol table even if it is empty. */ if ((bsdar->s_cnt != 0 && !(bsdar->options & AR_SS)) || bsdar->options & AR_S) { entry = archive_entry_new(); if (entry == NULL) bsdar_errc(bsdar, EX_SOFTWARE, 0, "archive_entry_new failed"); archive_entry_copy_pathname(entry, "/"); if ((bsdar->options & AR_D) == 0) archive_entry_set_mtime(entry, time(NULL), 0); archive_entry_set_size(entry, (bsdar->s_cnt + 1) * sizeof(uint32_t) + bsdar->s_sn_sz); AC(archive_write_header(a, entry)); nr = htobe32(bsdar->s_cnt); write_data(bsdar, a, &nr, sizeof(uint32_t)); write_data(bsdar, a, bsdar->s_so, sizeof(uint32_t) * bsdar->s_cnt); write_data(bsdar, a, bsdar->s_sn, bsdar->s_sn_sz); archive_entry_free(entry); } /* write the archive string table, if any. */ if (bsdar->as != NULL) { entry = archive_entry_new(); if (entry == NULL) bsdar_errc(bsdar, EX_SOFTWARE, 0, "archive_entry_new failed"); archive_entry_copy_pathname(entry, "//"); archive_entry_set_size(entry, bsdar->as_sz); AC(archive_write_header(a, entry)); write_data(bsdar, a, bsdar->as, bsdar->as_sz); archive_entry_free(entry); } /* write normal members. */ TAILQ_FOREACH(obj, &bsdar->v_obj, objs) { entry = archive_entry_new(); if (entry == NULL) bsdar_errc(bsdar, EX_SOFTWARE, 0, "archive_entry_new failed"); archive_entry_copy_pathname(entry, obj->name); archive_entry_set_uid(entry, obj->uid); archive_entry_set_gid(entry, obj->gid); archive_entry_set_mode(entry, obj->md); archive_entry_set_size(entry, obj->size); archive_entry_set_mtime(entry, obj->mtime, 0); archive_entry_set_dev(entry, obj->dev); archive_entry_set_ino(entry, obj->ino); archive_entry_set_filetype(entry, AE_IFREG); AC(archive_write_header(a, entry)); write_data(bsdar, a, obj->maddr, obj->size); archive_entry_free(entry); } AC(archive_write_close(a)); AC(archive_write_free(a)); } /* * Extract global symbols from ELF binary members. */ static void create_symtab_entry(struct bsdar *bsdar, void *maddr, size_t size) { Elf *e; Elf_Scn *scn; GElf_Shdr shdr; GElf_Sym sym; Elf_Data *data; char *name; size_t n, shstrndx; int elferr, tabndx, len, i; if ((e = elf_memory(maddr, size)) == NULL) { bsdar_warnc(bsdar, 0, "elf_memory() failed: %s", elf_errmsg(-1)); return; } if (elf_kind(e) != ELF_K_ELF) { /* Silently ignore non-elf member. */ elf_end(e); return; } if (elf_getshstrndx(e, &shstrndx) == 0) { bsdar_warnc(bsdar, EX_SOFTWARE, 0, "elf_getshstrndx failed: %s", elf_errmsg(-1)); elf_end(e); return; } tabndx = -1; scn = NULL; while ((scn = elf_nextscn(e, scn)) != NULL) { if (gelf_getshdr(scn, &shdr) != &shdr) { bsdar_warnc(bsdar, 0, "elf_getshdr failed: %s", elf_errmsg(-1)); continue; } if ((name = elf_strptr(e, shstrndx, shdr.sh_name)) == NULL) { bsdar_warnc(bsdar, 0, "elf_strptr failed: %s", elf_errmsg(-1)); continue; } if (strcmp(name, ".strtab") == 0) { tabndx = elf_ndxscn(scn); break; } } elferr = elf_errno(); if (elferr != 0) bsdar_warnc(bsdar, 0, "elf_nextscn failed: %s", elf_errmsg(elferr)); if (tabndx == -1) { bsdar_warnc(bsdar, 0, "can't find .strtab section"); elf_end(e); return; } scn = NULL; while ((scn = elf_nextscn(e, scn)) != NULL) { if (gelf_getshdr(scn, &shdr) != &shdr) { bsdar_warnc(bsdar, EX_SOFTWARE, 0, "elf_getshdr failed: %s", elf_errmsg(-1)); continue; } if (shdr.sh_type != SHT_SYMTAB) continue; data = NULL; n = 0; while (n < shdr.sh_size && (data = elf_getdata(scn, data)) != NULL) { len = data->d_size / shdr.sh_entsize; for (i = 0; i < len; i++) { if (gelf_getsym(data, i, &sym) != &sym) { bsdar_warnc(bsdar, EX_SOFTWARE, 0, "gelf_getsym failed: %s", elf_errmsg(-1)); continue; } /* keep only global or weak symbols */ if (GELF_ST_BIND(sym.st_info) != STB_GLOBAL && GELF_ST_BIND(sym.st_info) != STB_WEAK) continue; /* keep only defined symbols */ if (sym.st_shndx == SHN_UNDEF) continue; if ((name = elf_strptr(e, tabndx, sym.st_name)) == NULL) { bsdar_warnc(bsdar, EX_SOFTWARE, 0, "elf_strptr failed: %s", elf_errmsg(-1)); continue; } add_to_ar_sym_table(bsdar, name); } } } elferr = elf_errno(); if (elferr != 0) bsdar_warnc(bsdar, EX_SOFTWARE, 0, "elf_nextscn failed: %s", elf_errmsg(elferr)); elf_end(e); } /* * Append to the archive string table buffer. */ static void add_to_ar_str_table(struct bsdar *bsdar, const char *name) { if (bsdar->as == NULL) { bsdar->as_cap = _INIT_AS_CAP; bsdar->as_sz = 0; if ((bsdar->as = malloc(bsdar->as_cap)) == NULL) bsdar_errc(bsdar, EX_SOFTWARE, errno, "malloc failed"); } /* * The space required for holding one member name in as table includes: * strlen(name) + (1 for '/') + (1 for '\n') + (possibly 1 for padding). */ while (bsdar->as_sz + strlen(name) + 3 > bsdar->as_cap) { bsdar->as_cap *= 2; bsdar->as = realloc(bsdar->as, bsdar->as_cap); if (bsdar->as == NULL) bsdar_errc(bsdar, EX_SOFTWARE, errno, "realloc failed"); } strncpy(&bsdar->as[bsdar->as_sz], name, strlen(name)); bsdar->as_sz += strlen(name); bsdar->as[bsdar->as_sz++] = '/'; bsdar->as[bsdar->as_sz++] = '\n'; } /* * Append to the archive symbol table buffer. */ static void add_to_ar_sym_table(struct bsdar *bsdar, const char *name) { if (bsdar->s_so == NULL) { if ((bsdar->s_so = malloc(_INIT_SYMOFF_CAP)) == NULL) bsdar_errc(bsdar, EX_SOFTWARE, errno, "malloc failed"); bsdar->s_so_cap = _INIT_SYMOFF_CAP; bsdar->s_cnt = 0; } if (bsdar->s_sn == NULL) { if ((bsdar->s_sn = malloc(_INIT_SYMNAME_CAP)) == NULL) bsdar_errc(bsdar, EX_SOFTWARE, errno, "malloc failed"); bsdar->s_sn_cap = _INIT_SYMNAME_CAP; bsdar->s_sn_sz = 0; } if (bsdar->s_cnt * sizeof(uint32_t) >= bsdar->s_so_cap) { bsdar->s_so_cap *= 2; bsdar->s_so = realloc(bsdar->s_so, bsdar->s_so_cap); if (bsdar->s_so == NULL) bsdar_errc(bsdar, EX_SOFTWARE, errno, "realloc failed"); } bsdar->s_so[bsdar->s_cnt] = bsdar->rela_off; bsdar->s_cnt++; /* * The space required for holding one symbol name in sn table includes: * strlen(name) + (1 for '\n') + (possibly 1 for padding). */ while (bsdar->s_sn_sz + strlen(name) + 2 > bsdar->s_sn_cap) { bsdar->s_sn_cap *= 2; bsdar->s_sn = realloc(bsdar->s_sn, bsdar->s_sn_cap); if (bsdar->s_sn == NULL) bsdar_errc(bsdar, EX_SOFTWARE, errno, "realloc failed"); } strncpy(&bsdar->s_sn[bsdar->s_sn_sz], name, strlen(name)); bsdar->s_sn_sz += strlen(name); bsdar->s_sn[bsdar->s_sn_sz++] = '\0'; } Index: projects/runtime-coverage/usr.bin/grep/util.c =================================================================== --- projects/runtime-coverage/usr.bin/grep/util.c (revision 321457) +++ projects/runtime-coverage/usr.bin/grep/util.c (revision 321458) @@ -1,678 +1,670 @@ /* $NetBSD: util.c,v 1.9 2011/02/27 17:33:37 joerg Exp $ */ /* $FreeBSD$ */ /* $OpenBSD: util.c,v 1.39 2010/07/02 22:18:03 tedu Exp $ */ /*- * Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav * Copyright (C) 2008-2010 Gabor Kovesdan * Copyright (C) 2017 Kyle Evans * 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 __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef WITHOUT_FASTMATCH #include "fastmatch.h" #endif #include "grep.h" static bool first_match = true; /* * Parsing context; used to hold things like matches made and * other useful bits */ struct parsec { regmatch_t matches[MAX_MATCHES]; /* Matches made */ struct str ln; /* Current line */ size_t lnstart; /* Position in line */ size_t matchidx; /* Latest match index */ int printed; /* Metadata printed? */ bool binary; /* Binary file? */ }; static int procline(struct parsec *pc); static void printline(struct parsec *pc, int sep); static void printline_metadata(struct str *line, int sep); bool file_matching(const char *fname) { char *fname_base, *fname_buf; bool ret; ret = finclude ? false : true; fname_buf = strdup(fname); if (fname_buf == NULL) err(2, "strdup"); fname_base = basename(fname_buf); for (unsigned int i = 0; i < fpatterns; ++i) { if (fnmatch(fpattern[i].pat, fname, 0) == 0 || fnmatch(fpattern[i].pat, fname_base, 0) == 0) { if (fpattern[i].mode == EXCL_PAT) { ret = false; break; } else ret = true; } } free(fname_buf); return (ret); } static inline bool dir_matching(const char *dname) { bool ret; ret = dinclude ? false : true; for (unsigned int i = 0; i < dpatterns; ++i) { if (dname != NULL && fnmatch(dpattern[i].pat, dname, 0) == 0) { if (dpattern[i].mode == EXCL_PAT) return (false); else ret = true; } } return (ret); } /* * Processes a directory when a recursive search is performed with * the -R option. Each appropriate file is passed to procfile(). */ int grep_tree(char **argv) { FTS *fts; FTSENT *p; int c, fts_flags; bool ok; const char *wd[] = { ".", NULL }; c = fts_flags = 0; switch(linkbehave) { case LINK_EXPLICIT: fts_flags = FTS_COMFOLLOW; break; case LINK_SKIP: fts_flags = FTS_PHYSICAL; break; default: fts_flags = FTS_LOGICAL; } fts_flags |= FTS_NOSTAT | FTS_NOCHDIR; fts = fts_open((argv[0] == NULL) ? __DECONST(char * const *, wd) : argv, fts_flags, NULL); if (fts == NULL) err(2, "fts_open"); while ((p = fts_read(fts)) != NULL) { switch (p->fts_info) { case FTS_DNR: /* FALLTHROUGH */ case FTS_ERR: file_err = true; if(!sflag) warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); break; case FTS_D: /* FALLTHROUGH */ case FTS_DP: if (dexclude || dinclude) if (!dir_matching(p->fts_name) || !dir_matching(p->fts_path)) fts_set(fts, p, FTS_SKIP); break; case FTS_DC: /* Print a warning for recursive directory loop */ warnx("warning: %s: recursive directory loop", p->fts_path); break; default: /* Check for file exclusion/inclusion */ ok = true; if (fexclude || finclude) ok &= file_matching(p->fts_path); if (ok) c += procfile(p->fts_path); break; } } fts_close(fts); return (c); } /* * Opens a file and processes it. Each file is processed line-by-line * passing the lines to procline(). */ int procfile(const char *fn) { struct parsec pc; long long tail; struct file *f; struct stat sb; struct str *ln; mode_t s; int c, last_outed, t; bool doctx, printmatch, same_file; if (strcmp(fn, "-") == 0) { fn = label != NULL ? label : getstr(1); f = grep_open(NULL); } else { if (!stat(fn, &sb)) { /* Check if we need to process the file */ s = sb.st_mode & S_IFMT; if (s == S_IFDIR && dirbehave == DIR_SKIP) return (0); if ((s == S_IFIFO || s == S_IFCHR || s == S_IFBLK || s == S_IFSOCK) && devbehave == DEV_SKIP) return (0); } f = grep_open(fn); } if (f == NULL) { file_err = true; if (!sflag) warn("%s", fn); return (0); } /* Convenience */ ln = &pc.ln; pc.ln.file = grep_malloc(strlen(fn) + 1); strcpy(pc.ln.file, fn); pc.ln.line_no = 0; pc.ln.len = 0; pc.ln.boff = 0; pc.ln.off = -1; pc.binary = f->binary; pc.printed = 0; tail = 0; last_outed = 0; same_file = false; doctx = false; printmatch = true; if ((pc.binary && binbehave == BINFILE_BIN) || cflag || qflag || lflag || Lflag) printmatch = false; if (printmatch && (Aflag != 0 || Bflag != 0)) doctx = true; mcount = mlimit; for (c = 0; c == 0 || !(lflag || qflag); ) { /* Reset per-line statistics */ pc.printed = 0; pc.matchidx = 0; pc.lnstart = 0; pc.ln.boff = 0; pc.ln.off += pc.ln.len + 1; if ((pc.ln.dat = grep_fgetln(f, &pc.ln.len)) == NULL || - pc.ln.len == 0) { - if (pc.ln.line_no == 0 && matchall) - /* - * An empty file with an empty pattern and the - * -w flag does not match - */ - exit(matchall && wflag ? 1 : 0); - else - break; - } + pc.ln.len == 0) + break; if (pc.ln.len > 0 && pc.ln.dat[pc.ln.len - 1] == fileeol) --pc.ln.len; pc.ln.line_no++; /* Return if we need to skip a binary file */ if (pc.binary && binbehave == BINFILE_SKIP) { grep_close(f); free(pc.ln.file); free(f); return (0); } if ((t = procline(&pc)) == 0) ++c; /* Deal with any -B context or context separators */ if (t == 0 && doctx) { if (!first_match && (!same_file || last_outed > 0)) printf("--\n"); if (Bflag > 0) printqueue(); tail = Aflag; } /* Print the matching line, but only if not quiet/binary */ if (t == 0 && printmatch) { printline(&pc, ':'); while (pc.matchidx >= MAX_MATCHES) { /* Reset matchidx and try again */ pc.matchidx = 0; if (procline(&pc) == 0) printline(&pc, ':'); else break; } first_match = false; same_file = true; last_outed = 0; } if (t != 0 && doctx) { /* Deal with any -A context */ if (tail > 0) { grep_printline(&pc.ln, '-'); tail--; if (Bflag > 0) clearqueue(); } else { /* * Enqueue non-matching lines for -B context. * If we're not actually doing -B context or if * the enqueue resulted in a line being rotated * out, then go ahead and increment last_outed * to signify a gap between context/match. */ if (Bflag == 0 || (Bflag > 0 && enqueue(ln))) ++last_outed; } } /* Count the matches if we have a match limit */ if (t == 0 && mflag) { --mcount; if (mflag && mcount <= 0) break; } } if (Bflag > 0) clearqueue(); grep_close(f); if (cflag) { if (!hflag) printf("%s:", pc.ln.file); printf("%u\n", c); } if (lflag && !qflag && c != 0) printf("%s%c", fn, nullflag ? 0 : '\n'); if (Lflag && !qflag && c == 0) printf("%s%c", fn, nullflag ? 0 : '\n'); if (c && !cflag && !lflag && !Lflag && binbehave == BINFILE_BIN && f->binary && !qflag) printf(getstr(8), fn); free(pc.ln.file); free(f); return (c); } #define iswword(x) (iswalnum((x)) || (x) == L'_') /* * Processes a line comparing it with the specified patterns. Each pattern * is looped to be compared along with the full string, saving each and every * match, which is necessary to colorize the output and to count the * matches. The matching lines are passed to printline() to display the * appropriate output. */ static int procline(struct parsec *pc) { regmatch_t pmatch, lastmatch, chkmatch; wchar_t wbegin, wend; size_t st, nst; unsigned int i; int c = 0, r = 0, lastmatches = 0, leflags = eflags; size_t startm = 0, matchidx; unsigned int retry; matchidx = pc->matchidx; /* Special case: empty pattern with -w flag, check first character */ if (matchall && wflag) { if (pc->ln.len == 0) return (0); wend = L' '; if (sscanf(&pc->ln.dat[0], "%lc", &wend) != 1 || iswword(wend)) return (1); else return (0); } else if (matchall) return (0); st = pc->lnstart; nst = 0; /* Initialize to avoid a false positive warning from GCC. */ lastmatch.rm_so = lastmatch.rm_eo = 0; /* Loop to process the whole line */ while (st <= pc->ln.len) { lastmatches = 0; startm = matchidx; retry = 0; if (st > 0 && pc->ln.dat[st - 1] != fileeol) leflags |= REG_NOTBOL; /* Loop to compare with all the patterns */ for (i = 0; i < patterns; i++) { pmatch.rm_so = st; pmatch.rm_eo = pc->ln.len; #ifndef WITHOUT_FASTMATCH if (fg_pattern[i].pattern) r = fastexec(&fg_pattern[i], pc->ln.dat, 1, &pmatch, leflags); else #endif r = regexec(&r_pattern[i], pc->ln.dat, 1, &pmatch, leflags); if (r != 0) continue; /* Check for full match */ if (xflag && (pmatch.rm_so != 0 || (size_t)pmatch.rm_eo != pc->ln.len)) continue; /* Check for whole word match */ #ifndef WITHOUT_FASTMATCH if (wflag || fg_pattern[i].word) { #else if (wflag) { #endif wbegin = wend = L' '; if (pmatch.rm_so != 0 && sscanf(&pc->ln.dat[pmatch.rm_so - 1], "%lc", &wbegin) != 1) r = REG_NOMATCH; else if ((size_t)pmatch.rm_eo != pc->ln.len && sscanf(&pc->ln.dat[pmatch.rm_eo], "%lc", &wend) != 1) r = REG_NOMATCH; else if (iswword(wbegin) || iswword(wend)) r = REG_NOMATCH; /* * If we're doing whole word matching and we * matched once, then we should try the pattern * again after advancing just past the start of * the earliest match. This allows the pattern * to match later on in the line and possibly * still match a whole word. */ if (r == REG_NOMATCH && (retry == pc->lnstart || pmatch.rm_so + 1 < retry)) retry = pmatch.rm_so + 1; if (r == REG_NOMATCH) continue; } lastmatches++; lastmatch = pmatch; if (matchidx == 0) c++; /* * Replace previous match if the new one is earlier * and/or longer. This will lead to some amount of * extra work if -o/--color are specified, but it's * worth it from a correctness point of view. */ if (matchidx > startm) { chkmatch = pc->matches[matchidx - 1]; if (pmatch.rm_so < chkmatch.rm_so || (pmatch.rm_so == chkmatch.rm_so && (pmatch.rm_eo - pmatch.rm_so) > (chkmatch.rm_eo - chkmatch.rm_so))) { pc->matches[matchidx - 1] = pmatch; nst = pmatch.rm_eo; } } else { /* Advance as normal if not */ pc->matches[matchidx++] = pmatch; nst = pmatch.rm_eo; } /* avoid excessive matching - skip further patterns */ if ((color == NULL && !oflag) || qflag || lflag || matchidx >= MAX_MATCHES) { pc->lnstart = nst; lastmatches = 0; break; } } /* * Advance to just past the start of the earliest match, try * again just in case we still have a chance to match later in * the string. */ if (lastmatches == 0 && retry > pc->lnstart) { st = retry; continue; } /* One pass if we are not recording matches */ if (!wflag && ((color == NULL && !oflag) || qflag || lflag || Lflag)) break; /* If we didn't have any matches or REG_NOSUB set */ if (lastmatches == 0 || (cflags & REG_NOSUB)) nst = pc->ln.len; if (lastmatches == 0) /* No matches */ break; else if (st == nst && lastmatch.rm_so == lastmatch.rm_eo) /* Zero-length match -- advance one more so we don't get stuck */ nst++; /* Advance st based on previous matches */ st = nst; pc->lnstart = st; } /* Reflect the new matchidx in the context */ pc->matchidx = matchidx; if (vflag) c = !c; return (c ? 0 : 1); } /* * Safe malloc() for internal use. */ void * grep_malloc(size_t size) { void *ptr; if ((ptr = malloc(size)) == NULL) err(2, "malloc"); return (ptr); } /* * Safe calloc() for internal use. */ void * grep_calloc(size_t nmemb, size_t size) { void *ptr; if ((ptr = calloc(nmemb, size)) == NULL) err(2, "calloc"); return (ptr); } /* * Safe realloc() for internal use. */ void * grep_realloc(void *ptr, size_t size) { if ((ptr = realloc(ptr, size)) == NULL) err(2, "realloc"); return (ptr); } /* * Safe strdup() for internal use. */ char * grep_strdup(const char *str) { char *ret; if ((ret = strdup(str)) == NULL) err(2, "strdup"); return (ret); } /* * Print an entire line as-is, there are no inline matches to consider. This is * used for printing context. */ void grep_printline(struct str *line, int sep) { printline_metadata(line, sep); fwrite(line->dat, line->len, 1, stdout); putchar(fileeol); } static void printline_metadata(struct str *line, int sep) { bool printsep; printsep = false; if (!hflag) { if (!nullflag) { fputs(line->file, stdout); printsep = true; } else { printf("%s", line->file); putchar(0); } } if (nflag) { if (printsep) putchar(sep); printf("%d", line->line_no); printsep = true; } if (bflag) { if (printsep) putchar(sep); printf("%lld", (long long)(line->off + line->boff)); printsep = true; } if (printsep) putchar(sep); } /* * Prints a matching line according to the command line options. */ static void printline(struct parsec *pc, int sep) { size_t a = 0; size_t i, matchidx; regmatch_t match; /* If matchall, everything matches but don't actually print for -o */ if (oflag && matchall) return; matchidx = pc->matchidx; /* --color and -o */ if ((oflag || color) && matchidx > 0) { /* Only print metadata once per line if --color */ if (!oflag && pc->printed == 0) printline_metadata(&pc->ln, sep); for (i = 0; i < matchidx; i++) { match = pc->matches[i]; /* Don't output zero length matches */ if (match.rm_so == match.rm_eo) continue; /* * Metadata is printed on a per-line basis, so every * match gets file metadata with the -o flag. */ if (oflag) { pc->ln.boff = match.rm_so; printline_metadata(&pc->ln, sep); } else fwrite(pc->ln.dat + a, match.rm_so - a, 1, stdout); if (color) fprintf(stdout, "\33[%sm\33[K", color); fwrite(pc->ln.dat + match.rm_so, match.rm_eo - match.rm_so, 1, stdout); if (color) fprintf(stdout, "\33[m\33[K"); a = match.rm_eo; if (oflag) putchar('\n'); } if (!oflag) { if (pc->ln.len - a > 0) fwrite(pc->ln.dat + a, pc->ln.len - a, 1, stdout); putchar('\n'); } } else grep_printline(&pc->ln, sep); pc->printed++; } Index: projects/runtime-coverage =================================================================== --- projects/runtime-coverage (revision 321457) +++ projects/runtime-coverage (revision 321458) Property changes on: projects/runtime-coverage ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head:r321432-321457