summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile11
-rw-r--r--Makefile.inc123
-rw-r--r--bin/csh/Makefile57
-rw-r--r--bin/dd/args.c90
-rw-r--r--bin/dd/dd.17
-rw-r--r--contrib/bsnmp/snmp_mibII/mibII.c12
-rw-r--r--contrib/elftoolchain/readelf/readelf.c35
-rw-r--r--etc/defaults/rc.conf13
-rwxr-xr-xetc/periodic/daily/800.scrub-zfs10
-rwxr-xr-xetc/rc.d/jail2
-rw-r--r--lib/libc/sys/connect.210
-rw-r--r--lib/libc/sys/semget.213
-rw-r--r--lib/libedit/editline.361
-rw-r--r--lib/libedit/el.c7
-rw-r--r--lib/libedit/hist.h6
-rw-r--r--lib/libedit/keymacro.h4
-rw-r--r--lib/libedit/search.c6
-rw-r--r--lib/libedit/tokenizer.c6
-rw-r--r--lib/libedit/tty.c7
-rw-r--r--lib/libmemstat/memstat_uma.c1
-rwxr-xr-xshare/examples/jails/jib367
-rwxr-xr-xshare/examples/jails/jng416
-rw-r--r--share/i18n/esdb/MISC/MISC.alias8
-rw-r--r--share/man/man4/bridge.44
-rw-r--r--share/man/man4/inet.426
-rw-r--r--share/man/man7/build.713
-rw-r--r--share/mk/bsd.README21
-rw-r--r--share/mk/bsd.incs.mk4
-rw-r--r--share/mk/bsd.links.mk8
-rw-r--r--share/mk/bsd.man.mk32
-rw-r--r--share/mk/bsd.nls.mk3
-rw-r--r--share/mk/bsd.subdir.mk4
-rw-r--r--share/mk/bsd.sys.mk6
-rw-r--r--share/mk/bsd.test.mk19
-rw-r--r--share/mk/suite.test.mk53
-rw-r--r--sys/amd64/amd64/uma_machdep.c1
-rw-r--r--sys/arm/allwinner/a20/a20_mp.c4
-rw-r--r--sys/arm/altera/socfpga/socfpga_mp.c4
-rw-r--r--sys/arm/amlogic/aml8726/aml8726_mp.c3
-rw-r--r--sys/arm/arm/cpufunc.c174
-rw-r--r--sys/arm/arm/cpufunc_asm_arm11x6.S6
-rw-r--r--sys/arm/arm/cpufunc_asm_arm9.S4
-rw-r--r--sys/arm/arm/cpufunc_asm_armv5_ec.S4
-rw-r--r--sys/arm/arm/cpufunc_asm_armv7.S10
-rw-r--r--sys/arm/arm/cpufunc_asm_fa526.S13
-rw-r--r--sys/arm/arm/cpufunc_asm_xscale.S19
-rw-r--r--sys/arm/arm/cpufunc_asm_xscale_c3.S20
-rw-r--r--sys/arm/arm/cpuinfo.c7
-rw-r--r--sys/arm/arm/db_interface.c10
-rw-r--r--sys/arm/arm/debug_monitor.c2
-rw-r--r--sys/arm/arm/devmap.c5
-rw-r--r--sys/arm/arm/dump_machdep.c3
-rw-r--r--sys/arm/arm/elf_machdep.c2
-rw-r--r--sys/arm/arm/elf_trampoline.c5
-rw-r--r--sys/arm/arm/fiq.c2
-rw-r--r--sys/arm/arm/fusu.S91
-rw-r--r--sys/arm/arm/genassym.c16
-rw-r--r--sys/arm/arm/identcpu.c4
-rw-r--r--sys/arm/arm/locore-v6.S4
-rw-r--r--sys/arm/arm/machdep.c16
-rw-r--r--sys/arm/arm/minidump_machdep.c7
-rw-r--r--sys/arm/arm/mp_machdep.c8
-rw-r--r--sys/arm/arm/pmap-v6.c142
-rw-r--r--sys/arm/arm/sys_machdep.c9
-rw-r--r--sys/arm/arm/trap-v6.c47
-rw-r--r--sys/arm/arm/trap.c9
-rw-r--r--sys/arm/arm/vm_machdep.c1
-rw-r--r--sys/arm/at91/at91_machdep.c4
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2836_mp.c4
-rw-r--r--sys/arm/cavium/cns11xx/econa_machdep.c4
-rw-r--r--sys/arm/conf/NOTES2
-rw-r--r--sys/arm/freescale/imx/imx6_mp.c3
-rw-r--r--sys/arm/include/cpu-v4.h186
-rw-r--r--sys/arm/include/cpu-v6.h71
-rw-r--r--sys/arm/include/cpu.h8
-rw-r--r--sys/arm/include/cpuconf.h14
-rw-r--r--sys/arm/include/cpufunc.h33
-rw-r--r--sys/arm/include/kdb.h6
-rw-r--r--sys/arm/include/pmap-v6.h6
-rw-r--r--sys/arm/include/vm.h10
-rw-r--r--sys/arm/mv/armada38x/pmsu.c5
-rw-r--r--sys/arm/mv/armadaxp/armadaxp_mp.c3
-rw-r--r--sys/arm/rockchip/rk30xx_mp.c4
-rw-r--r--sys/arm/samsung/exynos/exynos5_mp.c4
-rw-r--r--sys/arm/ti/omap4/omap4_mp.c5
-rw-r--r--sys/arm/xilinx/zy7_mp.c4
-rw-r--r--sys/arm/xscale/i80321/ep80219_machdep.c402
-rw-r--r--sys/arm/xscale/i80321/files.ep8021911
-rw-r--r--sys/arm/xscale/i80321/files.i8021911
-rw-r--r--sys/arm/xscale/i80321/files.i803219
-rw-r--r--sys/arm/xscale/i80321/files.iq312448
-rw-r--r--sys/arm/xscale/i80321/i80321.c250
-rw-r--r--sys/arm/xscale/i80321/i80321_aau.c292
-rw-r--r--sys/arm/xscale/i80321/i80321_dma.c351
-rw-r--r--sys/arm/xscale/i80321/i80321_intr.h165
-rw-r--r--sys/arm/xscale/i80321/i80321_mcu.c90
-rw-r--r--sys/arm/xscale/i80321/i80321_pci.c401
-rw-r--r--sys/arm/xscale/i80321/i80321_space.c209
-rw-r--r--sys/arm/xscale/i80321/iq31244_7seg.c390
-rw-r--r--sys/arm/xscale/i80321/iq31244_machdep.c416
-rw-r--r--sys/arm/xscale/i80321/iq80321.c394
-rw-r--r--sys/arm/xscale/i80321/iq80321reg.h111
-rw-r--r--sys/arm/xscale/i80321/iq80321var.h53
-rw-r--r--sys/arm/xscale/i80321/obio.c163
-rw-r--r--sys/arm/xscale/i80321/obiovar.h58
-rw-r--r--sys/arm/xscale/i80321/std.ep802197
-rw-r--r--sys/arm/xscale/i80321/std.i802195
-rw-r--r--sys/arm/xscale/i80321/std.i803215
-rw-r--r--sys/arm/xscale/i80321/std.iq312447
-rw-r--r--sys/arm/xscale/i80321/uart_bus_i80321.c76
-rw-r--r--sys/arm/xscale/i80321/uart_cpu_i80321.c67
-rw-r--r--sys/arm/xscale/i8134x/crb_machdep.c6
-rw-r--r--sys/arm/xscale/i8134x/files.i813424
-rw-r--r--sys/arm/xscale/i8134x/i80321_timer.c (renamed from sys/arm/xscale/i80321/i80321_timer.c)4
-rw-r--r--sys/arm/xscale/i8134x/i80321_wdog.c (renamed from sys/arm/xscale/i80321/i80321_wdog.c)4
-rw-r--r--sys/arm/xscale/i8134x/i80321reg.h (renamed from sys/arm/xscale/i80321/i80321reg.h)92
-rw-r--r--sys/arm/xscale/i8134x/i80321var.h (renamed from sys/arm/xscale/i80321/i80321var.h)0
-rw-r--r--sys/arm/xscale/ixp425/avila_machdep.c4
-rw-r--r--sys/arm/xscale/pxa/pxa_machdep.c4
-rw-r--r--sys/arm64/arm64/locore.S4
-rw-r--r--sys/arm64/arm64/trap.c4
-rw-r--r--sys/arm64/arm64/uma_machdep.c1
-rw-r--r--sys/arm64/arm64/vm_machdep.c1
-rw-r--r--sys/arm64/include/kdb.h2
-rw-r--r--sys/boot/common/load_elf.c2
-rw-r--r--sys/boot/efi/boot1/boot1.c560
-rw-r--r--sys/boot/efi/boot1/boot_module.h13
-rw-r--r--sys/boot/efi/boot1/ufs_module.c53
-rw-r--r--sys/boot/efi/boot1/zfs_module.c59
-rw-r--r--sys/boot/efi/include/efidevp.h13
-rw-r--r--sys/boot/efi/libefi/efinet.c4
-rw-r--r--sys/boot/zfs/zfs.c2
-rw-r--r--sys/cam/ata/ata_all.c60
-rw-r--r--sys/cddl/dev/fbt/arm/fbt_isa.c2
-rw-r--r--sys/compat/cloudabi/cloudabi_proc.c8
-rw-r--r--sys/compat/linux/linux_fork.c20
-rw-r--r--sys/conf/files.arm4
-rw-r--r--sys/conf/options1
-rw-r--r--sys/conf/options.arm2
-rw-r--r--sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c5
-rw-r--r--sys/dev/ata/ata-all.c100
-rw-r--r--sys/dev/cfi/cfi_core.c15
-rw-r--r--sys/dev/cxgb/cxgb_sge.c2
-rw-r--r--sys/dev/e1000/e1000_80003es2lan.c33
-rw-r--r--sys/dev/e1000/e1000_82540.c10
-rw-r--r--sys/dev/e1000/e1000_82541.c7
-rw-r--r--sys/dev/e1000/e1000_82542.c4
-rw-r--r--sys/dev/e1000/e1000_82543.c4
-rw-r--r--sys/dev/e1000/e1000_82571.h5
-rw-r--r--sys/dev/e1000/e1000_82575.c169
-rw-r--r--sys/dev/e1000/e1000_82575.h5
-rw-r--r--sys/dev/e1000/e1000_api.c8
-rw-r--r--sys/dev/e1000/e1000_defines.h11
-rw-r--r--sys/dev/e1000/e1000_hw.h8
-rw-r--r--sys/dev/e1000/e1000_i210.c30
-rw-r--r--sys/dev/e1000/e1000_ich8lan.c938
-rw-r--r--sys/dev/e1000/e1000_ich8lan.h32
-rw-r--r--sys/dev/e1000/e1000_mac.h2
-rw-r--r--sys/dev/e1000/e1000_mbx.c36
-rw-r--r--sys/dev/e1000/e1000_nvm.h2
-rw-r--r--sys/dev/e1000/e1000_osdep.h25
-rw-r--r--sys/dev/e1000/e1000_phy.c10
-rw-r--r--sys/dev/e1000/e1000_regs.h9
-rw-r--r--sys/dev/e1000/if_em.c166
-rw-r--r--sys/dev/e1000/if_em.h3
-rw-r--r--sys/dev/e1000/if_igb.c14
-rw-r--r--sys/dev/hwpmc/hwpmc_mod.c8
-rw-r--r--sys/dev/hyperv/include/hyperv.h33
-rw-r--r--sys/dev/hyperv/netvsc/hv_net_vsc.c48
-rw-r--r--sys/dev/hyperv/netvsc/hv_net_vsc.h10
-rw-r--r--sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c693
-rw-r--r--sys/dev/hyperv/netvsc/hv_rndis_filter.c24
-rw-r--r--sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c13
-rw-r--r--sys/dev/hyperv/utilities/hv_kvp.c35
-rw-r--r--sys/dev/hyperv/utilities/hv_util.c58
-rw-r--r--sys/dev/hyperv/vmbus/hv_channel.c4
-rw-r--r--sys/dev/hyperv/vmbus/hv_channel_mgmt.c231
-rw-r--r--sys/dev/hyperv/vmbus/hv_connection.c79
-rw-r--r--sys/dev/hyperv/vmbus/hv_hv.c6
-rw-r--r--sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c36
-rw-r--r--sys/dev/hyperv/vmbus/hv_vmbus_priv.h9
-rw-r--r--sys/dev/ixgbe/if_ix.c18
-rw-r--r--sys/dev/mps/mps.c8
-rw-r--r--sys/dev/mps/mps_mapping.c59
-rw-r--r--sys/dev/mps/mpsvar.h2
-rw-r--r--sys/fs/cd9660/cd9660_vfsops.c3
-rw-r--r--sys/fs/ext2fs/ext2_inode_cnv.c12
-rw-r--r--sys/fs/msdosfs/msdosfs_vnops.c4
-rw-r--r--sys/kern/imgact_elf.c21
-rw-r--r--sys/kern/init_main.c7
-rw-r--r--sys/kern/kern_fork.c184
-rw-r--r--sys/kern/kern_kthread.c8
-rw-r--r--sys/kern/kern_malloc.c1
-rw-r--r--sys/kern/kern_mbuf.c93
-rw-r--r--sys/kern/kern_proc.c19
-rw-r--r--sys/kern/kern_racct.c3
-rw-r--r--sys/kern/sysv_sem.c10
-rw-r--r--sys/kern/vfs_aio.c644
-rw-r--r--sys/kern/vfs_bio.c2
-rw-r--r--sys/kern/vfs_mount.c34
-rw-r--r--sys/kern/vfs_syscalls.c3
-rw-r--r--sys/mips/mips/uma_machdep.c1
-rw-r--r--sys/mips/mips/vm_machdep.c1
-rw-r--r--sys/powerpc/fpu/fpu_emu.c42
-rw-r--r--sys/powerpc/fpu/fpu_explode.c6
-rw-r--r--sys/powerpc/powerpc/uma_machdep.c1
-rw-r--r--sys/riscv/include/asm.h4
-rw-r--r--sys/riscv/include/pcpu.h7
-rw-r--r--sys/riscv/riscv/exception.S21
-rw-r--r--sys/riscv/riscv/genassym.c1
-rw-r--r--sys/riscv/riscv/machdep.c11
-rw-r--r--sys/riscv/riscv/swtch.S37
-rw-r--r--sys/riscv/riscv/uma_machdep.c1
-rw-r--r--sys/riscv/riscv/vm_machdep.c3
-rw-r--r--sys/sparc64/sparc64/vm_machdep.c1
-rw-r--r--sys/sys/ata.h3
-rw-r--r--sys/sys/event.h2
-rw-r--r--sys/sys/proc.h13
-rw-r--r--sys/sys/socketvar.h2
-rw-r--r--sys/vm/memguard.c1
-rw-r--r--sys/vm/sg_pager.c3
-rw-r--r--sys/vm/uma.h2
-rw-r--r--sys/vm/uma_core.c112
-rw-r--r--sys/vm/uma_dbg.c98
-rw-r--r--sys/vm/uma_dbg.h3
-rw-r--r--sys/vm/uma_int.h2
-rw-r--r--sys/vm/vm_page.c1
-rw-r--r--tests/sys/acl/Makefile8
-rw-r--r--tools/regression/sysvsem/semtest.c9
-rw-r--r--tools/tools/ath/athaggrstats/main.c2
-rw-r--r--tools/tools/ath/athdebug/athdebug.c4
-rw-r--r--tools/tools/ath/athradar/athradar.c4
-rw-r--r--tools/tools/ath/athratestats/main.c2
-rw-r--r--tools/tools/ath/athregs/dumpregs.c4
-rw-r--r--tools/tools/ath/athspectral/athspectral.c4
-rw-r--r--tools/tools/ath/athstats/main.c2
-rwxr-xr-xtools/tools/nanobsd/defaults.sh46
-rw-r--r--tools/tools/nanobsd/embedded/common233
-rw-r--r--tools/tools/nanobsd/embedded/i386.cfg34
-rw-r--r--usr.sbin/bsdconfig/share/common.subr9
-rw-r--r--usr.sbin/bsdconfig/share/strings.subr173
-rw-r--r--usr.sbin/ctld/Makefile7
-rw-r--r--usr.sbin/ctld/ctld.c112
-rw-r--r--usr.sbin/ctld/ctld.h4
-rw-r--r--usr.sbin/ctld/parse.y93
-rw-r--r--usr.sbin/ctld/uclparse.c900
-rw-r--r--usr.sbin/freebsd-update/freebsd-update.sh2
247 files changed, 6234 insertions, 7149 deletions
diff --git a/Makefile b/Makefile
index 9e200a3..e56a7a7 100644
--- a/Makefile
+++ b/Makefile
@@ -21,6 +21,7 @@
# 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.
@@ -112,8 +113,8 @@
.else
TGTS= all all-man buildenv buildenvvars buildkernel buildworld \
- check-old check-old-dirs check-old-files check-old-libs \
- checkdpadd clean cleandepend cleandir cleanworld \
+ 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 \
@@ -121,7 +122,7 @@ TGTS= all all-man buildenv buildenvvars buildkernel buildworld \
installkernel.debug packagekernel packageworld \
reinstallkernel reinstallkernel.debug \
installworld kernel-toolchain libraries lint maninstall \
- obj objlink regress rerelease showconfig tags toolchain update \
+ obj objlink rerelease showconfig tags toolchain update \
_worldtmp _legacy _bootstrap-tools _cleanobj _obj \
_build-tools _cross-tools _includes _libraries _depend \
build32 builddtb distribute32 install32 xdev xdev-build xdev-install \
@@ -330,6 +331,10 @@ bmake: .PHONY
${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:
diff --git a/Makefile.inc1 b/Makefile.inc1
index 0030917..99f9798 100644
--- a/Makefile.inc1
+++ b/Makefile.inc1
@@ -37,6 +37,7 @@
# 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)
#
@@ -1121,16 +1122,14 @@ redistribute: .MAKE .PHONY
DISTRIBUTION=lib32
.endif
-distrib-dirs: .MAKE .PHONY
- ${_+_}cd ${.CURDIR}/etc; ${CROSSENV} PATH=${TMPPATH} ${MAKE} \
- ${IMAKE_INSTALL} ${IMAKE_MTREE} METALOG=${METALOG} ${.TARGET}
-
-distribution: .MAKE .PHONY
+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} installconfig
+.endif
#
# buildkernel and installkernel
@@ -1475,6 +1474,20 @@ signpackages: _pkgbootstrap
@pkg -o ABI_FILE=${WSTAGEDIR}/bin/sh repo ${REPODIR}/$$(pkg -o ABI_FILE=${WSTAGEDIR}/bin/sh config ABI) ${PKGSIGNKEY}
#
+#
+# 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
+ ${_+_}${LOCALBASE}/bin/kyua test -k ${TESTSBASE}/Kyuafile
+
+#
+#
# doxygen
#
# Build the API documentation with doxygen
diff --git a/bin/csh/Makefile b/bin/csh/Makefile
index 51ef3dd..deb6347 100644
--- a/bin/csh/Makefile
+++ b/bin/csh/Makefile
@@ -51,41 +51,40 @@ FILESDIR= ${SHAREDIR}/examples/tcsh
FILES= complete.tcsh csh-mode.el
.endif
-CATALOGS= et:et_EE.ISO8859-15 \
- finnish:fi_FI.ISO8859-1 \
- french:fr_FR.ISO8859-1 \
- german:de_DE.ISO8859-1 \
- greek:el_GR.ISO8859-7 \
- italian:it_IT.ISO8859-1 \
- ja:ja_JP.eucJP \
- russian:ru_RU.KOI8-R \
- spanish:es_ES.ISO8859-1 \
- ukrainian:uk_UA.KOI8-U
-
-NLSLINKS_fi_FI.ISO8859-1= fi_FI.ISO8859-15
-NLSLINKS_fr_FR.ISO8859-1= fr_BE.ISO8859-1 fr_BE.ISO8859-15 \
- fr_CA.ISO8859-1 fr_CA.ISO8859-15 fr_CH.ISO8859-1 \
- fr_CH.ISO8859-15 fr_FR.ISO8859-15
-NLSLINKS_de_DE.ISO8859-1= de_AT.ISO8859-1 de_AT.ISO8859-15 de_CH.ISO8859-1 \
- de_CH.ISO8859-15 de_DE.ISO8859-15
-NLSLINKS_it_IT.ISO8859-1= it_CH.ISO8859-1 it_CH.ISO8859-15 it_IT.ISO8859-15
-NLSLINKS_es_ES.ISO8859-1= es_ES.ISO8859-15
+CATALOGS= et:et_EE.UTF-8 \
+ finnish:fi_FI.UTF-8 \
+ french:fr_FR.UTF-8 \
+ german:de_DE.UTF-8 \
+ greek:el_GR.UTF-8 \
+ italian:it_IT.UTF-8 \
+ ja:ja_JP.UTF-8 \
+ russian:ru_RU.UTF-8 \
+ spanish:es_ES.UTF-8 \
+ ukrainian:uk_UA.UTF-8
+
+NLSLINKS_de_DE.UTF-8 = de_AT.UTF-8 de_CH.UTF-8
+NLSLINKS_fr_FR.UTF-8 = fr_BE.UTF-8 fr_CA.UTF-8 fr_CH.UTF-8
+NLSLINKS_it_IT.UTF-8 = it_CH.UTF-8
.if ${MK_NLS_CATALOGS} == "no" || defined(RESCUE)
CFLAGS+= -DNO_NLS_CATALOGS
.else
CFLAGS+= -DHAVE_ICONV
.if ${MK_ICONV} != "no"
-NLSLINKS_de_DE.ISO8859-1 += de_AT.UTF-8 de_CH.UTF-8 de_DE.UTF-8
-NLSLINKS_el_GR.ISO8859-7 = el_GR.UTF-8
-NLSLINKS_es_ES.ISO8859-1 += es_ES.UTF-8
-NLSLINKS_et_EE.ISO8859-15 = et_EE.UTF-8
-NLSLINKS_fi_FI.ISO8859-1 += fi_FI.UTF-8
-NLSLINKS_fr_FR.ISO8859-1 += fr_BE.UTF-8 fr_CA.UTF-8 fr_CH.UTF-8 fr_FR.UTF-8
-NLSLINKS_it_IT.ISO8859-1 += it_CH.UTF-8 it_IT.UTF-8
-NLSLINKS_ja_JP.eucJP = ja_JP.SJIS ja_JP.UTF-8
-NLSLINKS_ru_RU.KOI8-R = ru_RU.CP1251 ru_RU.CP866 ru_RU.ISO8859-5 ru_RU.UTF-8
-NLSLINKS_uk_UA.KOI8-U = uk_UA.ISO8859-5 uk_UA.UTF-8
+NLSLINKS_de_DE.UTF-8 += de_AT.ISO8859-1 de_AT.ISO8859-15 de_CH.ISO8859-1 \
+ de_CH.ISO8859-15 de_DE.ISO8859-1 de_DE.ISO8859-15
+NLSLINKS_el_GR.UTF-8 = el_GR.ISO8859-7
+NLSLINKS_es_ES.UTF-8 = es_ES.ISO8859-1 es_ES.ISO8859-15
+NLSLINKS_et_EE.UTF-8 = et_EE.ISO8859-15
+NLSLINKS_fi_FI.UTF-8 = fi_FI.ISO8859-1 fi_FI.ISO8859-15
+NLSLINKS_fr_FR.UTF-8 += fr_BE.ISO8859-1 fr_BE.ISO8859-15 \
+ fr_CA.ISO8859-1 fr_CA.ISO8859-15 fr_CH.ISO8859-1 \
+ fr_CH.ISO8859-15 fr_FR.ISO8859-1 fr_FR.ISO8859-15
+NLSLINKS_it_IT.UTF-8 += it_CH.ISO8859-1 it_CH.ISO8859-15 it_IT.ISO8859-1 \
+ it_IT.ISO8859-15
+NLSLINKS_ja_JP.UTF-8 = ja_JP.SJIS ja_JP.eucJP
+NLSLINKS_ru_RU.UTF-8 = ru_RU.CP1251 ru_RU.CP866 ru_RU.ISO8859-5 ru_RU.KOI8-R
+NLSLINKS_uk_UA.UTF-8 = uk_UA.ISO8859-5 uk_UA.KOI8-U
.else
# Above links can be installed from ports/shells/tcsh_nls
diff --git a/bin/dd/args.c b/bin/dd/args.c
index 2f197f8..1cbf3b3 100644
--- a/bin/dd/args.c
+++ b/bin/dd/args.c
@@ -360,6 +360,46 @@ c_conv(const void *a, const void *b)
((const struct conv *)b)->name));
}
+static uintmax_t
+postfix_to_mult(const char expr)
+{
+ uintmax_t mult;
+
+ mult = 0;
+ switch (expr) {
+ case 'B':
+ case 'b':
+ mult = 512;
+ break;
+ case 'K':
+ case 'k':
+ mult = 1 << 10;
+ break;
+ case 'M':
+ case 'm':
+ mult = 1 << 20;
+ break;
+ case 'G':
+ case 'g':
+ mult = 1 << 30;
+ break;
+ case 'T':
+ case 't':
+ mult = (uintmax_t)1 << 40;
+ break;
+ case 'P':
+ case 'p':
+ mult = (uintmax_t)1 << 50;
+ break;
+ case 'W':
+ case 'w':
+ mult = sizeof(int);
+ break;
+ }
+
+ return (mult);
+}
+
/*
* Convert an expression of the following forms to a uintmax_t.
* 1) A positive decimal number.
@@ -386,31 +426,7 @@ get_num(const char *val)
if (expr == val) /* No valid digits. */
errx(1, "%s: illegal numeric value", oper);
- mult = 0;
- switch (*expr) {
- case 'B':
- case 'b':
- mult = 512;
- break;
- case 'K':
- case 'k':
- mult = 1 << 10;
- break;
- case 'M':
- case 'm':
- mult = 1 << 20;
- break;
- case 'G':
- case 'g':
- mult = 1 << 30;
- break;
- case 'W':
- case 'w':
- mult = sizeof(int);
- break;
- default:
- ;
- }
+ mult = postfix_to_mult(*expr);
if (mult != 0) {
prevnum = num;
@@ -460,29 +476,7 @@ get_off_t(const char *val)
if (expr == val) /* No valid digits. */
errx(1, "%s: illegal numeric value", oper);
- mult = 0;
- switch (*expr) {
- case 'B':
- case 'b':
- mult = 512;
- break;
- case 'K':
- case 'k':
- mult = 1 << 10;
- break;
- case 'M':
- case 'm':
- mult = 1 << 20;
- break;
- case 'G':
- case 'g':
- mult = 1 << 30;
- break;
- case 'W':
- case 'w':
- mult = sizeof(int);
- break;
- }
+ mult = postfix_to_mult(*expr);
if (mult != 0) {
prevnum = num;
diff --git a/bin/dd/dd.1 b/bin/dd/dd.1
index 0908642..4047cdc 100644
--- a/bin/dd/dd.1
+++ b/bin/dd/dd.1
@@ -32,7 +32,7 @@
.\" @(#)dd.1 8.2 (Berkeley) 1/13/94
.\" $FreeBSD$
.\"
-.Dd August 28, 2014
+.Dd February 4, 2016
.Dt DD 1
.Os
.Sh NAME
@@ -332,10 +332,13 @@ If the number ends with a
.Dq Li k ,
.Dq Li m ,
.Dq Li g ,
+.Dq Li t ,
+.Dq Li p ,
or
.Dq Li w ,
the
-number is multiplied by 512, 1024 (1K), 1048576 (1M), 1073741824 (1G)
+number is multiplied by 512, 1024 (1K), 1048576 (1M), 1073741824 (1G),
+1099511627776 (1T), 1125899906842624 (1P)
or the number of bytes in an integer, respectively.
Two or more numbers may be separated by an
.Dq Li x
diff --git a/contrib/bsnmp/snmp_mibII/mibII.c b/contrib/bsnmp/snmp_mibII/mibII.c
index b62ee66..9079d1d 100644
--- a/contrib/bsnmp/snmp_mibII/mibII.c
+++ b/contrib/bsnmp/snmp_mibII/mibII.c
@@ -982,7 +982,7 @@ handle_rtmsg(struct rt_msghdr *rtm)
{
struct sockaddr *addrs[RTAX_MAX];
struct if_msghdr *ifm;
- struct ifa_msghdr ifam;
+ struct ifa_msghdr ifam, *ifamp;
struct ifma_msghdr *ifmam;
#ifdef RTM_IFANNOUNCE
struct if_announcemsghdr *ifan;
@@ -1002,8 +1002,9 @@ handle_rtmsg(struct rt_msghdr *rtm)
switch (rtm->rtm_type) {
case RTM_NEWADDR:
- memcpy(&ifam, rtm, sizeof(ifam));
- mib_extract_addrs(ifam.ifam_addrs, (u_char *)(&ifam + 1), addrs);
+ ifamp = (struct ifa_msghdr *)rtm;
+ memcpy(&ifam, ifamp, sizeof(ifam));
+ mib_extract_addrs(ifam.ifam_addrs, (u_char *)(ifamp + 1), addrs);
if (addrs[RTAX_IFA] == NULL || addrs[RTAX_NETMASK] == NULL)
break;
@@ -1029,8 +1030,9 @@ handle_rtmsg(struct rt_msghdr *rtm)
break;
case RTM_DELADDR:
- memcpy(&ifam, rtm, sizeof(ifam));
- mib_extract_addrs(ifam.ifam_addrs, (u_char *)(&ifam + 1), addrs);
+ ifamp = (struct ifa_msghdr *)rtm;
+ memcpy(&ifam, ifamp, sizeof(ifam));
+ mib_extract_addrs(ifam.ifam_addrs, (u_char *)(ifamp + 1), addrs);
if (addrs[RTAX_IFA] == NULL)
break;
diff --git a/contrib/elftoolchain/readelf/readelf.c b/contrib/elftoolchain/readelf/readelf.c
index 6902024..a017023 100644
--- a/contrib/elftoolchain/readelf/readelf.c
+++ b/contrib/elftoolchain/readelf/readelf.c
@@ -1053,8 +1053,9 @@ static struct {
static const char *
r_type(unsigned int mach, unsigned int type)
{
+ static char s_type[32];
+
switch(mach) {
- case EM_NONE: return "";
case EM_386:
case EM_IAMCU:
switch(type) {
@@ -1089,8 +1090,8 @@ r_type(unsigned int mach, unsigned int type)
case 35: return "R_386_TLS_DTPMOD32";
case 36: return "R_386_TLS_DTPOFF32";
case 37: return "R_386_TLS_TPOFF32";
- default: return "";
}
+ break;
case EM_AARCH64:
switch(type) {
case 0: return "R_AARCH64_NONE";
@@ -1145,6 +1146,16 @@ r_type(unsigned int mach, unsigned int type)
case 311: return "R_AARCH64_ADR_GOT_PAGE";
case 312: return "R_AARCH64_LD64_GOT_LO12_NC";
case 313: return "R_AARCH64_LD64_GOTPAGE_LO15";
+ case 560: return "R_AARCH64_TLSDESC_LD_PREL19";
+ case 561: return "R_AARCH64_TLSDESC_ADR_PREL21";
+ case 562: return "R_AARCH64_TLSDESC_ADR_PAGE21";
+ case 563: return "R_AARCH64_TLSDESC_LD64_LO12";
+ case 564: return "R_AARCH64_TLSDESC_ADD_LO12";
+ case 565: return "R_AARCH64_TLSDESC_OFF_G1";
+ case 566: return "R_AARCH64_TLSDESC_OFF_G0_NC";
+ case 567: return "R_AARCH64_TLSDESC_LDR";
+ case 568: return "R_AARCH64_TLSDESC_ADD";
+ case 569: return "R_AARCH64_TLSDESC_CALL";
case 1024: return "R_AARCH64_COPY";
case 1025: return "R_AARCH64_GLOB_DAT";
case 1026: return "R_AARCH64_JUMP_SLOT";
@@ -1154,8 +1165,8 @@ r_type(unsigned int mach, unsigned int type)
case 1030: return "R_AARCH64_TLS_TPREL64";
case 1031: return "R_AARCH64_TLSDESC";
case 1032: return "R_AARCH64_IRELATIVE";
- default: return "";
}
+ break;
case EM_ARM:
switch(type) {
case 0: return "R_ARM_NONE";
@@ -1206,8 +1217,8 @@ r_type(unsigned int mach, unsigned int type)
case 253: return "R_ARM_RABS32";
case 254: return "R_ARM_RPC24";
case 255: return "R_ARM_RBASE";
- default: return "";
}
+ break;
case EM_IA_64:
switch(type) {
case 0: return "R_IA_64_NONE";
@@ -1290,8 +1301,8 @@ r_type(unsigned int mach, unsigned int type)
case 182: return "R_IA_64_DTPREL64MSB";
case 183: return "R_IA_64_DTPREL64LSB";
case 186: return "R_IA_64_LTOFF_DTPREL22";
- default: return "";
}
+ break;
case EM_MIPS:
switch(type) {
case 0: return "R_MIPS_NONE";
@@ -1324,9 +1335,8 @@ r_type(unsigned int mach, unsigned int type)
case 48: return "R_MIPS_TLS_TPREL64";
case 49: return "R_MIPS_TLS_TPREL_HI16";
case 50: return "R_MIPS_TLS_TPREL_LO16";
-
- default: return "";
}
+ break;
case EM_PPC:
switch(type) {
case 0: return "R_PPC_NONE";
@@ -1406,8 +1416,8 @@ r_type(unsigned int mach, unsigned int type)
case 114: return "R_PPC_EMB_RELST_HA";
case 115: return "R_PPC_EMB_BIT_FLD";
case 116: return "R_PPC_EMB_RELSDA";
- default: return "";
}
+ break;
case EM_RISCV:
switch(type) {
case 0: return "R_RISCV_NONE";
@@ -1453,6 +1463,7 @@ r_type(unsigned int mach, unsigned int type)
case 44: return "R_RISCV_RVC_BRANCH";
case 45: return "R_RISCV_RVC_JUMP";
}
+ break;
case EM_SPARC:
case EM_SPARCV9:
switch(type) {
@@ -1536,8 +1547,8 @@ r_type(unsigned int mach, unsigned int type)
case 77: return "R_SPARC_TLS_DTPOFF64";
case 78: return "R_SPARC_TLS_TPOFF32";
case 79: return "R_SPARC_TLS_TPOFF64";
- default: return "";
}
+ break;
case EM_X86_64:
switch(type) {
case 0: return "R_X86_64_NONE";
@@ -1578,10 +1589,12 @@ r_type(unsigned int mach, unsigned int type)
case 35: return "R_X86_64_TLSDESC_CALL";
case 36: return "R_X86_64_TLSDESC";
case 37: return "R_X86_64_IRELATIVE";
- default: return "";
}
- default: return "";
+ break;
}
+
+ snprintf(s_type, sizeof(s_type), "<unknown: %#x>", type);
+ return (s_type);
}
static const char *
diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf
index a674acb..69b6d0f 100644
--- a/etc/defaults/rc.conf
+++ b/etc/defaults/rc.conf
@@ -716,5 +716,18 @@ if [ -z "${source_rc_confs_defined}" ]; then
;;
esac
done
+ # Re-do process to pick up [possibly] redefined $rc_conf_files
+ for i in ${rc_conf_files}; do
+ case ${sourced_files} in
+ *:$i:*)
+ ;;
+ *)
+ sourced_files="${sourced_files}:$i:"
+ if [ -r $i ]; then
+ . $i
+ fi
+ ;;
+ esac
+ done
}
fi
diff --git a/etc/periodic/daily/800.scrub-zfs b/etc/periodic/daily/800.scrub-zfs
index 359be13..64eac99 100755
--- a/etc/periodic/daily/800.scrub-zfs
+++ b/etc/periodic/daily/800.scrub-zfs
@@ -63,6 +63,11 @@ case "$daily_scrub_zfs_enable" in
_last_scrub=$(zpool history ${pool} | \
sed -ne '2s/ .*$//p')
fi
+ if [ -z "${_last_scrub}" ]; then
+ echo " skipping scrubbing of pool '${pool}':"
+ echo " can't get last scrubbing date"
+ continue
+ fi
# Now minus last scrub (both in seconds) converted to days.
_scrub_diff=$(expr -e \( $(date +%s) - \
@@ -73,11 +78,14 @@ case "$daily_scrub_zfs_enable" in
continue
fi
- _status="$(zpool status ${pool} | grep scrub:)"
+ _status="$(zpool status ${pool} | grep scan:)"
case "${_status}" in
*"scrub in progress"*)
echo " scrubbing of pool '${pool}' already in progress, skipping:"
;;
+ *"resilver in progress"*)
+ echo " resilvering of pool '${pool}' is in progress, skipping:"
+ ;;
*"none requested"*)
echo " starting first scrub (since reboot) of pool '${pool}':"
zpool scrub ${pool}
diff --git a/etc/rc.d/jail b/etc/rc.d/jail
index fa0bc46..b33f1b9 100755
--- a/etc/rc.d/jail
+++ b/etc/rc.d/jail
@@ -563,7 +563,7 @@ jail_warn()
# To relieve confusion, show a warning message.
case $_confwarn in
1) warn "Per-jail configuration via jail_* variables " \
- "is obsolete. Please consider to migrate to $jail_conf."
+ "is obsolete. Please consider migrating to $jail_conf."
;;
esac
}
diff --git a/lib/libc/sys/connect.2 b/lib/libc/sys/connect.2
index e3e5783..80f4407 100644
--- a/lib/libc/sys/connect.2
+++ b/lib/libc/sys/connect.2
@@ -28,7 +28,7 @@
.\" @(#)connect.2 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
-.Dd September 29, 2014
+.Dd February 4, 2016
.Dt CONNECT 2
.Os
.Sh NAME
@@ -58,6 +58,14 @@ another socket.
The other socket is specified by
.Fa name ,
which is an address in the communications space of the socket.
+.Fa namelen
+indicates the amount of space pointed to by
+.Fa name ,
+in bytes; the
+.Fa sa_len
+member of
+.Fa name
+is ignored.
Each communications space interprets the
.Fa name
argument in its own way.
diff --git a/lib/libc/sys/semget.2 b/lib/libc/sys/semget.2
index 945044d..debcf11 100644
--- a/lib/libc/sys/semget.2
+++ b/lib/libc/sys/semget.2
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd September 12, 1995
+.Dd February 7, 2016
.Dt SEMGET 2
.Os
.Sh NAME
@@ -132,6 +132,17 @@ already exists.
.It Bq Er EINVAL
The number of semaphores requested exceeds the system imposed maximum
per set.
+.It Bq Er EINVAL
+A semaphore set corresponding to
+.Fa key
+already exists and contains fewer semaphores than
+.Fa nsems .
+.It Bq Er EINVAL
+A semaphore set corresponding to
+.Fa key
+does not exist and
+.Fa nsems
+is 0 or negative.
.It Bq Er ENOSPC
Insufficiently many semaphores are available.
.It Bq Er ENOSPC
diff --git a/lib/libedit/editline.3 b/lib/libedit/editline.3
index 1e0ff5d..05ee76e 100644
--- a/lib/libedit/editline.3
+++ b/lib/libedit/editline.3
@@ -1,4 +1,4 @@
-.\" $NetBSD: editline.3,v 1.84 2014/12/25 13:39:41 wiz Exp $
+.\" $NetBSD: editline.3,v 1.85 2015/11/03 21:36:59 christos Exp $
.\"
.\" Copyright (c) 1997-2014 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -28,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd December 25, 2014
+.Dd November 3, 2015
.Dt EDITLINE 3
.Os
.Sh NAME
@@ -191,7 +191,7 @@ counterparts.
The following functions are available:
.Bl -tag -width 4n
.It Fn el_init
-Initialise the line editor, and return a data structure
+Initialize the line editor, and return a data structure
to be used by all other line editing functions, or
.Dv NULL
on failure.
@@ -521,61 +521,68 @@ are supported, along with actual type of
.Fa result :
.Bl -tag -width 4n
.It Dv EL_PROMPT , Fa "char *(*f)(EditLine *)" , Fa "char *c"
-Return a pointer to the function that displays the prompt in
+Set
.Fa f .
+to a pointer to the function that displays the prompt.
If
.Fa c
is not
.Dv NULL ,
-return the start/stop literal prompt character in it.
+set it to the start/stop literal prompt character.
.It Dv EL_RPROMPT , Fa "char *(*f)(EditLine *)" , Fa "char *c"
-Return a pointer to the function that displays the prompt in
+Set
.Fa f .
+to a pointer to the function that displays the prompt.
If
.Fa c
is not
.Dv NULL ,
-return the start/stop literal prompt character in it.
-.It Dv EL_EDITOR , Fa "const char **"
-Return the name of the editor, which will be one of
+set it to the start/stop literal prompt character.
+.It Dv EL_EDITOR , Fa "const char **n"
+Set the name of the editor in
+.Fa n ,
+which will be one of
.Dq emacs
or
.Dq vi .
.It Dv EL_GETTC , Fa "const char *name" , Fa "void *value"
-Return non-zero if
+If
.Fa name
is a valid
.Xr termcap 5
-capability
-and set
+capability set
.Fa value
to the current value of that capability.
-.It Dv EL_SIGNAL , Fa "int *"
-Return non-zero if
+.It Dv EL_SIGNAL , Fa "int *s"
+Set
+.Fa s
+to non zero if
.Nm
has installed private signal handlers (see
.Fn el_get
above).
-.It Dv EL_EDITMODE , Fa "int *"
-Return non-zero if editing is enabled.
+.It Dv EL_EDITMODE , Fa "int *c"
+Set
+.Fa c
+to non-zero if editing is enabled.
.It Dv EL_GETCFN , Fa "int (**f)(EditLine *, char *)"
Return a pointer to the function that read characters, which is equal to
.Dq Dv EL_BUILTIN_GETCFN
in the case of the default builtin function.
.It Dv EL_CLIENTDATA , Fa "void **data"
-Retrieve
+Set
.Fa data
-previously registered with the corresponding
+to the previously registered client data set by an
.Fn el_set
call.
-.It Dv EL_UNBUFFERED , Fa "int"
-Return non-zero if unbuffered mode is enabled.
-.It Dv EL_PREP_TERM , Fa "int"
-Sets or clears terminal editing mode.
+.It Dv EL_UNBUFFERED , Fa "int *c"
+Set
+.Fa c
+to non-zero if unbuffered mode is enabled.
.It Dv EL_GETFP , Fa "int fd", Fa "FILE **fp"
-Return in
+Set
.Fa fp
-the current
+to the current
.Nm editline
file pointer for
.Dq input
@@ -593,7 +600,7 @@ or
.Dv 2 .
.El
.It Fn el_source
-Initialise
+Initialize
.Nm
by reading the contents of
.Fa file .
@@ -671,7 +678,7 @@ and freed by
The following functions are available:
.Bl -tag -width 4n
.It Fn history_init
-Initialise the history list, and return a data structure
+Initialize the history list, and return a data structure
to be used by all other history list functions, or
.Dv NULL
on failure.
@@ -810,7 +817,7 @@ and freed by
The following functions are available:
.Bl -tag -width 4n
.It Fn tok_init
-Initialise the tokenizer, and return a data structure
+Initialize the tokenizer, and return a data structure
to be used by all other tokenizer functions.
.Fa IFS
contains the Input Field Separators, which defaults to
diff --git a/lib/libedit/el.c b/lib/libedit/el.c
index 57ea6e5..65bd86b 100644
--- a/lib/libedit/el.c
+++ b/lib/libedit/el.c
@@ -1,4 +1,4 @@
-/* $NetBSD: el.c,v 1.73 2014/06/18 18:12:28 christos Exp $ */
+/* $NetBSD: el.c,v 1.74 2015/12/08 12:56:55 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94";
#else
-__RCSID("$NetBSD: el.c,v 1.73 2014/06/18 18:12:28 christos Exp $");
+__RCSID("$NetBSD: el.c,v 1.74 2015/12/08 12:56:55 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
#include <sys/cdefs.h>
@@ -137,7 +137,8 @@ el_end(EditLine *el)
terminal_end(el);
keymacro_end(el);
map_end(el);
- tty_end(el);
+ if (!(el->el_flags & NO_TTY))
+ tty_end(el);
ch_end(el);
search_end(el);
hist_end(el);
diff --git a/lib/libedit/hist.h b/lib/libedit/hist.h
index 1cd7d9d..6ca6877 100644
--- a/lib/libedit/hist.h
+++ b/lib/libedit/hist.h
@@ -1,4 +1,4 @@
-/* $NetBSD: hist.h,v 1.14 2014/05/11 01:05:17 christos Exp $ */
+/* $NetBSD: hist.h,v 1.15 2016/01/30 15:05:27 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -47,10 +47,10 @@ typedef int (*hist_fun_t)(void *, TYPE(HistEvent) *, int, ...);
typedef struct el_history_t {
Char *buf; /* The history buffer */
- size_t sz; /* Size of history buffer */
+ size_t sz; /* Size of history buffer */
Char *last; /* The last character */
int eventno; /* Event we are looking for */
- void * ref; /* Argument for history fcns */
+ void *ref; /* Argument for history fcns */
hist_fun_t fun; /* Event access */
TYPE(HistEvent) ev; /* Event cookie */
} el_history_t;
diff --git a/lib/libedit/keymacro.h b/lib/libedit/keymacro.h
index 57a7a5d..139cda2 100644
--- a/lib/libedit/keymacro.h
+++ b/lib/libedit/keymacro.h
@@ -1,4 +1,4 @@
-/* $NetBSD: keymacro.h,v 1.2 2011/07/28 03:44:36 christos Exp $ */
+/* $NetBSD: keymacro.h,v 1.3 2016/01/29 19:59:11 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -48,7 +48,7 @@ typedef union keymacro_value_t {
typedef struct keymacro_node_t keymacro_node_t;
-typedef struct el_keymacromacro_t {
+typedef struct el_keymacro_t {
Char *buf; /* Key print buffer */
keymacro_node_t *map; /* Key map */
keymacro_value_t val; /* Local conversion buffer */
diff --git a/lib/libedit/search.c b/lib/libedit/search.c
index 3cd205a..df9999c 100644
--- a/lib/libedit/search.c
+++ b/lib/libedit/search.c
@@ -1,4 +1,4 @@
-/* $NetBSD: search.c,v 1.30 2011/10/04 15:27:04 christos Exp $ */
+/* $NetBSD: search.c,v 1.31 2016/01/30 04:02:51 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)search.c 8.1 (Berkeley) 6/4/93";
#else
-__RCSID("$NetBSD: search.c,v 1.30 2011/10/04 15:27:04 christos Exp $");
+__RCSID("$NetBSD: search.c,v 1.31 2016/01/30 04:02:51 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
#include <sys/cdefs.h>
@@ -149,7 +149,7 @@ el_match(const Char *str, const Char *pat)
if (re_comp(ct_encode_string(pat, &conv)) != NULL)
return 0;
else
- return re_exec(ct_encode_string(str, &conv) == 1);
+ return re_exec(ct_encode_string(str, &conv)) == 1;
#endif
}
diff --git a/lib/libedit/tokenizer.c b/lib/libedit/tokenizer.c
index e61ecaf..f5171c4 100644
--- a/lib/libedit/tokenizer.c
+++ b/lib/libedit/tokenizer.c
@@ -1,4 +1,4 @@
-/* $NetBSD: tokenizer.c,v 1.21 2011/08/16 16:25:15 christos Exp $ */
+/* $NetBSD: tokenizer.c,v 1.22 2016/01/30 04:02:51 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)tokenizer.c 8.1 (Berkeley) 6/4/93";
#else
-__RCSID("$NetBSD: tokenizer.c,v 1.21 2011/08/16 16:25:15 christos Exp $");
+__RCSID("$NetBSD: tokenizer.c,v 1.22 2016/01/30 04:02:51 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
#include <sys/cdefs.h>
@@ -448,5 +448,5 @@ FUN(tok,str)(TYPE(Tokenizer) *tok, const Char *line, int *argc,
memset(&li, 0, sizeof(li));
li.buffer = line;
li.cursor = li.lastchar = Strchr(line, '\0');
- return FUN(tok,line(tok, &li, argc, argv, NULL, NULL));
+ return FUN(tok,line)(tok, &li, argc, argv, NULL, NULL);
}
diff --git a/lib/libedit/tty.c b/lib/libedit/tty.c
index ecf2e2a..a508e43 100644
--- a/lib/libedit/tty.c
+++ b/lib/libedit/tty.c
@@ -1,4 +1,4 @@
-/* $NetBSD: tty.c,v 1.47 2015/05/14 10:44:15 christos Exp $ */
+/* $NetBSD: tty.c,v 1.49 2015/12/08 16:53:27 gson Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93";
#else
-__RCSID("$NetBSD: tty.c,v 1.47 2015/05/14 10:44:15 christos Exp $");
+__RCSID("$NetBSD: tty.c,v 1.49 2015/12/08 16:53:27 gson Exp $");
#endif
#endif /* not lint && not SCCSID */
#include <sys/cdefs.h>
@@ -582,6 +582,9 @@ protected void
/*ARGSUSED*/
tty_end(EditLine *el)
{
+ if (el->el_flags & EDIT_DISABLED)
+ return;
+
if (tty_setty(el, TCSAFLUSH, &el->el_tty.t_or) == -1) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile,
diff --git a/lib/libmemstat/memstat_uma.c b/lib/libmemstat/memstat_uma.c
index 8e89585..20cd520 100644
--- a/lib/libmemstat/memstat_uma.c
+++ b/lib/libmemstat/memstat_uma.c
@@ -29,6 +29,7 @@
#include <sys/param.h>
#include <sys/cpuset.h>
#include <sys/sysctl.h>
+#include <sys/_task.h>
#include <vm/vm.h>
#include <vm/vm_page.h>
diff --git a/share/examples/jails/jib b/share/examples/jails/jib
new file mode 100755
index 0000000..540df09
--- /dev/null
+++ b/share/examples/jails/jib
@@ -0,0 +1,367 @@
+#!/bin/sh
+#-
+# Copyright (c) 2016 Devin Teske
+# 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$
+#
+############################################################ IDENT(1)
+#
+# $Title: if_bridge(4) management script for vnet jails $
+#
+############################################################ INFORMATION
+#
+# Use this tool with jail.conf(5) (or rc.conf(5) ``legacy'' configuration) to
+# manage `vnet' interfaces. In jail.conf(5) format:
+#
+# ### BEGIN EXCERPT ###
+#
+# xxx {
+# host.hostname = "xxx.yyy";
+# path = "/vm/xxx";
+#
+# #
+# # NB: Below 2-lines required
+# # NB: The number of eNb_xxx interfaces should match the number of
+# # arguments given to `jib addm xxx' in exec.prestart value.
+# #
+# vnet;
+# vnet.interface = "e0b_xxx e1b_xxx ...";
+#
+# exec.clean;
+# exec.system_user = "root";
+# exec.jail_user = "root";
+#
+# #
+# # NB: Below 2-lines required
+# # NB: The number of arguments after `jib addm xxx' should match
+# # the number of eNb_xxx arguments in vnet.interface value.
+# #
+# exec.prestart += "jib addm xxx em0 em1 ...";
+# exec.poststop += "jib destroy xxx";
+#
+# # Standard recipe
+# exec.start += "/bin/sh /etc/rc";
+# exec.stop = "/bin/sh /etc/rc.shutdown";
+# exec.consolelog = "/var/log/jail_xxx_console.log";
+# mount.devfs;
+#
+# # Optional (default off)
+# #allow.mount;
+# #allow.set_hostname = 1;
+# #allow.sysvipc = 1;
+# #devfs_ruleset = "11"; # rule to unhide bpf for DHCP
+# }
+#
+# ### END EXCERPT ###
+#
+# In rc.conf(5) ``legacy'' format (used when /etc/jail.conf does not exist):
+#
+# ### BEGIN EXCERPT ###
+#
+# jail_enable="YES"
+# jail_list="xxx"
+#
+# #
+# # Global presets for all jails
+# #
+# jail_devfs_enable="YES" # mount devfs
+#
+# #
+# # Global options (default off)
+# #
+# #jail_mount_enable="YES" # mount /etc/fstab.{name}
+# #jail_set_hostname_allow="YES" # Allow hostname to change
+# #jail_sysvipc_allow="YES" # Allow SysV Interprocess Comm.
+#
+# # xxx
+# jail_xxx_hostname="xxx.shxd.cx" # hostname
+# jail_xxx_rootdir="/vm/xxx" # root directory
+# jail_xxx_vnet_interfaces="e0b_xxx e1bxxx ..." # vnet interface(s)
+# jail_xxx_exec_prestart0="jib addm xxx em0 em1 ..." # bridge interface(s)
+# jail_xxx_exec_poststop0="jib destroy xxx" # destroy interface(s)
+# #jail_xxx_mount_enable="YES" # mount /etc/fstab.xxx
+# #jail_xxx_devfs_ruleset="11" # rule to unhide bpf for DHCP
+#
+# ### END EXCERPT ###
+#
+# Note that the legacy rc.conf(5) format is converted to
+# /var/run/jail.{name}.conf by /etc/rc.d/jail if jail.conf(5) is missing.
+#
+# ASIDE: dhclient(8) inside a vnet jail...
+#
+# To allow dhclient(8) to work inside a vnet jail, make sure the following
+# appears in /etc/devfs.rules (which should be created if it doesn't exist):
+#
+# [devfsrules_jail=11]
+# add include $devfsrules_hide_all
+# add include $devfsrules_unhide_basic
+# add include $devfsrules_unhide_login
+# add include $devfsrules_unhide_bpf
+#
+# And set ether devfs.ruleset="11" (jail.conf(5)) or
+# jail_{name}_devfs_ruleset="11" (rc.conf(5)).
+#
+# NB: While this tool can't create every type of desirable topology, it should
+# handle most setups, minus some which considered exotic or purpose-built.
+#
+############################################################ GLOBALS
+
+pgm="${0##*/}" # Program basename
+
+#
+# Global exit status
+#
+SUCCESS=0
+FAILURE=1
+
+############################################################ FUNCTIONS
+
+usage()
+{
+ local action usage descr
+ exec >&2
+ echo "Usage: $pgm action [arguments]"
+ echo "Actions:"
+ for action in \
+ addm \
+ show \
+ show1 \
+ destroy \
+ ; do
+ eval usage=\"\$jib_${action}_usage\"
+ [ "$usage" ] || continue
+ eval descr=\"\$jib_${action}_descr\"
+ printf "\t%s\n\t\t%s\n" "$usage" "$descr"
+ done
+ exit $FAILURE
+}
+
+action_usage()
+{
+ local usage action="$1"
+ eval usage=\"\$jib_${action}_usage\"
+ echo "Usage: $pgm $usage" >&2
+ exit $FAILURE
+}
+
+mustberoot_to_continue()
+{
+ if [ "$( id -u )" -ne 0 ]; then
+ echo "Must run as root!" >&2
+ exit $FAILURE
+ fi
+}
+
+jib_addm_usage="addm [-b BRIDGE_NAME] NAME interface0 [interface1 ...]"
+jib_addm_descr="Creates e0b_NAME [e1b_NAME ...]"
+jib_addm()
+{
+ local OPTIND=1 OPTARG flag bridge=bridge
+ while getopts b: flag; do
+ case "$flag" in
+ b) bridge="${OPTARG:-bridge}" ;;
+ *) action_usage addm # NOTREACHED
+ esac
+ done
+ shift $(( $OPTIND - 1 ))
+
+ local name="$1"
+ [ "${name:-x}" = "${name#*[!0-9a-zA-Z_]}" -a $# -gt 1 ] ||
+ action_usage addm # NOTREACHED
+ shift 1 # name
+
+ mustberoot_to_continue
+
+ local iface iface_devid eiface_devid_a eiface_devid_b
+ local new num quad i=0
+ for iface in $*; do
+
+ # 1. Make sure the interface doesn't exist already
+ ifconfig "e${i}a_$name" > /dev/null 2>&1 && continue
+
+ # 2. Bring the interface up
+ ifconfig $iface up || return
+
+ # 3. Make sure the interface has been bridged
+ if ! ifconfig "$iface$bridge" > /dev/null 2>&1; then
+ new=$( ifconfig bridge create ) || return
+ ifconfig $new addm $iface || return
+ ifconfig $new name "$iface$bridge" || return
+ fi
+
+ # 4. Create a new interface to the bridge
+ new=$( ifconfig epair create ) || return
+ ifconfig "$iface$bridge" addm $new || return
+
+ # 5. Rename the new interface
+ ifconfig $new name "e${i}a_$name" || return
+ ifconfig ${new%a}b name "e${i}b_$name" || return
+
+ #
+ # 6. Set the MAC address of the new interface using a sensible
+ # algorithm to prevent conflicts on the network.
+ #
+ # The formula I'm using is ``SP:SS:SI:II:II:II'' where:
+ # + S denotes 16 bits of sum(1) data, split because P (below).
+ # + P denotes the special nibble whose value, if one of
+ # 2, 6, A, or E (but usually 2) denotes a privately
+ # administered MAC address (while remaining routable).
+ # + I denotes bits that are inherited from parent interface.
+ #
+ # The S bits are a CRC-16 checksum of NAME, allowing the jail
+ # to change the epair(4) generation order without affecting the
+ # MAC address. Meanwhile, if the jail NAME changes (e.g., it
+ # was duplicated and given a new name with no other changes),
+ # the underlying network interface changes, or the jail is
+ # moved to another host, the MAC address will be recalculated
+ # to a new, similarly unique value preventing conflict.
+ #
+ iface_devid=$( ifconfig $iface ether | awk '/ether/,$0=$2' )
+ eiface_devid_a=${iface_devid#??:??:?}
+ eiface_devid_b=${iface_devid#??:??:?}
+ num=$( set -- `echo -n $name | sum` && echo $1 )
+ quad=$(( $num & 15 ))
+ case "$quad" in
+ 10) quad=a ;; 11) quad=b ;; 12) quad=c ;;
+ 13) quad=d ;; 14) quad=e ;; 15) quad=f ;;
+ esac
+ eiface_devid_a=:$quad$eiface_devid_a
+ eiface_devid_b=:$quad$eiface_devid_b
+ num=$(( $num >> 4 ))
+ quad=$(( $num & 15 ))
+ case "$quad" in
+ 10) quad=a ;; 11) quad=b ;; 12) quad=c ;;
+ 13) quad=d ;; 14) quad=e ;; 15) quad=f ;;
+ esac
+ eiface_devid_a=$quad$eiface_devid_a
+ eiface_devid_b=$quad$eiface_devid_b
+ num=$(( $num >> 4 ))
+ quad=$(( $num & 15 ))
+ case "$quad" in
+ 10) quad=a ;; 11) quad=b ;; 12) quad=c ;;
+ 13) quad=d ;; 14) quad=e ;; 15) quad=f ;;
+ esac
+ eiface_devid_a=2:$quad$eiface_devid_a
+ eiface_devid_b=6:$quad$eiface_devid_b
+ num=$(( $num >> 4 ))
+ quad=$(( $num & 15 ))
+ case "$quad" in
+ 10) quad=a ;; 11) quad=b ;; 12) quad=c ;;
+ 13) quad=d ;; 14) quad=e ;; 15) quad=f ;;
+ esac
+ eiface_devid_a=$quad$eiface_devid_a
+ eiface_devid_b=$quad$eiface_devid_b
+ ifconfig "e${i}a_$name" ether $eiface_devid_a > /dev/null 2>&1
+ ifconfig "e${i}b_$name" ether $eiface_devid_b > /dev/null 2>&1
+
+ i=$(( $i + 1 )) # on to next ng{i}_name
+ done # for iface
+}
+
+jib_show_usage="show"
+jib_show_descr="List possible NAME values for \`show NAME'"
+jib_show1_usage="show NAME"
+jib_show1_descr="Lists ng0_NAME [ng1_NAME ...]"
+jib_show2_usage="show [NAME]"
+jib_show()
+{
+ local OPTIND=1 OPTARG flag
+ while getopts "" flag; do
+ case "$flag" in
+ *) action_usage show2 # NOTREACHED
+ esac
+ done
+ shift $(( $OPTIND - 1 ))
+ if [ $# -eq 0 ]; then
+ ifconfig | awk '
+ /^[^:[:space:]]+:/ {
+ iface = $1
+ sub(/:.*/, "", iface)
+ next
+ }
+ $1 == "groups:" {
+ for (n = split($0, group); n > 1; n--) {
+ if (group[n] != "bridge") continue
+ print iface
+ next
+ }
+ }' |
+ xargs -rn1 ifconfig |
+ awk '$1 == "member:" &&
+ sub(/^e[[:digit:]]+a_/, "", $2), $0 = $2' |
+ sort -u
+ return
+ fi
+ ifconfig | awk -v name="$1" '
+ match($0, /^e[[:digit:]]+a_/) && sub(/:.*/, "") &&
+ substr($1, RSTART + RLENGTH) == name
+ ' | sort
+}
+
+jib_destroy_usage="destroy NAME"
+jib_destroy_descr="Destroy e0b_NAME [e1b_NAME ...]"
+jib_destroy()
+{
+ local OPTIND=1 OPTARG flag
+ while getopts "" flag; do
+ case "$flag" in
+ *) action_usage destroy # NOTREACHED
+ esac
+ done
+ shift $(( $OPTIND -1 ))
+ local name="$1"
+ [ "${name:-x}" = "${name#*[!0-9a-zA-Z_]}" -a $# -eq 1 ] ||
+ action_usage destroy # NOTREACHED
+ mustberoot_to_continue
+ jib_show "$name" | xargs -rn1 -I eiface ifconfig eiface destroy
+}
+
+############################################################ MAIN
+
+#
+# Command-line arguments
+#
+action="$1"
+[ "$action" ] || usage # NOTREACHED
+
+#
+# Validate action argument
+#
+if [ "$BASH_VERSION" ]; then
+ type="$( type -t "jib_$action" )" || usage # NOTREACHED
+else
+ type="$( type "jib_$action" 2> /dev/null )" || usage # NOTREACHED
+fi
+case "$type" in
+*function)
+ shift 1 # action
+ eval "jib_$action" \"\$@\"
+ ;;
+*) usage # NOTREACHED
+esac
+
+################################################################################
+# END
+################################################################################
diff --git a/share/examples/jails/jng b/share/examples/jails/jng
new file mode 100755
index 0000000..605db90
--- /dev/null
+++ b/share/examples/jails/jng
@@ -0,0 +1,416 @@
+#!/bin/sh
+#-
+# Copyright (c) 2016 Devin Teske
+# 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$
+#
+############################################################ IDENT(1)
+#
+# $Title: netgraph(4) management script for vnet jails $
+#
+############################################################ INFORMATION
+#
+# Use this tool with jail.conf(5) (or rc.conf(5) ``legacy'' configuration) to
+# manage `vnet' interfaces. In jail.conf(5) format:
+#
+# ### BEGIN EXCERPT ###
+#
+# xxx {
+# host.hostname = "xxx.yyy";
+# path = "/vm/xxx";
+#
+# #
+# # NB: Below 2-lines required
+# # NB: The number of ngN_xxx interfaces should match the number of
+# # arguments given to `jng bridge xxx' in exec.prestart value.
+# #
+# vnet;
+# vnet.interface = "ng0_xxx ng1_xxx ...";
+#
+# exec.clean;
+# exec.system_user = "root";
+# exec.jail_user = "root";
+#
+# #
+# # NB: Below 2-lines required
+# # NB: The number of arguments after `jng bridge xxx' should match
+# # the number of ngN_xxx arguments in vnet.interface value.
+# #
+# exec.prestart += "jng bridge xxx em0 em1 ...";
+# exec.poststop += "jng shutdown xxx";
+#
+# # Standard recipe
+# exec.start += "/bin/sh /etc/rc";
+# exec.stop = "/bin/sh /etc/rc.shutdown";
+# exec.consolelog = "/var/log/jail_xxx_console.log";
+# mount.devfs;
+#
+# # Optional (default off)
+# #allow.mount;
+# #allow.set_hostname = 1;
+# #allow.sysvipc = 1;
+# #devfs_ruleset = "11"; # rule to unhide bpf for DHCP
+# }
+#
+# ### END EXCERPT ###
+#
+# In rc.conf(5) ``legacy'' format (used when /etc/jail.conf does not exist):
+#
+# ### BEGIN EXCERPT ###
+#
+# jail_enable="YES"
+# jail_list="xxx"
+#
+# #
+# # Global presets for all jails
+# #
+# jail_devfs_enable="YES" # mount devfs
+#
+# #
+# # Global options (default off)
+# #
+# #jail_mount_enable="YES" # mount /etc/fstab.{name}
+# #jail_set_hostname_allow="YES" # Allow hostname to change
+# #jail_sysvipc_allow="YES" # Allow SysV Interprocess Comm.
+#
+# # xxx
+# jail_xxx_hostname="xxx.shxd.cx" # hostname
+# jail_xxx_rootdir="/vm/xxx" # root directory
+# jail_xxx_vnet_interfaces="ng0_xxx ng1xxx ..." # vnet interface(s)
+# jail_xxx_exec_prestart0="jng bridge xxx em0 em1 ..." # bridge interface(s)
+# jail_xxx_exec_poststop0="jng shutdown xxx" # destroy interface(s)
+# #jail_xxx_mount_enable="YES" # mount /etc/fstab.xxx
+# #jail_xxx_devfs_ruleset="11" # rule to unhide bpf for DHCP
+#
+# ### END EXCERPT ###
+#
+# Note that the legacy rc.conf(5) format is converted to
+# /var/run/jail.{name}.conf by /etc/rc.d/jail if jail.conf(5) is missing.
+#
+# ASIDE: dhclient(8) inside a vnet jail...
+#
+# To allow dhclient(8) to work inside a vnet jail, make sure the following
+# appears in /etc/devfs.rules (which should be created if it doesn't exist):
+#
+# [devfsrules_jail=11]
+# add include $devfsrules_hide_all
+# add include $devfsrules_unhide_basic
+# add include $devfsrules_unhide_login
+# add include $devfsrules_unhide_bpf
+#
+# And set ether devfs.ruleset="11" (jail.conf(5)) or
+# jail_{name}_devfs_ruleset="11" (rc.conf(5)).
+#
+# NB: While this tool can't create every type of desirable topology, it should
+# handle most setups, minus some which considered exotic or purpose-built.
+#
+############################################################ GLOBALS
+
+pgm="${0##*/}" # Program basename
+
+#
+# Global exit status
+#
+SUCCESS=0
+FAILURE=1
+
+############################################################ FUNCTIONS
+
+usage()
+{
+ local action usage descr
+ exec >&2
+ echo "Usage: $pgm action [arguments]"
+ echo "Actions:"
+ for action in \
+ bridge \
+ graph \
+ show \
+ show1 \
+ shutdown \
+ ; do
+ eval usage=\"\$jng_${action}_usage\"
+ [ "$usage" ] || continue
+ eval descr=\"\$jng_${action}_descr\"
+ printf "\t%s\n\t\t%s\n" "$usage" "$descr"
+ done
+ exit $FAILURE
+}
+
+action_usage()
+{
+ local usage action="$1"
+ eval usage=\"\$jng_${action}_usage\"
+ echo "Usage: $pgm $usage" >&2
+ exit $FAILURE
+}
+
+mustberoot_to_continue()
+{
+ if [ "$( id -u )" -ne 0 ]; then
+ echo "Must run as root!" >&2
+ exit $FAILURE
+ fi
+}
+
+jng_bridge_usage="bridge [-b BRIDGE_NAME] NAME interface0 [interface1 ...]"
+jng_bridge_descr="Create ng0_NAME [ng1_NAME ...]"
+jng_bridge()
+{
+ local OPTIND=1 OPTARG flag bridge=bridge
+ while getopts b: flag; do
+ case "$flag" in
+ b) bridge="$OPTARG"
+ [ "$bridge" ] || action_usage bridge ;; # NOTREACHED
+ *) action_usage bridge # NOTREACHED
+ esac
+ done
+ shift $(( $OPTIND - 1 ))
+
+ local name="$1"
+ [ "${name:-x}" = "${name#*[!0-9a-zA-Z_]}" -a $# -gt 1 ] ||
+ action_usage bridge # NOTREACHED
+ shift 1 # name
+
+ mustberoot_to_continue
+
+ local iface iface_devid eiface eiface_devid
+ local new num quad i=0
+ for iface in $*; do
+
+ # 0. Make sure the interface doesn't exist already
+ eiface=ng${i}_$name
+ ngctl msg "$eiface:" getifname > /dev/null 2>&1 && continue
+
+ # 1. Bring the interface up
+ ifconfig $iface up || return
+
+ # 2. Set promiscuous mode and don't overwrite src addr
+ ngctl msg $iface: setpromisc 1 || return
+ ngctl msg $iface: setautosrc 0 || return
+
+ # 3. Make sure the interface has been bridged
+ if ! ngctl info ${iface}bridge: > /dev/null 2>&1; then
+ ngctl mkpeer $iface: bridge lower link0 || return
+ ngctl connect $iface: $iface:lower upper link1 ||
+ return
+ ngctl name $iface:lower ${iface}bridge || return
+ fi
+
+ # 3.5. Optionally create a secondary bridge
+ if [ "$bridge" != "bridge" ] &&
+ ! ngctl info "$iface$bridge:" > /dev/null 2>&1
+ then
+ num=2
+ while ngctl msg ${iface}bridge: getstats $num \
+ > /dev/null 2>&1
+ do
+ num=$(( $num + 1 ))
+ done
+ ngctl mkpeer $iface:lower bridge link$num link1 ||
+ return
+ ngctl name ${iface}bridge:link$num "$iface$bridge" ||
+ return
+ fi
+
+ # 4. Create a new interface to the bridge
+ num=2
+ while ngctl msg "$iface$bridge:" getstats $num > /dev/null 2>&1
+ do
+ num=$(( $num + 1 ))
+ done
+ ngctl mkpeer "$iface$bridge:" eiface link$num ether || return
+
+ # 5. Rename the new interface
+ while [ ${#eiface} -gt 15 ]; do # OS limitation
+ eiface=${eiface%?}
+ done
+ new=$( set -- `ngctl show -n "$iface$bridge:link$num"` &&
+ echo $2 ) || return
+ ngctl name "$iface$bridge:link$num" $eiface || return
+ ifconfig $new name $eiface || return
+
+ #
+ # 6. Set the MAC address of the new interface using a sensible
+ # algorithm to prevent conflicts on the network.
+ #
+ # The formula I'm using is ``SP:SS:SI:II:II:II'' where:
+ # + S denotes 16 bits of sum(1) data, split because P (below).
+ # + P denotes the special nibble whose value, if one of
+ # 2, 6, A, or E (but usually 2) denotes a privately
+ # administered MAC address (while remaining routable).
+ # + I denotes bits that are inherited from parent interface.
+ #
+ # The S bits are a CRC-16 checksum of NAME, allowing the jail
+ # to change link numbers in ng_bridge(4) without affecting the
+ # MAC address. Meanwhile, if the jail NAME changes (e.g., it
+ # was duplicated and given a new name with no other changes),
+ # the underlying network interface changes, or the jail is
+ # moved to another host, the MAC address will be recalculated
+ # to a new, similarly unique value preventing conflict.
+ #
+ iface_devid=$( ifconfig $iface ether | awk '/ether/,$0=$2' )
+ eiface_devid=${iface_devid#??:??:?}
+ num=$( set -- `echo -n $name | sum` && echo $1 )
+ quad=$(( $num & 15 ))
+ case "$quad" in
+ 10) quad=a ;; 11) quad=b ;; 12) quad=c ;;
+ 13) quad=d ;; 14) quad=e ;; 15) quad=f ;;
+ esac
+ eiface_devid=:$quad$eiface_devid
+ num=$(( $num >> 4 ))
+ quad=$(( $num & 15 ))
+ case "$quad" in
+ 10) quad=a ;; 11) quad=b ;; 12) quad=c ;;
+ 13) quad=d ;; 14) quad=e ;; 15) quad=f ;;
+ esac
+ eiface_devid=$quad$eiface_devid
+ num=$(( $num >> 4 ))
+ quad=$(( $num & 15 ))
+ case "$quad" in
+ 10) quad=a ;; 11) quad=b ;; 12) quad=c ;;
+ 13) quad=d ;; 14) quad=e ;; 15) quad=f ;;
+ esac
+ eiface_devid=2:$quad$eiface_devid
+ num=$(( $num >> 4 ))
+ quad=$(( $num & 15 ))
+ case "$quad" in
+ 10) quad=a ;; 11) quad=b ;; 12) quad=c ;;
+ 13) quad=d ;; 14) quad=e ;; 15) quad=f ;;
+ esac
+ eiface_devid=$quad$eiface_devid
+ ifconfig $eiface ether $eiface_devid > /dev/null 2>&1
+
+ i=$(( $i + 1 )) # on to next ng{i}_name
+ done # for iface
+}
+
+jng_graph_usage="graph [-f] [-T type] [-o output]"
+jng_graph_descr="Generate network graph (default output is \`jng.svg')"
+jng_graph()
+{
+ local OPTIND=1 OPTARG flag
+ local output=jng.svg output_type= force=
+ while getopts fo:T: flag; do
+ case "$flag" in
+ f) force=1 ;;
+ o) output="$OPTARG" ;;
+ T) output_type="$OPTARG" ;;
+ *) action_usage graph # NOTREACHED
+ esac
+ done
+ shift $(( $OPTIND - 1 ))
+ [ $# -eq 0 -a "$output" ] || action_usage graph # NOTREACHED
+ mustberoot_to_continue
+ if [ -e "$output" -a ! "$force" ]; then
+ echo "$output: Already exists (use \`-f' to overwrite)" >&2
+ return $FAILURE
+ fi
+ if [ ! "$output_type" ]; then
+ local valid suffix
+ valid=$( dot -Txxx 2>&1 )
+ for suffix in ${valid##*:}; do
+ [ "$output" != "${output%.$suffix}" ] || continue
+ output_type=$suffix
+ break
+ done
+ fi
+ ngctl dot | dot ${output_type:+-T "$output_type"} -o "$output"
+}
+
+jng_show_usage="show"
+jng_show_descr="List possible NAME values for \`show NAME'"
+jng_show1_usage="show NAME"
+jng_show1_descr="Lists ng0_NAME [ng1_NAME ...]"
+jng_show2_usage="show [NAME]"
+jng_show()
+{
+ local OPTIND=1 OPTARG flag
+ while getopts "" flag; do
+ case "$flag" in
+ *) action_usage show2 # NOTREACHED
+ esac
+ done
+ shift $(( $OPTIND - 1 ))
+ mustberoot_to_continue
+ if [ $# -eq 0 ]; then
+ ngctl ls | awk '$4=="bridge",$0=$2' |
+ xargs -rn1 -Ibridge ngctl show bridge: |
+ awk 'sub(/^ng[[:digit:]]+_/, "", $2), $0 = $2' |
+ sort -u
+ return
+ fi
+ ngctl ls | awk -v name="$1" '
+ match($2, /^ng[[:digit:]]+_/) &&
+ substr($2, RSTART + RLENGTH) == name &&
+ $4 == "eiface", $0 = $2
+ ' | sort
+}
+
+jng_shutdown_usage="shutdown NAME"
+jng_shutdown_descr="Shutdown ng0_NAME [ng1_NAME ...]"
+jng_shutdown()
+{
+ local OPTIND=1 OPTARG flag
+ while getopts "" flag; do
+ case "$flag" in
+ *) action_usage shutdown # NOTREACHED
+ esac
+ done
+ shift $(( $OPTIND -1 ))
+ local name="$1"
+ [ "${name:-x}" = "${name#*[!0-9a-zA-Z_]}" -a $# -eq 1 ] ||
+ action_usage shutdown # NOTREACHED
+ mustberoot_to_continue
+ jng_show "$name" | xargs -rn1 -I eiface ngctl shutdown eiface:
+}
+
+############################################################ MAIN
+
+#
+# Command-line arguments
+#
+action="$1"
+[ "$action" ] || usage # NOTREACHED
+
+#
+# Validate action argument
+#
+if [ "$BASH_VERSION" ]; then
+ type="$( type -t "jng_$action" )" || usage # NOTREACHED
+else
+ type="$( type "jng_$action" 2> /dev/null )" || usage # NOTREACHED
+fi
+case "$type" in
+*function)
+ shift 1 # action
+ eval "jng_$action" \"\$@\"
+ ;;
+*) usage # NOTREACHED
+esac
+
+################################################################################
+# END
+################################################################################
diff --git a/share/i18n/esdb/MISC/MISC.alias b/share/i18n/esdb/MISC/MISC.alias
index 90e2ccd..6ffad5d 100644
--- a/share/i18n/esdb/MISC/MISC.alias
+++ b/share/i18n/esdb/MISC/MISC.alias
@@ -29,10 +29,10 @@ JISX0208:1990 x0208
JOHAB cp1361
-SHIFT_JIS csshiftjis
-SHIFT_JIS ms_kanji
-SHIFT_JIS sjis
+Shift_JIS csshiftjis
+Shift_JIS ms_kanji
+Shift_JIS sjis
-SHIFT_JIS-2004 shift_jisx0213
+Shift_JIS-2004 shift_jisx0213
TDS565 iso-ir-230
diff --git a/share/man/man4/bridge.4 b/share/man/man4/bridge.4
index cecffc5..d3410d5 100644
--- a/share/man/man4/bridge.4
+++ b/share/man/man4/bridge.4
@@ -425,8 +425,8 @@ cloned_interfaces="bridge0"
ifconfig_bridge0="addm wlan0 addm fxp0 up"
.Ed
.Pp
-For the bridge to forward packets all member interfaces and the bridge need
-to be up.
+For the bridge to forward packets,
+all member interfaces and the bridge need to be up.
The above example would also require:
.Bd -literal -offset indent
create_args_wlan0="wlanmode hostap"
diff --git a/share/man/man4/inet.4 b/share/man/man4/inet.4
index a1d0a1c..07e7354 100644
--- a/share/man/man4/inet.4
+++ b/share/man/man4/inet.4
@@ -28,7 +28,7 @@
.\" From: @(#)inet.4 8.1 (Berkeley) 6/5/93
.\" $FreeBSD$
.\"
-.Dd April 7, 2015
+.Dd Feb 4, 2016
.Dt INET 4
.Os
.Sh NAME
@@ -164,33 +164,11 @@ MIB.
In addition to the variables supported by the transport protocols
(for which the respective manual pages may be consulted),
the following general variables are defined:
-.Bl -tag -width IPCTL_FASTFORWARDING
+.Bl -tag -width IPCTL_ACCEPTSOURCEROUTE
.It Dv IPCTL_FORWARDING
.Pq ip.forwarding
Boolean: enable/disable forwarding of IP packets.
Defaults to off.
-.It Dv IPCTL_FASTFORWARDING
-.Pq ip.fastforwarding
-Boolean: enable/disable the use of
-.Tn fast IP forwarding
-code.
-Defaults to off.
-When
-.Tn fast IP forwarding
-is enabled, IP packets are forwarded directly to the appropriate network
-interface with direct processing to completion, which greatly improves
-the throughput.
-All packets for local IP addresses, non-unicast, or with IP options are
-handled by the normal IP input processing path.
-All features of the normal (slow) IP forwarding path are supported
-including firewall (through
-.Xr pfil 9
-hooks) checking, except
-.Xr ipsec 4
-tunnel brokering.
-The
-.Tn IP fastforwarding
-path does not generate ICMP redirect or source quench messages.
.It Dv IPCTL_SENDREDIRECTS
.Pq ip.redirect
Boolean: enable/disable sending of ICMP redirects in response to
diff --git a/share/man/man7/build.7 b/share/man/man7/build.7
index be6fe09..b32d7ed 100644
--- a/share/man/man7/build.7
+++ b/share/man/man7/build.7
@@ -107,6 +107,16 @@ section below, and by the variables documented in
The following list provides the names and actions for the targets
supported by the build system:
.Bl -tag -width ".Cm cleandepend"
+.It Cm check
+Run tests for a given subdirectory.
+The default directory used is
+.Pa ${.OBJDIR} ,
+but the check directory can be changed with
+.Pa ${CHECKDIR} .
+.It Cm checkworld
+Run the
+.Fx
+test suite on installed world.
.It Cm clean
Remove any files created during the build process.
.It Cm cleandepend
@@ -653,6 +663,7 @@ make TARGET=sparc64 DESTDIR=/clients/sparc64 installworld
.Xr mergemaster 8 ,
.Xr portsnap 8 ,
.Xr reboot 8 ,
-.Xr shutdown 8
+.Xr shutdown 8 ,
+.Xr tests 7
.Sh AUTHORS
.An Mike W. Meyer Aq Mt mwm@mired.org
diff --git a/share/mk/bsd.README b/share/mk/bsd.README
index b1a68e8..1ae1510 100644
--- a/share/mk/bsd.README
+++ b/share/mk/bsd.README
@@ -448,6 +448,17 @@ It has seven targets:
all:
build the test programs.
+ check:
+ runs the test programs from CHECKDIR with kyua test.
+
+ The beforecheck and aftercheck targets will be invoked, if
+ defined, to execute commands before and after the realcheck
+ target has been executed, respectively.
+
+ The devel/kyua package must be installed before invoking this
+ target.
+
+ See CHECKDIR for more details.
clean:
remove the test programs and any object files.
cleandir:
@@ -466,12 +477,6 @@ It has seven targets:
run lint on the source files.
tags:
create a tags file for the source files.
- test:
- runs the test programs from the object directory; if the
- Makefile does not itself define the target test, the
- targets beforetest and aftertest may also be used to
- cause actions immediately before and after the test
- target is executed.
It sets/uses the following variables, among many others:
@@ -485,6 +490,10 @@ TESTSDIR Path to the installed tests. Must be a subdirectory of
${TESTSBASE}/${RELDIR:H} , e.g. /usr/tests/bin/ls when
included from bin/ls/tests .
+CHECKDIR The directory that 'make check' executes tests from.
+
+ The value of CHECKDIR defaults to .OBJDIR.
+
KYUAFILE If 'auto' (the default), generate a Kyuafile out of the
test programs defined in the Makefile. If 'yes', then a
manually-crafted Kyuafile must be supplied with the
diff --git a/share/mk/bsd.incs.mk b/share/mk/bsd.incs.mk
index 06d04ed..05daf2f 100644
--- a/share/mk/bsd.incs.mk
+++ b/share/mk/bsd.incs.mk
@@ -87,8 +87,8 @@ _${group}INS: ${_${group}INCS}
.if defined(INCSLINKS) && !empty(INCSLINKS)
installincludes:
.for s t in ${INCSLINKS}
- @${ECHO} "$t -> $s" ; \
- ${INSTALL_SYMLINK} ${TAG_ARGS:D${TAG_ARGS},development} $s ${DESTDIR}$t
+ @${ECHO} "${DESTDIR}${t} -> ${s}" ; \
+ ${INSTALL_SYMLINK} ${TAG_ARGS:D${TAG_ARGS},development} ${s} ${DESTDIR}${t}
.endfor
.endif
.endif # !target(installincludes)
diff --git a/share/mk/bsd.links.mk b/share/mk/bsd.links.mk
index 87b808f..e69f3a0 100644
--- a/share/mk/bsd.links.mk
+++ b/share/mk/bsd.links.mk
@@ -15,10 +15,10 @@ afterinstall: _installlinks
.ORDER: realinstall _installlinks
_installlinks:
.for s t in ${LINKS}
- @${ECHO} "$t -> $s" ;\
- ${INSTALL_LINK} ${TAG_ARGS} ${DESTDIR}$s ${DESTDIR}$t
+ @${ECHO} "${t} -> ${s}" ;\
+ ${INSTALL_LINK} ${TAG_ARGS} ${DESTDIR}${s} ${DESTDIR}${t}
.endfor
.for s t in ${SYMLINKS}
- @${ECHO} "$t -> $s" ;\
- ${INSTALL_SYMLINK} ${TAG_ARGS} $s ${DESTDIR}/$t
+ @${ECHO} "${t} -> ${s}" ;\
+ ${INSTALL_SYMLINK} ${TAG_ARGS} ${s} ${DESTDIR}/${t}
.endfor
diff --git a/share/mk/bsd.man.mk b/share/mk/bsd.man.mk
index 0fee377..ee28844 100644
--- a/share/mk/bsd.man.mk
+++ b/share/mk/bsd.man.mk
@@ -172,6 +172,17 @@ ${__target}: ${__page}
.endif # ${MK_MANCOMPRESS} == "no"
+.if !defined(NO_MLINKS) && defined(MLINKS) && !empty(MLINKS)
+.for _oname _osect _dname _dsect in ${MLINKS:C/\.([^.]*)$/.\1 \1/}
+_MANLINKS+= ${MANDIR}${_osect}${MANSUBDIR}/${_oname} \
+ ${MANDIR}${_dsect}${MANSUBDIR}/${_dname}
+.if defined(MANBUILDCAT) && !empty(MANBUILDCAT)
+_MANLINKS+= ${CATDIR}${_osect}${MANSUBDIR}/${_oname} \
+ ${CATDIR}${_dsect}${MANSUBDIR}/${_dname}
+.endif
+.endfor
+.endif
+
maninstall: _maninstall
_maninstall:
.if defined(MAN) && !empty(MAN)
@@ -216,25 +227,10 @@ _maninstall: ${MAN}
.endfor
.endif # ${MK_MANCOMPRESS} == "no"
.endif
-
-.if !defined(NO_MLINKS) && defined(MLINKS) && !empty(MLINKS)
-.for _oname _osect _dname _dsect in ${MLINKS:C/\.([^.]*)$/.\1 \1/}
- @l=${DESTDIR}${MANDIR}${_osect}${MANSUBDIR}/${_oname}; \
- t=${DESTDIR}${MANDIR}${_dsect}${MANSUBDIR}/${_dname}; \
- ${ECHO} $${t}${ZEXT} -\> $${l}${ZEXT}; \
- rm -f $${t} $${t}${MCOMPRESS_EXT}; \
- ${INSTALL_LINK} ${TAG_ARGS} $${l}${ZEXT} $${t}${ZEXT}
+.for l t in ${_MANLINKS}
+ rm -f ${DESTDIR}${t} ${DESTDIR}${t}${MCOMPRESS_EXT}; \
+ ${INSTALL_LINK} ${TAG_ARGS} ${DESTDIR}${l}${ZEXT} ${DESTDIR}${t}${ZEXT}
.endfor
-.if defined(MANBUILDCAT) && !empty(MANBUILDCAT)
-.for _oname _osect _dname _dsect in ${MLINKS:C/\.([^.]*)$/.\1 \1/}
- @l=${DESTDIR}${MANDIR}${_osect}${MANSUBDIR}/${_oname}; \
- t=${DESTDIR}${MANDIR}${_dsect}${MANSUBDIR}/${_dname}; \
- ${ECHO} $${t}${ZEXT} -\> $${l}${ZEXT}; \
- rm -f $${t} $${t}${MCOMPRESS_EXT}; \
- ${INSTALL_LINK} ${TAG_ARGS} $${l}${ZEXT} $${t}${ZEXT}
-.endfor
-.endif
-.endif
manlint:
.if defined(MAN) && !empty(MAN)
diff --git a/share/mk/bsd.nls.mk b/share/mk/bsd.nls.mk
index c578361..d160a2b 100644
--- a/share/mk/bsd.nls.mk
+++ b/share/mk/bsd.nls.mk
@@ -73,6 +73,9 @@ SYMLINKS+= ${NLSSYMLINKS}
.for file in ${NLS}
NLSNAME_${file:T}= ${file:T:R}/${NLSNAME}.cat
.if defined(NLSLINKS_${file:R}) && !empty(NLSLINKS_${file:R})
+.if !empty(NLSLINKS_${file:R}:M${file:R})
+.error NLSLINKS_${file:R} contains itself: ${file:R}
+.endif
NLSLINKS+= ${file:R}
.endif
.for dst in ${NLSLINKS_${file:R}}
diff --git a/share/mk/bsd.subdir.mk b/share/mk/bsd.subdir.mk
index dbe74f4..8631e65 100644
--- a/share/mk/bsd.subdir.mk
+++ b/share/mk/bsd.subdir.mk
@@ -43,11 +43,11 @@ SUBDIR_TARGETS+= \
checkdpadd clean cleandepend cleandir cleanilinks \
cleanobj depend distribute files includes installconfig \
installfiles installincludes realinstall lint maninstall \
- manlint obj objlink regress tags \
+ manlint obj objlink tags \
# Described above.
STANDALONE_SUBDIR_TARGETS+= \
- obj checkdpadd clean cleandepend cleandir \
+ obj check checkdpadd clean cleandepend cleandir \
cleanilinks cleanobj installconfig \
.include <bsd.init.mk>
diff --git a/share/mk/bsd.sys.mk b/share/mk/bsd.sys.mk
index 7ac7917..2ce5beb 100644
--- a/share/mk/bsd.sys.mk
+++ b/share/mk/bsd.sys.mk
@@ -178,11 +178,11 @@ CXXFLAGS+= ${CXXFLAGS.${COMPILER_TYPE}}
# or expect to ever be up-to-date.
PHONY_NOTMAIN = afterdepend afterinstall all beforedepend beforeinstall \
beforelinking build build-tools buildconfig buildfiles \
- buildincludes checkdpadd clean cleandepend cleandir cleanobj \
- configure depend dependall distclean distribute exe \
+ buildincludes check checkdpadd clean cleandepend cleandir \
+ cleanobj configure depend dependall distclean distribute exe \
files html includes install installconfig installfiles \
installincludes lint obj objlink objs objwarn realall \
- realdepend realinstall regress subdir-all subdir-depend \
+ realdepend realinstall subdir-all subdir-depend \
subdir-install tags whereobj
# we don't want ${PROG} to be PHONY
diff --git a/share/mk/bsd.test.mk b/share/mk/bsd.test.mk
index b0d4939..64a4f0d 100644
--- a/share/mk/bsd.test.mk
+++ b/share/mk/bsd.test.mk
@@ -61,11 +61,15 @@ _TESTS=
.include <plain.test.mk>
.include <tap.test.mk>
+# kyua automatically descends directories; only run make check on the
+# top-level directory
+.if !make(check)
.for ts in ${TESTS_SUBDIRS}
.if empty(SUBDIR:M${ts})
SUBDIR+= ${ts}
.endif
.endfor
+.endif
# it is rare for test cases to have man pages
.if !defined(MAN)
@@ -80,19 +84,14 @@ PROGS_TARGETS+= install
.include <suite.test.mk>
.endif
-.if !target(realtest)
-realtest: .PHONY
+.if !target(realcheck)
+realcheck: .PHONY
@echo "$@ not defined; skipping"
.endif
-test: .PHONY
-.ORDER: beforetest realtest
-test: beforetest realtest
-
-.if target(aftertest)
-.ORDER: realtest aftertest
-test: aftertest
-.endif
+beforecheck realcheck aftercheck check: .PHONY
+.ORDER: beforecheck realcheck aftercheck
+check: beforecheck realcheck aftercheck
.ifdef PROG
# we came here via bsd.progs.mk below
diff --git a/share/mk/suite.test.mk b/share/mk/suite.test.mk
index 2b87d7f..646d2eb 100644
--- a/share/mk/suite.test.mk
+++ b/share/mk/suite.test.mk
@@ -50,15 +50,12 @@ FILES+= Kyuafile
FILESDIR_Kyuafile= ${TESTSDIR}
.endif
-.if ${KYUAFILE:tl} == "auto"
-CLEANFILES+= Kyuafile Kyuafile.tmp
-.endif
-
.for _T in ${_TESTS}
_TEST_METADATA.${_T}= ${TEST_METADATA} ${TEST_METADATA.${_T}}
.endfor
.if ${KYUAFILE:tl} == "auto"
+CLEANFILES+= Kyuafile Kyuafile.tmp
Kyuafile: Makefile
@{ \
echo '-- Automatically generated by bsd.test.mk.'; \
@@ -78,9 +75,11 @@ Kyuafile: Makefile
@mv ${.TARGET}.tmp ${.TARGET}
.endif
+CHECKDIR?= ${DESTDIR}${TESTSDIR}
+
KYUA= ${LOCALBASE}/bin/kyua
-.if exists(${KYUA})
-# Definition of the "make test" target and supporting variables.
+
+# Definition of the "make check" target and supporting variables.
#
# This target, by necessity, can only work for native builds (i.e. a FreeBSD
# host building a release for the same system). The target runs Kyua, which is
@@ -89,35 +88,15 @@ KYUA= ${LOCALBASE}/bin/kyua
# Due to the dependencies of the binaries built by the source tree and how they
# are used by tests, it is highly possible for a execution of "make test" to
# report bogus results unless the new binaries are put in place.
-realtest: .PHONY
- @echo "*** WARNING: make test is experimental"
- @echo "***"
- @echo "*** Using this test does not preclude you from running the tests"
- @echo "*** installed in ${TESTSBASE}. This test run may raise false"
- @echo "*** positives and/or false negatives."
- @echo
- @${KYUA} test -k ${DESTDIR}${TESTSDIR}/Kyuafile; \
- result=0; \
- echo; \
- echo "*** Once again, note that "make test" is unsupported."; \
- test $${result} -eq 0
-.endif
-beforetest: .PHONY
-.if defined(TESTSDIR)
-.if ${TESTSDIR} == ${TESTSBASE}
-# Forbid running from ${TESTSBASE}. It can cause false positives/negatives and
-# it does not cover all the tests (e.g. it misses testing software in external).
- @echo "*** Sorry, you cannot use make test from src/tests. Install the"
- @echo "*** tests into their final location and run them from ${TESTSBASE}"
- @false
-.else
- @echo "*** Using this test does not preclude you from running the tests"
- @echo "*** installed in ${TESTSBASE}. This test run may raise false"
- @echo "*** positives and/or false negatives."
-.endif
-.else
- @echo "*** No TESTSDIR defined; nothing to do."
- @false
-.endif
- @echo
+realcheck: .PHONY
+ @if [ ! -x ${KYUA} ]; then \
+ echo; \
+ echo "kyua binary not installed at expected location (${.TARGET})"; \
+ echo; \
+ echo "Please install via pkg install, or specify the path to the kyua"; \
+ echo "package via the \$${LOCALBASE} variable, e.g. "; \
+ echo "LOCALBASE=\"${LOCALBASE}\""; \
+ false; \
+ fi
+ @${KYUA} test -k ${CHECKDIR}/Kyuafile
diff --git a/sys/amd64/amd64/uma_machdep.c b/sys/amd64/amd64/uma_machdep.c
index db566ae..fc343ca 100644
--- a/sys/amd64/amd64/uma_machdep.c
+++ b/sys/amd64/amd64/uma_machdep.c
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/systm.h>
+#include <sys/taskqueue.h>
#include <vm/vm.h>
#include <vm/vm_page.h>
#include <vm/vm_pageout.h>
diff --git a/sys/arm/allwinner/a20/a20_mp.c b/sys/arm/allwinner/a20/a20_mp.c
index 27cbb3d..ba9ce9a 100644
--- a/sys/arm/allwinner/a20/a20_mp.c
+++ b/sys/arm/allwinner/a20/a20_mp.c
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/pmap.h>
+#include <machine/cpu.h>
#include <machine/smp.h>
#include <machine/fdt.h>
#include <machine/intr.h>
@@ -101,8 +102,7 @@ platform_mp_start_ap(void)
&cpucfg) != 0)
panic("Couldn't map the CPUCFG\n");
- cpu_idcache_wbinv_all();
- cpu_l2cache_wbinv_all();
+ dcache_wbinv_poc_all();
bus_space_write_4(fdtbus_bs_tag, cpucfg, CPUCFG_P_REG0,
pmap_kextract((vm_offset_t)mpentry));
diff --git a/sys/arm/altera/socfpga/socfpga_mp.c b/sys/arm/altera/socfpga/socfpga_mp.c
index 46977f6..e057eb3 100644
--- a/sys/arm/altera/socfpga/socfpga_mp.c
+++ b/sys/arm/altera/socfpga/socfpga_mp.c
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/pmap.h>
+#include <machine/cpu.h>
#include <machine/smp.h>
#include <machine/fdt.h>
#include <machine/intr.h>
@@ -162,8 +163,7 @@ platform_mp_start_ap(void)
bus_space_write_region_4(fdtbus_bs_tag, ram, 0,
(uint32_t *)&socfpga_trampoline, 8);
- cpu_idcache_wbinv_all();
- cpu_l2cache_wbinv_all();
+ dcache_wbinv_poc_all();
/* Put CPU1 out from reset */
bus_space_write_4(fdtbus_bs_tag, rst, MPUMODRST, 0);
diff --git a/sys/arm/amlogic/aml8726/aml8726_mp.c b/sys/arm/amlogic/aml8726/aml8726_mp.c
index 779a793..c508135 100644
--- a/sys/arm/amlogic/aml8726/aml8726_mp.c
+++ b/sys/arm/amlogic/aml8726/aml8726_mp.c
@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/pmap.h>
+#include <machine/cpu.h>
#include <machine/bus.h>
#include <machine/smp.h>
#include <machine/fdt.h>
@@ -485,7 +486,7 @@ platform_mp_start_ap(void)
value |= AML_SCU_CONTROL_ENABLE;
SCU_WRITE_4(AML_SCU_CONTROL_REG, value);
SCU_BARRIER(AML_SCU_CONTROL_REG);
- cpu_idcache_wbinv_all();
+ dcache_wbinv_poc_all();
/* Set the boot address and power on each AP. */
paddr = pmap_kextract((vm_offset_t)mpentry);
diff --git a/sys/arm/arm/cpufunc.c b/sys/arm/arm/cpufunc.c
index 514a6b1..1398991 100644
--- a/sys/arm/arm/cpufunc.c
+++ b/sys/arm/arm/cpufunc.c
@@ -60,18 +60,7 @@ __FBSDID("$FreeBSD$");
#include <machine/cpuconf.h>
#include <machine/cpufunc.h>
-#if defined(CPU_XSCALE_80321) || defined(CPU_XSCALE_80219)
-#include <arm/xscale/i80321/i80321reg.h>
-#include <arm/xscale/i80321/i80321var.h>
-#endif
-
-/*
- * Some definitions in i81342reg.h clash with i80321reg.h.
- * This only happens for the LINT kernel. As it happens,
- * we don't need anything from i81342reg.h that we already
- * got from somewhere else during a LINT compile.
- */
-#if defined(CPU_XSCALE_81342) && !defined(COMPILING_LINT)
+#if defined(CPU_XSCALE_81342)
#include <arm/xscale/i8134x/i81342reg.h>
#endif
@@ -99,8 +88,6 @@ u_int arm_cache_level;
u_int arm_cache_type[14];
u_int arm_cache_loc;
-int ctrl;
-
#ifdef CPU_ARM9
struct cpu_functions arm9_cpufuncs = {
/* CPU functions */
@@ -121,7 +108,6 @@ struct cpu_functions arm9_cpufuncs = {
/* Cache operations */
- arm9_icache_sync_all, /* icache_sync_all */
arm9_icache_sync_range, /* icache_sync_range */
arm9_dcache_wbinv_all, /* dcache_wbinv_all */
@@ -173,7 +159,6 @@ struct cpu_functions armv5_ec_cpufuncs = {
/* Cache operations */
- armv5_ec_icache_sync_all, /* icache_sync_all */
armv5_ec_icache_sync_range, /* icache_sync_range */
armv5_ec_dcache_wbinv_all, /* dcache_wbinv_all */
@@ -224,7 +209,6 @@ struct cpu_functions sheeva_cpufuncs = {
/* Cache operations */
- armv5_ec_icache_sync_all, /* icache_sync_all */
armv5_ec_icache_sync_range, /* icache_sync_range */
armv5_ec_dcache_wbinv_all, /* dcache_wbinv_all */
@@ -275,7 +259,6 @@ struct cpu_functions pj4bv7_cpufuncs = {
armv7_tlb_flushID_SE, /* tlb_flushD_SE */
/* Cache operations */
- armv7_idcache_wbinv_all, /* icache_sync_all */
armv7_icache_sync_range, /* icache_sync_range */
armv7_dcache_wbinv_all, /* dcache_wbinv_all */
@@ -306,9 +289,7 @@ struct cpu_functions pj4bv7_cpufuncs = {
};
#endif /* CPU_MV_PJ4B */
-#if defined(CPU_XSCALE_80321) || \
- defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \
- defined(CPU_XSCALE_80219)
+#if defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425)
struct cpu_functions xscale_cpufuncs = {
/* CPU functions */
@@ -329,7 +310,6 @@ struct cpu_functions xscale_cpufuncs = {
/* Cache operations */
- xscale_cache_syncI, /* icache_sync_all */
xscale_cache_syncI_rng, /* icache_sync_range */
xscale_cache_purgeD, /* dcache_wbinv_all */
@@ -359,8 +339,7 @@ struct cpu_functions xscale_cpufuncs = {
xscale_setup /* cpu setup */
};
#endif
-/* CPU_XSCALE_80321 || CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425
- CPU_XSCALE_80219 */
+/* CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425 */
#ifdef CPU_XSCALE_81342
struct cpu_functions xscalec3_cpufuncs = {
@@ -382,7 +361,6 @@ struct cpu_functions xscalec3_cpufuncs = {
/* Cache operations */
- xscalec3_cache_syncI, /* icache_sync_all */
xscalec3_cache_syncI_rng, /* icache_sync_range */
xscalec3_cache_purgeD, /* dcache_wbinv_all */
@@ -434,7 +412,6 @@ struct cpu_functions fa526_cpufuncs = {
/* Cache operations */
- fa526_icache_sync_all, /* icache_sync_all */
fa526_icache_sync_range, /* icache_sync_range */
fa526_dcache_wbinv_all, /* dcache_wbinv_all */
@@ -486,7 +463,6 @@ struct cpu_functions arm1176_cpufuncs = {
/* Cache operations */
- arm11x6_icache_sync_all, /* icache_sync_all */
arm11x6_icache_sync_range, /* icache_sync_range */
arm11x6_dcache_wbinv_all, /* dcache_wbinv_all */
@@ -542,7 +518,6 @@ struct cpu_functions cortexa_cpufuncs = {
/* Cache operations */
- armv7_icache_sync_all, /* icache_sync_all */
armv7_icache_sync_range, /* icache_sync_range */
armv7_dcache_wbinv_all, /* dcache_wbinv_all */
@@ -588,10 +563,10 @@ u_int cpu_reset_needs_v4_MMU_disable; /* flag used in locore.s */
#if defined(CPU_ARM9) || \
defined (CPU_ARM9E) || \
- defined(CPU_ARM1176) || defined(CPU_XSCALE_80321) || \
+ defined(CPU_ARM1176) || \
defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \
defined(CPU_FA526) || defined(CPU_MV_PJ4B) || \
- defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) || \
+ defined(CPU_XSCALE_81342) || \
defined(CPU_CORTEXA) || defined(CPU_KRAIT)
/* Global cache line sizes, use 32 as default */
@@ -829,18 +804,6 @@ set_cpufuncs()
}
#endif /* CPU_FA526 */
-#if defined(CPU_XSCALE_80321) || defined(CPU_XSCALE_80219)
- if (cputype == CPU_ID_80321_400 || cputype == CPU_ID_80321_600 ||
- cputype == CPU_ID_80321_400_B0 || cputype == CPU_ID_80321_600_B0 ||
- cputype == CPU_ID_80219_400 || cputype == CPU_ID_80219_600) {
- cpufuncs = xscale_cpufuncs;
- cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */
- get_cachetype_cp15();
- pmap_pte_init_xscale();
- goto out;
- }
-#endif /* CPU_XSCALE_80321 */
-
#if defined(CPU_XSCALE_81342)
if (cputype == CPU_ID_81342) {
cpufuncs = xscalec3_cpufuncs;
@@ -924,7 +887,6 @@ arm9_setup(void)
/* Set the control register */
cpu_control(cpuctrlmask, cpuctrl);
- ctrl = cpuctrl;
}
#endif /* CPU_ARM9 */
@@ -963,7 +925,6 @@ arm10_setup(void)
cpuctrl |= CPU_CONTROL_VECRELOC;
/* Set the control register */
- ctrl = cpuctrl;
cpu_control(0xffffffff, cpuctrl);
/* And again. */
@@ -1005,47 +966,12 @@ cpu_scc_setup_ccnt(void)
void
arm11x6_setup(void)
{
- int cpuctrl, cpuctrl_wax;
uint32_t auxctrl, auxctrl_wax;
uint32_t tmp, tmp2;
- uint32_t sbz=0;
uint32_t cpuid;
cpuid = cpu_ident();
- cpuctrl =
- CPU_CONTROL_MMU_ENABLE |
- CPU_CONTROL_DC_ENABLE |
- CPU_CONTROL_WBUF_ENABLE |
- CPU_CONTROL_32BP_ENABLE |
- CPU_CONTROL_32BD_ENABLE |
- CPU_CONTROL_LABT_ENABLE |
- CPU_CONTROL_SYST_ENABLE |
- CPU_CONTROL_IC_ENABLE |
- CPU_CONTROL_UNAL_ENABLE;
-
- /*
- * "write as existing" bits
- * inverse of this is mask
- */
- cpuctrl_wax =
- (3 << 30) | /* SBZ */
- (1 << 29) | /* FA */
- (1 << 28) | /* TR */
- (3 << 26) | /* SBZ */
- (3 << 19) | /* SBZ */
- (1 << 17); /* SBZ */
-
- cpuctrl |= CPU_CONTROL_BPRD_ENABLE;
- cpuctrl |= CPU_CONTROL_V6_EXTPAGE;
-
-#ifdef __ARMEB__
- cpuctrl |= CPU_CONTROL_BEND_ENABLE;
-#endif
-
- if (vector_page == ARM_VECTORS_HIGH)
- cpuctrl |= CPU_CONTROL_VECRELOC;
-
auxctrl = 0;
auxctrl_wax = ~0;
@@ -1057,19 +983,6 @@ arm11x6_setup(void)
auxctrl_wax = ~ARM1176_AUXCTL_PHD;
}
- /* Clear out the cache */
- cpu_idcache_wbinv_all();
-
- /* Now really make sure they are clean. */
- __asm volatile ("mcr\tp15, 0, %0, c7, c7, 0" : : "r"(sbz));
-
- /* Allow detection code to find the VFP if it's fitted. */
- cp15_cpacr_set(0x0fffffff);
-
- /* Set the control register */
- ctrl = cpuctrl;
- cpu_control(~cpuctrl_wax, cpuctrl);
-
tmp = cp15_actlr_get();
tmp2 = tmp;
tmp &= auxctrl_wax;
@@ -1077,9 +990,6 @@ arm11x6_setup(void)
if (tmp != tmp2)
cp15_actlr_set(tmp);
- /* And again. */
- cpu_idcache_wbinv_all();
-
cpu_scc_setup_ccnt();
}
#endif /* CPU_ARM1176 */
@@ -1088,33 +998,8 @@ arm11x6_setup(void)
void
pj4bv7_setup(void)
{
- int cpuctrl;
pj4b_config();
-
- cpuctrl = CPU_CONTROL_MMU_ENABLE;
-#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
- cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
-#endif
- cpuctrl |= CPU_CONTROL_DC_ENABLE;
- cpuctrl |= (0xf << 3);
- cpuctrl |= CPU_CONTROL_BPRD_ENABLE;
- cpuctrl |= CPU_CONTROL_IC_ENABLE;
- if (vector_page == ARM_VECTORS_HIGH)
- cpuctrl |= CPU_CONTROL_VECRELOC;
- cpuctrl |= (0x5 << 16) | (1 < 22);
- cpuctrl |= CPU_CONTROL_V6_EXTPAGE;
-
- /* Clear out the cache */
- cpu_idcache_wbinv_all();
-
- /* Set the control register */
- ctrl = cpuctrl;
- cpu_control(0xFFFFFFFF, cpuctrl);
-
- /* And again. */
- cpu_idcache_wbinv_all();
-
cpu_scc_setup_ccnt();
}
#endif /* CPU_MV_PJ4B */
@@ -1124,45 +1009,6 @@ pj4bv7_setup(void)
void
cortexa_setup(void)
{
- int cpuctrl, cpuctrlmask;
-
- cpuctrlmask = CPU_CONTROL_MMU_ENABLE | /* MMU enable [0] */
- CPU_CONTROL_AFLT_ENABLE | /* Alignment fault [1] */
- CPU_CONTROL_DC_ENABLE | /* DCache enable [2] */
- CPU_CONTROL_BPRD_ENABLE | /* Branch prediction [11] */
- CPU_CONTROL_IC_ENABLE | /* ICache enable [12] */
- CPU_CONTROL_VECRELOC; /* Vector relocation [13] */
-
- cpuctrl = CPU_CONTROL_MMU_ENABLE |
- CPU_CONTROL_IC_ENABLE |
- CPU_CONTROL_DC_ENABLE |
- CPU_CONTROL_BPRD_ENABLE;
-
-#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
- cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
-#endif
-
- /* Switch to big endian */
-#ifdef __ARMEB__
- cpuctrl |= CPU_CONTROL_BEND_ENABLE;
-#endif
-
- /* Check if the vector page is at the high address (0xffff0000) */
- if (vector_page == ARM_VECTORS_HIGH)
- cpuctrl |= CPU_CONTROL_VECRELOC;
-
- /* Clear out the cache */
- cpu_idcache_wbinv_all();
-
- /* Set the control register */
- ctrl = cpuctrl;
- cpu_control(cpuctrlmask, cpuctrl);
-
- /* And again. */
- cpu_idcache_wbinv_all();
-#if defined(SMP) && !defined(ARM_NEW_PMAP)
- armv7_auxctrl((1 << 6) | (1 << 0), (1 << 6) | (1 << 0)); /* Enable SMP + TLB broadcasting */
-#endif
cpu_scc_setup_ccnt();
}
@@ -1202,14 +1048,12 @@ fa526_setup(void)
cpu_idcache_wbinv_all();
/* Set the control register */
- ctrl = cpuctrl;
cpu_control(0xffffffff, cpuctrl);
}
#endif /* CPU_FA526 */
-#if defined(CPU_XSCALE_80321) || \
- defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \
- defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342)
+#if defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \
+ defined(CPU_XSCALE_81342)
void
xscale_setup(void)
{
@@ -1257,7 +1101,6 @@ xscale_setup(void)
* Set the control register. Note that bits 6:3 must always
* be set to 1.
*/
- ctrl = cpuctrl;
/* cpu_control(cpuctrlmask, cpuctrl);*/
cpu_control(0xffffffff, cpuctrl);
@@ -1276,5 +1119,4 @@ xscale_setup(void)
__asm __volatile("mcr p15, 0, %0, c1, c0, 1"
: : "r" (auxctl));
}
-#endif /* CPU_XSCALE_80321 || CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425
- CPU_XSCALE_80219 */
+#endif /* CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425 */
diff --git a/sys/arm/arm/cpufunc_asm_arm11x6.S b/sys/arm/arm/cpufunc_asm_arm11x6.S
index be6d530..793c690 100644
--- a/sys/arm/arm/cpufunc_asm_arm11x6.S
+++ b/sys/arm/arm/cpufunc_asm_arm11x6.S
@@ -132,12 +132,6 @@ ENTRY_NP(arm11x6_dcache_wbinv_all)
RET
END(arm11x6_dcache_wbinv_all)
-ENTRY_NP(arm11x6_icache_sync_all)
- Flush_D_cache(r0)
- Invalidate_I_cache(r0, r1)
- RET
-END(arm11x6_icache_sync_all)
-
ENTRY_NP(arm11x6_icache_sync_range)
add r1, r1, r0
sub r1, r1, #1
diff --git a/sys/arm/arm/cpufunc_asm_arm9.S b/sys/arm/arm/cpufunc_asm_arm9.S
index 9247b0c..aaadcfe 100644
--- a/sys/arm/arm/cpufunc_asm_arm9.S
+++ b/sys/arm/arm/cpufunc_asm_arm9.S
@@ -85,9 +85,7 @@ ENTRY_NP(arm9_icache_sync_range)
subs r1, r1, ip
bhi .Larm9_sync_next
mov pc, lr
-END(arm9_icache_sync_range)
-ENTRY_NP(arm9_icache_sync_all)
.Larm9_icache_sync_all:
/*
* We assume that the code here can never be out of sync with the
@@ -109,7 +107,7 @@ ENTRY_NP(arm9_icache_sync_all)
subs s_max, s_max, s_inc
bhs .Lnext_set /* Next set */
mov pc, lr
-END(arm9_icache_sync_all)
+END(arm9_icache_sync_range)
.Larm9_line_size:
.word _C_LABEL(arm_pdcache_line_size)
diff --git a/sys/arm/arm/cpufunc_asm_armv5_ec.S b/sys/arm/arm/cpufunc_asm_armv5_ec.S
index 31174c6..29e22b0 100644
--- a/sys/arm/arm/cpufunc_asm_armv5_ec.S
+++ b/sys/arm/arm/cpufunc_asm_armv5_ec.S
@@ -91,9 +91,7 @@ ENTRY_NP(armv5_ec_icache_sync_range)
bpl 1b
mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
RET
-END(armv5_ec_icache_sync_range)
-ENTRY_NP(armv5_ec_icache_sync_all)
.Larmv5_ec_icache_sync_all:
/*
* We assume that the code here can never be out of sync with the
@@ -109,7 +107,7 @@ ENTRY_NP(armv5_ec_icache_sync_all)
bne 1b /* More to do? */
mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
RET
-END(armv5_ec_icache_sync_all)
+END(armv5_ec_icache_sync_range)
.Larmv5_ec_line_size:
.word _C_LABEL(arm_pdcache_line_size)
diff --git a/sys/arm/arm/cpufunc_asm_armv7.S b/sys/arm/arm/cpufunc_asm_armv7.S
index 42ccc6d..affd5281 100644
--- a/sys/arm/arm/cpufunc_asm_armv7.S
+++ b/sys/arm/arm/cpufunc_asm_armv7.S
@@ -252,16 +252,6 @@ ENTRY(armv7_idcache_wbinv_range)
RET
END(armv7_idcache_wbinv_range)
-ENTRY_NP(armv7_icache_sync_all)
-#ifdef SMP
- mcr CP15_ICIALLUIS
-#else
- mcr CP15_ICIALLU
-#endif
- dsb /* data synchronization barrier */
- isb /* instruction synchronization barrier */
- RET
-END(armv7_icache_sync_all)
ENTRY_NP(armv7_icache_sync_range)
ldr ip, .Larmv7_icache_line_size
diff --git a/sys/arm/arm/cpufunc_asm_fa526.S b/sys/arm/arm/cpufunc_asm_fa526.S
index 38cb11a..20530ac 100644
--- a/sys/arm/arm/cpufunc_asm_fa526.S
+++ b/sys/arm/arm/cpufunc_asm_fa526.S
@@ -83,12 +83,6 @@ ENTRY(fa526_idcache_wbinv_all)
mov pc, lr
END(fa526_idcache_wbinv_all)
-ENTRY(fa526_icache_sync_all)
- mov r0, #0
- mcr p15, 0, r0, c7, c5, 0 /* invalidate I$ */
- mov pc, lr
-END(fa526_icache_sync_all)
-
ENTRY(fa526_dcache_wbinv_all)
mov r0, #0
mcr p15, 0, r0, c7, c14, 0 /* clean and invalidate D$ */
@@ -170,7 +164,7 @@ END(fa526_idcache_wbinv_range)
ENTRY(fa526_icache_sync_range)
cmp r1, #0x4000
- bhs _C_LABEL(fa526_icache_sync_all)
+ bhs .Lfa526_icache_sync_all
and r2, r0, #(CACHELINE_SIZE - 1)
add r1, r1, r2
@@ -184,6 +178,11 @@ ENTRY(fa526_icache_sync_range)
2: mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */
mov pc, lr
+
+.Lfa526_icache_sync_all:
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 /* invalidate I$ */
+ mov pc, lr
END(fa526_icache_sync_range)
ENTRY(fa526_context_switch)
diff --git a/sys/arm/arm/cpufunc_asm_xscale.S b/sys/arm/arm/cpufunc_asm_xscale.S
index 3031b8c..8b9848c 100644
--- a/sys/arm/arm/cpufunc_asm_xscale.S
+++ b/sys/arm/arm/cpufunc_asm_xscale.S
@@ -80,9 +80,6 @@ __FBSDID("$FreeBSD$");
*/
#define DCACHE_SIZE 0x00008000
-.Lblock_userspace_access:
- .word _C_LABEL(block_userspace_access)
-
/*
* CPWAIT -- Canonical method to wait for CP15 update.
* From: Intel 80200 manual, section 2.3.3.
@@ -137,11 +134,6 @@ ENTRY(xscale_setttb)
mrs r3, cpsr
orr r1, r3, #(PSR_I | PSR_F)
msr cpsr_fsxc, r1
-#else
- ldr r3, .Lblock_userspace_access
- ldr r2, [r3]
- orr r1, r2, #1
- str r1, [r3]
#endif
stmfd sp!, {r0-r3, lr}
bl _C_LABEL(xscale_cache_cleanID)
@@ -165,8 +157,6 @@ ENTRY(xscale_setttb)
#ifdef CACHE_CLEAN_BLOCK_INTR
msr cpsr_fsxc, r3
-#else
- str r2, [r3]
#endif
RET
END(xscale_setttb)
@@ -273,14 +263,9 @@ _C_LABEL(xscale_minidata_clean_size):
#define XSCALE_CACHE_CLEAN_UNBLOCK \
msr cpsr_fsxc, r3
#else
-#define XSCALE_CACHE_CLEAN_BLOCK \
- ldr r3, .Lblock_userspace_access ; \
- ldr ip, [r3] ; \
- orr r0, ip, #1 ; \
- str r0, [r3]
+#define XSCALE_CACHE_CLEAN_BLOCK
-#define XSCALE_CACHE_CLEAN_UNBLOCK \
- str ip, [r3]
+#define XSCALE_CACHE_CLEAN_UNBLOCK
#endif /* CACHE_CLEAN_BLOCK_INTR */
#define XSCALE_CACHE_CLEAN_PROLOGUE \
diff --git a/sys/arm/arm/cpufunc_asm_xscale_c3.S b/sys/arm/arm/cpufunc_asm_xscale_c3.S
index cb770a8..4e2c999 100644
--- a/sys/arm/arm/cpufunc_asm_xscale_c3.S
+++ b/sys/arm/arm/cpufunc_asm_xscale_c3.S
@@ -82,9 +82,6 @@ __FBSDID("$FreeBSD$");
*/
#define DCACHE_SIZE 0x00008000
-.Lblock_userspace_access:
- .word _C_LABEL(block_userspace_access)
-
/*
* CPWAIT -- Canonical method to wait for CP15 update.
* From: Intel 80200 manual, section 2.3.3.
@@ -130,16 +127,8 @@ __FBSDID("$FreeBSD$");
msr cpsr_fsxc, r4 ; \
ldmfd sp!, {r4}
#else
-#define XSCALE_CACHE_CLEAN_BLOCK \
- stmfd sp!, {r4} ; \
- ldr r4, .Lblock_userspace_access ; \
- ldr ip, [r4] ; \
- orr r0, ip, #1 ; \
- str r0, [r4]
-
-#define XSCALE_CACHE_CLEAN_UNBLOCK \
- str ip, [r3] ; \
- ldmfd sp!, {r4}
+#define XSCALE_CACHE_CLEAN_BLOCK
+#define XSCALE_CACHE_CLEAN_UNBLOCK
#endif /* CACHE_CLEAN_BLOCK_INTR */
@@ -352,11 +341,6 @@ ENTRY(xscalec3_setttb)
mrs r3, cpsr
orr r1, r3, #(PSR_I | PSR_F)
msr cpsr_fsxc, r1
-#else
- ldr r3, .Lblock_userspace_access
- ldr r2, [r3]
- orr r1, r2, #1
- str r1, [r3]
#endif
stmfd sp!, {r0-r3, lr}
bl _C_LABEL(xscalec3_cache_cleanID)
diff --git a/sys/arm/arm/cpuinfo.c b/sys/arm/arm/cpuinfo.c
index 5e96cae..b2d96a7 100644
--- a/sys/arm/arm/cpuinfo.c
+++ b/sys/arm/arm/cpuinfo.c
@@ -31,8 +31,8 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
+#include <machine/cpu.h>
#include <machine/cpuinfo.h>
-#include <machine/cpu-v6.h>
struct cpuinfo cpuinfo =
{
@@ -83,14 +83,16 @@ cpuinfo_init(void)
/* CP15 c0,c0 regs 0-7 exist on all CPUs (although aliased with MIDR) */
cpuinfo.ctr = cp15_ctr_get();
cpuinfo.tcmtr = cp15_tcmtr_get();
+#if __ARM_ARCH >= 6
cpuinfo.tlbtr = cp15_tlbtr_get();
cpuinfo.mpidr = cp15_mpidr_get();
cpuinfo.revidr = cp15_revidr_get();
+#endif
/* if CPU is not v7 cpu id scheme */
if (cpuinfo.architecture != 0xF)
return;
-
+#if __ARM_ARCH >= 6
cpuinfo.id_pfr0 = cp15_id_pfr0_get();
cpuinfo.id_pfr1 = cp15_id_pfr1_get();
cpuinfo.id_dfr0 = cp15_id_dfr0_get();
@@ -144,6 +146,7 @@ cpuinfo_init(void)
}
cpuinfo.dcache_line_mask = cpuinfo.dcache_line_size - 1;
cpuinfo.icache_line_mask = cpuinfo.icache_line_size - 1;
+#endif
}
/*
diff --git a/sys/arm/arm/db_interface.c b/sys/arm/arm/db_interface.c
index 613dc08..bc49dc6 100644
--- a/sys/arm/arm/db_interface.c
+++ b/sys/arm/arm/db_interface.c
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
#include "opt_ddb.h"
#include <sys/param.h>
+#include <sys/cons.h>
#include <sys/proc.h>
#include <sys/reboot.h>
#include <sys/systm.h> /* just for boothowto */
@@ -53,9 +54,9 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_extern.h>
#include <machine/db_machdep.h>
+#include <machine/cpu.h>
#include <machine/machdep.h>
#include <machine/vmparam.h>
-#include <machine/cpu.h>
#include <ddb/ddb.h>
#include <ddb/db_access.h>
@@ -63,7 +64,7 @@ __FBSDID("$FreeBSD$");
#include <ddb/db_output.h>
#include <ddb/db_variables.h>
#include <ddb/db_sym.h>
-#include <sys/cons.h>
+
static int nil = 0;
@@ -245,11 +246,10 @@ db_write_bytes(vm_offset_t addr, size_t size, char *data)
}
/* make sure the caches and memory are in sync */
- cpu_icache_sync_range(addr, size);
+ icache_sync(addr, size);
/* In case the current page tables have been modified ... */
- cpu_tlb_flushID();
- cpu_cpwait();
+ tlb_flush_all();
return (0);
}
diff --git a/sys/arm/arm/debug_monitor.c b/sys/arm/arm/debug_monitor.c
index e216e34..eaf88e9 100644
--- a/sys/arm/arm/debug_monitor.c
+++ b/sys/arm/arm/debug_monitor.c
@@ -845,8 +845,10 @@ dbg_arch_supported(void)
{
switch (dbg_model) {
+#ifdef not_yet
case ID_DFR0_CP_DEBUG_M_V6:
case ID_DFR0_CP_DEBUG_M_V6_1:
+#endif
case ID_DFR0_CP_DEBUG_M_V7:
case ID_DFR0_CP_DEBUG_M_V7_1: /* fall through */
return (TRUE);
diff --git a/sys/arm/arm/devmap.c b/sys/arm/arm/devmap.c
index 380e129..011b579 100644
--- a/sys/arm/arm/devmap.c
+++ b/sys/arm/arm/devmap.c
@@ -40,7 +40,9 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/vm_extern.h>
#include <vm/pmap.h>
+#ifdef __arm__
#include <machine/acle-compat.h>
+#endif
#include <machine/armreg.h>
#include <machine/devmap.h>
#include <machine/vmparam.h>
@@ -53,9 +55,6 @@ static boolean_t devmap_bootstrap_done = false;
#define PTE_DEVICE VM_MEMATTR_DEVICE
#elif defined(__arm__)
#define MAX_VADDR ARM_VECTORS_HIGH
-#if __ARM_ARCH >= 6
-#define PTE_DEVICE VM_MEMATTR_DEVICE
-#endif
#endif
/*
diff --git a/sys/arm/arm/dump_machdep.c b/sys/arm/arm/dump_machdep.c
index e87d3e7..2c11141 100644
--- a/sys/arm/arm/dump_machdep.c
+++ b/sys/arm/arm/dump_machdep.c
@@ -59,8 +59,7 @@ dumpsys_wbinv_all(void)
* have already been stopped, and their flush/invalidate was done as
* part of stopping.
*/
- cpu_idcache_wbinv_all();
- cpu_l2cache_wbinv_all();
+ dcache_wbinv_poc_all();
#ifdef __XSCALE__
xscale_cache_clean_minidata();
#endif
diff --git a/sys/arm/arm/elf_machdep.c b/sys/arm/arm/elf_machdep.c
index 7dbdc91..2ec659a 100644
--- a/sys/arm/arm/elf_machdep.c
+++ b/sys/arm/arm/elf_machdep.c
@@ -282,7 +282,7 @@ elf_cpu_load_file(linker_file_t lf)
#else
cpu_dcache_wb_range((vm_offset_t)lf->address, (vm_size_t)lf->size);
cpu_l2cache_wb_range((vm_offset_t)lf->address, (vm_size_t)lf->size);
- cpu_icache_sync_all();
+ cpu_icache_sync_range((vm_offset_t)lf->address, (vm_size_t)lf->size);
#endif
return (0);
}
diff --git a/sys/arm/arm/elf_trampoline.c b/sys/arm/arm/elf_trampoline.c
index 6c086ea..22f0f44 100644
--- a/sys/arm/arm/elf_trampoline.c
+++ b/sys/arm/arm/elf_trampoline.c
@@ -67,9 +67,7 @@ extern void fa526_idcache_wbinv_all(void);
extern void armv5_ec_idcache_wbinv_all(void);
#elif defined(CPU_ARM1176)
#define cpu_idcache_wbinv_all armv6_idcache_wbinv_all
-#elif defined(CPU_XSCALE_80321) || \
- defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \
- defined(CPU_XSCALE_80219)
+#elif defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425)
#define cpu_idcache_wbinv_all xscale_cache_purgeID
extern void xscale_cache_purgeID(void);
#elif defined(CPU_XSCALE_81342)
@@ -127,7 +125,6 @@ static int arm_dcache_l2_assoc;
static int arm_dcache_l2_linesize;
-int block_userspace_access = 0;
extern int arm9_dcache_sets_inc;
extern int arm9_dcache_sets_max;
extern int arm9_dcache_index_max;
diff --git a/sys/arm/arm/fiq.c b/sys/arm/arm/fiq.c
index 94231de..f475a30 100644
--- a/sys/arm/arm/fiq.c
+++ b/sys/arm/arm/fiq.c
@@ -81,8 +81,8 @@ fiq_installhandler(void *func, size_t size)
#if !defined(__ARM_FIQ_INDIRECT)
vector_page_setprot(VM_PROT_READ);
- cpu_icache_sync_range((vm_offset_t) fiqvector, size);
#endif
+ icache_sync((vm_offset_t) fiqvector, size);
}
/*
diff --git a/sys/arm/arm/fusu.S b/sys/arm/arm/fusu.S
index 54d263c..ba50e67 100644
--- a/sys/arm/arm/fusu.S
+++ b/sys/arm/arm/fusu.S
@@ -183,51 +183,10 @@ END(fusword)
*/
ENTRY(fuswintr)
- ldr r3, =(VM_MAXUSER_ADDRESS-1)
- cmp r0, r3
- mvncs r0, #0
- RETc(cs)
-
- ldr r2, Lblock_userspace_access
- ldr r2, [r2]
- teq r2, #0
- mvnne r0, #0x00000000
- RETne
-
- GET_PCB(r2)
- ldr r2, [r2]
-
-#ifdef DIAGNOSTIC
- teq r2, #0x00000000
- beq .Lfusupcbfault
-#endif
-
- adr r1, _C_LABEL(fusubailout)
- str r1, [r2, #PCB_ONFAULT]
-
- ldrbt r3, [r0], #1
- ldrbt ip, [r0]
-#ifdef __ARMEB__
- orr r0, ip, r3, asl #8
-#else
- orr r0, r3, ip, asl #8
-#endif
-
- mov r1, #0x00000000
- str r1, [r2, #PCB_ONFAULT]
+ mov r0, #-1
RET
END(fuswintr)
-Lblock_userspace_access:
- .word _C_LABEL(block_userspace_access)
-
- .data
- .align 2
- .global _C_LABEL(block_userspace_access)
-_C_LABEL(block_userspace_access):
- .word 0
- .text
-
/*
* fubyte(caddr_t uaddr);
* Fetch a byte from the user's address space.
@@ -268,20 +227,6 @@ END(fubyte)
mvn r0, #0x00000000
RET
-/*
- * Handle faults from [fs]u*(). Clean up and return -1. This differs from
- * fusufault() in that trap() will recognise it and return immediately rather
- * than trying to page fault.
- */
-
-/* label must be global as fault.c references it */
- .global _C_LABEL(fusubailout)
-_C_LABEL(fusubailout):
- mov r0, #0x00000000
- str r0, [r2, #PCB_ONFAULT]
- mvn r0, #0x00000000
- RET
-
#ifdef DIAGNOSTIC
/*
* Handle earlier faults from [fs]u*(), due to no pcb
@@ -335,39 +280,7 @@ END(suword)
*/
ENTRY(suswintr)
- ldr r3, =(VM_MAXUSER_ADDRESS-1)
- cmp r0, r3
- mvncs r0, #0
- RETc(cs)
-
- ldr r2, Lblock_userspace_access
- ldr r2, [r2]
- teq r2, #0
- mvnne r0, #0x00000000
- RETne
-
- GET_PCB(r2)
- ldr r2, [r2]
-
-#ifdef DIAGNOSTIC
- teq r2, #0x00000000
- beq .Lfusupcbfault
-#endif
-
- adr r3, _C_LABEL(fusubailout)
- str r3, [r2, #PCB_ONFAULT]
-
-#ifdef __ARMEB__
- mov ip, r1, lsr #8
- strbt ip, [r0], #1
-#else
- strbt r1, [r0], #1
- mov r1, r1, lsr #8
-#endif
- strbt r1, [r0]
-
- mov r0, #0x00000000
- str r0, [r2, #PCB_ONFAULT]
+ mov r0, #-1
RET
END(suswintr)
diff --git a/sys/arm/arm/genassym.c b/sys/arm/arm/genassym.c
index eb4e51b..4149771 100644
--- a/sys/arm/arm/genassym.c
+++ b/sys/arm/arm/genassym.c
@@ -45,7 +45,6 @@ __FBSDID("$FreeBSD$");
#include <machine/frame.h>
#include <machine/pcb.h>
#include <machine/cpu.h>
-#include <machine/cpu-v6.h>
#include <machine/proc.h>
#include <machine/cpufunc.h>
#include <machine/cpuinfo.h>
@@ -59,7 +58,6 @@ __FBSDID("$FreeBSD$");
#include <netinet/ip_var.h>
ASSYM(KERNBASE, KERNBASE);
-ASSYM(PCB_NOALIGNFLT, PCB_NOALIGNFLT);
#if __ARM_ARCH >= 6
ASSYM(CPU_ASID_KERNEL,CPU_ASID_KERNEL);
#endif
@@ -67,7 +65,6 @@ ASSYM(PCB_ONFAULT, offsetof(struct pcb, pcb_onfault));
#if __ARM_ARCH < 6
ASSYM(PCB_DACR, offsetof(struct pcb, pcb_dacr));
#endif
-ASSYM(PCB_FLAGS, offsetof(struct pcb, pcb_flags));
ASSYM(PCB_PAGEDIR, offsetof(struct pcb, pcb_pagedir));
#if __ARM_ARCH < 6
ASSYM(PCB_L1VEC, offsetof(struct pcb, pcb_l1vec));
@@ -93,24 +90,15 @@ ASSYM(M_DATA, offsetof(struct mbuf, m_data));
ASSYM(M_NEXT, offsetof(struct mbuf, m_next));
ASSYM(IP_SRC, offsetof(struct ip, ip_src));
ASSYM(IP_DST, offsetof(struct ip, ip_dst));
-ASSYM(CF_SETTTB, offsetof(struct cpu_functions, cf_setttb));
-ASSYM(CF_CONTROL, offsetof(struct cpu_functions, cf_control));
ASSYM(CF_CONTEXT_SWITCH, offsetof(struct cpu_functions, cf_context_switch));
ASSYM(CF_DCACHE_WB_RANGE, offsetof(struct cpu_functions, cf_dcache_wb_range));
-ASSYM(CF_L2CACHE_WB_RANGE, offsetof(struct cpu_functions, cf_l2cache_wb_range));
ASSYM(CF_IDCACHE_WBINV_ALL, offsetof(struct cpu_functions, cf_idcache_wbinv_all));
ASSYM(CF_L2CACHE_WBINV_ALL, offsetof(struct cpu_functions, cf_l2cache_wbinv_all));
ASSYM(CF_TLB_FLUSHID_SE, offsetof(struct cpu_functions, cf_tlb_flushID_SE));
-ASSYM(CF_ICACHE_SYNC, offsetof(struct cpu_functions, cf_icache_sync_all));
-
-ASSYM(V_TRAP, offsetof(struct vmmeter, v_trap));
-ASSYM(V_SOFT, offsetof(struct vmmeter, v_soft));
-ASSYM(V_INTR, offsetof(struct vmmeter, v_intr));
ASSYM(TD_PCB, offsetof(struct thread, td_pcb));
ASSYM(TD_FLAGS, offsetof(struct thread, td_flags));
ASSYM(TD_PROC, offsetof(struct thread, td_proc));
-ASSYM(TD_FRAME, offsetof(struct thread, td_frame));
ASSYM(TD_MD, offsetof(struct thread, td_md));
ASSYM(TD_LOCK, offsetof(struct thread, td_lock));
ASSYM(MD_TP, offsetof(struct mdthread, md_tp));
@@ -147,10 +135,6 @@ ASSYM(PMAP_INCLUDE_PTE_SYNC, 1);
#endif
ASSYM(TDF_ASTPENDING, TDF_ASTPENDING);
ASSYM(TDF_NEEDRESCHED, TDF_NEEDRESCHED);
-ASSYM(P_TRACED, P_TRACED);
-ASSYM(P_SIGEVENT, P_SIGEVENT);
-ASSYM(P_PROFIL, P_PROFIL);
-ASSYM(TRAPFRAMESIZE, sizeof(struct trapframe));
ASSYM(MAXCOMLEN, MAXCOMLEN);
ASSYM(MAXCPU, MAXCPU);
diff --git a/sys/arm/arm/identcpu.c b/sys/arm/arm/identcpu.c
index 6c5764c..2b7fec4 100644
--- a/sys/arm/arm/identcpu.c
+++ b/sys/arm/arm/identcpu.c
@@ -321,7 +321,6 @@ print_enadis(int enadis, char *s)
printf(" %s %sabled", s, (enadis == 0) ? "dis" : "en");
}
-extern int ctrl;
enum cpu_class cpu_class = CPU_CLASS_NONE;
u_int cpu_pfr(int num)
@@ -388,9 +387,10 @@ void
identify_arm_cpu(void)
{
u_int cpuid, reg, size, sets, ways;
- u_int8_t type, linesize;
+ u_int8_t type, linesize, ctrl;
int i;
+ ctrl = cpu_get_control();
cpuid = cpu_ident();
if (cpuid == 0) {
diff --git a/sys/arm/arm/locore-v6.S b/sys/arm/arm/locore-v6.S
index eda6014..b93af2c 100644
--- a/sys/arm/arm/locore-v6.S
+++ b/sys/arm/arm/locore-v6.S
@@ -132,9 +132,9 @@ ASENTRY_NP(_start)
bic r7, #CPU_CONTROL_DC_ENABLE
bic r7, #CPU_CONTROL_MMU_ENABLE
bic r7, #CPU_CONTROL_IC_ENABLE
- bic r7, #CPU_CONTROL_UNAL_ENABLE
bic r7, #CPU_CONTROL_BPRD_ENABLE
bic r7, #CPU_CONTROL_SW_ENABLE
+ orr r7, #CPU_CONTROL_UNAL_ENABLE
orr r7, #CPU_CONTROL_AFLT_ENABLE
orr r7, #CPU_CONTROL_VECRELOC
mcr CP15_SCTLR(r7)
@@ -456,9 +456,9 @@ ASENTRY_NP(mpentry)
bic r0, #CPU_CONTROL_MMU_ENABLE
bic r0, #CPU_CONTROL_DC_ENABLE
bic r0, #CPU_CONTROL_IC_ENABLE
- bic r0, #CPU_CONTROL_UNAL_ENABLE
bic r0, #CPU_CONTROL_BPRD_ENABLE
bic r0, #CPU_CONTROL_SW_ENABLE
+ orr r0, #CPU_CONTROL_UNAL_ENABLE
orr r0, #CPU_CONTROL_AFLT_ENABLE
orr r0, #CPU_CONTROL_VECRELOC
mcr CP15_SCTLR(r0)
diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c
index 8d7c39c..4e7cb70 100644
--- a/sys/arm/arm/machdep.c
+++ b/sys/arm/arm/machdep.c
@@ -123,7 +123,6 @@ __FBSDID("$FreeBSD$");
#include <ddb/ddb.h>
#if __ARM_ARCH >= 6
-#include <machine/cpu-v6.h>
DB_SHOW_COMMAND(cp15, db_show_cp15)
{
@@ -397,7 +396,7 @@ arm_vector_init(vm_offset_t va, int which)
}
/* Now sync the vectors. */
- cpu_icache_sync_range(va, (ARM_NVEC * 2) * sizeof(u_int));
+ icache_sync(va, (ARM_NVEC * 2) * sizeof(u_int));
vector_page = va;
@@ -479,12 +478,7 @@ void
cpu_flush_dcache(void *ptr, size_t len)
{
- cpu_dcache_wb_range((uintptr_t)ptr, len);
-#ifdef ARM_L2_PIPT
- cpu_l2cache_wb_range((uintptr_t)vtophys(ptr), len);
-#else
- cpu_l2cache_wb_range((uintptr_t)ptr, len);
-#endif
+ dcache_wb_poc((vm_offset_t)ptr, (vm_paddr_t)vtophys(ptr), len);
}
/* Get current clock frequency for the given cpu id. */
@@ -1622,7 +1616,7 @@ initarm(struct arm_boot_params *abp)
cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2)) | DOMAIN_CLIENT);
pmap_pa = kernel_l1pt.pv_pa;
- setttb(kernel_l1pt.pv_pa);
+ cpu_setttb(kernel_l1pt.pv_pa);
cpu_tlb_flushID();
cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2));
@@ -1675,7 +1669,7 @@ initarm(struct arm_boot_params *abp)
/*
* We must now clean the cache again....
* Cleaning may be done by reading new data to displace any
- * dirty data in the cache. This will have happened in setttb()
+ * dirty data in the cache. This will have happened in cpu_setttb()
* but since we are boot strapping the addresses used for the read
* may have just been remapped and thus the cache could be out
* of sync. A re-clean after the switch will cure this.
@@ -1867,7 +1861,7 @@ initarm(struct arm_boot_params *abp)
/*
* We must now clean the cache again....
* Cleaning may be done by reading new data to displace any
- * dirty data in the cache. This will have happened in setttb()
+ * dirty data in the cache. This will have happened in cpu_setttb()
* but since we are boot strapping the addresses used for the read
* may have just been remapped and thus the cache could be out
* of sync. A re-clean after the switch will cure this.
diff --git a/sys/arm/arm/minidump_machdep.c b/sys/arm/arm/minidump_machdep.c
index a351fb7..2eb4bfd 100644
--- a/sys/arm/arm/minidump_machdep.c
+++ b/sys/arm/arm/minidump_machdep.c
@@ -45,11 +45,11 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/pmap.h>
#include <machine/atomic.h>
+#include <machine/cpu.h>
#include <machine/elf.h>
#include <machine/md_var.h>
-#include <machine/vmparam.h>
#include <machine/minidump.h>
-#include <machine/cpufunc.h>
+#include <machine/vmparam.h>
CTASSERT(sizeof(struct kerneldumpheader) == 512);
@@ -203,8 +203,7 @@ minidumpsys(struct dumperinfo *di)
* by time we get to here, all that remains is to flush the L1 for the
* current CPU, then the L2.
*/
- cpu_idcache_wbinv_all();
- cpu_l2cache_wbinv_all();
+ dcache_wbinv_poc_all();
counter = 0;
/* Walk page table pages, set bits in vm_page_dump */
diff --git a/sys/arm/arm/mp_machdep.c b/sys/arm/arm/mp_machdep.c
index 6cedd46..8643860 100644
--- a/sys/arm/arm/mp_machdep.c
+++ b/sys/arm/arm/mp_machdep.c
@@ -123,9 +123,7 @@ cpu_mp_start(void)
dpcpu[i] = (void *)kmem_malloc(kernel_arena, DPCPU_SIZE,
M_WAITOK | M_ZERO);
- cpu_idcache_wbinv_all();
- cpu_l2cache_wbinv_all();
- cpu_idcache_wbinv_all();
+ dcache_wbinv_poc_all();
/* Initialize boot code and start up processors */
platform_mp_start_ap();
@@ -283,7 +281,7 @@ ipi_stop(void *dummy __unused)
* stop will do the l2 cache flush after all other cores
* have done their l1 flushes and stopped.
*/
- cpu_idcache_wbinv_all();
+ dcache_wbinv_poc_all();
/* Indicate we are stopped */
CPU_SET_ATOMIC(cpu, &stopped_cpus);
@@ -381,7 +379,7 @@ ipi_handler(void *arg)
* stop will do the l2 cache flush after all other cores
* have done their l1 flushes and stopped.
*/
- cpu_idcache_wbinv_all();
+ dcache_wbinv_poc_all();
/* Indicate we are stopped */
CPU_SET_ATOMIC(cpu, &stopped_cpus);
diff --git a/sys/arm/arm/pmap-v6.c b/sys/arm/arm/pmap-v6.c
index d4ab930..525280c 100644
--- a/sys/arm/arm/pmap-v6.c
+++ b/sys/arm/arm/pmap-v6.c
@@ -3,8 +3,8 @@
* Copyright (c) 1994 John S. Dyson
* Copyright (c) 1994 David Greenman
* Copyright (c) 2005-2010 Alan L. Cox <alc@cs.rice.edu>
- * Copyright (c) 2014 Svatopluk Kraus <onwahe@gmail.com>
- * Copyright (c) 2014 Michal Meloun <meloun@miracle.cz>
+ * Copyright (c) 2014-2016 Svatopluk Kraus <skra@FreeBSD.org>
+ * Copyright (c) 2014-2016 Michal Meloun <mmel@FreeBSD.org>
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
@@ -141,7 +141,6 @@ __FBSDID("$FreeBSD$");
#include <machine/md_var.h>
#include <machine/pmap_var.h>
#include <machine/cpu.h>
-#include <machine/cpu-v6.h>
#include <machine/pcb.h>
#include <machine/sf_buf.h>
#ifdef SMP
@@ -223,11 +222,14 @@ int pmap_debug_level = 1;
/*
* PTE2 descriptors creation macros.
*/
-#define PTE2_KPT(pa) PTE2_KERN(pa, PTE2_AP_KRW, pt_memattr)
-#define PTE2_KPT_NG(pa) PTE2_KERN_NG(pa, PTE2_AP_KRW, pt_memattr)
+#define PTE2_ATTR_DEFAULT vm_memattr_to_pte2(VM_MEMATTR_DEFAULT)
+#define PTE2_ATTR_PT vm_memattr_to_pte2(pt_memattr)
-#define PTE2_KRW(pa) PTE2_KERN(pa, PTE2_AP_KRW, PTE2_ATTR_NORMAL)
-#define PTE2_KRO(pa) PTE2_KERN(pa, PTE2_AP_KR, PTE2_ATTR_NORMAL)
+#define PTE2_KPT(pa) PTE2_KERN(pa, PTE2_AP_KRW, PTE2_ATTR_PT)
+#define PTE2_KPT_NG(pa) PTE2_KERN_NG(pa, PTE2_AP_KRW, PTE2_ATTR_PT)
+
+#define PTE2_KRW(pa) PTE2_KERN(pa, PTE2_AP_KRW, PTE2_ATTR_DEFAULT)
+#define PTE2_KRO(pa) PTE2_KERN(pa, PTE2_AP_KR, PTE2_ATTR_DEFAULT)
#define PV_STATS
#ifdef PV_STATS
@@ -262,10 +264,6 @@ static uint32_t ttb_flags;
static vm_memattr_t pt_memattr;
ttb_entry_t pmap_kern_ttb;
-/* XXX use converion function*/
-#define PTE2_ATTR_NORMAL VM_MEMATTR_DEFAULT
-#define PTE1_ATTR_NORMAL ATTR_TO_L1(PTE2_ATTR_NORMAL)
-
struct pmap kernel_pmap_store;
LIST_HEAD(pmaplist, pmap);
static struct pmaplist allpmaps;
@@ -399,6 +397,37 @@ static uint32_t tex_class[8] = {
};
#undef TEX
+static uint32_t pte2_attr_tab[8] = {
+ PTE2_ATTR_WB_WA, /* 0 - VM_MEMATTR_WB_WA */
+ PTE2_ATTR_NOCACHE, /* 1 - VM_MEMATTR_NOCACHE */
+ PTE2_ATTR_DEVICE, /* 2 - VM_MEMATTR_DEVICE */
+ PTE2_ATTR_SO, /* 3 - VM_MEMATTR_SO */
+ PTE2_ATTR_WT, /* 4 - VM_MEMATTR_WRITE_THROUGH */
+ 0, /* 5 - NOT USED YET */
+ 0, /* 6 - NOT USED YET */
+ 0 /* 7 - NOT USED YET */
+};
+CTASSERT(VM_MEMATTR_WB_WA == 0);
+CTASSERT(VM_MEMATTR_NOCACHE == 1);
+CTASSERT(VM_MEMATTR_DEVICE == 2);
+CTASSERT(VM_MEMATTR_SO == 3);
+CTASSERT(VM_MEMATTR_WRITE_THROUGH == 4);
+
+static inline uint32_t
+vm_memattr_to_pte2(vm_memattr_t ma)
+{
+
+ KASSERT((u_int)ma < 5, ("%s: bad vm_memattr_t %d", __func__, ma));
+ return (pte2_attr_tab[(u_int)ma]);
+}
+
+static inline uint32_t
+vm_page_pte2_attr(vm_page_t m)
+{
+
+ return (vm_memattr_to_pte2(m->md.pat_mode));
+}
+
/*
* Convert TEX definition entry to TTB flags.
*/
@@ -713,7 +742,7 @@ pmap_bootstrap_prepare(vm_paddr_t last)
pt1_entry_t *pte1p;
pt2_entry_t *pte2p;
u_int i;
- uint32_t actlr_mask, actlr_set;
+ uint32_t actlr_mask, actlr_set, l1_attr;
/*
* Now, we are going to make real kernel mapping. Note that we are
@@ -776,10 +805,10 @@ pmap_bootstrap_prepare(vm_paddr_t last)
pte1_store(pte1p++, PTE1_LINK(pa));
/* Make section mappings for kernel. */
+ l1_attr = ATTR_TO_L1(PTE2_ATTR_DEFAULT);
pte1p = kern_pte1(KERNBASE);
for (pa = KERNEL_V2P(KERNBASE); pa < last; pa += PTE1_SIZE)
- pte1_store(pte1p++, PTE1_KERN(pa, PTE1_AP_KRW,
- ATTR_TO_L1(PTE2_ATTR_WB_WA)));
+ pte1_store(pte1p++, PTE1_KERN(pa, PTE1_AP_KRW, l1_attr));
/*
* Get free and aligned space for PT2MAP and make L1 page table links
@@ -988,13 +1017,14 @@ pmap_preboot_map_attr(vm_paddr_t pa, vm_offset_t va, vm_size_t size,
vm_prot_t prot, vm_memattr_t attr)
{
u_int num;
- u_int l1_attr, l1_prot, l2_prot;
+ u_int l1_attr, l1_prot, l2_prot, l2_attr;
pt1_entry_t *pte1p;
pt2_entry_t *pte2p;
l2_prot = prot & VM_PROT_WRITE ? PTE2_AP_KRW : PTE2_AP_KR;
+ l2_attr = vm_memattr_to_pte2(attr);
l1_prot = ATTR_TO_L1(l2_prot);
- l1_attr = ATTR_TO_L1(attr);
+ l1_attr = ATTR_TO_L1(l2_attr);
/* Map all the pages. */
num = round_page(size);
@@ -1007,7 +1037,7 @@ pmap_preboot_map_attr(vm_paddr_t pa, vm_offset_t va, vm_size_t size,
num -= PTE1_SIZE;
} else {
pte2p = pmap_preboot_vtopte2(va);
- pte2_store(pte2p, PTE2_KERN(pa, l2_prot, attr));
+ pte2_store(pte2p, PTE2_KERN(pa, l2_prot, l2_attr));
va += PAGE_SIZE;
pa += PAGE_SIZE;
num -= PAGE_SIZE;
@@ -1247,7 +1277,7 @@ PMAP_INLINE void
pmap_kenter(vm_offset_t va, vm_paddr_t pa)
{
- pmap_kenter_prot_attr(va, pa, PTE2_AP_KRW, PTE2_ATTR_NORMAL);
+ pmap_kenter_prot_attr(va, pa, PTE2_AP_KRW, PTE2_ATTR_DEFAULT);
}
/*
@@ -1320,7 +1350,8 @@ pmap_map(vm_offset_t *virt, vm_paddr_t start, vm_paddr_t end, int prot)
vm_offset_t va, sva;
vm_paddr_t pte1_offset;
pt1_entry_t npte1;
- u_int l1prot,l2prot;
+ uint32_t l1prot, l2prot;
+ uint32_t l1attr, l2attr;
PDEBUG(1, printf("%s: virt = %#x, start = %#x, end = %#x (size = %#x),"
" prot = %d\n", __func__, *virt, start, end, end - start, prot));
@@ -1329,6 +1360,9 @@ pmap_map(vm_offset_t *virt, vm_paddr_t start, vm_paddr_t end, int prot)
l2prot |= (prot & VM_PROT_EXECUTE) ? PTE2_X : PTE2_NX;
l1prot = ATTR_TO_L1(l2prot);
+ l2attr = PTE2_ATTR_DEFAULT;
+ l1attr = ATTR_TO_L1(l2attr);
+
va = *virt;
/*
* Does the physical address range's size and alignment permit at
@@ -1351,13 +1385,12 @@ pmap_map(vm_offset_t *virt, vm_paddr_t start, vm_paddr_t end, int prot)
if ((start & PTE1_OFFSET) == 0 && end - start >= PTE1_SIZE) {
KASSERT((va & PTE1_OFFSET) == 0,
("%s: misaligned va %#x", __func__, va));
- npte1 = PTE1_KERN(start, l1prot, PTE1_ATTR_NORMAL);
+ npte1 = PTE1_KERN(start, l1prot, l1attr);
pmap_kenter_pte1(va, npte1);
va += PTE1_SIZE;
start += PTE1_SIZE;
} else {
- pmap_kenter_prot_attr(va, start, l2prot,
- PTE2_ATTR_NORMAL);
+ pmap_kenter_prot_attr(va, start, l2prot, l2attr);
va += PAGE_SIZE;
start += PAGE_SIZE;
}
@@ -1527,7 +1560,7 @@ pmap_page_init(vm_page_t m)
TAILQ_INIT(&m->md.pv_list);
pt2_wirecount_init(m);
- m->md.pat_mode = PTE2_ATTR_NORMAL;
+ m->md.pat_mode = VM_MEMATTR_DEFAULT;
}
/*
@@ -1562,7 +1595,7 @@ pmap_pt2pg_zero(vm_page_t m)
if (pte2_load(sysmaps->CMAP2) != 0)
panic("%s: CMAP2 busy", __func__);
pte2_store(sysmaps->CMAP2, PTE2_KERN_NG(pa, PTE2_AP_KRW,
- m->md.pat_mode));
+ vm_page_pte2_attr(m)));
/* Even VM_ALLOC_ZERO request is only advisory. */
if ((m->flags & PG_ZERO) == 0)
pagezero(sysmaps->CADDR2);
@@ -1586,7 +1619,7 @@ pmap_pt2pg_init(pmap_t pmap, vm_offset_t va, vm_page_t m)
pt2_entry_t *pte2p;
/* Check page attributes. */
- if (pmap_page_get_memattr(m) != pt_memattr)
+ if (m->md.pat_mode != pt_memattr)
pmap_page_set_memattr(m, pt_memattr);
/* Zero page and init wire counts. */
@@ -1717,10 +1750,10 @@ pmap_qenter(vm_offset_t sva, vm_page_t *ma, int count)
pa = VM_PAGE_TO_PHYS(m);
pte2 = pte2_load(pte2p);
if ((pte2_pa(pte2) != pa) ||
- (pte2_attr(pte2) != m->md.pat_mode)) {
+ (pte2_attr(pte2) != vm_page_pte2_attr(m))) {
anychanged++;
pte2_store(pte2p, PTE2_KERN(pa, PTE2_AP_KRW,
- m->md.pat_mode));
+ vm_page_pte2_attr(m)));
}
pte2p++;
}
@@ -3770,7 +3803,7 @@ validate:
/*
* Now validate mapping with desired protection/wiring.
*/
- npte2 = PTE2(pa, PTE2_NM, m->md.pat_mode);
+ npte2 = PTE2(pa, PTE2_NM, vm_page_pte2_attr(m));
if (prot & VM_PROT_WRITE) {
if (pte2_is_managed(npte2))
vm_page_aflag_set(m, PGA_WRITEABLE);
@@ -3795,7 +3828,7 @@ validate:
*/
if ((opte2 & ~(PTE2_NM | PTE2_A)) != (npte2 & ~(PTE2_NM | PTE2_A))) {
/*
- * Sync icache if exec permission and attribute PTE2_ATTR_WB_WA
+ * Sync icache if exec permission and attribute VM_MEMATTR_WB_WA
* is set. Do it now, before the mapping is stored and made
* valid for hardware table walk. If done later, there is a race
* for other threads of current process in lazy loading case.
@@ -3810,7 +3843,7 @@ validate:
* (2) Now, we do it on a page basis.
*/
if ((prot & VM_PROT_EXECUTE) && pmap != kernel_pmap &&
- m->md.pat_mode == PTE2_ATTR_WB_WA &&
+ m->md.pat_mode == VM_MEMATTR_WB_WA &&
(opa != pa || (opte2 & PTE2_NX)))
cache_icache_sync_fresh(va, pa, PAGE_SIZE);
@@ -4410,14 +4443,14 @@ pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m,
l2prot |= PTE2_U | PTE2_NG;
if ((prot & VM_PROT_EXECUTE) == 0)
l2prot |= PTE2_NX;
- else if (m->md.pat_mode == PTE2_ATTR_WB_WA && pmap != kernel_pmap) {
+ else if (m->md.pat_mode == VM_MEMATTR_WB_WA && pmap != kernel_pmap) {
/*
- * Sync icache if exec permission and attribute PTE2_ATTR_WB_WA
+ * Sync icache if exec permission and attribute VM_MEMATTR_WB_WA
* is set. QQQ: For more info, see comments in pmap_enter().
*/
cache_icache_sync_fresh(va, pa, PAGE_SIZE);
}
- pte2_store(pte2p, PTE2(pa, l2prot, m->md.pat_mode));
+ pte2_store(pte2p, PTE2(pa, l2prot, vm_page_pte2_attr(m)));
return (mpt2pg);
}
@@ -4481,14 +4514,14 @@ pmap_enter_pte1(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot)
l1prot |= PTE1_U | PTE1_NG;
if ((prot & VM_PROT_EXECUTE) == 0)
l1prot |= PTE1_NX;
- else if (m->md.pat_mode == PTE2_ATTR_WB_WA && pmap != kernel_pmap) {
+ else if (m->md.pat_mode == VM_MEMATTR_WB_WA && pmap != kernel_pmap) {
/*
- * Sync icache if exec permission and attribute PTE2_ATTR_WB_WA
+ * Sync icache if exec permission and attribute VM_MEMATTR_WB_WA
* is set. QQQ: For more info, see comments in pmap_enter().
*/
cache_icache_sync_fresh(va, pa, PTE1_SIZE);
}
- pte1_store(pte1p, PTE1(pa, l1prot, ATTR_TO_L1(m->md.pat_mode)));
+ pte1_store(pte1p, PTE1(pa, l1prot, ATTR_TO_L1(vm_page_pte2_attr(m))));
pmap_pte1_mappings++;
CTR3(KTR_PMAP, "%s: success for va %#lx in pmap %p", __func__, va,
@@ -4552,7 +4585,7 @@ pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_object_t object,
pt1_entry_t *pte1p;
vm_paddr_t pa, pte2_pa;
vm_page_t p;
- int pat_mode;
+ vm_memattr_t pat_mode;
u_int l1attr, l1prot;
VM_OBJECT_ASSERT_WLOCKED(object);
@@ -4598,7 +4631,7 @@ pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_object_t object,
* is done here, so readonly mapping must be done elsewhere.
*/
l1prot = PTE1_U | PTE1_NG | PTE1_RW | PTE1_M | PTE1_A;
- l1attr = ATTR_TO_L1(pat_mode);
+ l1attr = ATTR_TO_L1(vm_memattr_to_pte2(pat_mode));
PMAP_LOCK(pmap);
for (pa = pte2_pa; pa < pte2_pa + size; pa += PTE1_SIZE) {
pte1p = pmap_pte1(pmap, addr);
@@ -5492,7 +5525,8 @@ pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma)
mtx_lock(&sysmaps->lock);
if (*sysmaps->CMAP2)
panic("%s: CMAP2 busy", __func__);
- pte2_store(sysmaps->CMAP2, PTE2_KERN_NG(pa, PTE2_AP_KRW, ma));
+ pte2_store(sysmaps->CMAP2, PTE2_KERN_NG(pa, PTE2_AP_KRW,
+ vm_memattr_to_pte2(ma)));
dcache_wbinv_poc((vm_offset_t)sysmaps->CADDR2, pa, PAGE_SIZE);
pte2_clear(sysmaps->CMAP2);
tlb_flush((vm_offset_t)sysmaps->CADDR2);
@@ -5583,7 +5617,7 @@ pmap_zero_page(vm_page_t m)
if (pte2_load(sysmaps->CMAP2) != 0)
panic("%s: CMAP2 busy", __func__);
pte2_store(sysmaps->CMAP2, PTE2_KERN_NG(VM_PAGE_TO_PHYS(m), PTE2_AP_KRW,
- m->md.pat_mode));
+ vm_page_pte2_attr(m)));
pagezero(sysmaps->CADDR2);
pte2_clear(sysmaps->CMAP2);
tlb_flush((vm_offset_t)sysmaps->CADDR2);
@@ -5608,7 +5642,7 @@ pmap_zero_page_area(vm_page_t m, int off, int size)
if (pte2_load(sysmaps->CMAP2) != 0)
panic("%s: CMAP2 busy", __func__);
pte2_store(sysmaps->CMAP2, PTE2_KERN_NG(VM_PAGE_TO_PHYS(m), PTE2_AP_KRW,
- m->md.pat_mode));
+ vm_page_pte2_attr(m)));
if (off == 0 && size == PAGE_SIZE)
pagezero(sysmaps->CADDR2);
else
@@ -5633,7 +5667,7 @@ pmap_zero_page_idle(vm_page_t m)
panic("%s: CMAP3 busy", __func__);
sched_pin();
pte2_store(CMAP3, PTE2_KERN_NG(VM_PAGE_TO_PHYS(m), PTE2_AP_KRW,
- m->md.pat_mode));
+ vm_page_pte2_attr(m)));
pagezero(CADDR3);
pte2_clear(CMAP3);
tlb_flush((vm_offset_t)CADDR3);
@@ -5659,9 +5693,9 @@ pmap_copy_page(vm_page_t src, vm_page_t dst)
if (pte2_load(sysmaps->CMAP2) != 0)
panic("%s: CMAP2 busy", __func__);
pte2_store(sysmaps->CMAP1, PTE2_KERN_NG(VM_PAGE_TO_PHYS(src),
- PTE2_AP_KR | PTE2_NM, src->md.pat_mode));
+ PTE2_AP_KR | PTE2_NM, vm_page_pte2_attr(src)));
pte2_store(sysmaps->CMAP2, PTE2_KERN_NG(VM_PAGE_TO_PHYS(dst),
- PTE2_AP_KRW, dst->md.pat_mode));
+ PTE2_AP_KRW, vm_page_pte2_attr(dst)));
bcopy(sysmaps->CADDR1, sysmaps->CADDR2, PAGE_SIZE);
pte2_clear(sysmaps->CMAP1);
tlb_flush((vm_offset_t)sysmaps->CADDR1);
@@ -5698,10 +5732,10 @@ pmap_copy_pages(vm_page_t ma[], vm_offset_t a_offset, vm_page_t mb[],
b_pg_offset = b_offset & PAGE_MASK;
cnt = min(cnt, PAGE_SIZE - b_pg_offset);
pte2_store(sysmaps->CMAP1, PTE2_KERN_NG(VM_PAGE_TO_PHYS(a_pg),
- PTE2_AP_KR | PTE2_NM, a_pg->md.pat_mode));
+ PTE2_AP_KR | PTE2_NM, vm_page_pte2_attr(a_pg)));
tlb_flush_local((vm_offset_t)sysmaps->CADDR1);
pte2_store(sysmaps->CMAP2, PTE2_KERN_NG(VM_PAGE_TO_PHYS(b_pg),
- PTE2_AP_KRW, b_pg->md.pat_mode));
+ PTE2_AP_KRW, vm_page_pte2_attr(b_pg)));
tlb_flush_local((vm_offset_t)sysmaps->CADDR2);
a_cp = sysmaps->CADDR1 + a_pg_offset;
b_cp = sysmaps->CADDR2 + b_pg_offset;
@@ -5731,7 +5765,7 @@ pmap_quick_enter_page(vm_page_t m)
KASSERT(pte2_load(pte2p) == 0, ("%s: PTE2 busy", __func__));
pte2_store(pte2p, PTE2_KERN_NG(VM_PAGE_TO_PHYS(m), PTE2_AP_KRW,
- pmap_page_get_memattr(m)));
+ vm_page_pte2_attr(m)));
return (qmap_addr);
}
@@ -5993,13 +6027,15 @@ void
pmap_kenter_device(vm_offset_t va, vm_size_t size, vm_paddr_t pa)
{
vm_offset_t sva;
+ uint32_t l2attr;
KASSERT((size & PAGE_MASK) == 0,
("%s: device mapping not page-sized", __func__));
sva = va;
+ l2attr = vm_memattr_to_pte2(VM_MEMATTR_DEVICE);
while (size != 0) {
- pmap_kenter_prot_attr(va, pa, PTE2_AP_KRW, PTE2_ATTR_DEVICE);
+ pmap_kenter_prot_attr(va, pa, PTE2_AP_KRW, l2attr);
va += PAGE_SIZE;
pa += PAGE_SIZE;
size -= PAGE_SIZE;
@@ -6037,7 +6073,7 @@ pmap_set_pcb_pagedir(pmap_t pmap, struct pcb *pcb)
* The range must be within a single page.
*/
static void
-pmap_dcache_wb_pou(vm_paddr_t pa, vm_size_t size, vm_memattr_t ma)
+pmap_dcache_wb_pou(vm_paddr_t pa, vm_size_t size, uint32_t attr)
{
struct sysmaps *sysmaps;
@@ -6049,7 +6085,7 @@ pmap_dcache_wb_pou(vm_paddr_t pa, vm_size_t size, vm_memattr_t ma)
mtx_lock(&sysmaps->lock);
if (*sysmaps->CMAP3)
panic("%s: CMAP3 busy", __func__);
- pte2_store(sysmaps->CMAP3, PTE2_KERN_NG(pa, PTE2_AP_KRW, ma));
+ pte2_store(sysmaps->CMAP3, PTE2_KERN_NG(pa, PTE2_AP_KRW, attr));
dcache_wb_pou((vm_offset_t)sysmaps->CADDR3 + (pa & PAGE_MASK), size);
pte2_clear(sysmaps->CMAP3);
tlb_flush((vm_offset_t)sysmaps->CADDR3);
@@ -6073,7 +6109,7 @@ cache_icache_sync_fresh(vm_offset_t va, vm_paddr_t pa, vm_size_t size)
m = PHYS_TO_VM_PAGE(pa);
KASSERT(m != NULL, ("%s: vm_page_t is null for %#x",
__func__, pa));
- pmap_dcache_wb_pou(pa, len, m->md.pat_mode);
+ pmap_dcache_wb_pou(pa, len, vm_page_pte2_attr(m));
}
/*
* I-cache is VIPT. Only way how to flush all virtual mappings
@@ -6101,7 +6137,7 @@ pmap_sync_icache(pmap_t pmap, vm_offset_t va, vm_size_t size)
m = PHYS_TO_VM_PAGE(pa);
KASSERT(m != NULL, ("%s: vm_page_t is null for %#x",
__func__, pa));
- pmap_dcache_wb_pou(pa, len, m->md.pat_mode);
+ pmap_dcache_wb_pou(pa, len, vm_page_pte2_attr(m));
}
}
/*
@@ -6298,7 +6334,7 @@ pmap_zero_page_check(vm_page_t m)
if (pte2_load(sysmaps->CMAP2) != 0)
panic("%s: CMAP2 busy", __func__);
pte2_store(sysmaps->CMAP2, PTE2_KERN_NG(VM_PAGE_TO_PHYS(m), PTE2_AP_KRW,
- m->md.pat_mode));
+ vm_page_pte2_attr(m)));
end = (uint32_t*)(sysmaps->CADDR2 + PAGE_SIZE);
for (p = (uint32_t*)sysmaps->CADDR2; p < end; p++)
if (*p != 0)
diff --git a/sys/arm/arm/sys_machdep.c b/sys/arm/arm/sys_machdep.c
index efebda3..b893a90 100644
--- a/sys/arm/arm/sys_machdep.c
+++ b/sys/arm/arm/sys_machdep.c
@@ -45,7 +45,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_extern.h>
#include <machine/acle-compat.h>
-#include <machine/cpu-v6.h>
+#include <machine/cpu.h>
#include <machine/sysarch.h>
#include <machine/vmparam.h>
@@ -153,8 +153,13 @@ arm32_drain_writebuf(struct thread *td, void *args)
{
/* No args. */
- td->td_retval[0] = 0;
+#if __ARM_ARCH < 6
cpu_drain_writebuf();
+#else
+ dsb();
+ cpu_l2cache_drain_writebuf();
+#endif
+ td->td_retval[0] = 0;
return (0);
}
diff --git a/sys/arm/arm/trap-v6.c b/sys/arm/arm/trap-v6.c
index adc29c6..81a6ee4 100644
--- a/sys/arm/arm/trap-v6.c
+++ b/sys/arm/arm/trap-v6.c
@@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$");
#include <machine/acle-compat.h>
#include <machine/cpu.h>
-#include <machine/cpu-v6.h>
#include <machine/frame.h>
#include <machine/machdep.h>
#include <machine/pcb.h>
@@ -70,7 +69,6 @@ __FBSDID("$FreeBSD$");
#include <sys/dtrace_bsd.h>
#endif
-extern char fusubailout[];
extern char cachebailout[];
#ifdef DEBUG
@@ -293,7 +291,10 @@ abort_handler(struct trapframe *tf, int prefetch)
#ifdef INVARIANTS
void *onfault;
#endif
+
+ PCPU_INC(cnt.v_trap);
td = curthread;
+
fsr = (prefetch) ? cp15_ifsr_get(): cp15_dfsr_get();
#if __ARM_ARCH >= 7
far = (prefetch) ? cp15_ifar_get() : cp15_dfar_get();
@@ -334,24 +335,23 @@ abort_handler(struct trapframe *tf, int prefetch)
* they are not from KVA space. Thus, no action is needed here.
*/
+ /*
+ * (1) Handle access and R/W hardware emulation aborts.
+ * (2) Check that abort is not on pmap essential address ranges.
+ * There is no way how to fix it, so we don't even try.
+ */
rv = pmap_fault(PCPU_GET(curpmap), far, fsr, idx, usermode);
if (rv == KERN_SUCCESS)
return;
- if (rv == KERN_INVALID_ADDRESS)
- goto nogo;
- /*
- * Now, when we handled imprecise and debug aborts, the rest of
- * aborts should be really related to mapping.
- */
-
- PCPU_INC(cnt.v_trap);
-
#ifdef KDB
if (kdb_active) {
kdb_reenter();
goto out;
}
#endif
+ if (rv == KERN_INVALID_ADDRESS)
+ goto nogo;
+
if (__predict_false((td->td_pflags & TDP_NOFAULTING) != 0)) {
/*
* Due to both processor errata and lazy TLB invalidation when
@@ -418,6 +418,14 @@ abort_handler(struct trapframe *tf, int prefetch)
}
/*
+ * At this point, we're dealing with one of the following aborts:
+ *
+ * FAULT_ICACHE - I-cache maintenance
+ * FAULT_TRAN_xx - Translation
+ * FAULT_PERM_xx - Permission
+ */
+
+ /*
* Don't pass faulting cache operation to vm_fault(). We don't want
* to handle all vm stuff at this moment.
*/
@@ -435,23 +443,6 @@ abort_handler(struct trapframe *tf, int prefetch)
goto out;
}
- /*
- * At this point, we're dealing with one of the following aborts:
- *
- * FAULT_TRAN_xx - Translation
- * FAULT_PERM_xx - Permission
- *
- * These are the main virtual memory-related faults signalled by
- * the MMU.
- */
-
- /* fusubailout is used by [fs]uswintr to avoid page faulting. */
- if (__predict_false(pcb->pcb_onfault == fusubailout)) {
- tf->tf_r0 = EFAULT;
- tf->tf_pc = (register_t)pcb->pcb_onfault;
- return;
- }
-
va = trunc_page(far);
if (va >= KERNBASE) {
/*
diff --git a/sys/arm/arm/trap.c b/sys/arm/arm/trap.c
index e43ec8e..eb4d683 100644
--- a/sys/arm/arm/trap.c
+++ b/sys/arm/arm/trap.c
@@ -111,8 +111,6 @@ __FBSDID("$FreeBSD$");
#define ReadWord(a) (*((volatile unsigned int *)(a)))
-extern char fusubailout[];
-
#ifdef DEBUG
int last_fault_code; /* For the benefit of pmap_fault_fixup() */
#endif
@@ -255,13 +253,6 @@ abort_handler(struct trapframe *tf, int type)
* the MMU.
*/
- /* fusubailout is used by [fs]uswintr to avoid page faulting */
- if (__predict_false(pcb->pcb_onfault == fusubailout)) {
- tf->tf_r0 = EFAULT;
- tf->tf_pc = (register_t)(intptr_t) pcb->pcb_onfault;
- return;
- }
-
/*
* Make sure the Program Counter is sane. We could fall foul of
* someone executing Thumb code, in which case the PC might not
diff --git a/sys/arm/arm/vm_machdep.c b/sys/arm/arm/vm_machdep.c
index 6a70cbf..601be07 100644
--- a/sys/arm/arm/vm_machdep.c
+++ b/sys/arm/arm/vm_machdep.c
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sysctl.h>
#include <sys/sysent.h>
#include <sys/unistd.h>
+#include <sys/taskqueue.h>
#include <machine/acle-compat.h>
#include <machine/cpu.h>
diff --git a/sys/arm/at91/at91_machdep.c b/sys/arm/at91/at91_machdep.c
index 936f145..e904780 100644
--- a/sys/arm/at91/at91_machdep.c
+++ b/sys/arm/at91/at91_machdep.c
@@ -566,7 +566,7 @@ initarm(struct arm_boot_params *abp)
arm_devmap_bootstrap(l1pagetable, at91_devmap);
cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2)) | DOMAIN_CLIENT);
- setttb(kernel_l1pt.pv_pa);
+ cpu_setttb(kernel_l1pt.pv_pa);
cpu_tlb_flushID();
cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2));
@@ -612,7 +612,7 @@ initarm(struct arm_boot_params *abp)
/*
* We must now clean the cache again....
* Cleaning may be done by reading new data to displace any
- * dirty data in the cache. This will have happened in setttb()
+ * dirty data in the cache. This will have happened in cpu_setttb()
* but since we are boot strapping the addresses used for the read
* may have just been remapped and thus the cache could be out
* of sync. A re-clean after the switch will cure this.
diff --git a/sys/arm/broadcom/bcm2835/bcm2836_mp.c b/sys/arm/broadcom/bcm2835/bcm2836_mp.c
index 93cc0d8..d6c84cb 100644
--- a/sys/arm/broadcom/bcm2835/bcm2836_mp.c
+++ b/sys/arm/broadcom/bcm2835/bcm2836_mp.c
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/pmap.h>
+#include <machine/cpu.h>
#include <machine/smp.h>
#include <machine/bus.h>
#include <machine/fdt.h>
@@ -123,8 +124,7 @@ platform_mp_start_ap(void)
BSWR4(MBOX3CLR_CORE(i), 0xffffffff);
}
wmb();
- cpu_idcache_wbinv_all();
- cpu_l2cache_wbinv_all();
+ dcache_wbinv_poc_all();
/* boot secondary CPUs */
for (i = 1; i < mp_ncpus; i++) {
diff --git a/sys/arm/cavium/cns11xx/econa_machdep.c b/sys/arm/cavium/cns11xx/econa_machdep.c
index 1591053..e212a10 100644
--- a/sys/arm/cavium/cns11xx/econa_machdep.c
+++ b/sys/arm/cavium/cns11xx/econa_machdep.c
@@ -275,7 +275,7 @@ initarm(struct arm_boot_params *abp)
arm_devmap_bootstrap(l1pagetable, econa_devmap);
cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
- setttb(kernel_l1pt.pv_pa);
+ cpu_setttb(kernel_l1pt.pv_pa);
cpu_tlb_flushID();
cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
cninit();
@@ -297,7 +297,7 @@ initarm(struct arm_boot_params *abp)
/*
* We must now clean the cache again....
* Cleaning may be done by reading new data to displace any
- * dirty data in the cache. This will have happened in setttb()
+ * dirty data in the cache. This will have happened in cpu_setttb()
* but since we are boot strapping the addresses used for the read
* may have just been remapped and thus the cache could be out
* of sync. A re-clean after the switch will cure this.
diff --git a/sys/arm/conf/NOTES b/sys/arm/conf/NOTES
index f4259f2..db64f8e 100644
--- a/sys/arm/conf/NOTES
+++ b/sys/arm/conf/NOTES
@@ -5,8 +5,6 @@ machine arm
cpu CPU_ARM9
cpu CPU_ARM9E
cpu CPU_FA526
-cpu CPU_XSCALE_80219
-cpu CPU_XSCALE_80321
cpu CPU_XSCALE_81342
cpu CPU_XSCALE_IXP425
cpu CPU_XSCALE_IXP435
diff --git a/sys/arm/freescale/imx/imx6_mp.c b/sys/arm/freescale/imx/imx6_mp.c
index 3208f67..7aa9aab 100644
--- a/sys/arm/freescale/imx/imx6_mp.c
+++ b/sys/arm/freescale/imx/imx6_mp.c
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/pmap.h>
+#include <machine/cpu.h>
#include <machine/smp.h>
#include <machine/fdt.h>
#include <machine/intr.h>
@@ -149,7 +150,7 @@ platform_mp_start_ap(void)
val = bus_space_read_4(fdtbus_bs_tag, scu, SCU_CONTROL_REG);
bus_space_write_4(fdtbus_bs_tag, scu, SCU_CONTROL_REG,
val | SCU_CONTROL_ENABLE);
- cpu_idcache_wbinv_all();
+ dcache_wbinv_poc_all();
/*
* For each AP core, set the entry point address and argument registers,
diff --git a/sys/arm/include/cpu-v4.h b/sys/arm/include/cpu-v4.h
new file mode 100644
index 0000000..0d66dee
--- /dev/null
+++ b/sys/arm/include/cpu-v4.h
@@ -0,0 +1,186 @@
+/*-
+ * Copyright 2016 Svatopluk Kraus <skra@FreeBSD.org>
+ * Copyright 2016 Michal Meloun <mmel@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifndef MACHINE_CPU_V4_H
+#define MACHINE_CPU_V4_H
+
+/* There are no user serviceable parts here, they may change without notice */
+#ifndef _KERNEL
+#error Only include this file in the kernel
+#endif
+
+#include <machine/acle-compat.h>
+#include <machine/atomic.h>
+#include <machine/cpufunc.h>
+#include <machine/cpuinfo.h>
+#include <machine/sysreg.h>
+
+#if __ARM_ARCH >= 6
+#error Never include this file for ARMv6
+#else
+
+#define CPU_ASID_KERNEL 0
+
+/*
+ * Macros to generate CP15 (system control processor) read/write functions.
+ */
+#define _FX(s...) #s
+
+#define _RF0(fname, aname...) \
+static __inline register_t \
+fname(void) \
+{ \
+ register_t reg; \
+ __asm __volatile("mrc\t" _FX(aname): "=r" (reg)); \
+ return(reg); \
+}
+
+#define _R64F0(fname, aname) \
+static __inline uint64_t \
+fname(void) \
+{ \
+ uint64_t reg; \
+ __asm __volatile("mrrc\t" _FX(aname): "=r" (reg)); \
+ return(reg); \
+}
+
+#define _WF0(fname, aname...) \
+static __inline void \
+fname(void) \
+{ \
+ __asm __volatile("mcr\t" _FX(aname)); \
+}
+
+#define _WF1(fname, aname...) \
+static __inline void \
+fname(register_t reg) \
+{ \
+ __asm __volatile("mcr\t" _FX(aname):: "r" (reg)); \
+}
+
+
+/*
+ * Publicly accessible functions
+ */
+
+
+/* Various control registers */
+
+_RF0(cp15_cpacr_get, CP15_CPACR(%0))
+_WF1(cp15_cpacr_set, CP15_CPACR(%0))
+_RF0(cp15_dfsr_get, CP15_DFSR(%0))
+_RF0(cp15_ttbr_get, CP15_TTBR0(%0))
+_RF0(cp15_dfar_get, CP15_DFAR(%0))
+/* XScale */
+_RF0(cp15_actlr_get, CP15_ACTLR(%0))
+_WF1(cp15_actlr_set, CP15_ACTLR(%0))
+
+/*CPU id registers */
+_RF0(cp15_midr_get, CP15_MIDR(%0))
+_RF0(cp15_ctr_get, CP15_CTR(%0))
+_RF0(cp15_tcmtr_get, CP15_TCMTR(%0))
+_RF0(cp15_tlbtr_get, CP15_TLBTR(%0))
+
+#undef _FX
+#undef _RF0
+#undef _WF0
+#undef _WF1
+
+
+/*
+ * armv4/5 compatibility shims.
+ *
+ * These functions provide armv4 cache maintenance using the new armv6 names.
+ * Included here are just the functions actually used now in common code; it may
+ * be necessary to add things here over time.
+ *
+ * The callers of the dcache functions expect these routines to handle address
+ * and size values which are not aligned to cacheline boundaries; the armv4 and
+ * armv5 asm code handles that.
+ */
+
+static __inline void
+tlb_flush_all(void)
+{
+ cpu_tlb_flushID();
+ cpu_cpwait();
+}
+
+static __inline void
+icache_sync(vm_offset_t va, vm_size_t size)
+{
+ cpu_icache_sync_range(va, size);
+}
+
+static __inline void
+dcache_inv_poc(vm_offset_t va, vm_paddr_t pa, vm_size_t size)
+{
+
+ cpu_dcache_inv_range(va, size);
+#ifdef ARM_L2_PIPT
+ cpu_l2cache_inv_range(pa, size);
+#else
+ cpu_l2cache_inv_range(va, size);
+#endif
+}
+
+static __inline void
+dcache_inv_poc_dma(vm_offset_t va, vm_paddr_t pa, vm_size_t size)
+{
+
+ /* See armv6 code, above, for why we do L2 before L1 in this case. */
+#ifdef ARM_L2_PIPT
+ cpu_l2cache_inv_range(pa, size);
+#else
+ cpu_l2cache_inv_range(va, size);
+#endif
+ cpu_dcache_inv_range(va, size);
+}
+
+static __inline void
+dcache_wb_poc(vm_offset_t va, vm_paddr_t pa, vm_size_t size)
+{
+
+ cpu_dcache_wb_range(va, size);
+#ifdef ARM_L2_PIPT
+ cpu_l2cache_wb_range(pa, size);
+#else
+ cpu_l2cache_wb_range(va, size);
+#endif
+}
+
+static __inline void
+dcache_wbinv_poc_all(void)
+{
+ cpu_idcache_wbinv_all();
+ cpu_l2cache_wbinv_all();
+}
+
+#endif /* _KERNEL */
+
+#endif /* MACHINE_CPU_V4_H */
diff --git a/sys/arm/include/cpu-v6.h b/sys/arm/include/cpu-v6.h
index bb8649a..e537c10 100644
--- a/sys/arm/include/cpu-v6.h
+++ b/sys/arm/include/cpu-v6.h
@@ -32,19 +32,32 @@
/* There are no user serviceable parts here, they may change without notice */
#ifndef _KERNEL
#error Only include this file in the kernel
-#else
+#endif
#include <machine/acle-compat.h>
-#include "machine/atomic.h"
-#include "machine/cpufunc.h"
-#include "machine/cpuinfo.h"
-#include "machine/sysreg.h"
+#include <machine/atomic.h>
+#include <machine/cpufunc.h>
+#include <machine/cpuinfo.h>
+#include <machine/sysreg.h>
+
+#if __ARM_ARCH < 6
+#error Only include this file for ARMv6
+#else
#define CPU_ASID_KERNEL 0
+void dcache_wbinv_poc_all(void); /* !!! NOT SMP coherent function !!! */
vm_offset_t dcache_wb_pou_checked(vm_offset_t, vm_size_t);
vm_offset_t icache_inv_pou_checked(vm_offset_t, vm_size_t);
+#ifdef DEV_PMU
+#include <sys/pcpu.h>
+#define PMU_OVSR_C 0x80000000 /* Cycle Counter */
+extern uint32_t ccnt_hi[MAXCPU];
+extern int pmu_attched;
+#endif /* DEV_PMU */
+
+
/*
* Macros to generate CP15 (system control processor) read/write functions.
*/
@@ -277,12 +290,6 @@ _W64F1(cp15_cnthp_cval_set, CP15_CNTHP_CVAL(%Q0, %R0))
#undef _WF0
#undef _WF1
-#if __ARM_ARCH >= 6
-/*
- * Cache and TLB maintenance operations for armv6+ code. The #else block
- * provides armv4/v5 implementations for a few of these used in common code.
- */
-
/*
* TLB maintenance operations.
*/
@@ -577,48 +584,6 @@ cp15_ttbr_set(uint32_t reg)
isb();
tlb_flush_all_ng_local();
}
-
-#else /* ! __ARM_ARCH >= 6 */
-
-/*
- * armv4/5 compatibility shims.
- *
- * These functions provide armv4 cache maintenance using the new armv6 names.
- * Included here are just the functions actually used now in common code; it may
- * be necessary to add things here over time.
- *
- * The callers of the dcache functions expect these routines to handle address
- * and size values which are not aligned to cacheline boundaries; the armv4 and
- * armv5 asm code handles that.
- */
-
-static __inline void
-dcache_inv_poc(vm_offset_t va, vm_paddr_t pa, vm_size_t size)
-{
-
- cpu_dcache_inv_range(va, size);
- cpu_l2cache_inv_range(va, size);
-}
-
-static __inline void
-dcache_inv_poc_dma(vm_offset_t va, vm_paddr_t pa, vm_size_t size)
-{
-
- /* See armv6 code, above, for why we do L2 before L1 in this case. */
- cpu_l2cache_inv_range(va, size);
- cpu_dcache_inv_range(va, size);
-}
-
-static __inline void
-dcache_wb_poc(vm_offset_t va, vm_paddr_t pa, vm_size_t size)
-{
-
- cpu_dcache_wb_range(va, size);
- cpu_l2cache_wb_range(va, size);
-}
-
-#endif /* __ARM_ARCH >= 6 */
-
#endif /* _KERNEL */
#endif /* !MACHINE_CPU_V6_H */
diff --git a/sys/arm/include/cpu.h b/sys/arm/include/cpu.h
index 782471e..0d79e68 100644
--- a/sys/arm/include/cpu.h
+++ b/sys/arm/include/cpu.h
@@ -14,12 +14,8 @@ void swi_vm(void *);
#ifdef _KERNEL
#if __ARM_ARCH >= 6
#include <machine/cpu-v6.h>
-#ifdef DEV_PMU
-#include <sys/pcpu.h>
-#define PMU_OVSR_C 0x80000000 /* Cycle Counter */
-extern uint32_t ccnt_hi[MAXCPU];
-extern int pmu_attched;
-#endif /* DEV_PMU */
+#else
+#include <machine/cpu-v4.h>
#endif /* __ARM_ARCH >= 6 */
static __inline uint64_t
diff --git a/sys/arm/include/cpuconf.h b/sys/arm/include/cpuconf.h
index ecee280..24a3b8f 100644
--- a/sys/arm/include/cpuconf.h
+++ b/sys/arm/include/cpuconf.h
@@ -53,7 +53,6 @@
#define CPU_NTYPES (defined(CPU_ARM9) + \
defined(CPU_ARM9E) + \
defined(CPU_ARM1176) + \
- defined(CPU_XSCALE_80321) + \
defined(CPU_XSCALE_PXA2X0) + \
defined(CPU_FA526) + \
defined(CPU_XSCALE_IXP425)) + \
@@ -71,8 +70,7 @@
#endif
#if (defined(CPU_ARM9E) || \
- defined(CPU_XSCALE_80321) || \
- defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) || \
+ defined(CPU_XSCALE_81342) || \
defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425))
#define ARM_ARCH_5 1
#else
@@ -163,9 +161,8 @@
#define ARM_MMU_V7 0
#endif
-#if (defined(CPU_XSCALE_80321) || \
- defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \
- defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342))
+#if (defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \
+ defined(CPU_XSCALE_81342))
#define ARM_MMU_XSCALE 1
#else
#define ARM_MMU_XSCALE 0
@@ -180,11 +177,10 @@
/*
* Step 4: Define features that may be present on a subset of CPUs
*
- * ARM_XSCALE_PMU Performance Monitoring Unit on 80200 and 80321
+ * ARM_XSCALE_PMU Performance Monitoring Unit on 81342
*/
-#if (defined(CPU_XSCALE_80321) || \
- defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342))
+#if (defined(CPU_XSCALE_81342))
#define ARM_XSCALE_PMU 1
#else
#define ARM_XSCALE_PMU 0
diff --git a/sys/arm/include/cpufunc.h b/sys/arm/include/cpufunc.h
index aad0feb..eb445b4 100644
--- a/sys/arm/include/cpufunc.h
+++ b/sys/arm/include/cpufunc.h
@@ -79,7 +79,6 @@ struct cpu_functions {
*
* We define the following primitives:
*
- * icache_sync_all Synchronize I-cache
* icache_sync_range Synchronize I-cache range
*
* dcache_wbinv_all Write-back and Invalidate D-cache
@@ -104,7 +103,7 @@ struct cpu_functions {
* state (such as when it may have lines tagged as valid
* that belong to a previous set of mappings).
*
- * I-cache Synch (all or range):
+ * I-cache Sync range:
* The goal is to synchronize the instruction stream,
* so you may beed to write-back dirty D-cache blocks
* first. If a range is requested, and you can't
@@ -130,7 +129,6 @@ struct cpu_functions {
* Valid virtual addresses must be passed to each
* cache operation.
*/
- void (*cf_icache_sync_all) (void);
void (*cf_icache_sync_range) (vm_offset_t, vm_size_t);
void (*cf_dcache_wbinv_all) (void);
@@ -163,9 +161,12 @@ struct cpu_functions {
extern struct cpu_functions cpufuncs;
extern u_int cputype;
+#if __ARM_ARCH < 6
#define cpu_cpwait() cpufuncs.cf_cpwait()
+#endif
#define cpu_control(c, e) cpufuncs.cf_control(c, e)
+#if __ARM_ARCH < 6
#define cpu_setttb(t) cpufuncs.cf_setttb(t)
#define cpu_tlb_flushID() cpufuncs.cf_tlb_flushID()
@@ -173,7 +174,6 @@ extern u_int cputype;
#define cpu_tlb_flushD() cpufuncs.cf_tlb_flushD()
#define cpu_tlb_flushD_SE(e) cpufuncs.cf_tlb_flushD_SE(e)
-#define cpu_icache_sync_all() cpufuncs.cf_icache_sync_all()
#define cpu_icache_sync_range(a, s) cpufuncs.cf_icache_sync_range((a), (s))
#define cpu_dcache_wbinv_all() cpufuncs.cf_dcache_wbinv_all()
@@ -184,13 +184,16 @@ extern u_int cputype;
#define cpu_idcache_inv_all() cpufuncs.cf_idcache_inv_all()
#define cpu_idcache_wbinv_all() cpufuncs.cf_idcache_wbinv_all()
#define cpu_idcache_wbinv_range(a, s) cpufuncs.cf_idcache_wbinv_range((a), (s))
+#endif
#define cpu_l2cache_wbinv_all() cpufuncs.cf_l2cache_wbinv_all()
#define cpu_l2cache_wb_range(a, s) cpufuncs.cf_l2cache_wb_range((a), (s))
#define cpu_l2cache_inv_range(a, s) cpufuncs.cf_l2cache_inv_range((a), (s))
#define cpu_l2cache_wbinv_range(a, s) cpufuncs.cf_l2cache_wbinv_range((a), (s))
#define cpu_l2cache_drain_writebuf() cpufuncs.cf_l2cache_drain_writebuf()
+#if __ARM_ARCH < 6
#define cpu_drain_writebuf() cpufuncs.cf_drain_writebuf()
+#endif
#define cpu_sleep(m) cpufuncs.cf_sleep(m)
#define cpu_setup() cpufuncs.cf_setup()
@@ -205,6 +208,7 @@ u_int cpufunc_control (u_int clear, u_int bic);
void cpu_domains (u_int domains);
u_int cpu_faultstatus (void);
u_int cpu_faultaddress (void);
+u_int cpu_get_control (void);
u_int cpu_pfr (int);
#if defined(CPU_FA526)
@@ -214,7 +218,6 @@ void fa526_context_switch (void);
void fa526_cpu_sleep (int);
void fa526_tlb_flushID_SE (u_int);
-void fa526_icache_sync_all (void);
void fa526_icache_sync_range(vm_offset_t start, vm_size_t end);
void fa526_dcache_wbinv_all (void);
void fa526_dcache_wbinv_range(vm_offset_t start, vm_size_t end);
@@ -231,8 +234,7 @@ void arm9_tlb_flushID_SE (u_int va);
void arm9_context_switch (void);
#endif
-#if defined(CPU_ARM9)
-void arm9_icache_sync_all (void);
+#if defined(CPU_ARM9)
void arm9_icache_sync_range (vm_offset_t, vm_size_t);
void arm9_dcache_wbinv_all (void);
@@ -275,7 +277,6 @@ void armv6_idcache_wbinv_all (void);
void armv7_setttb (u_int);
void armv7_tlb_flushID (void);
void armv7_tlb_flushID_SE (u_int);
-void armv7_icache_sync_all (void);
void armv7_icache_sync_range (vm_offset_t, vm_size_t);
void armv7_idcache_wbinv_range (vm_offset_t, vm_size_t);
void armv7_idcache_inv_all (void);
@@ -319,7 +320,6 @@ void armv6_idcache_inv_all (void);
void arm11x6_setttb (u_int);
void arm11x6_idcache_wbinv_all (void);
void arm11x6_dcache_wbinv_all (void);
-void arm11x6_icache_sync_all (void);
void arm11x6_icache_sync_range (vm_offset_t, vm_size_t);
void arm11x6_idcache_wbinv_range (vm_offset_t, vm_size_t);
void arm11x6_setup (void);
@@ -329,7 +329,6 @@ void arm11x6_sleep (int); /* no ref. for errata */
#if defined(CPU_ARM9E)
void armv5_ec_setttb(u_int);
-void armv5_ec_icache_sync_all(void);
void armv5_ec_icache_sync_range(vm_offset_t, vm_size_t);
void armv5_ec_dcache_wbinv_all(void);
@@ -342,10 +341,9 @@ void armv5_ec_idcache_wbinv_range(vm_offset_t, vm_size_t);
#endif
#if defined(CPU_ARM9) || defined(CPU_ARM9E) || \
- defined(CPU_XSCALE_80321) || \
defined(CPU_FA526) || \
defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \
- defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342)
+ defined(CPU_XSCALE_81342)
void armv4_tlb_flushID (void);
void armv4_tlb_flushD (void);
@@ -355,9 +353,8 @@ void armv4_drain_writebuf (void);
void armv4_idcache_inv_all (void);
#endif
-#if defined(CPU_XSCALE_80321) || \
- defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \
- defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342)
+#if defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \
+ defined(CPU_XSCALE_81342)
void xscale_cpwait (void);
void xscale_cpu_sleep (int mode);
@@ -395,8 +392,7 @@ void xscale_cache_flushD_rng (vm_offset_t start, vm_size_t end);
void xscale_context_switch (void);
void xscale_setup (void);
-#endif /* CPU_XSCALE_80321 || CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425
- CPU_XSCALE_80219 */
+#endif /* CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425 */
#ifdef CPU_XSCALE_81342
@@ -423,9 +419,6 @@ void xscalec3_context_switch (void);
#endif /* CPU_XSCALE_81342 */
-#define setttb cpu_setttb
-#define drain_writebuf cpu_drain_writebuf
-
/*
* Macros for manipulating CPU interrupts
*/
diff --git a/sys/arm/include/kdb.h b/sys/arm/include/kdb.h
index fb50c78..c7968ab 100644
--- a/sys/arm/include/kdb.h
+++ b/sys/arm/include/kdb.h
@@ -29,10 +29,10 @@
#ifndef _MACHINE_KDB_H_
#define _MACHINE_KDB_H_
+#include <machine/cpu.h>
+#include <machine/db_machdep.h>
#include <machine/frame.h>
#include <machine/psl.h>
-#include <machine/cpufunc.h>
-#include <machine/db_machdep.h>
#define KDB_STOPPEDPCB(pc) &stoppcbs[pc->pc_cpuid]
@@ -56,7 +56,7 @@ static __inline void
kdb_cpu_sync_icache(unsigned char *addr, size_t size)
{
- cpu_icache_sync_range((vm_offset_t)addr, size);
+ icache_sync((vm_offset_t)addr, size);
}
static __inline void
diff --git a/sys/arm/include/pmap-v6.h b/sys/arm/include/pmap-v6.h
index d522384..0678977 100644
--- a/sys/arm/include/pmap-v6.h
+++ b/sys/arm/include/pmap-v6.h
@@ -115,7 +115,7 @@ struct pv_chunk;
struct md_page {
TAILQ_HEAD(,pv_entry) pv_list;
uint16_t pt2_wirecount[4];
- int pat_mode;
+ vm_memattr_t pat_mode;
};
struct pmap {
@@ -173,7 +173,7 @@ struct pv_chunk {
struct pcb;
extern ttb_entry_t pmap_kern_ttb; /* TTB for kernel pmap */
-#define pmap_page_get_memattr(m) ((vm_memattr_t)(m)->md.pat_mode)
+#define pmap_page_get_memattr(m) ((m)->md.pat_mode)
#define pmap_page_is_write_mapped(m) (((m)->aflags & PGA_WRITEABLE) != 0)
/*
@@ -250,6 +250,8 @@ void pmap_preboot_map_attr(vm_paddr_t, vm_offset_t, vm_size_t, vm_prot_t,
*/
void vector_page_setprot(int);
+#define PTE_DEVICE VM_MEMATTR_DEVICE
+
#endif /* _KERNEL */
// -----------------------------------------------------------------------------
diff --git a/sys/arm/include/vm.h b/sys/arm/include/vm.h
index 552460e..eb67025 100644
--- a/sys/arm/include/vm.h
+++ b/sys/arm/include/vm.h
@@ -34,11 +34,11 @@
#if __ARM_ARCH >= 6
#include <machine/pte-v6.h>
-#define VM_MEMATTR_WB_WA ((vm_memattr_t)PTE2_ATTR_WB_WA)
-#define VM_MEMATTR_NOCACHE ((vm_memattr_t)PTE2_ATTR_NOCACHE)
-#define VM_MEMATTR_DEVICE ((vm_memattr_t)PTE2_ATTR_DEVICE)
-#define VM_MEMATTR_SO ((vm_memattr_t)PTE2_ATTR_SO)
-#define VM_MEMATTR_WRITE_THROUGH ((vm_memattr_t)PTE2_ATTR_WT)
+#define VM_MEMATTR_WB_WA ((vm_memattr_t)0)
+#define VM_MEMATTR_NOCACHE ((vm_memattr_t)1)
+#define VM_MEMATTR_DEVICE ((vm_memattr_t)2)
+#define VM_MEMATTR_SO ((vm_memattr_t)3)
+#define VM_MEMATTR_WRITE_THROUGH ((vm_memattr_t)4)
#define VM_MEMATTR_DEFAULT VM_MEMATTR_WB_WA
#define VM_MEMATTR_UNCACHEABLE VM_MEMATTR_SO /* misused by DMA */
diff --git a/sys/arm/mv/armada38x/pmsu.c b/sys/arm/mv/armada38x/pmsu.c
index a84ede0..110278b 100644
--- a/sys/arm/mv/armada38x/pmsu.c
+++ b/sys/arm/mv/armada38x/pmsu.c
@@ -36,10 +36,12 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/resource.h>
+#include <sys/systm.h>
#include <vm/vm.h>
#include <vm/pmap.h>
+#include <machine/cpu.h>
#include <machine/fdt.h>
#include <machine/smp.h>
@@ -143,8 +145,7 @@ pmsu_boot_secondary_cpu(void)
bus_space_write_4(fdtbus_bs_tag, vaddr, PMSU_BOOT_ADDR_REDIRECT_OFFSET(1),
pmap_kextract((vm_offset_t)mpentry));
- cpu_idcache_wbinv_all();
- cpu_l2cache_wbinv_all();
+ dcache_wbinv_poc_all();
armv7_sev();
bus_space_unmap(fdtbus_bs_tag, vaddr, MV_PMSU_REGS_LEN);
diff --git a/sys/arm/mv/armadaxp/armadaxp_mp.c b/sys/arm/mv/armadaxp/armadaxp_mp.c
index 4ccf7e3..52f3508 100644
--- a/sys/arm/mv/armadaxp/armadaxp_mp.c
+++ b/sys/arm/mv/armadaxp/armadaxp_mp.c
@@ -40,6 +40,7 @@
#include <dev/fdt/fdt_common.h>
+#include <machine/cpu.h>
#include <machine/smp.h>
#include <machine/fdt.h>
#include <machine/armreg.h>
@@ -174,7 +175,7 @@ platform_mp_start_ap(void)
bus_space_write_4(fdtbus_bs_tag, CPU_PMU(cpu_num), CPU_PMU_BOOT,
pmap_kextract((vm_offset_t)mpentry));
- cpu_idcache_wbinv_all();
+ dcache_wbinv_poc_all();
for (cpu_num = 1; cpu_num < mp_ncpus; cpu_num++ )
bus_space_write_4(fdtbus_bs_tag, MP, MP_SW_RESET(cpu_num), 0);
diff --git a/sys/arm/rockchip/rk30xx_mp.c b/sys/arm/rockchip/rk30xx_mp.c
index 38b6b41..5de2eff 100644
--- a/sys/arm/rockchip/rk30xx_mp.c
+++ b/sys/arm/rockchip/rk30xx_mp.c
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/pmap.h>
+#include <machine/cpu.h>
#include <machine/smp.h>
#include <machine/fdt.h>
#include <machine/intr.h>
@@ -171,8 +172,7 @@ platform_mp_start_ap(void)
bus_space_write_region_4(fdtbus_bs_tag, imem, 0,
(uint32_t *)&rk30xx_boot2, 8);
- cpu_idcache_wbinv_all();
- cpu_l2cache_wbinv_all();
+ dcache_wbinv_poc_all();
/* Start all cores */
val = bus_space_read_4(fdtbus_bs_tag, pmu, PMU_PWRDN_CON);
diff --git a/sys/arm/samsung/exynos/exynos5_mp.c b/sys/arm/samsung/exynos/exynos5_mp.c
index 8eb0d29..44b2844 100644
--- a/sys/arm/samsung/exynos/exynos5_mp.c
+++ b/sys/arm/samsung/exynos/exynos5_mp.c
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/pmap.h>
+#include <machine/cpu.h>
#include <machine/smp.h>
#include <machine/fdt.h>
#include <machine/intr.h>
@@ -135,8 +136,7 @@ platform_mp_start_ap(void)
bus_space_write_4(fdtbus_bs_tag, sysram, 0x0,
pmap_kextract((vm_offset_t)mpentry));
- cpu_idcache_wbinv_all();
- cpu_l2cache_wbinv_all();
+ dcache_wbinv_poc_all();
armv7_sev();
bus_space_unmap(fdtbus_bs_tag, sysram, 0x100);
diff --git a/sys/arm/ti/omap4/omap4_mp.c b/sys/arm/ti/omap4/omap4_mp.c
index 1a095ab..6cea1cc 100644
--- a/sys/arm/ti/omap4/omap4_mp.c
+++ b/sys/arm/ti/omap4/omap4_mp.c
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/pmap.h>
+#include <machine/cpu.h>
#include <machine/smp.h>
#include <machine/fdt.h>
#include <machine/intr.h>
@@ -72,8 +73,8 @@ platform_mp_start_ap(void)
/* Enable the SCU */
*(volatile unsigned int *)scu_addr |= 1;
//*(volatile unsigned int *)(scu_addr + 0x30) |= 1;
- cpu_idcache_wbinv_all();
- cpu_l2cache_wbinv_all();
+ dcache_wbinv_poc_all();
+
ti_smc0(0x200, 0xfffffdff, MODIFY_AUX_CORE_0);
ti_smc0(pmap_kextract((vm_offset_t)mpentry), 0, WRITE_AUX_CORE_1);
armv7_sev();
diff --git a/sys/arm/xilinx/zy7_mp.c b/sys/arm/xilinx/zy7_mp.c
index f71740c..74528ef 100644
--- a/sys/arm/xilinx/zy7_mp.c
+++ b/sys/arm/xilinx/zy7_mp.c
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/pmap.h>
+#include <machine/cpu.h>
#include <machine/smp.h>
#include <machine/fdt.h>
#include <machine/intr.h>
@@ -104,8 +105,7 @@ platform_mp_start_ap(void)
* magic location, 0xfffffff0, isn't in the SCU's filtering range so it
* needs a write-back too.
*/
- cpu_idcache_wbinv_all();
- cpu_l2cache_wbinv_all();
+ dcache_wbinv_poc_all();
/* Wake up CPU1. */
armv7_sev();
diff --git a/sys/arm/xscale/i80321/ep80219_machdep.c b/sys/arm/xscale/i80321/ep80219_machdep.c
deleted file mode 100644
index 6c0d1f5..0000000
--- a/sys/arm/xscale/i80321/ep80219_machdep.c
+++ /dev/null
@@ -1,402 +0,0 @@
-/* $NetBSD: hpc_machdep.c,v 1.70 2003/09/16 08:18:22 agc Exp $ */
-
-/*-
- * Copyright (c) 1994-1998 Mark Brinicombe.
- * Copyright (c) 1994 Brini.
- * All rights reserved.
- *
- * This code is derived from software written for Brini by Mark Brinicombe
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Brini.
- * 4. The name of the company nor the name of the author may be used to
- * endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
- *
- * RiscBSD kernel project
- *
- * machdep.c
- *
- * Machine dependant functions for kernel setup
- *
- * This file needs a lot of work.
- *
- * Created : 17/09/94
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "opt_kstack_pages.h"
-
-#define _ARM32_BUS_DMA_PRIVATE
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/sysproto.h>
-#include <sys/signalvar.h>
-#include <sys/imgact.h>
-#include <sys/kernel.h>
-#include <sys/ktr.h>
-#include <sys/linker.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mutex.h>
-#include <sys/pcpu.h>
-#include <sys/proc.h>
-#include <sys/ptrace.h>
-#include <sys/cons.h>
-#include <sys/bio.h>
-#include <sys/bus.h>
-#include <sys/buf.h>
-#include <sys/exec.h>
-#include <sys/kdb.h>
-#include <sys/msgbuf.h>
-#include <machine/reg.h>
-#include <machine/cpu.h>
-
-#include <vm/vm.h>
-#include <vm/pmap.h>
-#include <vm/vm_object.h>
-#include <vm/vm_page.h>
-#include <vm/vm_map.h>
-#include <machine/devmap.h>
-#include <machine/vmparam.h>
-#include <machine/pcb.h>
-#include <machine/undefined.h>
-#include <machine/machdep.h>
-#include <machine/metadata.h>
-#include <machine/armreg.h>
-#include <machine/bus.h>
-#include <machine/physmem.h>
-#include <sys/reboot.h>
-
-#include <arm/xscale/i80321/i80321reg.h>
-#include <arm/xscale/i80321/i80321var.h>
-#include <arm/xscale/i80321/iq80321reg.h>
-#include <arm/xscale/i80321/obiovar.h>
-
-#define KERNEL_PT_SYS 0 /* Page table for mapping proc0 zero page */
-#define KERNEL_PT_IOPXS 1
-#define KERNEL_PT_BEFOREKERN 2
-#define KERNEL_PT_AFKERNEL 3 /* L2 table for mapping after kernel */
-#define KERNEL_PT_AFKERNEL_NUM 9
-
-/* this should be evenly divisable by PAGE_SIZE / L2_TABLE_SIZE_REAL (or 4) */
-#define NUM_KERNEL_PTS (KERNEL_PT_AFKERNEL + KERNEL_PT_AFKERNEL_NUM)
-
-struct pv_addr kernel_pt_table[NUM_KERNEL_PTS];
-
-/* Physical and virtual addresses for some global pages */
-
-struct pv_addr systempage;
-struct pv_addr msgbufpv;
-struct pv_addr irqstack;
-struct pv_addr undstack;
-struct pv_addr abtstack;
-struct pv_addr kernelstack;
-struct pv_addr minidataclean;
-
-
-/* #define IQ80321_OBIO_BASE 0xfe800000UL */
-/* #define IQ80321_OBIO_SIZE 0x00100000UL */
-
-/* Static device mappings. */
-static const struct arm_devmap_entry ep80219_devmap[] = {
- /*
- * Map the on-board devices VA == PA so that we can access them
- * with the MMU on or off.
- */
- {
- IQ80321_OBIO_BASE,
- IQ80321_OBIO_BASE,
- IQ80321_OBIO_SIZE,
- VM_PROT_READ|VM_PROT_WRITE,
- PTE_DEVICE,
- },
- {
- IQ80321_IOW_VBASE,
- VERDE_OUT_XLATE_IO_WIN0_BASE,
- VERDE_OUT_XLATE_IO_WIN_SIZE,
- VM_PROT_READ|VM_PROT_WRITE,
- PTE_DEVICE,
- },
- {
- IQ80321_80321_VBASE,
- VERDE_PMMR_BASE,
- VERDE_PMMR_SIZE,
- VM_PROT_READ|VM_PROT_WRITE,
- PTE_DEVICE,
- },
- {
- 0,
- 0,
- 0,
- 0,
- 0,
- }
-};
-
-extern vm_offset_t xscale_cache_clean_addr;
-
-void *
-initarm(struct arm_boot_params *abp)
-{
- struct pv_addr kernel_l1pt;
- struct pv_addr dpcpu;
- int loop, i;
- u_int l1pagetable;
- vm_offset_t freemempos;
- vm_offset_t freemem_pt;
- vm_offset_t afterkern;
- vm_offset_t freemem_after;
- vm_offset_t lastaddr;
- uint32_t memsize, memstart;
-
- lastaddr = parse_boot_param(abp);
- arm_physmem_kernaddr = abp->abp_physaddr;
- set_cpufuncs();
- pcpu_init(pcpup, 0, sizeof(struct pcpu));
- PCPU_SET(curthread, &thread0);
-
- /* Do basic tuning, hz etc */
- init_param1();
-
- freemempos = 0xa0200000;
- /* Define a macro to simplify memory allocation */
-#define valloc_pages(var, np) \
- alloc_pages((var).pv_pa, (np)); \
- (var).pv_va = (var).pv_pa + 0x20000000;
-
-#define alloc_pages(var, np) \
- freemempos -= (np * PAGE_SIZE); \
- (var) = freemempos; \
- memset((char *)(var), 0, ((np) * PAGE_SIZE));
-
- while (((freemempos - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) != 0)
- freemempos -= PAGE_SIZE;
- valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE);
- for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) {
- if (!(loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL))) {
- valloc_pages(kernel_pt_table[loop],
- L2_TABLE_SIZE / PAGE_SIZE);
- } else {
- kernel_pt_table[loop].pv_pa = freemempos +
- (loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL)) *
- L2_TABLE_SIZE_REAL;
- kernel_pt_table[loop].pv_va =
- kernel_pt_table[loop].pv_pa + 0x20000000;
- }
- }
- freemem_pt = freemempos;
- freemempos = 0xa0100000;
- /*
- * Allocate a page for the system page mapped to V0x00000000
- * This page will just contain the system vectors and can be
- * shared by all processes.
- */
- valloc_pages(systempage, 1);
-
- /* Allocate dynamic per-cpu area. */
- valloc_pages(dpcpu, DPCPU_SIZE / PAGE_SIZE);
- dpcpu_init((void *)dpcpu.pv_va, 0);
-
- /* Allocate stacks for all modes */
- valloc_pages(irqstack, IRQ_STACK_SIZE);
- valloc_pages(abtstack, ABT_STACK_SIZE);
- valloc_pages(undstack, UND_STACK_SIZE);
- valloc_pages(kernelstack, kstack_pages);
- alloc_pages(minidataclean.pv_pa, 1);
- valloc_pages(msgbufpv, round_page(msgbufsize) / PAGE_SIZE);
- /*
- * Allocate memory for the l1 and l2 page tables. The scheme to avoid
- * wasting memory by allocating the l1pt on the first 16k memory was
- * taken from NetBSD rpc_machdep.c. NKPT should be greater than 12 for
- * this to work (which is supposed to be the case).
- */
-
- /*
- * Now we start construction of the L1 page table
- * We start by mapping the L2 page tables into the L1.
- * This means that we can replace L1 mappings later on if necessary
- */
- l1pagetable = kernel_l1pt.pv_va;
-
- /* Map the L2 pages tables in the L1 page table */
- pmap_link_l2pt(l1pagetable, ARM_VECTORS_HIGH & ~(0x00100000 - 1),
- &kernel_pt_table[KERNEL_PT_SYS]);
- pmap_link_l2pt(l1pagetable, IQ80321_IOPXS_VBASE,
- &kernel_pt_table[KERNEL_PT_IOPXS]);
- pmap_link_l2pt(l1pagetable, KERNBASE,
- &kernel_pt_table[KERNEL_PT_BEFOREKERN]);
- pmap_map_chunk(l1pagetable, KERNBASE, IQ80321_SDRAM_START, 0x100000,
- VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
- pmap_map_chunk(l1pagetable, KERNBASE + 0x100000, IQ80321_SDRAM_START + 0x100000,
- 0x100000, VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
- pmap_map_chunk(l1pagetable, KERNBASE + 0x200000, IQ80321_SDRAM_START + 0x200000,
- (((uint32_t)(lastaddr) - KERNBASE - 0x200000) + L1_S_SIZE) & ~(L1_S_SIZE - 1),
- VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
- freemem_after = ((int)lastaddr + PAGE_SIZE) & ~(PAGE_SIZE - 1);
- afterkern = round_page(((vm_offset_t)lastaddr + L1_S_SIZE) & ~(L1_S_SIZE
- - 1));
- for (i = 0; i < KERNEL_PT_AFKERNEL_NUM; i++) {
- pmap_link_l2pt(l1pagetable, afterkern + i * 0x00100000,
- &kernel_pt_table[KERNEL_PT_AFKERNEL + i]);
- }
- pmap_map_entry(l1pagetable, afterkern, minidataclean.pv_pa,
- VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
-
-
- /* Map the Mini-Data cache clean area. */
- xscale_setup_minidata(l1pagetable, afterkern,
- minidataclean.pv_pa);
-
- /* Map the vector page. */
- pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa,
- VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
- arm_devmap_bootstrap(l1pagetable, ep80219_devmap);
- /*
- * Give the XScale global cache clean code an appropriately
- * sized chunk of unmapped VA space starting at 0xff000000
- * (our device mappings end before this address).
- */
- xscale_cache_clean_addr = 0xff000000U;
-
- cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
- setttb(kernel_l1pt.pv_pa);
- cpu_tlb_flushID();
- cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
- /*
- * Pages were allocated during the secondary bootstrap for the
- * stacks for different CPU modes.
- * We must now set the r13 registers in the different CPU modes to
- * point to these stacks.
- * Since the ARM stacks use STMFD etc. we must set r13 to the top end
- * of the stack memory.
- */
- set_stackptrs(0);
-
- /*
- * We must now clean the cache again....
- * Cleaning may be done by reading new data to displace any
- * dirty data in the cache. This will have happened in setttb()
- * but since we are boot strapping the addresses used for the read
- * may have just been remapped and thus the cache could be out
- * of sync. A re-clean after the switch will cure this.
- * After booting there are no gross relocations of the kernel thus
- * this problem will not occur after initarm().
- */
- cpu_idcache_wbinv_all();
- cpu_setup();
-
- /*
- * Fetch the SDRAM start/size from the i80321 SDRAM configration
- * registers.
- */
- i80321_calibrate_delay();
- i80321_sdram_bounds(obio_bs_tag, IQ80321_80321_VBASE + VERDE_MCU_BASE,
- &memstart, &memsize);
- physmem = memsize / PAGE_SIZE;
- cninit();
-
- undefined_init();
-
- init_proc0(kernelstack.pv_va);
-
- /* Enable MMU, I-cache, D-cache, write buffer. */
-
- arm_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL);
- vm_max_kernel_address = 0xe0000000;
- pmap_bootstrap(pmap_curmaxkvaddr, &kernel_l1pt);
- msgbufp = (void*)msgbufpv.pv_va;
- msgbufinit(msgbufp, msgbufsize);
- mutex_init();
-
- /*
- * Add the physical ram we have available.
- *
- * Exclude the kernel (and all the things we allocated which immediately
- * follow the kernel) from the VM allocation pool but not from crash
- * dumps. virtual_avail is a global variable which tracks the kva we've
- * "allocated" while setting up pmaps.
- *
- * Prepare the list of physical memory available to the vm subsystem.
- */
- arm_physmem_hardware_region(IQ80321_SDRAM_START, memsize);
- arm_physmem_exclude_region(freemem_pt, abp->abp_physaddr -
- freemem_pt, EXFLAG_NOALLOC);
- arm_physmem_exclude_region(freemempos, abp->abp_physaddr - 0x100000 -
- freemempos, EXFLAG_NOALLOC);
- arm_physmem_exclude_region(abp->abp_physaddr,
- virtual_avail - KERNVIRTADDR, EXFLAG_NOALLOC);
- arm_physmem_init_kernel_globals();
-
- init_param2(physmem);
- kdb_init();
- return ((void *)(kernelstack.pv_va + USPACE_SVC_STACK_TOP -
- sizeof(struct pcb)));
-}
-
-extern int
-machdep_pci_route_interrupt(device_t pcib, device_t dev, int pin)
-{
- int bus;
- int device;
- int func;
- uint32_t busno;
- struct i80321_pci_softc *sc = device_get_softc(pcib);
- bus = pci_get_bus(dev);
- device = pci_get_slot(dev);
- func = pci_get_function(dev);
- busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR);
- busno = PCIXSR_BUSNO(busno);
- if (busno == 0xff)
- busno = 0;
- if (bus != busno)
- goto no_mapping;
- switch (device) {
- /* EP80219 PCI */
- case 1: /* Ethernet i82555 10/100 */
- printf("Device %d routed to irq %d\n", device, ICU_INT_XINT(0));
- return (ICU_INT_XINT(0));
- case 2: /* UART */
- printf("Device %d routed to irq %d\n", device, ICU_INT_XINT(1));
- return (ICU_INT_XINT(1));
- case 3:
- /*
- * The S-ATA chips are behind the bridge, and all of
- * the S-ATA interrupts are wired together.
- */
- printf("Device %d routed to irq %d\n", device, ICU_INT_XINT(2));
- return (ICU_INT_XINT(2));
- case 4: /* MINI-PIC_INT */
- printf("Device %d routed to irq %d\n", device, ICU_INT_XINT(3));
- return( ICU_INT_XINT(3));
- default:
-no_mapping:
- printf("No mapping for %d/%d/%d/%c\n", bus, device, func, pin);
-
- }
- return (0);
-
-}
diff --git a/sys/arm/xscale/i80321/files.ep80219 b/sys/arm/xscale/i80321/files.ep80219
deleted file mode 100644
index 0eaf9db..0000000
--- a/sys/arm/xscale/i80321/files.ep80219
+++ /dev/null
@@ -1,11 +0,0 @@
-#$FreeBSD$
-#
-#
-# EP80219 Board Specific
-#
-arm/xscale/i80321/iq80321.c standard
-arm/xscale/i80321/ep80219_machdep.c standard
-arm/xscale/i80321/obio.c standard
-arm/xscale/i80321/uart_cpu_i80321.c optional uart
-arm/xscale/i80321/uart_bus_i80321.c optional uart
-dev/uart/uart_dev_ns8250.c optional uart
diff --git a/sys/arm/xscale/i80321/files.i80219 b/sys/arm/xscale/i80321/files.i80219
deleted file mode 100644
index 306376b..0000000
--- a/sys/arm/xscale/i80321/files.i80219
+++ /dev/null
@@ -1,11 +0,0 @@
-#$FreeBSD$
-#
-# IOP Specific
-#
-arm/xscale/i80321/i80321.c standard
-arm/xscale/i80321/i80321_dma.c optional dma
-arm/xscale/i80321/i80321_mcu.c standard
-arm/xscale/i80321/i80321_pci.c optional pci
-arm/xscale/i80321/i80321_space.c standard
-arm/xscale/i80321/i80321_timer.c standard
-arm/xscale/i80321/i80321_wdog.c optional iopwdog
diff --git a/sys/arm/xscale/i80321/files.i80321 b/sys/arm/xscale/i80321/files.i80321
deleted file mode 100644
index bd318af..0000000
--- a/sys/arm/xscale/i80321/files.i80321
+++ /dev/null
@@ -1,9 +0,0 @@
-#$FreeBSD$
-arm/xscale/i80321/i80321.c standard
-arm/xscale/i80321/i80321_aau.c optional aau
-arm/xscale/i80321/i80321_dma.c optional dma
-arm/xscale/i80321/i80321_mcu.c standard
-arm/xscale/i80321/i80321_pci.c optional pci
-arm/xscale/i80321/i80321_space.c standard
-arm/xscale/i80321/i80321_timer.c standard
-arm/xscale/i80321/i80321_wdog.c optional iopwdog
diff --git a/sys/arm/xscale/i80321/files.iq31244 b/sys/arm/xscale/i80321/files.iq31244
deleted file mode 100644
index d28d49b..0000000
--- a/sys/arm/xscale/i80321/files.iq31244
+++ /dev/null
@@ -1,8 +0,0 @@
-#$FreeBSD$
-arm/xscale/i80321/iq80321.c standard
-arm/xscale/i80321/iq31244_machdep.c standard
-arm/xscale/i80321/iq31244_7seg.c optional iq31244_7seg
-arm/xscale/i80321/obio.c standard
-arm/xscale/i80321/uart_cpu_i80321.c optional uart
-arm/xscale/i80321/uart_bus_i80321.c optional uart
-dev/uart/uart_dev_ns8250.c optional uart
diff --git a/sys/arm/xscale/i80321/i80321.c b/sys/arm/xscale/i80321/i80321.c
deleted file mode 100644
index e65f38d..0000000
--- a/sys/arm/xscale/i80321/i80321.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/* $NetBSD: i80321.c,v 1.15 2003/10/06 16:06:05 thorpej Exp $ */
-
-/*-
- * Copyright (c) 2002 Wasabi Systems, Inc.
- * All rights reserved.
- *
- * Written by Jason R. Thorpe for Wasabi Systems, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed for the NetBSD Project by
- * Wasabi Systems, Inc.
- * 4. The name of Wasabi Systems, Inc. may not be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
- * 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.
- */
-
-/*
- * Autoconfiguration support for the Intel i80321 I/O Processor.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-
-#define _ARM32_BUS_DMA_PRIVATE
-#include <machine/bus.h>
-#include <machine/intr.h>
-
-#include <arm/xscale/i80321/i80321reg.h>
-#include <arm/xscale/i80321/i80321var.h>
-#include <arm/xscale/i80321/i80321_intr.h>
-
-#include <dev/pci/pcireg.h>
-
-volatile uint32_t intr_enabled;
-uint32_t intr_steer = 0;
-/*
- * Statically-allocated bus_space stucture used to access the
- * i80321's own registers.
- */
-struct bus_space i80321_bs_tag;
-
-/*
- * There can be only one i80321, so we keep a global pointer to
- * the softc, so board-specific code can use features of the
- * i80321 without having to have a handle on the softc itself.
- */
-struct i80321_softc *i80321_softc;
-
-#define PCI_MAPREG_MEM_ADDR(x) ((x) & 0xfffffff0)
-/*
- * i80321_attach:
- *
- * Board-independent attach routine for the i80321.
- */
-void
-i80321_attach(struct i80321_softc *sc)
-{
-
- i80321_softc = sc;
- uint32_t preg;
-
- /* We expect the Memory Controller to be already sliced off. */
-
- /*
- * Program the Inbound windows.
- */
- bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR0,
- (0xffffffff - (sc->sc_iwin[0].iwin_size - 1)) & 0xffffffc0);
- bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IATVR0,
- sc->sc_iwin[0].iwin_xlate);
- if (sc->sc_is_host) {
- bus_space_write_4(sc->sc_st, sc->sc_atu_sh,
- PCIR_BARS, sc->sc_iwin[0].iwin_base_lo);
- bus_space_write_4(sc->sc_st, sc->sc_atu_sh,
- PCIR_BARS + 0x04, sc->sc_iwin[0].iwin_base_hi);
- } else {
- sc->sc_iwin[0].iwin_base_lo = bus_space_read_4(sc->sc_st,
- sc->sc_atu_sh, PCIR_BARS);
- sc->sc_iwin[0].iwin_base_hi = bus_space_read_4(sc->sc_st,
- sc->sc_atu_sh, PCIR_BARS + 0x04);
- sc->sc_iwin[0].iwin_base_lo =
- PCI_MAPREG_MEM_ADDR(sc->sc_iwin[0].iwin_base_lo);
- }
-
- bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR1,
- (0xffffffff - (sc->sc_iwin[1].iwin_size - 1)) & 0xffffffc0);
-
- /* no xlate for window 1 */
- if (sc->sc_is_host) {
- bus_space_write_4(sc->sc_st, sc->sc_atu_sh,
- PCIR_BARS + 0x08, sc->sc_iwin[1].iwin_base_lo);
- bus_space_write_4(sc->sc_st, sc->sc_atu_sh,
- PCIR_BARS + 0x0c, sc->sc_iwin[1].iwin_base_hi);
- } else {
- sc->sc_iwin[1].iwin_base_lo = bus_space_read_4(sc->sc_st,
- sc->sc_atu_sh, PCIR_BARS + 0x08);
- sc->sc_iwin[1].iwin_base_hi = bus_space_read_4(sc->sc_st,
- sc->sc_atu_sh, PCIR_BARS + 0x0c);
- sc->sc_iwin[1].iwin_base_lo =
- PCI_MAPREG_MEM_ADDR(sc->sc_iwin[1].iwin_base_lo);
- }
-
- bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR2,
- (0xffffffff - (sc->sc_iwin[2].iwin_size - 1)) & 0xffffffc0);
- bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IATVR2,
- sc->sc_iwin[2].iwin_xlate);
-
- if (sc->sc_is_host) {
- bus_space_write_4(sc->sc_st, sc->sc_atu_sh,
- PCIR_BARS + 0x10, sc->sc_iwin[2].iwin_base_lo);
- bus_space_write_4(sc->sc_st, sc->sc_atu_sh,
- PCIR_BARS + 0x14, sc->sc_iwin[2].iwin_base_hi);
- } else {
- sc->sc_iwin[2].iwin_base_lo = bus_space_read_4(sc->sc_st,
- sc->sc_atu_sh, PCIR_BARS + 0x10);
- sc->sc_iwin[2].iwin_base_hi = bus_space_read_4(sc->sc_st,
- sc->sc_atu_sh, PCIR_BARS + 0x14);
- sc->sc_iwin[2].iwin_base_lo =
- PCI_MAPREG_MEM_ADDR(sc->sc_iwin[2].iwin_base_lo);
- }
- bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR3,
- (0xffffffff - (sc->sc_iwin[3].iwin_size - 1)) & 0xffffffc0);
- bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IATVR3,
- sc->sc_iwin[3].iwin_xlate);
-
- if (sc->sc_is_host) {
- bus_space_write_4(sc->sc_st, sc->sc_atu_sh,
- ATU_IABAR3, sc->sc_iwin[3].iwin_base_lo);
- bus_space_write_4(sc->sc_st, sc->sc_atu_sh,
- ATU_IAUBAR3, sc->sc_iwin[3].iwin_base_hi);
- } else {
- sc->sc_iwin[3].iwin_base_lo = bus_space_read_4(sc->sc_st,
- sc->sc_atu_sh, ATU_IABAR3);
- sc->sc_iwin[3].iwin_base_hi = bus_space_read_4(sc->sc_st,
- sc->sc_atu_sh, ATU_IAUBAR3);
- sc->sc_iwin[3].iwin_base_lo =
- PCI_MAPREG_MEM_ADDR(sc->sc_iwin[3].iwin_base_lo);
- }
- /*
- * Mask (disable) the ATU interrupt sources.
- * XXX May want to revisit this if we encounter
- * XXX an application that wants it.
- */
- bus_space_write_4(sc->sc_st, sc->sc_atu_sh,
- ATU_ATUIMR,
- ATUIMR_IMW1BU|ATUIMR_ISCEM|ATUIMR_RSCEM|ATUIMR_PST|
- ATUIMR_DPE|ATUIMR_P_SERR_ASRT|ATUIMR_PMA|ATUIMR_PTAM|
- ATUIMR_PTAT|ATUIMR_PMPE);
-
- /*
- * Program the outbound windows.
- */
- bus_space_write_4(sc->sc_st, sc->sc_atu_sh,
- ATU_OIOWTVR, sc->sc_ioout_xlate);
-
- if (!sc->sc_is_host) {
- sc->sc_owin[0].owin_xlate_lo = sc->sc_iwin[1].iwin_base_lo;
- sc->sc_owin[0].owin_xlate_hi = sc->sc_iwin[1].iwin_base_hi;
- }
- bus_space_write_4(sc->sc_st, sc->sc_atu_sh,
- ATU_OMWTVR0, sc->sc_owin[0].owin_xlate_lo);
- bus_space_write_4(sc->sc_st, sc->sc_atu_sh,
- ATU_OUMWTVR0, sc->sc_owin[0].owin_xlate_hi);
-
- bus_space_write_4(sc->sc_st, sc->sc_atu_sh,
- ATU_OMWTVR1, sc->sc_owin[1].owin_xlate_lo);
- bus_space_write_4(sc->sc_st, sc->sc_atu_sh,
- ATU_OUMWTVR1, sc->sc_owin[1].owin_xlate_hi);
-
- /*
- * Set up the ATU configuration register. All we do
- * right now is enable Outbound Windows.
- */
- bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_ATUCR,
- ATUCR_OUT_EN);
-
- /*
- * Enable bus mastering, memory access, SERR, and parity
- * checking on the ATU.
- */
- if (sc->sc_is_host) {
- preg = bus_space_read_4(sc->sc_st, sc->sc_atu_sh,
- PCIR_COMMAND);
- preg |= PCIM_CMD_MEMEN |
- PCIM_CMD_BUSMASTEREN | PCIM_CMD_PERRESPEN |
- PCIM_CMD_SERRESPEN;
- bus_space_write_4(sc->sc_st, sc->sc_atu_sh,
- PCIR_COMMAND, preg);
- }
- /* Initialize the bus space tags. */
- i80321_io_bs_init(&sc->sc_pci_iot, sc);
- i80321_mem_bs_init(&sc->sc_pci_memt, sc);
- intr_enabled = 0;
- i80321_set_intrmask();
- i80321_set_intrsteer();
-}
-
-
-static __inline uint32_t
-i80321_iintsrc_read(void)
-{
- uint32_t iintsrc;
-
- __asm __volatile("mrc p6, 0, %0, c8, c0, 0"
- : "=r" (iintsrc));
-
- /*
- * The IINTSRC register shows bits that are active even
- * if they are masked in INTCTL, so we have to mask them
- * off with the interrupts we consider enabled.
- */
- return (iintsrc & intr_enabled);
-}
-
-int
-arm_get_next_irq(int last __unused)
-{
- int irq;
-
- if ((irq = i80321_iintsrc_read()))
- return (ffs(irq) - 1);
- return (-1);
-}
diff --git a/sys/arm/xscale/i80321/i80321_aau.c b/sys/arm/xscale/i80321/i80321_aau.c
deleted file mode 100644
index 288411b..0000000
--- a/sys/arm/xscale/i80321/i80321_aau.c
+++ /dev/null
@@ -1,292 +0,0 @@
-/*-
- * Copyright (c) 2005 Olivier Houchard. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/malloc.h>
-#include <sys/rman.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/proc.h>
-
-#include <vm/vm.h>
-#include <vm/pmap.h>
-#include <vm/vm_map.h>
-#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/md_var.h>
-
-#include <arm/xscale/i80321/i80321reg.h>
-#include <arm/xscale/i80321/i80321var.h>
-#include <arm/xscale/i80321/iq80321reg.h>
-#include <arm/xscale/i80321/iq80321var.h>
-#include <arm/xscale/i80321/i80321_intr.h>
-
-typedef struct i80321_aaudesc_s {
- vm_paddr_t next_desc;
- uint32_t sar[4];
- vm_paddr_t local_addr;
- vm_size_t count;
- uint32_t descr_ctrl;
-} __packed i80321_aaudesc_t;
-
-typedef struct i80321_aauring_s {
- i80321_aaudesc_t *desc;
- vm_paddr_t phys_addr;
- bus_dmamap_t map;
-} i80321_aauring_t;
-
-#define AAU_RING_SIZE 64
-
-struct i80321_aau_softc {
- bus_space_tag_t sc_st;
- bus_space_handle_t sc_aau_sh;
- bus_dma_tag_t dmatag;
- i80321_aauring_t aauring[AAU_RING_SIZE];
- int flags;
-#define BUSY 0x1
- int unit;
- struct mtx mtx;
-};
-
-static int
-i80321_aau_probe(device_t dev)
-{
- device_set_desc(dev, "I80321 AAU");
- return (0);
-}
-
-static struct i80321_aau_softc *aau_softc;
-
-static void
-i80321_mapphys(void *arg, bus_dma_segment_t *segs, int nseg, int error)
-{
- vm_paddr_t *addr = (vm_paddr_t *)arg;
-
- *addr = segs->ds_addr;
-}
-
-#define AAU_REG_WRITE(softc, reg, val) \
- bus_space_write_4((softc)->sc_st, (softc)->sc_aau_sh, \
- (reg), (val))
-#define AAU_REG_READ(softc, reg) \
- bus_space_read_4((softc)->sc_st, (softc)->sc_aau_sh, \
- (reg))
-
-static int aau_bzero(void *, int, int);
-
-static int
-i80321_aau_attach(device_t dev)
-{
- struct i80321_aau_softc *softc = device_get_softc(dev);
- struct i80321_softc *sc = device_get_softc(device_get_parent(dev));
- struct i80321_aaudesc_s *aaudescs;
-
- mtx_init(&softc->mtx, "AAU mtx", NULL, MTX_SPIN);
- softc->sc_st = sc->sc_st;
- if (bus_space_subregion(softc->sc_st, sc->sc_sh, VERDE_AAU_BASE,
- VERDE_AAU_SIZE, &softc->sc_aau_sh) != 0)
- panic("%s: unable to subregion AAU registers",
- device_get_name(dev));
- if (bus_dma_tag_create(NULL, sizeof(i80321_aaudesc_t), 0,
- BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
- AAU_RING_SIZE * sizeof(i80321_aaudesc_t),
- 1, sizeof(i80321_aaudesc_t), BUS_DMA_ALLOCNOW, busdma_lock_mutex,
- &Giant, &softc->dmatag))
- panic("Couldn't create a dma tag");
- if (bus_dmamem_alloc(softc->dmatag, (void **)&aaudescs,
- BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &softc->aauring[0].map))
- panic("Couldn't alloc dma memory");
-
- for (int i = 0; i < AAU_RING_SIZE; i++) {
- if (i > 0)
- if (bus_dmamap_create(softc->dmatag, 0,
- &softc->aauring[i].map))
- panic("Couldn't create dma map");
- softc->aauring[i].desc = &aaudescs[i];
- bus_dmamap_load(softc->dmatag, softc->aauring[i].map,
- softc->aauring[i].desc, sizeof(i80321_aaudesc_t),
- i80321_mapphys, &softc->aauring[i].phys_addr, 0);
- bzero(softc->aauring[i].desc, sizeof(i80321_aaudesc_t));
- }
- aau_softc = softc;
- _arm_bzero = aau_bzero;
- _min_bzero_size = 1024;
- return (0);
-}
-
-static __inline void
-test_virt_addr(void *addr, int len)
-{
- int to_nextpage;
-
- while (len > 0) {
- *(char *)addr = 0;
- to_nextpage = ((vm_offset_t)addr & ~PAGE_MASK) +
- PAGE_SIZE - (vm_offset_t)addr;
- if (to_nextpage >= len)
- break;
- len -= to_nextpage;
- addr = (void *)((vm_offset_t)addr + to_nextpage);
- }
-}
-
-static int
-aau_bzero(void *dst, int len, int flags)
-{
- struct i80321_aau_softc *sc = aau_softc;
- i80321_aaudesc_t *desc;
- int ret;
- int csr;
- int descnb = 0;
- int tmplen = len;
- int to_nextpagedst;
- int min_hop;
- vm_paddr_t pa, tmppa;
-
- if (!sc)
- return (-1);
- mtx_lock_spin(&sc->mtx);
- if (sc->flags & BUSY) {
- mtx_unlock_spin(&sc->mtx);
- return (-1);
- }
- sc->flags |= BUSY;
- mtx_unlock_spin(&sc->mtx);
- desc = sc->aauring[0].desc;
- if (flags & IS_PHYSICAL) {
- desc->local_addr = (vm_paddr_t)dst;
- desc->next_desc = 0;
- desc->count = len;
- desc->descr_ctrl = 2 << 1 | 1 << 31; /* Fill, enable dest write */
- bus_dmamap_sync(sc->dmatag, sc->aauring[0].map,
- BUS_DMASYNC_PREWRITE);
- } else {
- test_virt_addr(dst, len);
- if ((vm_offset_t)dst & (31))
- cpu_dcache_wb_range((vm_offset_t)dst & ~31, 32);
- if (((vm_offset_t)dst + len) & 31)
- cpu_dcache_wb_range(((vm_offset_t)dst + len) & ~31,
- 32);
- cpu_dcache_inv_range((vm_offset_t)dst, len);
- while (tmplen > 0) {
- pa = vtophys(dst);
- to_nextpagedst = ((vm_offset_t)dst & ~PAGE_MASK) +
- PAGE_SIZE - (vm_offset_t)dst;
- while (to_nextpagedst < tmplen) {
- tmppa = vtophys((vm_offset_t)dst +
- to_nextpagedst);
- if (tmppa != pa + to_nextpagedst)
- break;
- to_nextpagedst += PAGE_SIZE;
- }
- min_hop = to_nextpagedst;
- if (min_hop < 64) {
- tmplen -= min_hop;
- bzero(dst, min_hop);
- cpu_dcache_wbinv_range((vm_offset_t)dst,
- min_hop);
-
- dst = (void *)((vm_offset_t)dst + min_hop);
- if (tmplen <= 0 && descnb > 0) {
- sc->aauring[descnb - 1].desc->next_desc
- = 0;
- bus_dmamap_sync(sc->dmatag,
- sc->aauring[descnb - 1].map,
- BUS_DMASYNC_PREWRITE);
- }
- continue;
- }
- desc->local_addr = pa;
- desc->count = tmplen > min_hop ? min_hop : tmplen;
- desc->descr_ctrl = 2 << 1 | 1 << 31; /* Fill, enable dest write */;
- if (min_hop < tmplen) {
- tmplen -= min_hop;
- dst = (void *)((vm_offset_t)dst + min_hop);
- } else
- tmplen = 0;
- if (descnb + 1 >= AAU_RING_SIZE) {
- mtx_lock_spin(&sc->mtx);
- sc->flags &= ~BUSY;
- mtx_unlock_spin(&sc->mtx);
- return (-1);
- }
- if (tmplen > 0) {
- desc->next_desc = sc->aauring[descnb + 1].
- phys_addr;
- bus_dmamap_sync(sc->dmatag,
- sc->aauring[descnb].map,
- BUS_DMASYNC_PREWRITE);
- desc = sc->aauring[descnb + 1].desc;
- descnb++;
- } else {
- desc->next_desc = 0;
- bus_dmamap_sync(sc->dmatag,
- sc->aauring[descnb].map,
- BUS_DMASYNC_PREWRITE);
- }
-
- }
-
- }
- AAU_REG_WRITE(sc, 0x0c /* Descriptor addr */,
- sc->aauring[0].phys_addr);
- AAU_REG_WRITE(sc, 0 /* Control register */, 1 << 0/* Start transfer */);
- while ((csr = AAU_REG_READ(sc, 0x4)) & (1 << 10));
- /* Wait until it's done. */
- if (csr & (1 << 5)) /* error */
- ret = -1;
- else
- ret = 0;
- /* Clear the interrupt. */
- AAU_REG_WRITE(sc, 0x4, csr);
- /* Stop the AAU. */
- AAU_REG_WRITE(sc, 0, 0);
- mtx_lock_spin(&sc->mtx);
- sc->flags &= ~BUSY;
- mtx_unlock_spin(&sc->mtx);
- return (ret);
-}
-
-static device_method_t i80321_aau_methods[] = {
- DEVMETHOD(device_probe, i80321_aau_probe),
- DEVMETHOD(device_attach, i80321_aau_attach),
- {0, 0},
-};
-
-static driver_t i80321_aau_driver = {
- "i80321_aau",
- i80321_aau_methods,
- sizeof(struct i80321_aau_softc),
-};
-
-static devclass_t i80321_aau_devclass;
-
-DRIVER_MODULE(i80321_aau, iq, i80321_aau_driver, i80321_aau_devclass, 0, 0);
diff --git a/sys/arm/xscale/i80321/i80321_dma.c b/sys/arm/xscale/i80321/i80321_dma.c
deleted file mode 100644
index abf7dcc..0000000
--- a/sys/arm/xscale/i80321/i80321_dma.c
+++ /dev/null
@@ -1,351 +0,0 @@
-/*-
- * Copyright (c) 2005 Olivier Houchard. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/malloc.h>
-#include <sys/rman.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/proc.h>
-
-#include <vm/vm.h>
-#include <vm/pmap.h>
-#include <vm/vm_map.h>
-#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/md_var.h>
-
-#include <arm/xscale/i80321/i80321reg.h>
-#include <arm/xscale/i80321/i80321var.h>
-#include <arm/xscale/i80321/iq80321reg.h>
-#include <arm/xscale/i80321/iq80321var.h>
-#include <arm/xscale/i80321/i80321_intr.h>
-
-typedef struct i80321_dmadesc_s {
- vm_paddr_t next_desc;
- vm_paddr_t low_pciaddr;
- vm_paddr_t high_pciaddr;
- vm_paddr_t local_addr;
- vm_size_t count;
- uint32_t descr_ctrl;
- uint64_t unused;
-} __packed i80321_dmadesc_t;
-
-typedef struct i80321_dmaring_s {
- i80321_dmadesc_t *desc;
- vm_paddr_t phys_addr;
- bus_dmamap_t map;
-} i80321_dmaring_t;
-
-#define DMA_RING_SIZE 64
-
-struct i80321_dma_softc {
- bus_space_tag_t sc_st;
- bus_space_handle_t sc_dma_sh;
- bus_dma_tag_t dmatag;
- i80321_dmaring_t dmaring[DMA_RING_SIZE];
- int flags;
-#define BUSY 0x1
- int unit;
- struct mtx mtx;
-};
-
-static int
-i80321_dma_probe(device_t dev)
-{
- device_set_desc(dev, "I80321 DMA Unit");
- return (0);
-}
-
-static struct i80321_dma_softc *softcs[2]; /* XXX */
-
-static void
-i80321_mapphys(void *arg, bus_dma_segment_t *segs, int nseg, int error)
-{
- vm_paddr_t *addr = (vm_paddr_t *)arg;
-
- *addr = segs->ds_addr;
-}
-
-#define DMA_REG_WRITE(softc, reg, val) \
- bus_space_write_4((softc)->sc_st, (softc)->sc_dma_sh, \
- (reg), (val))
-#define DMA_REG_READ(softc, reg) \
- bus_space_read_4((softc)->sc_st, (softc)->sc_dma_sh, \
- (reg))
-
-#define DMA_CLEAN_MASK (0x2|0x4|0x8|0x20|0x100|0x200)
-static int dma_memcpy(void *, void *, int, int);
-
-static int
-i80321_dma_attach(device_t dev)
-{
- struct i80321_dma_softc *softc = device_get_softc(dev);
- struct i80321_softc *sc = device_get_softc(device_get_parent(dev));
- int unit = device_get_unit(dev);
- i80321_dmadesc_t *dmadescs;
-
- mtx_init(&softc->mtx, "DMA engine mtx", NULL, MTX_SPIN);
- softc->sc_st = sc->sc_st;
- if (bus_space_subregion(softc->sc_st, sc->sc_sh, unit == 0 ?
- VERDE_DMA_BASE0 : VERDE_DMA_BASE1, VERDE_DMA_SIZE,
- &softc->sc_dma_sh) != 0)
- panic("%s: unable to subregion DMA registers",
- device_get_name(dev));
- if (bus_dma_tag_create(NULL, sizeof(i80321_dmadesc_t),
- 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
- DMA_RING_SIZE * sizeof(i80321_dmadesc_t), 1,
- sizeof(i80321_dmadesc_t), BUS_DMA_ALLOCNOW, busdma_lock_mutex,
- &Giant, &softc->dmatag))
- panic("Couldn't create a dma tag");
- DMA_REG_WRITE(softc, 0, 0);
- if (bus_dmamem_alloc(softc->dmatag, (void **)&dmadescs,
- BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &softc->dmaring[0].map))
- panic("Couldn't alloc dma memory");
- for (int i = 0; i < DMA_RING_SIZE; i++) {
- if (i > 0)
- if (bus_dmamap_create(softc->dmatag, 0,
- &softc->dmaring[i].map))
- panic("Couldn't alloc dmamap");
- softc->dmaring[i].desc = &dmadescs[i];
- bus_dmamap_load(softc->dmatag, softc->dmaring[i].map,
- softc->dmaring[i].desc, sizeof(i80321_dmadesc_t),
- i80321_mapphys, &softc->dmaring[i].phys_addr, 0);
- }
- softc->unit = unit;
- softcs[unit] = softc;
- _arm_memcpy = dma_memcpy;
- _min_memcpy_size = 1024;
- return (0);
-}
-
-static __inline int
-virt_addr_is_valid(void *addr, int len, int write, int is_kernel)
-{
- int to_nextpage;
- char tmp = 0;
-
- while (len > 0) {
- if (write) {
- if (is_kernel)
- *(char *)addr = 0;
- else if (subyte(addr, 0) != 0) {
- return (0);
- }
- } else {
- if (is_kernel)
- badaddr_read(addr, 1, &tmp);
- else if (fubyte(addr) == -1) {
- return (0);
- }
- }
- to_nextpage = ((vm_offset_t)addr & ~PAGE_MASK) +
- PAGE_SIZE - (vm_offset_t)addr;
- if (to_nextpage >= len)
- break;
- len -= to_nextpage;
- addr = (void *)((vm_offset_t)addr + to_nextpage);
- }
- return (1);
-}
-
-static int
-dma_memcpy(void *dst, void *src, int len, int flags)
-{
- struct i80321_dma_softc *sc;
- i80321_dmadesc_t *desc;
- int ret;
- int csr;
- int descnb = 0;
- int tmplen = len;
- int to_nextpagesrc, to_nextpagedst;
- int min_hop;
- vm_paddr_t pa, pa2, tmppa;
- pmap_t pmap = vmspace_pmap(curthread->td_proc->p_vmspace);
-
- if (!softcs[0] || !softcs[1])
- return (-1);
- mtx_lock_spin(&softcs[0]->mtx);
- if (softcs[0]->flags & BUSY) {
- mtx_unlock_spin(&softcs[0]->mtx);
- mtx_lock_spin(&softcs[1]->mtx);
- if (softcs[1]->flags & BUSY) {
- mtx_unlock(&softcs[1]->mtx);
- return (-1);
- }
- sc = softcs[1];
- } else
- sc = softcs[0];
- sc->flags |= BUSY;
- mtx_unlock_spin(&sc->mtx);
- desc = sc->dmaring[0].desc;
- if (flags & IS_PHYSICAL) {
- desc->next_desc = 0;
- desc->low_pciaddr = (vm_paddr_t)src;
- desc->high_pciaddr = 0;
- desc->local_addr = (vm_paddr_t)dst;
- desc->count = len;
- desc->descr_ctrl = 1 << 6; /* Local memory to local memory. */
- bus_dmamap_sync(sc->dmatag,
- sc->dmaring[0].map,
- BUS_DMASYNC_PREWRITE);
- } else {
- if (!virt_addr_is_valid(dst, len, 1, !(flags & DST_IS_USER)) ||
- !virt_addr_is_valid(src, len, 0, !(flags & SRC_IS_USER))) {
- mtx_lock_spin(&sc->mtx);
- sc->flags &= ~BUSY;
- mtx_unlock_spin(&sc->mtx);
- return (-1);
- }
- cpu_dcache_wb_range((vm_offset_t)src, len);
- if ((vm_offset_t)dst & (31))
- cpu_dcache_wb_range((vm_offset_t)dst & ~31, 32);
- if (((vm_offset_t)dst + len) & 31)
- cpu_dcache_wb_range(((vm_offset_t)dst + len) & ~31,
- 32);
- cpu_dcache_inv_range((vm_offset_t)dst, len);
- while (tmplen > 0) {
- pa = (flags & SRC_IS_USER) ?
- pmap_extract(pmap, (vm_offset_t)src) :
- vtophys(src);
- pa2 = (flags & DST_IS_USER) ?
- pmap_extract(pmap, (vm_offset_t)dst) :
- vtophys(dst);
- to_nextpagesrc = ((vm_offset_t)src & ~PAGE_MASK) +
- PAGE_SIZE - (vm_offset_t)src;
- to_nextpagedst = ((vm_offset_t)dst & ~PAGE_MASK) +
- PAGE_SIZE - (vm_offset_t)dst;
- while (to_nextpagesrc < tmplen) {
- tmppa = (flags & SRC_IS_USER) ?
- pmap_extract(pmap, (vm_offset_t)src +
- to_nextpagesrc) :
- vtophys((vm_offset_t)src +
- to_nextpagesrc);
- if (tmppa != pa + to_nextpagesrc)
- break;
- to_nextpagesrc += PAGE_SIZE;
- }
- while (to_nextpagedst < tmplen) {
- tmppa = (flags & DST_IS_USER) ?
- pmap_extract(pmap, (vm_offset_t)dst +
- to_nextpagedst) :
- vtophys((vm_offset_t)dst +
- to_nextpagedst);
- if (tmppa != pa2 + to_nextpagedst)
- break;
- to_nextpagedst += PAGE_SIZE;
- }
- min_hop = to_nextpagedst > to_nextpagesrc ?
- to_nextpagesrc : to_nextpagedst;
- if (min_hop < 64) {
- tmplen -= min_hop;
- memcpy(dst, src, min_hop);
- cpu_dcache_wbinv_range((vm_offset_t)dst,
- min_hop);
-
- src = (void *)((vm_offset_t)src + min_hop);
- dst = (void *)((vm_offset_t)dst + min_hop);
- if (tmplen <= 0 && descnb > 0) {
- sc->dmaring[descnb - 1].desc->next_desc
- = 0;
- bus_dmamap_sync(sc->dmatag,
- sc->dmaring[descnb - 1].map,
- BUS_DMASYNC_PREWRITE);
- }
- continue;
- }
- desc->low_pciaddr = pa;
- desc->high_pciaddr = 0;
- desc->local_addr = pa2;
- desc->count = tmplen > min_hop ? min_hop : tmplen;
- desc->descr_ctrl = 1 << 6;
- if (min_hop < tmplen) {
- tmplen -= min_hop;
- src = (void *)((vm_offset_t)src + min_hop);
- dst = (void *)((vm_offset_t)dst + min_hop);
- } else
- tmplen = 0;
- if (descnb + 1 >= DMA_RING_SIZE) {
- mtx_lock_spin(&sc->mtx);
- sc->flags &= ~BUSY;
- mtx_unlock_spin(&sc->mtx);
- return (-1);
- }
- if (tmplen > 0) {
- desc->next_desc = sc->dmaring[descnb + 1].
- phys_addr;
- bus_dmamap_sync(sc->dmatag,
- sc->dmaring[descnb].map,
- BUS_DMASYNC_PREWRITE);
- desc = sc->dmaring[descnb + 1].desc;
- descnb++;
- } else {
- desc->next_desc = 0;
- bus_dmamap_sync(sc->dmatag,
- sc->dmaring[descnb].map,
- BUS_DMASYNC_PREWRITE);
- }
-
- }
-
- }
- DMA_REG_WRITE(sc, 4 /* Status register */,
- DMA_REG_READ(sc, 4) | DMA_CLEAN_MASK);
- DMA_REG_WRITE(sc, 0x10 /* Descriptor addr */,
- sc->dmaring[0].phys_addr);
- DMA_REG_WRITE(sc, 0 /* Control register */, 1 | 2/* Start transfer */);
- while ((csr = DMA_REG_READ(sc, 0x4)) & (1 << 10));
- /* Wait until it's done. */
- if (csr & 0x2e) /* error */
- ret = -1;
- else
- ret = 0;
- DMA_REG_WRITE(sc, 0, 0);
- mtx_lock_spin(&sc->mtx);
- sc->flags &= ~BUSY;
- mtx_unlock_spin(&sc->mtx);
- return (ret);
-}
-
-static device_method_t i80321_dma_methods[] = {
- DEVMETHOD(device_probe, i80321_dma_probe),
- DEVMETHOD(device_attach, i80321_dma_attach),
- {0, 0},
-};
-
-static driver_t i80321_dma_driver = {
- "i80321_dma",
- i80321_dma_methods,
- sizeof(struct i80321_dma_softc),
-};
-
-static devclass_t i80321_dma_devclass;
-
-DRIVER_MODULE(i80321_dma, iq, i80321_dma_driver, i80321_dma_devclass, 0, 0);
diff --git a/sys/arm/xscale/i80321/i80321_intr.h b/sys/arm/xscale/i80321/i80321_intr.h
deleted file mode 100644
index 29003a0..0000000
--- a/sys/arm/xscale/i80321/i80321_intr.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/* $NetBSD: i80321_intr.h,v 1.5 2004/01/12 10:25:06 scw Exp $ */
-
-/*-
- * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
- * All rights reserved.
- *
- * Written by Jason R. Thorpe for Wasabi Systems, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed for the NetBSD Project by
- * Wasabi Systems, Inc.
- * 4. The name of Wasabi Systems, Inc. may not be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
- * 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 _I80321_INTR_H_
-#define _I80321_INTR_H_
-
-#define ARM_IRQ_HANDLER _C_LABEL(i80321_intr_dispatch)
-
-#ifndef _LOCORE
-
-#include <machine/armreg.h>
-#include <machine/cpufunc.h>
-
-#include <arm/xscale/i80321/i80321reg.h>
-
-void i80321_do_pending(void);
-
-extern __volatile uint32_t intr_enabled;
-extern uint32_t intr_steer;
-
-static __inline void __attribute__((__unused__))
-i80321_set_intrmask(void)
-{
-
- __asm __volatile("mcr p6, 0, %0, c0, c0, 0"
- :
- : "r" (intr_enabled & ICU_INT_HWMASK));
-}
-
-static __inline void
-i80321_set_intrsteer(void)
-{
-
- __asm __volatile("mcr p6, 0, %0, c4, c0, 0"
- :
- : "r" (intr_steer & ICU_INT_HWMASK));
-}
-
-#if defined ( CPU_XSCALE_80219 )
-#define INT_SWMASK \
- ((1U << ICU_INT_bit26) | \
- (1U << ICU_INT_bit25) | \
- (1U << ICU_INT_bit23) | \
- (1U << ICU_INT_bit22) | \
- (1U << ICU_INT_bit7) | \
- (1U << ICU_INT_bit6) | \
- (1U << ICU_INT_bit5) | \
- (1U << ICU_INT_bit4))
-#else
-#define INT_SWMASK \
- ((1U << ICU_INT_bit26) | (1U << ICU_INT_bit22) | \
- (1U << ICU_INT_bit5) | (1U << ICU_INT_bit4))
-#endif
-
-#if 0
-static __inline void __attribute__((__unused__))
-i80321_splx(int new)
-{
- extern __volatile uint32_t intr_enabled;
- extern __volatile int current_spl_level;
- extern __volatile int i80321_ipending;
- extern void i80321_do_pending(void);
- int oldirqstate, hwpend;
-
- /* Don't let the compiler re-order this code with preceding code */
- __insn_barrier();
-
- current_spl_level = new;
-
- hwpend = (i80321_ipending & ICU_INT_HWMASK) & ~new;
- if (hwpend != 0) {
- oldirqstate = disable_interrupts(PSR_I);
- intr_enabled |= hwpend;
- i80321_set_intrmask();
- restore_interrupts(oldirqstate);
- }
-
- if ((i80321_ipending & INT_SWMASK) & ~new)
- i80321_do_pending();
-}
-
-static __inline int __attribute__((__unused__))
-i80321_splraise(int ipl)
-{
- extern __volatile int current_spl_level;
- extern int i80321_imask[];
- int old;
-
- old = current_spl_level;
- current_spl_level |= i80321_imask[ipl];
-
- /* Don't let the compiler re-order this code with subsequent code */
- __insn_barrier();
-
- return (old);
-}
-
-static __inline int __attribute__((__unused__))
-i80321_spllower(int ipl)
-{
- extern __volatile int current_spl_level;
- extern int i80321_imask[];
- int old = current_spl_level;
-
- i80321_splx(i80321_imask[ipl]);
- return(old);
-}
-
-#endif
-#if !defined(EVBARM_SPL_NOINLINE)
-
-#define splx(new) i80321_splx(new)
-#define _spllower(ipl) i80321_spllower(ipl)
-#define _splraise(ipl) i80321_splraise(ipl)
-void _setsoftintr(int);
-
-#else
-
-int _splraise(int);
-int _spllower(int);
-void splx(int);
-void _setsoftintr(int);
-
-#endif /* ! EVBARM_SPL_NOINLINE */
-
-#endif /* _LOCORE */
-
-#endif /* _I80321_INTR_H_ */
diff --git a/sys/arm/xscale/i80321/i80321_mcu.c b/sys/arm/xscale/i80321/i80321_mcu.c
deleted file mode 100644
index a51a433..0000000
--- a/sys/arm/xscale/i80321/i80321_mcu.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/* $NetBSD: i80321_mcu.c,v 1.2 2003/07/15 00:24:54 lukem Exp $ */
-
-/*-
- * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
- * All rights reserved.
- *
- * Written by Jason R. Thorpe for Wasabi Systems, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed for the NetBSD Project by
- * Wasabi Systems, Inc.
- * 4. The name of Wasabi Systems, Inc. may not be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
- * 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.
- */
-
-/*
- * Intel i80321 I/O Processor memory controller support.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-
-#include <machine/bus.h>
-
-#include <arm/xscale/i80321/i80321reg.h>
-#include <arm/xscale/i80321/i80321var.h>
-
-/*
- * i80321_sdram_bounds:
- *
- * Retrieve the start and size of SDRAM.
- */
-void
-i80321_sdram_bounds(bus_space_tag_t st, bus_space_handle_t sh,
- vm_paddr_t *start, vm_size_t *size)
-{
- uint32_t sdbr, sbr0, sbr1;
- uint32_t bank0, bank1;
-
- sdbr = bus_space_read_4(st, sh, MCU_SDBR);
- sbr0 = bus_space_read_4(st, sh, MCU_SBR0);
- sbr1 = bus_space_read_4(st, sh, MCU_SBR1);
-
-#ifdef VERBOSE_INIT_ARM
- printf("i80321: SBDR = 0x%08x SBR0 = 0x%08x SBR1 = 0x%08x\n",
- sdbr, sbr0, sbr1);
-#endif
-
- *start = sdbr;
-
- sdbr = (sdbr >> 25) & 0x1f;
-
- sbr0 &= 0x3f;
- sbr1 &= 0x3f;
-
- bank0 = (sbr0 - sdbr) << 25;
- bank1 = (sbr1 - sbr0) << 25;
-
-#ifdef VERBOSE_INIT_ARM
- printf("i80321: BANK0 = 0x%08x BANK1 = 0x%08x\n", bank0, bank1);
-#endif
-
- *size = bank0 + bank1;
-}
diff --git a/sys/arm/xscale/i80321/i80321_pci.c b/sys/arm/xscale/i80321/i80321_pci.c
deleted file mode 100644
index 5f78577..0000000
--- a/sys/arm/xscale/i80321/i80321_pci.c
+++ /dev/null
@@ -1,401 +0,0 @@
-/* $NetBSD: i80321_pci.c,v 1.4 2003/07/15 00:24:54 lukem Exp $ */
-
-/*-
- * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
- * All rights reserved.
- *
- * Written by Jason R. Thorpe for Wasabi Systems, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed for the NetBSD Project by
- * Wasabi Systems, Inc.
- * 4. The name of Wasabi Systems, Inc. may not be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
- * 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.
- */
-
-/*
- * PCI configuration support for i80321 I/O Processor chip.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/rman.h>
-
-#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/pcb.h>
-#include <vm/vm.h>
-#include <vm/pmap.h>
-#include <vm/vm_extern.h>
-
-#include <arm/xscale/i80321/i80321reg.h>
-#include <arm/xscale/i80321/i80321var.h>
-#include <arm/xscale/i80321/i80321_intr.h>
-
-#include <dev/pci/pcib_private.h>
-#include "pcib_if.h"
-
-#include <dev/pci/pcireg.h>
-extern struct i80321_softc *i80321_softc;
-
-static int
-i80321_pci_probe(device_t dev)
-{
- device_set_desc(dev, "i80321 PCI bus");
- return (0);
-}
-
-static int
-i80321_pci_attach(device_t dev)
-{
-
- uint32_t busno;
- struct i80321_pci_softc *sc = device_get_softc(dev);
-
- sc->sc_st = i80321_softc->sc_st;
- sc->sc_atu_sh = i80321_softc->sc_atu_sh;
- busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR);
- busno = PCIXSR_BUSNO(busno);
- if (busno == 0xff)
- busno = 0;
- sc->sc_dev = dev;
- sc->sc_busno = busno;
- sc->sc_pciio = &i80321_softc->sc_pci_iot;
- sc->sc_pcimem = &i80321_softc->sc_pci_memt;
- sc->sc_mem = i80321_softc->sc_owin[0].owin_xlate_lo +
- VERDE_OUT_XLATE_MEM_WIN_SIZE;
-
- sc->sc_io = i80321_softc->sc_iow_vaddr;
- /* Initialize memory and i/o rmans. */
- sc->sc_io_rman.rm_type = RMAN_ARRAY;
- sc->sc_io_rman.rm_descr = "I80321 PCI I/O Ports";
- if (rman_init(&sc->sc_io_rman) != 0 ||
- rman_manage_region(&sc->sc_io_rman,
- sc->sc_io,
- sc->sc_io +
- VERDE_OUT_XLATE_IO_WIN_SIZE) != 0) {
- panic("i80321_pci_probe: failed to set up I/O rman");
- }
- sc->sc_mem_rman.rm_type = RMAN_ARRAY;
- sc->sc_mem_rman.rm_descr = "I80321 PCI Memory";
- if (rman_init(&sc->sc_mem_rman) != 0 ||
- rman_manage_region(&sc->sc_mem_rman,
- 0, VERDE_OUT_XLATE_MEM_WIN_SIZE) != 0) {
- panic("i80321_pci_probe: failed to set up memory rman");
- }
- sc->sc_irq_rman.rm_type = RMAN_ARRAY;
- sc->sc_irq_rman.rm_descr = "i80321 PCI IRQs";
- if (rman_init(&sc->sc_irq_rman) != 0 ||
- rman_manage_region(&sc->sc_irq_rman, 26, 32) != 0)
- panic("i80321_pci_probe: failed to set up IRQ rman");
- device_add_child(dev, "pci", -1);
- return (bus_generic_attach(dev));
-}
-
-static int
-i80321_pci_maxslots(device_t dev)
-{
- return (PCI_SLOTMAX);
-}
-
-
-
-static int
-i80321_pci_conf_setup(struct i80321_pci_softc *sc, int bus, int slot, int func,
- int reg, uint32_t *addr)
-{
- uint32_t busno;
-
- busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR);
- busno = PCIXSR_BUSNO(busno);
- if (busno == 0xff)
- busno = 0;
-
- /*
- * If the bus # is the same as our own, then use Type 0 cycles,
- * else use Type 1.
- *
- * XXX We should filter out all non-private devices here!
- * XXX How does private space interact with PCI-PCI bridges?
- */
- if (bus == busno) {
- if (slot > (31 - 16))
- return (1);
- /*
- * NOTE: PCI-X requires that that devices updated their
- * PCIXSR on every config write with the device number
- * specified in AD[15:11]. If we don't set this field,
- * each device could end of thinking it is at device 0,
- * which can cause a number of problems. Doing this
- * unconditionally should be OK when only PCI devices
- * are present.
- */
- bus &= 0xff;
- slot &= 0x1f;
- func &= 0x07;
-
- *addr = (1U << (slot + 16)) |
- (slot << 11) | (func << 8) | reg;
- } else {
- *addr = (bus << 16) | (slot << 11) | (func << 8) | reg | 1;
- }
-
- return (0);
-}
-
-static u_int32_t
-i80321_pci_read_config(device_t dev, u_int bus, u_int slot, u_int func,
- u_int reg, int bytes)
-{
- struct i80321_pci_softc *sc = device_get_softc(dev);
- uint32_t isr;
- uint32_t addr;
- u_int32_t ret = 0;
- vm_offset_t va;
- int err = 0;
- if (i80321_pci_conf_setup(sc, bus, slot, func, reg & ~3, &addr))
- return (-1);
- bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OCCAR,
- addr);
-
- va = sc->sc_atu_sh;
- switch (bytes) {
- case 1:
- err = badaddr_read((void*)(va + ATU_OCCDR + (reg & 3)), 1, &ret);
- break;
- case 2:
- err = badaddr_read((void*)(va + ATU_OCCDR + (reg & 3)), 2, &ret);
- break;
- case 4:
- err = badaddr_read((void *)(va + ATU_OCCDR), 4, &ret);
- break;
- default:
- printf("i80321_read_config: invalid size %d\n", bytes);
- ret = -1;
- }
- if (err) {
-
- isr = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_ATUISR);
- bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_ATUISR,
- isr & (ATUISR_P_SERR_DET|ATUISR_PMA|ATUISR_PTAM|
- ATUISR_PTAT|ATUISR_PMPE));
- return (-1);
- }
- return (ret);
-}
-
-static void
-i80321_pci_write_config(device_t dev, u_int bus, u_int slot, u_int func,
- u_int reg, u_int32_t data, int bytes)
-{
- struct i80321_pci_softc *sc = device_get_softc(dev);
- uint32_t addr;
-
- if (i80321_pci_conf_setup(sc, bus, slot, func, reg & ~3, &addr))
- return;
-
-
- bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OCCAR,
- addr);
- switch (bytes) {
- case 1:
- bus_space_write_1(sc->sc_st, sc->sc_atu_sh, ATU_OCCDR +
- (reg & 3), data);
- break;
- case 2:
- bus_space_write_2(sc->sc_st, sc->sc_atu_sh, ATU_OCCDR +
- (reg & 3), data);
- break;
- case 4:
- bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OCCDR, data);
- break;
- default:
- printf("i80321_pci_write_config: Invalid size : %d\n", bytes);
- }
-
-}
-
-static int
-i80321_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
-{
- struct i80321_pci_softc *sc = device_get_softc(dev);
- switch (which) {
- case PCIB_IVAR_DOMAIN:
- *result = 0;
- return (0);
- case PCIB_IVAR_BUS:
- *result = sc->sc_busno;
- return (0);
-
- }
- return (ENOENT);
-}
-
-static int
-i80321_write_ivar(device_t dev, device_t child, int which, uintptr_t result)
-{
- struct i80321_pci_softc * sc = device_get_softc(dev);
-
- switch (which) {
- case PCIB_IVAR_DOMAIN:
- return (EINVAL);
- case PCIB_IVAR_BUS:
- sc->sc_busno = result;
- return (0);
- }
- return (ENOENT);
-}
-
-static struct resource *
-i80321_pci_alloc_resource(device_t bus, device_t child, int type, int *rid,
- u_long start, u_long end, u_long count, u_int flags)
-{
- struct i80321_pci_softc *sc = device_get_softc(bus);
- struct resource *rv;
- struct rman *rm;
- bus_space_tag_t bt = NULL;
- bus_space_handle_t bh = 0;
-
- switch (type) {
- case SYS_RES_IRQ:
- rm = &sc->sc_irq_rman;
- break;
- case SYS_RES_MEMORY:
- rm = &sc->sc_mem_rman;
- bt = sc->sc_pcimem;
- bh = (start >= 0x80000000 && start < 0x84000000) ? 0x80000000 :
- sc->sc_mem;
- start &= (0x1000000 - 1);
- end &= (0x1000000 - 1);
- break;
- case SYS_RES_IOPORT:
- rm = &sc->sc_io_rman;
- bt = sc->sc_pciio;
- bh = sc->sc_io;
- if (start < sc->sc_io) {
- start = start - 0x90000000 + sc->sc_io;
- end = end - 0x90000000 + sc->sc_io;
- }
- break;
- default:
- return (NULL);
- }
-
- rv = rman_reserve_resource(rm, start, end, count, flags, child);
- if (rv == NULL)
- return (NULL);
- rman_set_rid(rv, *rid);
- if (type != SYS_RES_IRQ) {
- if (type == SYS_RES_MEMORY)
- bh += (rman_get_start(rv));
- rman_set_bustag(rv, bt);
- rman_set_bushandle(rv, bh);
- if (flags & RF_ACTIVE) {
- if (bus_activate_resource(child, type, *rid, rv)) {
- rman_release_resource(rv);
- return (NULL);
- }
- }
- }
- return (rv);
-}
-
-static int
-i80321_pci_activate_resource(device_t bus, device_t child, int type, int rid,
- struct resource *r)
-{
- u_long p;
- int error;
-
- if (type == SYS_RES_MEMORY) {
- error = bus_space_map(rman_get_bustag(r),
- rman_get_bushandle(r), rman_get_size(r), 0, &p);
- if (error)
- return (error);
- rman_set_bushandle(r, p);
-
- }
- return (rman_activate_resource(r));
-}
-
-static int
-i80321_pci_setup_intr(device_t dev, device_t child,
- struct resource *ires, int flags, driver_filter_t *filt,
- driver_intr_t *intr, void *arg, void **cookiep)
-{
- return (BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags,
- filt, intr, arg, cookiep));
-}
-
-static int
-i80321_pci_teardown_intr(device_t dev, device_t child, struct resource *res,
- void *cookie)
-{
- return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, res, cookie));
-}
-
-static device_method_t i80321_pci_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, i80321_pci_probe),
- DEVMETHOD(device_attach, i80321_pci_attach),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
- DEVMETHOD(device_suspend, bus_generic_suspend),
- DEVMETHOD(device_resume, bus_generic_resume),
-
- /* Bus interface */
- DEVMETHOD(bus_read_ivar, i80321_read_ivar),
- DEVMETHOD(bus_write_ivar, i80321_write_ivar),
- DEVMETHOD(bus_alloc_resource, i80321_pci_alloc_resource),
- DEVMETHOD(bus_release_resource, bus_generic_release_resource),
- DEVMETHOD(bus_activate_resource, i80321_pci_activate_resource),
- DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
- DEVMETHOD(bus_setup_intr, i80321_pci_setup_intr),
- DEVMETHOD(bus_teardown_intr, i80321_pci_teardown_intr),
-
- /* pcib interface */
- DEVMETHOD(pcib_maxslots, i80321_pci_maxslots),
- DEVMETHOD(pcib_read_config, i80321_pci_read_config),
- DEVMETHOD(pcib_write_config, i80321_pci_write_config),
- DEVMETHOD(pcib_route_interrupt, machdep_pci_route_interrupt),
-
- DEVMETHOD_END
-};
-
-static driver_t i80321_pci_driver = {
- "pcib",
- i80321_pci_methods,
- sizeof(struct i80321_pci_softc),
-};
-
-static devclass_t i80321_pci_devclass;
-
-DRIVER_MODULE(ipci, iq, i80321_pci_driver, i80321_pci_devclass, 0, 0);
diff --git a/sys/arm/xscale/i80321/i80321_space.c b/sys/arm/xscale/i80321/i80321_space.c
deleted file mode 100644
index 64c2225..0000000
--- a/sys/arm/xscale/i80321/i80321_space.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/* $NetBSD: i80321_space.c,v 1.6 2003/10/06 15:43:35 thorpej Exp $ */
-
-/*-
- * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
- * All rights reserved.
- *
- * Written by Jason R. Thorpe for Wasabi Systems, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed for the NetBSD Project by
- * Wasabi Systems, Inc.
- * 4. The name of Wasabi Systems, Inc. may not be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
- * 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.
- */
-
-/*
- * bus_space functions for i80321 I/O Processor.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-
-#include <machine/pcb.h>
-
-#include <vm/vm.h>
-#include <vm/vm_kern.h>
-#include <vm/pmap.h>
-#include <vm/vm_page.h>
-#include <vm/vm_extern.h>
-
-#include <machine/bus.h>
-
-#include <arm/xscale/i80321/i80321reg.h>
-#include <arm/xscale/i80321/i80321var.h>
-
-/* Prototypes for all the bus_space structure functions */
-bs_protos(i80321);
-bs_protos(i80321_io);
-bs_protos(i80321_mem);
-
-void
-i80321_bs_init(bus_space_tag_t bs, void *cookie)
-{
-
- *bs = *arm_base_bs_tag;
- bs->bs_privdata = cookie;
-}
-
-void
-i80321_io_bs_init(bus_space_tag_t bs, void *cookie)
-{
-
- *bs = *arm_base_bs_tag;
- bs->bs_privdata = cookie;
-
- bs->bs_map = i80321_io_bs_map;
- bs->bs_unmap = i80321_io_bs_unmap;
- bs->bs_alloc = i80321_io_bs_alloc;
- bs->bs_free = i80321_io_bs_free;
-
-}
-
-void
-i80321_mem_bs_init(bus_space_tag_t bs, void *cookie)
-{
-
- *bs = *arm_base_bs_tag;
- bs->bs_privdata = cookie;
-
- bs->bs_map = i80321_mem_bs_map;
- bs->bs_unmap = i80321_mem_bs_unmap;
- bs->bs_alloc = i80321_mem_bs_alloc;
- bs->bs_free = i80321_mem_bs_free;
-
-}
-
-/* *** Routines shared by i80321, PCI IO, and PCI MEM. *** */
-
-int
-i80321_bs_subregion(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t offset,
- bus_size_t size, bus_space_handle_t *nbshp)
-{
-
- *nbshp = bsh + offset;
- return (0);
-}
-
-void
-i80321_bs_barrier(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t offset,
- bus_size_t len, int flags)
-{
-
- /* Nothing to do. */
-}
-
-/* *** Routines for PCI IO. *** */
-
-extern struct i80321_softc *i80321_softc;
-int
-i80321_io_bs_map(bus_space_tag_t tag, bus_addr_t bpa, bus_size_t size, int flags,
- bus_space_handle_t *bshp)
-{
- struct i80321_softc *sc = i80321_softc;
- vm_offset_t winvaddr;
- uint32_t busbase;
-
- if (bpa >= sc->sc_ioout_xlate &&
- bpa < (sc->sc_ioout_xlate + VERDE_OUT_XLATE_IO_WIN_SIZE)) {
- busbase = sc->sc_ioout_xlate;
- winvaddr = sc->sc_iow_vaddr;
- } else
- return (EINVAL);
-
- if ((bpa + size) >= (busbase + VERDE_OUT_XLATE_IO_WIN_SIZE))
- return (EINVAL);
-
- /*
- * Found the window -- PCI I/O space is mapped at a fixed
- * virtual address by board-specific code. Translate the
- * bus address to the virtual address.
- */
- *bshp = winvaddr + (bpa - busbase);
-
- return (0);
-}
-
-void
-i80321_io_bs_unmap(bus_space_tag_t tag, bus_space_handle_t h, bus_size_t size)
-{
-
- /* Nothing to do. */
-}
-
-int
-i80321_io_bs_alloc(bus_space_tag_t tag, bus_addr_t rstart, bus_addr_t rend,
- bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags,
- bus_addr_t *bpap, bus_space_handle_t *bshp)
-{
-
- panic("i80321_io_bs_alloc(): not implemented");
-}
-
-void
-i80321_io_bs_free(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t size)
-{
-
- panic("i80321_io_bs_free(): not implemented");
-}
-
-
-/* *** Routines for PCI MEM. *** */
-extern int badaddr_read(void *, int, void *);
-int
-i80321_mem_bs_map(bus_space_tag_t tag, bus_addr_t bpa, bus_size_t size, int flags,
- bus_space_handle_t *bshp)
-{
-
- *bshp = (vm_offset_t)pmap_mapdev(bpa, size);
- return (0);
-}
-
-void
-i80321_mem_bs_unmap(bus_space_tag_t tag, bus_space_handle_t h, bus_size_t size)
-{
-
- pmap_unmapdev((vm_offset_t)h, size);
-}
-
-int
-i80321_mem_bs_alloc(bus_space_tag_t tag, bus_addr_t rstart, bus_addr_t rend,
- bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags,
- bus_addr_t *bpap, bus_space_handle_t *bshp)
-{
-
- panic("i80321_mem_bs_alloc(): not implemented");
-}
-
-void
-i80321_mem_bs_free(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t size)
-{
-
- panic("i80321_mem_bs_free(): not implemented");
-}
diff --git a/sys/arm/xscale/i80321/iq31244_7seg.c b/sys/arm/xscale/i80321/iq31244_7seg.c
deleted file mode 100644
index 3737094..0000000
--- a/sys/arm/xscale/i80321/iq31244_7seg.c
+++ /dev/null
@@ -1,390 +0,0 @@
-/* $NetBSD: iq31244_7seg.c,v 1.2 2003/07/15 00:25:01 lukem Exp $ */
-
-/*-
- * Copyright (c) 2001, 2002, 2003 Wasabi Systems, Inc.
- * All rights reserved.
- *
- * Written by Jason R. Thorpe for Wasabi Systems, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed for the NetBSD Project by
- * Wasabi Systems, Inc.
- * 4. The name of Wasabi Systems, Inc. may not be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
- * 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.
- */
-
-/*
- * Support for the 7-segment display on the Intel IQ31244.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/sysctl.h>
-
-#include <machine/bus.h>
-
-#include <arm/xscale/i80321/iq80321reg.h>
-#include <arm/xscale/i80321/iq80321var.h>
-
-#define WRITE(x, v) *((__volatile uint8_t *) (x)) = (v)
-
-static int snakestate;
-
-/*
- * The 7-segment display looks like so:
- *
- * A
- * +-----+
- * | |
- * F | | B
- * | G |
- * +-----+
- * | |
- * E | | C
- * | D |
- * +-----+ o DP
- *
- * Setting a bit clears the corresponding segment on the
- * display.
- */
-#define SEG_A (1 << 0)
-#define SEG_B (1 << 1)
-#define SEG_C (1 << 2)
-#define SEG_D (1 << 3)
-#define SEG_E (1 << 4)
-#define SEG_F (1 << 5)
-#define SEG_G (1 << 6)
-#define SEG_DP (1 << 7)
-
-static const uint8_t digitmap[] = {
-/* +#####+
- * # #
- * # #
- * # #
- * +-----+
- * # #
- * # #
- * # #
- * +#####+
- */
- SEG_G,
-
-/* +-----+
- * | #
- * | #
- * | #
- * +-----+
- * | #
- * | #
- * | #
- * +-----+
- */
- SEG_A|SEG_D|SEG_E|SEG_F|SEG_G,
-
-/* +#####+
- * | #
- * | #
- * | #
- * +#####+
- * # |
- * # |
- * # |
- * +#####+
- */
- SEG_C|SEG_F,
-
-/* +#####+
- * | #
- * | #
- * | #
- * +#####+
- * | #
- * | #
- * | #
- * +#####+
- */
- SEG_E|SEG_F,
-
-/* +-----+
- * # #
- * # #
- * # #
- * +#####+
- * | #
- * | #
- * | #
- * +-----+
- */
- SEG_A|SEG_D|SEG_E,
-
-/* +#####+
- * # |
- * # |
- * # |
- * +#####+
- * | #
- * | #
- * | #
- * +#####+
- */
- SEG_B|SEG_E,
-
-/* +#####+
- * # |
- * # |
- * # |
- * +#####+
- * # #
- * # #
- * # #
- * +#####+
- */
- SEG_B,
-
-/* +#####+
- * | #
- * | #
- * | #
- * +-----+
- * | #
- * | #
- * | #
- * +-----+
- */
- SEG_D|SEG_E|SEG_F,
-
-/* +#####+
- * # #
- * # #
- * # #
- * +#####+
- * # #
- * # #
- * # #
- * +#####+
- */
- 0,
-
-/* +#####+
- * # #
- * # #
- * # #
- * +#####+
- * | #
- * | #
- * | #
- * +-----+
- */
- SEG_D|SEG_E,
-};
-
-static uint8_t
-iq80321_7seg_xlate(char c)
-{
- uint8_t rv;
-
- if (c >= '0' && c <= '9')
- rv = digitmap[c - '0'];
- else if (c == '.')
- rv = (uint8_t) ~SEG_DP;
- else
- rv = 0xff;
-
- return (rv);
-}
-
-void
-iq80321_7seg(char a, char b)
-{
- uint8_t msb, lsb;
-
- msb = iq80321_7seg_xlate(a);
- lsb = iq80321_7seg_xlate(b);
-
- snakestate = 0;
-
- WRITE(IQ80321_7SEG_MSB, msb);
- WRITE(IQ80321_7SEG_LSB, lsb);
-}
-
-static const uint8_t snakemap[][2] = {
-
-/* +#####+ +#####+
- * | | | |
- * | | | |
- * | | | |
- * +-----+ +-----+
- * | | | |
- * | | | |
- * | | | |
- * +-----+ +-----+
- */
- { ~SEG_A, ~SEG_A },
-
-/* +-----+ +-----+
- * # | | #
- * # | | #
- * # | | #
- * +-----+ +-----+
- * | | | |
- * | | | |
- * | | | |
- * +-----+ +-----+
- */
- { ~SEG_F, ~SEG_B },
-
-/* +-----+ +-----+
- * | | | |
- * | | | |
- * | | | |
- * +#####+ +#####+
- * | | | |
- * | | | |
- * | | | |
- * +-----+ +-----+
- */
- { ~SEG_G, ~SEG_G },
-
-/* +-----+ +-----+
- * | | | |
- * | | | |
- * | | | |
- * +-----+ +-----+
- * | # # |
- * | # # |
- * | # # |
- * +-----+ +-----+
- */
- { ~SEG_C, ~SEG_E },
-
-/* +-----+ +-----+
- * | | | |
- * | | | |
- * | | | |
- * +-----+ +-----+
- * | | | |
- * | | | |
- * | | | |
- * +#####+ +#####+
- */
- { ~SEG_D, ~SEG_D },
-
-/* +-----+ +-----+
- * | | | |
- * | | | |
- * | | | |
- * +-----+ +-----+
- * # | | #
- * # | | #
- * # | | #
- * +-----+ +-----+
- */
- { ~SEG_E, ~SEG_C },
-
-/* +-----+ +-----+
- * | | | |
- * | | | |
- * | | | |
- * +#####+ +#####+
- * | | | |
- * | | | |
- * | | | |
- * +-----+ +-----+
- */
- { ~SEG_G, ~SEG_G },
-
-/* +-----+ +-----+
- * | # # |
- * | # # |
- * | # # |
- * +-----+ +-----+
- * | | | |
- * | | | |
- * | | | |
- * +-----+ +-----+
- */
- { ~SEG_B, ~SEG_F },
-};
-
-static SYSCTL_NODE(_hw, OID_AUTO, sevenseg, CTLFLAG_RD, 0, "7 seg");
-static int freq = 20;
-SYSCTL_INT(_hw_sevenseg, OID_AUTO, freq, CTLFLAG_RW, &freq, 0,
- "7 Seg update frequency");
-static void
-iq31244_7seg_snake(void)
-{
- static int snakefreq;
- int cur = snakestate;
-
- snakefreq++;
- if ((snakefreq % freq))
- return;
- WRITE(IQ80321_7SEG_MSB, snakemap[cur][0]);
- WRITE(IQ80321_7SEG_LSB, snakemap[cur][1]);
-
- snakestate = (cur + 1) & 7;
-}
-
-struct iq31244_7seg_softc {
- device_t dev;
-};
-
-static int
-iq31244_7seg_probe(device_t dev)
-{
-
- device_set_desc(dev, "IQ31244 7seg");
- return (0);
-}
-
-extern void (*i80321_hardclock_hook)(void);
-static int
-iq31244_7seg_attach(device_t dev)
-{
-
- i80321_hardclock_hook = iq31244_7seg_snake;
- return (0);
-}
-
-static device_method_t iq31244_7seg_methods[] = {
- DEVMETHOD(device_probe, iq31244_7seg_probe),
- DEVMETHOD(device_attach, iq31244_7seg_attach),
- {0, 0},
-};
-
-static driver_t iq31244_7seg_driver = {
- "iqseg",
- iq31244_7seg_methods,
- sizeof(struct iq31244_7seg_softc),
-};
-static devclass_t iq31244_7seg_devclass;
-
-DRIVER_MODULE(iqseg, iq, iq31244_7seg_driver, iq31244_7seg_devclass, 0, 0);
diff --git a/sys/arm/xscale/i80321/iq31244_machdep.c b/sys/arm/xscale/i80321/iq31244_machdep.c
deleted file mode 100644
index eb19f78..0000000
--- a/sys/arm/xscale/i80321/iq31244_machdep.c
+++ /dev/null
@@ -1,416 +0,0 @@
-/* $NetBSD: hpc_machdep.c,v 1.70 2003/09/16 08:18:22 agc Exp $ */
-
-/*-
- * Copyright (c) 1994-1998 Mark Brinicombe.
- * Copyright (c) 1994 Brini.
- * All rights reserved.
- *
- * This code is derived from software written for Brini by Mark Brinicombe
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Brini.
- * 4. The name of the company nor the name of the author may be used to
- * endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
- *
- * RiscBSD kernel project
- *
- * machdep.c
- *
- * Machine dependant functions for kernel setup
- *
- * This file needs a lot of work.
- *
- * Created : 17/09/94
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "opt_kstack_pages.h"
-
-#define _ARM32_BUS_DMA_PRIVATE
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/sysproto.h>
-#include <sys/signalvar.h>
-#include <sys/imgact.h>
-#include <sys/kernel.h>
-#include <sys/ktr.h>
-#include <sys/linker.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mutex.h>
-#include <sys/pcpu.h>
-#include <sys/proc.h>
-#include <sys/ptrace.h>
-#include <sys/cons.h>
-#include <sys/bio.h>
-#include <sys/bus.h>
-#include <sys/buf.h>
-#include <sys/exec.h>
-#include <sys/kdb.h>
-#include <sys/msgbuf.h>
-#include <machine/reg.h>
-#include <machine/cpu.h>
-#include <machine/physmem.h>
-
-#include <vm/vm.h>
-#include <vm/pmap.h>
-#include <vm/vm_object.h>
-#include <vm/vm_page.h>
-#include <vm/vm_map.h>
-#include <machine/devmap.h>
-#include <machine/vmparam.h>
-#include <machine/pcb.h>
-#include <machine/undefined.h>
-#include <machine/machdep.h>
-#include <machine/metadata.h>
-#include <machine/armreg.h>
-#include <machine/bus.h>
-#include <sys/reboot.h>
-
-#include <arm/xscale/i80321/i80321reg.h>
-#include <arm/xscale/i80321/i80321var.h>
-#include <arm/xscale/i80321/iq80321reg.h>
-#include <arm/xscale/i80321/obiovar.h>
-
-#define KERNEL_PT_SYS 0 /* Page table for mapping proc0 zero page */
-#define KERNEL_PT_IOPXS 1
-#define KERNEL_PT_BEFOREKERN 2
-#define KERNEL_PT_AFKERNEL 3 /* L2 table for mapping after kernel */
-#define KERNEL_PT_AFKERNEL_NUM 9
-
-/* this should be evenly divisable by PAGE_SIZE / L2_TABLE_SIZE_REAL (or 4) */
-#define NUM_KERNEL_PTS (KERNEL_PT_AFKERNEL + KERNEL_PT_AFKERNEL_NUM)
-
-struct pv_addr kernel_pt_table[NUM_KERNEL_PTS];
-
-/* Physical and virtual addresses for some global pages */
-
-struct pv_addr systempage;
-struct pv_addr msgbufpv;
-struct pv_addr irqstack;
-struct pv_addr undstack;
-struct pv_addr abtstack;
-struct pv_addr kernelstack;
-struct pv_addr minidataclean;
-
-#define IQ80321_OBIO_BASE 0xfe800000UL
-#define IQ80321_OBIO_SIZE 0x00100000UL
-/* Static device mappings. */
-static const struct arm_devmap_entry iq80321_devmap[] = {
- /*
- * Map the on-board devices VA == PA so that we can access them
- * with the MMU on or off.
- */
- {
- IQ80321_OBIO_BASE,
- IQ80321_OBIO_BASE,
- IQ80321_OBIO_SIZE,
- VM_PROT_READ|VM_PROT_WRITE,
- PTE_DEVICE,
- },
- {
- IQ80321_IOW_VBASE,
- VERDE_OUT_XLATE_IO_WIN0_BASE,
- VERDE_OUT_XLATE_IO_WIN_SIZE,
- VM_PROT_READ|VM_PROT_WRITE,
- PTE_DEVICE,
- },
-
- {
- IQ80321_80321_VBASE,
- VERDE_PMMR_BASE,
- VERDE_PMMR_SIZE,
- VM_PROT_READ|VM_PROT_WRITE,
- PTE_DEVICE,
- },
- {
- 0,
- 0,
- 0,
- 0,
- 0,
- }
-};
-
-#define SDRAM_START 0xa0000000
-
-extern vm_offset_t xscale_cache_clean_addr;
-
-void *
-initarm(struct arm_boot_params *abp)
-{
- struct pv_addr kernel_l1pt;
- struct pv_addr dpcpu;
- int loop, i;
- u_int l1pagetable;
- vm_offset_t freemempos;
- vm_offset_t freemem_pt;
- vm_offset_t afterkern;
- vm_offset_t freemem_after;
- vm_offset_t lastaddr;
- uint32_t memsize, memstart;
-
- lastaddr = parse_boot_param(abp);
- arm_physmem_kernaddr = abp->abp_physaddr;
- set_cpufuncs();
- pcpu_init(pcpup, 0, sizeof(struct pcpu));
- PCPU_SET(curthread, &thread0);
-
- /* Do basic tuning, hz etc */
- init_param1();
-
- freemempos = 0xa0200000;
- /* Define a macro to simplify memory allocation */
-#define valloc_pages(var, np) \
- alloc_pages((var).pv_pa, (np)); \
- (var).pv_va = (var).pv_pa + 0x20000000;
-
-#define alloc_pages(var, np) \
- freemempos -= (np * PAGE_SIZE); \
- (var) = freemempos; \
- memset((char *)(var), 0, ((np) * PAGE_SIZE));
-
- while (((freemempos - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) != 0)
- freemempos -= PAGE_SIZE;
- valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE);
- for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) {
- if (!(loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL))) {
- valloc_pages(kernel_pt_table[loop],
- L2_TABLE_SIZE / PAGE_SIZE);
- } else {
- kernel_pt_table[loop].pv_pa = freemempos +
- (loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL)) *
- L2_TABLE_SIZE_REAL;
- kernel_pt_table[loop].pv_va =
- kernel_pt_table[loop].pv_pa + 0x20000000;
- }
- }
- freemem_pt = freemempos;
- freemempos = 0xa0100000;
- /*
- * Allocate a page for the system page mapped to V0x00000000
- * This page will just contain the system vectors and can be
- * shared by all processes.
- */
- valloc_pages(systempage, 1);
-
- /* Allocate dynamic per-cpu area. */
- valloc_pages(dpcpu, DPCPU_SIZE / PAGE_SIZE);
- dpcpu_init((void *)dpcpu.pv_va, 0);
-
- /* Allocate stacks for all modes */
- valloc_pages(irqstack, IRQ_STACK_SIZE);
- valloc_pages(abtstack, ABT_STACK_SIZE);
- valloc_pages(undstack, UND_STACK_SIZE);
- valloc_pages(kernelstack, kstack_pages);
- alloc_pages(minidataclean.pv_pa, 1);
- valloc_pages(msgbufpv, round_page(msgbufsize) / PAGE_SIZE);
- /*
- * Allocate memory for the l1 and l2 page tables. The scheme to avoid
- * wasting memory by allocating the l1pt on the first 16k memory was
- * taken from NetBSD rpc_machdep.c. NKPT should be greater than 12 for
- * this to work (which is supposed to be the case).
- */
-
- /*
- * Now we start construction of the L1 page table
- * We start by mapping the L2 page tables into the L1.
- * This means that we can replace L1 mappings later on if necessary
- */
- l1pagetable = kernel_l1pt.pv_va;
-
- /* Map the L2 pages tables in the L1 page table */
- pmap_link_l2pt(l1pagetable, ARM_VECTORS_HIGH & ~(0x00100000 - 1),
- &kernel_pt_table[KERNEL_PT_SYS]);
- pmap_link_l2pt(l1pagetable, IQ80321_IOPXS_VBASE,
- &kernel_pt_table[KERNEL_PT_IOPXS]);
- pmap_link_l2pt(l1pagetable, KERNBASE,
- &kernel_pt_table[KERNEL_PT_BEFOREKERN]);
- pmap_map_chunk(l1pagetable, KERNBASE, SDRAM_START, 0x100000,
- VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
- pmap_map_chunk(l1pagetable, KERNBASE + 0x100000, SDRAM_START + 0x100000,
- 0x100000, VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
- pmap_map_chunk(l1pagetable, KERNBASE + 0x200000, SDRAM_START + 0x200000,
- (((uint32_t)(lastaddr) - KERNBASE - 0x200000) + L1_S_SIZE) & ~(L1_S_SIZE - 1),
- VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
- freemem_after = ((int)lastaddr + PAGE_SIZE) & ~(PAGE_SIZE - 1);
- afterkern = round_page(((vm_offset_t)lastaddr + L1_S_SIZE) & ~(L1_S_SIZE
- - 1));
- for (i = 0; i < KERNEL_PT_AFKERNEL_NUM; i++) {
- pmap_link_l2pt(l1pagetable, afterkern + i * 0x00100000,
- &kernel_pt_table[KERNEL_PT_AFKERNEL + i]);
- }
- pmap_map_entry(l1pagetable, afterkern, minidataclean.pv_pa,
- VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
-
-
- /* Map the Mini-Data cache clean area. */
- xscale_setup_minidata(l1pagetable, afterkern,
- minidataclean.pv_pa);
-
- /* Map the vector page. */
- pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa,
- VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
- arm_devmap_bootstrap(l1pagetable, iq80321_devmap);
- /*
- * Give the XScale global cache clean code an appropriately
- * sized chunk of unmapped VA space starting at 0xff000000
- * (our device mappings end before this address).
- */
- xscale_cache_clean_addr = 0xff000000U;
-
- cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
- setttb(kernel_l1pt.pv_pa);
- cpu_tlb_flushID();
- cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
- /*
- * Pages were allocated during the secondary bootstrap for the
- * stacks for different CPU modes.
- * We must now set the r13 registers in the different CPU modes to
- * point to these stacks.
- * Since the ARM stacks use STMFD etc. we must set r13 to the top end
- * of the stack memory.
- */
- set_stackptrs(0);
-
- /*
- * We must now clean the cache again....
- * Cleaning may be done by reading new data to displace any
- * dirty data in the cache. This will have happened in setttb()
- * but since we are boot strapping the addresses used for the read
- * may have just been remapped and thus the cache could be out
- * of sync. A re-clean after the switch will cure this.
- * After booting there are no gross relocations of the kernel thus
- * this problem will not occur after initarm().
- */
- cpu_idcache_wbinv_all();
- cpu_setup();
-
- /*
- * Fetch the SDRAM start/size from the i80321 SDRAM configration
- * registers.
- */
- i80321_calibrate_delay();
- i80321_sdram_bounds(obio_bs_tag, IQ80321_80321_VBASE + VERDE_MCU_BASE,
- &memstart, &memsize);
- physmem = memsize / PAGE_SIZE;
- cninit();
-
- undefined_init();
-
- init_proc0(kernelstack.pv_va);
-
- /* Enable MMU, I-cache, D-cache, write buffer. */
-
- arm_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL);
- pmap_curmaxkvaddr = afterkern + PAGE_SIZE;
- vm_max_kernel_address = 0xe0000000;
- pmap_bootstrap(pmap_curmaxkvaddr, &kernel_l1pt);
- msgbufp = (void*)msgbufpv.pv_va;
- msgbufinit(msgbufp, msgbufsize);
- mutex_init();
-
- /*
- * Add the physical ram we have available.
- *
- * Exclude the kernel (and all the things we allocated which immediately
- * follow the kernel) from the VM allocation pool but not from crash
- * dumps. virtual_avail is a global variable which tracks the kva we've
- * "allocated" while setting up pmaps.
- *
- * Prepare the list of physical memory available to the vm subsystem.
- */
- arm_physmem_hardware_region(SDRAM_START, memsize);
- arm_physmem_exclude_region(freemem_pt, abp->abp_physaddr -
- freemem_pt, EXFLAG_NOALLOC);
- arm_physmem_exclude_region(freemempos, abp->abp_physaddr - 0x100000 -
- freemempos, EXFLAG_NOALLOC);
- arm_physmem_exclude_region(abp->abp_physaddr,
- virtual_avail - KERNVIRTADDR, EXFLAG_NOALLOC);
- arm_physmem_init_kernel_globals();
-
- init_param2(physmem);
- kdb_init();
- return ((void *)(kernelstack.pv_va + USPACE_SVC_STACK_TOP -
- sizeof(struct pcb)));
-}
-
-extern int
-machdep_pci_route_interrupt(device_t pcib, device_t dev, int pin)
-{
- int bus;
- int device;
- int func;
- uint32_t busno;
- struct i80321_pci_softc *sc = device_get_softc(pcib);
- bus = pci_get_bus(dev);
- device = pci_get_slot(dev);
- func = pci_get_function(dev);
- busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR);
- busno = PCIXSR_BUSNO(busno);
- if (busno == 0xff)
- busno = 0;
- if (bus != busno)
- goto no_mapping;
- switch (device) {
- /* IQ31244 PCI */
- case 1: /* PCIX-PCIX bridge */
- /*
- * The S-ATA chips are behind the bridge, and all of
- * the S-ATA interrupts are wired together.
- */
- return (ICU_INT_XINT(2));
- case 2: /* PCI slot */
- /* All pins are wired together. */
- return (ICU_INT_XINT(3));
- case 3: /* i82546 dual Gig-E */
- if (pin == 1 || pin == 2)
- return (ICU_INT_XINT(0));
- goto no_mapping;
- /* IQ80321 PCI */
- case 4: /* i82544 Gig-E */
- case 8: /*
- * Apparently you can set the device for the ethernet adapter
- * to 8 with a jumper, so handle that as well
- */
- if (pin == 1)
- return (ICU_INT_XINT(0));
- goto no_mapping;
- case 6: /* S-PCI-X slot */
- if (pin == 1)
- return (ICU_INT_XINT(2));
- if (pin == 2)
- return (ICU_INT_XINT(3));
- goto no_mapping;
- default:
-no_mapping:
- printf("No mapping for %d/%d/%d/%c\n", bus, device, func, pin);
-
- }
- return (0);
-
-}
diff --git a/sys/arm/xscale/i80321/iq80321.c b/sys/arm/xscale/i80321/iq80321.c
deleted file mode 100644
index fb34455..0000000
--- a/sys/arm/xscale/i80321/iq80321.c
+++ /dev/null
@@ -1,394 +0,0 @@
-/* $NetBSD: i80321_mainbus.c,v 1.13 2003/12/17 22:03:24 abs Exp $ */
-
-/*-
- * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
- * All rights reserved.
- *
- * Written by Jason R. Thorpe for Wasabi Systems, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed for the NetBSD Project by
- * Wasabi Systems, Inc.
- * 4. The name of Wasabi Systems, Inc. may not be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
- * 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.
- */
-
-/*
- * IQ80321 front-end for the i80321 I/O Processor. We take care
- * of setting up the i80321 memory map, PCI interrupt routing, etc.,
- * which are all specific to the board the i80321 is wired up to.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#define _ARM32_BUS_DMA_PRIVATE
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/malloc.h>
-#include <sys/rman.h>
-#include <machine/armreg.h>
-#include <machine/bus.h>
-#include <machine/intr.h>
-
-#include <arm/xscale/i80321/i80321reg.h>
-#include <arm/xscale/i80321/i80321var.h>
-#include <arm/xscale/i80321/iq80321reg.h>
-#include <arm/xscale/i80321/iq80321var.h>
-#include <arm/xscale/i80321/i80321_intr.h>
-
-#include <dev/pci/pcireg.h>
-
-
-int iq80321_probe(device_t);
-void iq80321_identify(driver_t *, device_t);
-int iq80321_attach(device_t);
-
-int
-iq80321_probe(device_t dev)
-{
- device_set_desc(dev, "Intel 80321");
- return (BUS_PROBE_NOWILDCARD);
-}
-
-void
-iq80321_identify(driver_t *driver, device_t parent)
-{
-
- BUS_ADD_CHILD(parent, 0, "iq", 0);
-}
-
-static struct arm32_dma_range i80321_dr;
-static int dma_range_init = 0;
-
-struct arm32_dma_range *
-bus_dma_get_range(void)
-{
- if (dma_range_init == 0)
- return (NULL);
- return (&i80321_dr);
-}
-
-int
-bus_dma_get_range_nb(void)
-{
- if (dma_range_init == 0)
- return (0);
- return (1);
-}
-
-#define PCI_MAPREG_MEM_PREFETCHABLE_MASK 0x00000008
-#define PCI_MAPREG_MEM_TYPE_64BIT 0x00000004
-
-int
-iq80321_attach(device_t dev)
-{
- struct i80321_softc *sc = device_get_softc(dev);
- int b0u, b0l, b1u, b1l;
- vm_paddr_t memstart = 0;
- vm_size_t memsize = 0;
- int busno;
-
- /*
- * Fill in the space tag for the i80321's own devices,
- * and hand-craft the space handle for it (the device
- * was mapped during early bootstrap).
- */
- i80321_bs_init(&i80321_bs_tag, sc);
- sc->sc_st = &i80321_bs_tag;
- sc->sc_sh = IQ80321_80321_VBASE;
- sc->dev = dev;
- sc->sc_is_host = 1;
-
- /*
- * Slice off a subregion for the Memory Controller -- we need it
- * here in order read the memory size.
- */
- if (bus_space_subregion(sc->sc_st, sc->sc_sh, VERDE_MCU_BASE,
- VERDE_MCU_SIZE, &sc->sc_mcu_sh))
- panic("%s: unable to subregion MCU registers",
- device_get_name(dev));
-
- if (bus_space_subregion(sc->sc_st, sc->sc_sh, VERDE_ATU_BASE,
- VERDE_ATU_SIZE, &sc->sc_atu_sh))
- panic("%s: unable to subregion ATU registers",
- device_get_name(dev));
-
- /*
- * We have mapped the PCI I/O windows in the early
- * bootstrap phase.
- */
- sc->sc_iow_vaddr = IQ80321_IOW_VBASE;
-
- /*
- * Check the configuration of the ATU to see if another BIOS
- * has configured us. If a PC BIOS didn't configure us, then:
- * IQ80321: BAR0 00000000.0000000c BAR1 is 00000000.8000000c.
- * IQ31244: BAR0 00000000.00000004 BAR1 is 00000000.0000000c.
- * If a BIOS has configured us, at least one of those should be
- * different. This is pretty fragile, but it's not clear what
- * would work better.
- */
- b0l = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, PCIR_BARS+0x0);
- b0u = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, PCIR_BARS+0x4);
- b1l = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, PCIR_BARS+0x8);
- b1u = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, PCIR_BARS+0xc);
-
-#ifdef VERBOSE_INIT_ARM
- printf("i80321: BAR0 = %08x.%08x BAR1 = %08x.%08x\n",
- b0l,b0u, b1l, b1u );
-#endif
-
-#define PCI_MAPREG_MEM_ADDR_MASK 0xfffffff0
- b0l &= PCI_MAPREG_MEM_ADDR_MASK;
- b0u &= PCI_MAPREG_MEM_ADDR_MASK;
- b1l &= PCI_MAPREG_MEM_ADDR_MASK;
- b1u &= PCI_MAPREG_MEM_ADDR_MASK;
-
-#ifdef VERBOSE_INIT_ARM
- printf("i80219: BAR0 = %08x.%08x BAR1 = %08x.%08x\n",
- b0l,b0u, b1l, b1u );
-#endif
-
- if ((b0u != b1u) || (b0l != 0) || ((b1l & ~0x80000000U) != 0))
- sc->sc_is_host = 0;
- else
- sc->sc_is_host = 1;
-
- /* FIXME: i force it's */
-
-#ifdef CPU_XSCALE_80219
- sc->sc_is_host = 1;
-#endif
-
- i80321_sdram_bounds(sc->sc_st, sc->sc_mcu_sh, &memstart, &memsize);
- /*
- * We set up the Inbound Windows as follows:
- *
- * 0 Access to i80321 PMMRs
- *
- * 1 Reserve space for private devices
- *
- * 2 RAM access
- *
- * 3 Unused.
- *
- * This chunk needs to be customized for each IOP321 application.
- */
-#if 0
- sc->sc_iwin[0].iwin_base_lo = VERDE_PMMR_BASE;
- sc->sc_iwin[0].iwin_base_hi = 0;
- sc->sc_iwin[0].iwin_xlate = VERDE_PMMR_BASE;
- sc->sc_iwin[0].iwin_size = VERDE_PMMR_SIZE;
-#endif
- if (sc->sc_is_host) {
-
- /* Map PCI:Local 1:1. */
- sc->sc_iwin[1].iwin_base_lo = VERDE_OUT_XLATE_MEM_WIN0_BASE |
- PCI_MAPREG_MEM_PREFETCHABLE_MASK |
- PCI_MAPREG_MEM_TYPE_64BIT;
- sc->sc_iwin[1].iwin_base_hi = 0;
- } else {
-
- sc->sc_iwin[1].iwin_base_lo = 0;
- sc->sc_iwin[1].iwin_base_hi = 0;
- }
- sc->sc_iwin[1].iwin_xlate = VERDE_OUT_XLATE_MEM_WIN0_BASE;
- sc->sc_iwin[1].iwin_size = VERDE_OUT_XLATE_MEM_WIN_SIZE;
-
- if (sc->sc_is_host) {
- sc->sc_iwin[2].iwin_base_lo = memstart |
- PCI_MAPREG_MEM_PREFETCHABLE_MASK |
- PCI_MAPREG_MEM_TYPE_64BIT;
- sc->sc_iwin[2].iwin_base_hi = 0;
- } else {
- sc->sc_iwin[2].iwin_base_lo = 0;
- sc->sc_iwin[2].iwin_base_hi = 0;
- }
- sc->sc_iwin[2].iwin_xlate = memstart;
- sc->sc_iwin[2].iwin_size = memsize;
-
- if (sc->sc_is_host) {
- sc->sc_iwin[3].iwin_base_lo = 0 |
- PCI_MAPREG_MEM_PREFETCHABLE_MASK |
- PCI_MAPREG_MEM_TYPE_64BIT;
- } else {
- sc->sc_iwin[3].iwin_base_lo = 0;
- }
- sc->sc_iwin[3].iwin_base_hi = 0;
- sc->sc_iwin[3].iwin_xlate = 0;
- sc->sc_iwin[3].iwin_size = 0;
-
-#ifdef VERBOSE_INIT_ARM
- printf("i80321: Reserve space for private devices (Inbound Window 1) \n hi:0x%08x lo:0x%08x xlate:0x%08x size:0x%08x\n",
- sc->sc_iwin[1].iwin_base_hi,
- sc->sc_iwin[1].iwin_base_lo,
- sc->sc_iwin[1].iwin_xlate,
- sc->sc_iwin[1].iwin_size
- );
- printf("i80321: RAM access (Inbound Window 2) \n hi:0x%08x lo:0x%08x xlate:0x%08x size:0x%08x\n",
- sc->sc_iwin[2].iwin_base_hi,
- sc->sc_iwin[2].iwin_base_lo,
- sc->sc_iwin[2].iwin_xlate,
- sc->sc_iwin[2].iwin_size
- );
-#endif
-
- /*
- * We set up the Outbound Windows as follows:
- *
- * 0 Access to private PCI space.
- *
- * 1 Unused.
- */
-#define PCI_MAPREG_MEM_ADDR(x) ((x) & 0xfffffff0)
- sc->sc_owin[0].owin_xlate_lo =
- PCI_MAPREG_MEM_ADDR(sc->sc_iwin[1].iwin_base_lo);
- sc->sc_owin[0].owin_xlate_hi = sc->sc_iwin[1].iwin_base_hi;
- /*
- * Set the Secondary Outbound I/O window to map
- * to PCI address 0 for all 64K of the I/O space.
- */
- sc->sc_ioout_xlate = 0;
- i80321_attach(sc);
- i80321_dr.dr_sysbase = sc->sc_iwin[2].iwin_xlate;
- i80321_dr.dr_busbase = PCI_MAPREG_MEM_ADDR(sc->sc_iwin[2].iwin_base_lo);
- i80321_dr.dr_len = sc->sc_iwin[2].iwin_size;
- dma_range_init = 1;
- busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR);
- busno = PCIXSR_BUSNO(busno);
- if (busno == 0xff)
- busno = 0;
- sc->sc_irq_rman.rm_type = RMAN_ARRAY;
- sc->sc_irq_rman.rm_descr = "i80321 IRQs";
- if (rman_init(&sc->sc_irq_rman) != 0 ||
- rman_manage_region(&sc->sc_irq_rman, 0, 25) != 0)
- panic("i80321_attach: failed to set up IRQ rman");
-
- device_add_child(dev, "obio", 0);
- device_add_child(dev, "itimer", 0);
- device_add_child(dev, "iopwdog", 0);
-#ifndef CPU_XSCALE_80219
- device_add_child(dev, "iqseg", 0);
-#endif
- device_add_child(dev, "pcib", busno);
- device_add_child(dev, "i80321_dma", 0);
- device_add_child(dev, "i80321_dma", 1);
-#ifndef CPU_XSCALE_80219
- device_add_child(dev, "i80321_aau", 0);
-#endif
- bus_generic_probe(dev);
- bus_generic_attach(dev);
-
- return (0);
-}
-
-void
-arm_mask_irq(uintptr_t nb)
-{
- intr_enabled &= ~(1 << nb);
- i80321_set_intrmask();
-}
-
-void
-arm_unmask_irq(uintptr_t nb)
-{
- intr_enabled |= (1 << nb);
- i80321_set_intrmask();
-}
-
-
-void
-cpu_reset()
-{
- (void) disable_interrupts(PSR_I|PSR_F);
- *(__volatile uint32_t *)(IQ80321_80321_VBASE + VERDE_ATU_BASE +
- ATU_PCSR) = PCSR_RIB | PCSR_RPB;
- printf("Reset failed!\n");
- for(;;);
-}
-
-static struct resource *
-iq80321_alloc_resource(device_t dev, device_t child, int type, int *rid,
- u_long start, u_long end, u_long count, u_int flags)
-{
- struct i80321_softc *sc = device_get_softc(dev);
- struct resource *rv;
-
- if (type == SYS_RES_IRQ) {
- rv = rman_reserve_resource(&sc->sc_irq_rman,
- start, end, count, flags, child);
- if (rv != NULL)
- rman_set_rid(rv, *rid);
- return (rv);
- }
- return (NULL);
-}
-
-static int
-iq80321_setup_intr(device_t dev, device_t child,
- struct resource *ires, int flags, driver_filter_t *filt,
- driver_intr_t *intr, void *arg, void **cookiep)
-{
- int error;
-
- error = BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags,
- filt, intr, arg, cookiep);
- if (error)
- return (error);
- intr_enabled |= 1 << rman_get_start(ires);
- i80321_set_intrmask();
-
- return (0);
-}
-
-static int
-iq80321_teardown_intr(device_t dev, device_t child, struct resource *res,
- void *cookie)
-{
- return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, res, cookie));
-}
-
-static device_method_t iq80321_methods[] = {
- DEVMETHOD(device_probe, iq80321_probe),
- DEVMETHOD(device_attach, iq80321_attach),
- DEVMETHOD(device_identify, iq80321_identify),
- DEVMETHOD(bus_alloc_resource, iq80321_alloc_resource),
- DEVMETHOD(bus_setup_intr, iq80321_setup_intr),
- DEVMETHOD(bus_teardown_intr, iq80321_teardown_intr),
- {0, 0},
-};
-
-static driver_t iq80321_driver = {
- "iq",
- iq80321_methods,
- sizeof(struct i80321_softc),
-};
-static devclass_t iq80321_devclass;
-
-DRIVER_MODULE(iq, nexus, iq80321_driver, iq80321_devclass, 0, 0);
diff --git a/sys/arm/xscale/i80321/iq80321reg.h b/sys/arm/xscale/i80321/iq80321reg.h
deleted file mode 100644
index d887fcd..0000000
--- a/sys/arm/xscale/i80321/iq80321reg.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/* $NetBSD: iq80321reg.h,v 1.4 2003/05/14 19:46:39 thorpej Exp $ */
-
-/*-
- * Copyright (c) 2002 Wasabi Systems, Inc.
- * All rights reserved.
- *
- * Written by Jason R. Thorpe for Wasabi Systems, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed for the NetBSD Project by
- * Wasabi Systems, Inc.
- * 4. The name of Wasabi Systems, Inc. may not be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
- * 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 _IQ80321REG_H_
-#define _IQ80321REG_H_
-
-/*
- * Memory map and register definitions for the Intel IQ80321
- * Evaluation Board.
- */
-
-/*
- * The memory map of the IQ80321 looks like so:
- *
- * ------------------------------
- * Intel 80321 IOP Reserved
- * FFFF E900 ------------------------------
- * Peripheral Memory Mapped
- * Registers
- * FFFF E000 ------------------------------
- * On-board devices
- * FE80 0000 ------------------------------
- * SDRAM
- * A000 0000 ------------------------------
- * Reserved
- * 9100 0000 ------------------------------
- * Flash
- * 9080 0000 ------------------------------
- * Reserved
- * 9002 0000 ------------------------------
- * ATU Outbound Transaction
- * Windows
- * 8000 0000 ------------------------------
- * ATU Outbound Direct
- * Addressing Windows
- * 0000 1000 ------------------------------
- * Initialization Boot Code
- * from Flash
- * 0000 0000 ------------------------------
- */
-
-/*
- * We allocate a page table for VA 0xfe400000 (4MB) and map the
- * PCI I/O space (64K) and i80321 memory-mapped registers (4K) there.
- */
-#define IQ80321_IOPXS_VBASE 0xfe400000UL
-#define IQ80321_IOW_VBASE IQ80321_IOPXS_VBASE
-#define IQ80321_80321_VBASE (IQ80321_IOW_VBASE + \
- VERDE_OUT_XLATE_IO_WIN_SIZE)
-
-#define IQ80321_SDRAM_START 0xa0000000
-/*
- * The IQ80321 on-board devices are mapped VA==PA during bootstrap.
- * Conveniently, the size of the on-board register space is 1 section
- * mapping.
- */
-#define IQ80321_OBIO_BASE 0xfe800000UL
-#define IQ80321_OBIO_SIZE 0x00100000UL /* 1MB */
-
-#define IQ80321_UART1 0xfe800000UL /* TI 16550 */
-
-#if defined( CPU_XSCALE_80321 )
-#define IQ80321_7SEG_MSB 0xfe840000UL
-#define IQ80321_7SEG_LSB 0xfe850000UL
-
-#define IQ80321_ROT_SWITCH 0xfe8d0000UL
-
-#define IQ80321_BATTERY_STAT 0xfe8f0000UL
-#define BATTERY_STAT_PRES (1U << 0)
-#define BATTERY_STAT_CHRG (1U << 1)
-#define BATTERY_STAT_DISCHRG (1U << 2)
-#endif /* CPU_XSCALE_80321 */
-
-#endif /* _IQ80321REG_H_ */
diff --git a/sys/arm/xscale/i80321/iq80321var.h b/sys/arm/xscale/i80321/iq80321var.h
deleted file mode 100644
index 4a03500..0000000
--- a/sys/arm/xscale/i80321/iq80321var.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* $NetBSD: iq80321var.h,v 1.1 2002/03/27 21:51:30 thorpej Exp $ */
-
-/*-
- * Copyright (c) 2002 Wasabi Systems, Inc.
- * All rights reserved.
- *
- * Written by Jason R. Thorpe for Wasabi Systems, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed for the NetBSD Project by
- * Wasabi Systems, Inc.
- * 4. The name of Wasabi Systems, Inc. may not be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
- * 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 _IQ80321_IQ80321VAR_H_
-#define _IQ80321_IQ80321VAR_H_
-
-#include <dev/pci/pcivar.h>
-
-void iq80321_7seg(char, char);
-void iq80321_7seg_snake(void);
-
-#if 0
-void iq80321_pci_init(pci_chipset_tag_t, void *);
-#endif
-
-#endif /* _IQ80321_IQ80321VAR_H_ */
diff --git a/sys/arm/xscale/i80321/obio.c b/sys/arm/xscale/i80321/obio.c
deleted file mode 100644
index 55218cc..0000000
--- a/sys/arm/xscale/i80321/obio.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/* $NetBSD: obio.c,v 1.11 2003/07/15 00:25:05 lukem Exp $ */
-
-/*-
- * Copyright (c) 2001, 2002, 2003 Wasabi Systems, Inc.
- * All rights reserved.
- *
- * Written by Jason R. Thorpe for Wasabi Systems, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed for the NetBSD Project by
- * Wasabi Systems, Inc.
- * 4. The name of Wasabi Systems, Inc. may not be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
- * 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.
- */
-
-/*
- * On-board device autoconfiguration support for Intel IQ80321
- * evaluation boards.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/rman.h>
-#include <sys/malloc.h>
-
-#include <machine/bus.h>
-
-#include <arm/xscale/i80321/i80321reg.h>
-
-#include <arm/xscale/i80321/iq80321reg.h>
-#include <arm/xscale/i80321/obiovar.h>
-
-bus_space_tag_t obio_bs_tag;
-
-int obio_probe(device_t);
-int obio_attach(device_t);
-
-int
-obio_probe(device_t dev)
-{
- return (0);
-}
-
-int
-obio_attach(device_t dev)
-{
- struct obio_softc *sc = device_get_softc(dev);
-
- obio_bs_tag = arm_base_bs_tag;
- sc->oba_st = obio_bs_tag;
- sc->oba_addr = IQ80321_OBIO_BASE;
- sc->oba_size = IQ80321_OBIO_SIZE;
- sc->oba_rman.rm_type = RMAN_ARRAY;
- sc->oba_rman.rm_descr = "OBIO I/O";
- if (rman_init(&sc->oba_rman) != 0 ||
- rman_manage_region(&sc->oba_rman,
- sc->oba_addr, sc->oba_addr + sc->oba_size) != 0)
- panic("obio_attach: failed to set up I/O rman");
- sc->oba_irq_rman.rm_type = RMAN_ARRAY;
- sc->oba_irq_rman.rm_descr = "OBIO IRQ";
- if (rman_init(&sc->oba_irq_rman) != 0 ||
- rman_manage_region(&sc->oba_irq_rman, 28, 28) != 0)
- panic("obio_attach: failed to set up IRQ rman");
- device_add_child(dev, "uart", 0);
- bus_generic_probe(dev);
- bus_generic_attach(dev);
- return (0);
-}
-
-static struct resource *
-obio_alloc_resource(device_t bus, device_t child, int type, int *rid,
- u_long start, u_long end, u_long count, u_int flags)
-{
- struct resource *rv;
- struct rman *rm;
- bus_space_tag_t bt = NULL;
- bus_space_handle_t bh = 0;
- struct obio_softc *sc = device_get_softc(bus);
-
- switch (type) {
- case SYS_RES_IRQ:
- rm = &sc->oba_irq_rman;
- break;
- case SYS_RES_MEMORY:
- return (NULL);
- case SYS_RES_IOPORT:
- rm = &sc->oba_rman;
- bt = sc->oba_st;
- bh = sc->oba_addr;
- start = bh;
- break;
- default:
- return (NULL);
- }
-
-
- rv = rman_reserve_resource(rm, start, end, count, flags, child);
- if (rv == NULL)
- return (NULL);
- if (type == SYS_RES_IRQ)
- return (rv);
- rman_set_rid(rv, *rid);
- rman_set_bustag(rv, bt);
- rman_set_bushandle(rv, bh);
-
- return (rv);
-
-}
-
-static int
-obio_activate_resource(device_t bus, device_t child, int type, int rid,
- struct resource *r)
-{
- return (0);
-}
-static device_method_t obio_methods[] = {
- DEVMETHOD(device_probe, obio_probe),
- DEVMETHOD(device_attach, obio_attach),
-
- DEVMETHOD(bus_alloc_resource, obio_alloc_resource),
- DEVMETHOD(bus_activate_resource, obio_activate_resource),
- DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
- DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
-
- {0, 0},
-};
-
-static driver_t obio_driver = {
- "obio",
- obio_methods,
- sizeof(struct obio_softc),
-};
-static devclass_t obio_devclass;
-
-DRIVER_MODULE(obio, iq, obio_driver, obio_devclass, 0, 0);
diff --git a/sys/arm/xscale/i80321/obiovar.h b/sys/arm/xscale/i80321/obiovar.h
deleted file mode 100644
index 182b52f..0000000
--- a/sys/arm/xscale/i80321/obiovar.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* $NetBSD: obiovar.h,v 1.4 2003/06/16 17:40:53 thorpej Exp $ */
-
-/*-
- * Copyright (c) 2002, 2003 Wasabi Systems, Inc.
- * All rights reserved.
- *
- * Written by Jason R. Thorpe for Wasabi Systems, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed for the NetBSD Project by
- * Wasabi Systems, Inc.
- * 4. The name of Wasabi Systems, Inc. may not be used to endorse
- * or promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
- * 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 _IQ80321_OBIOVAR_H_
-#define _IQ80321_OBIOVAR_H_
-
-#include <sys/rman.h>
-
-struct obio_softc {
- bus_space_tag_t oba_st; /* bus space tag */
- bus_addr_t oba_addr; /* address of device */
- bus_size_t oba_size; /* size of device */
- int oba_width; /* bus width */
- int oba_irq; /* XINT interrupt bit # */
- struct rman oba_rman;
- struct rman oba_irq_rman;
-
-};
-extern bus_space_tag_t obio_bs_tag;
-
-#endif /* _IQ80321_OBIOVAR_H_ */
diff --git a/sys/arm/xscale/i80321/std.ep80219 b/sys/arm/xscale/i80321/std.ep80219
deleted file mode 100644
index 9f5cbb7..0000000
--- a/sys/arm/xscale/i80321/std.ep80219
+++ /dev/null
@@ -1,7 +0,0 @@
-#EP80219 board configuration
-#$FreeBSD$
-include "../xscale/i80321/std.i80219"
-files "../xscale/i80321/files.ep80219"
-makeoptions KERNPHYSADDR=0xa0200000
-makeoptions KERNVIRTADDR=0xc0200000
-options COUNTS_PER_SEC=198000000
diff --git a/sys/arm/xscale/i80321/std.i80219 b/sys/arm/xscale/i80321/std.i80219
deleted file mode 100644
index 7cc8f37..0000000
--- a/sys/arm/xscale/i80321/std.i80219
+++ /dev/null
@@ -1,5 +0,0 @@
-#XScale i80219 generic configuration
-#$FreeBSD$
-files "../xscale/i80321/files.i80219"
-include "../xscale/std.xscale-be"
-cpu CPU_XSCALE_80219
diff --git a/sys/arm/xscale/i80321/std.i80321 b/sys/arm/xscale/i80321/std.i80321
deleted file mode 100644
index 8142bdf..0000000
--- a/sys/arm/xscale/i80321/std.i80321
+++ /dev/null
@@ -1,5 +0,0 @@
-#XScale i80321 generic configuration
-#$FreeBSD$
-files "../xscale/i80321/files.i80321"
-include "../xscale/std.xscale-be"
-cpu CPU_XSCALE_80321
diff --git a/sys/arm/xscale/i80321/std.iq31244 b/sys/arm/xscale/i80321/std.iq31244
deleted file mode 100644
index c4c23bf..0000000
--- a/sys/arm/xscale/i80321/std.iq31244
+++ /dev/null
@@ -1,7 +0,0 @@
-#IQ31244 board configuration
-#$FreeBSD$
-include "../xscale/i80321/std.i80321"
-files "../xscale/i80321/files.iq31244"
-makeoptions KERNPHYSADDR=0xa0200000
-makeoptions KERNVIRTADDR=0xc0200000
-options COUNTS_PER_SEC=198000000
diff --git a/sys/arm/xscale/i80321/uart_bus_i80321.c b/sys/arm/xscale/i80321/uart_bus_i80321.c
deleted file mode 100644
index 5bb903d..0000000
--- a/sys/arm/xscale/i80321/uart_bus_i80321.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*-
- * Copyright (c) 2004 Olivier Houchard. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <machine/bus.h>
-#include <sys/rman.h>
-#include <machine/resource.h>
-
-#include <dev/pci/pcivar.h>
-
-#include <dev/uart/uart.h>
-#include <dev/uart/uart_bus.h>
-#include <dev/uart/uart_cpu.h>
-
-#include "uart_if.h"
-
-static int uart_i80321_probe(device_t dev);
-
-static device_method_t uart_i80321_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, uart_i80321_probe),
- DEVMETHOD(device_attach, uart_bus_attach),
- DEVMETHOD(device_detach, uart_bus_detach),
- { 0, 0 }
-};
-
-static driver_t uart_i80321_driver = {
- uart_driver_name,
- uart_i80321_methods,
- sizeof(struct uart_softc),
-};
-
-extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs;
-static int
-uart_i80321_probe(device_t dev)
-{
- struct uart_softc *sc;
-
- sc = device_get_softc(dev);
- sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs);
- sc->sc_class = &uart_ns8250_class;
- bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas));
- return(uart_bus_probe(dev, 0, 0, 0, 0));
-}
-
-
-DRIVER_MODULE(uart, obio, uart_i80321_driver, uart_devclass, 0, 0);
diff --git a/sys/arm/xscale/i80321/uart_cpu_i80321.c b/sys/arm/xscale/i80321/uart_cpu_i80321.c
deleted file mode 100644
index a3faec7..0000000
--- a/sys/arm/xscale/i80321/uart_cpu_i80321.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*-
- * Copyright (c) 2003 Marcel Moolenaar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/cons.h>
-#include <machine/bus.h>
-
-#include <dev/uart/uart.h>
-#include <dev/uart/uart_cpu.h>
-
-#include <arm/xscale/i80321/i80321var.h>
-#include <arm/xscale/i80321/obiovar.h>
-
-bus_space_tag_t uart_bus_space_io;
-bus_space_tag_t uart_bus_space_mem;
-
-int
-uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2)
-{
- return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0);
-}
-
-int
-uart_cpu_getdev(int devtype, struct uart_devinfo *di)
-{
- di->ops = uart_getops(&uart_ns8250_class);
- di->bas.chan = 0;
- di->bas.bst = obio_bs_tag;
- di->bas.regshft = 0;
- di->bas.rclk = 0;
- di->baudrate = 115200;
- di->databits = 8;
- di->stopbits = 1;
- di->parity = UART_PARITY_NONE;
- uart_bus_space_io = obio_bs_tag;
- uart_bus_space_mem = NULL;
- di->bas.bsh = 0xfe800000;
- return (0);
-}
diff --git a/sys/arm/xscale/i8134x/crb_machdep.c b/sys/arm/xscale/i8134x/crb_machdep.c
index 2bd77a5..2936963 100644
--- a/sys/arm/xscale/i8134x/crb_machdep.c
+++ b/sys/arm/xscale/i8134x/crb_machdep.c
@@ -92,7 +92,7 @@ __FBSDID("$FreeBSD$");
#include <sys/reboot.h>
-#include <arm/xscale/i80321/i80321var.h> /* For i80321_calibrate_delay() */
+#include <arm/xscale/i8134x/i80321var.h> /* For i80321_calibrate_delay() */
#include <arm/xscale/i8134x/i81342reg.h>
#include <arm/xscale/i8134x/i81342var.h>
@@ -267,7 +267,7 @@ initarm(struct arm_boot_params *abp)
xscale_cache_clean_addr = 0xff000000U;
cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
- setttb(kernel_l1pt.pv_pa);
+ cpu_setttb(kernel_l1pt.pv_pa);
cpu_tlb_flushID();
cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
/*
@@ -284,7 +284,7 @@ initarm(struct arm_boot_params *abp)
/*
* We must now clean the cache again....
* Cleaning may be done by reading new data to displace any
- * dirty data in the cache. This will have happened in setttb()
+ * dirty data in the cache. This will have happened in cpu_setttb()
* but since we are boot strapping the addresses used for the read
* may have just been remapped and thus the cache could be out
* of sync. A re-clean after the switch will cure this.
diff --git a/sys/arm/xscale/i8134x/files.i81342 b/sys/arm/xscale/i8134x/files.i81342
index ed93e6b..63c715c 100644
--- a/sys/arm/xscale/i8134x/files.i81342
+++ b/sys/arm/xscale/i8134x/files.i81342
@@ -1,7 +1,7 @@
# $FreeBSD$
arm/arm/bus_space_base.c standard
-arm/xscale/i80321/i80321_timer.c standard
-arm/xscale/i80321/i80321_wdog.c optional iopwdog
+arm/xscale/i8134x/i80321_timer.c standard
+arm/xscale/i8134x/i80321_wdog.c optional iopwdog
arm/xscale/i8134x/i81342.c standard
arm/xscale/i8134x/i81342_mcu.c standard
arm/xscale/i8134x/i81342_pci.c optional pci
diff --git a/sys/arm/xscale/i80321/i80321_timer.c b/sys/arm/xscale/i8134x/i80321_timer.c
index 3b4e5a1..ea15d92 100644
--- a/sys/arm/xscale/i80321/i80321_timer.c
+++ b/sys/arm/xscale/i8134x/i80321_timer.c
@@ -59,8 +59,8 @@ __FBSDID("$FreeBSD$");
#include <machine/frame.h>
#include <machine/resource.h>
#include <machine/intr.h>
-#include <arm/xscale/i80321/i80321reg.h>
-#include <arm/xscale/i80321/i80321var.h>
+#include <arm/xscale/i8134x/i80321reg.h>
+#include <arm/xscale/i8134x/i80321var.h>
#ifdef CPU_XSCALE_81342
#define ICU_INT_TIMER0 (8) /* XXX: Can't include i81342reg.h because
diff --git a/sys/arm/xscale/i80321/i80321_wdog.c b/sys/arm/xscale/i8134x/i80321_wdog.c
index 9be98d2..c11c78a 100644
--- a/sys/arm/xscale/i80321/i80321_wdog.c
+++ b/sys/arm/xscale/i8134x/i80321_wdog.c
@@ -54,8 +54,8 @@ __FBSDID("$FreeBSD$");
#include <machine/cpufunc.h>
#include <machine/machdep.h>
-#include <arm/xscale/i80321/i80321reg.h>
-#include <arm/xscale/i80321/i80321var.h>
+#include <arm/xscale/i8134x/i80321reg.h>
+#include <arm/xscale/i8134x/i80321var.h>
struct iopwdog_softc {
diff --git a/sys/arm/xscale/i80321/i80321reg.h b/sys/arm/xscale/i8134x/i80321reg.h
index 53617f9..b6dd4fe 100644
--- a/sys/arm/xscale/i80321/i80321reg.h
+++ b/sys/arm/xscale/i8134x/i80321reg.h
@@ -91,19 +91,9 @@
#define VERDE_MCU_BASE 0x0500
#define VERDE_MCU_SIZE 0x0100
-#if defined(CPU_XSCALE_80321)
-#define VERDE_SSP_BASE 0x0600
-#define VERDE_SSP_SIZE 0x0080
-#endif
-
#define VERDE_PBIU_BASE 0x0680
#define VERDE_PBIU_SIZE 0x0080
-#if defined(CPU_XSCALE_80321)
-#define VERDE_AAU_BASE 0x0800
-#define VERDE_AAU_SIZE 0x0100
-#endif
-
#define VERDE_I2C_BASE 0x1680
#define VERDE_I2C_BASE0 (VERDE_I2C_BASE + 0x00)
#define VERDE_I2C_BASE1 (VERDE_I2C_BASE + 0x20)
@@ -340,21 +330,13 @@
#define ICU_INT_XINT(x) ((x) + ICU_INT_XINT0)
#define ICU_INT_bit26 26
-#if defined (CPU_XSCALE_80219)
-#define ICU_INT_bit25 25 /* reserved */
-#else
/* CPU_XSCALE_80321 */
#define ICU_INT_SSP 25 /* SSP serial port */
-#endif
#define ICU_INT_MUE 24 /* msg unit error */
-#if defined (CPU_XSCALE_80219)
-#define ICU_INT_bit23 23 /* reserved */
-#else
/* CPU_XSCALE_80321 */
#define ICU_INT_AAUE 23 /* AAU error */
-#endif
#define ICU_INT_bit22 22
#define ICU_INT_DMA1E 21 /* DMA Ch 1 error */
@@ -372,14 +354,9 @@
#define ICU_INT_TMR0 9 /* timer 0 */
#define ICU_INT_CPPM 8 /* core processor PMU */
-#if defined(CPU_XSCALE_80219)
-#define ICU_INT_bit7 7 /* reserved */
-#define ICU_INT_bit6 6 /* reserved */
-#else
/* CPU_XSCALE_80321 */
#define ICU_INT_AAU_EOC 7 /* AAU end-of-chain */
#define ICU_INT_AAU_EOT 6 /* AAU end-of-transfer */
-#endif
#define ICU_INT_bit5 5
#define ICU_INT_bit4 4
@@ -388,81 +365,12 @@
#define ICU_INT_DMA0_EOC 1 /* DMA0 end-of-chain */
#define ICU_INT_DMA0_EOT 0 /* DMA0 end-of-transfer */
-#if defined (CPU_XSCALE_80219)
-#define ICU_INT_HWMASK (0xffffffff & \
- ~((1 << ICU_INT_bit26) | \
- (1 << ICU_INT_bit25) | \
- (1 << ICU_INT_bit23) | \
- (1 << ICU_INT_bit22) | \
- (1 << ICU_INT_bit7) | \
- (1 << ICU_INT_bit6) | \
- (1 << ICU_INT_bit5) | \
- (1 << ICU_INT_bit4)))
-
-#else
/* CPU_XSCALE_80321 */
#define ICU_INT_HWMASK (0xffffffff & \
~((1 << ICU_INT_bit26) | \
(1 << ICU_INT_bit22) | \
(1 << ICU_INT_bit5) | \
(1 << ICU_INT_bit4)))
-#endif
-
-/*
- * SSP Serial Port
- */
-#if defined (CPU_XSCALE_80321)
-
-#define SSP_SSCR0 0x00 /* SSC control 0 */
-#define SSP_SSCR1 0x04 /* SSC control 1 */
-#define SSP_SSSR 0x08 /* SSP status */
-#define SSP_SSITR 0x0c /* SSP interrupt test */
-#define SSP_SSDR 0x10 /* SSP data */
-
-#define SSP_SSCR0_DSIZE(x) ((x) - 1)/* data size: 4..16 */
-#define SSP_SSCR0_FRF_SPI (0 << 4) /* Motorola Serial Periph Iface */
-#define SSP_SSCR0_FRF_SSP (1U << 4)/* TI Sync. Serial Protocol */
-#define SSP_SSCR0_FRF_UWIRE (2U << 4)/* NatSemi Microwire */
-#define SSP_SSCR0_FRF_rsvd (3U << 4)/* reserved */
-#define SSP_SSCR0_ECS (1U << 6)/* external clock select */
-#define SSP_SSCR0_SSE (1U << 7)/* sync. serial port enable */
-#define SSP_SSCR0_SCR(x) ((x) << 8)/* serial clock rate */
- /* bit rate = 3.6864 * 10e6 /
- (2 * (SCR + 1)) */
-
-#define SSP_SSCR1_RIE (1U << 0)/* Rx FIFO interrupt enable */
-#define SSP_SSCR1_TIE (1U << 1)/* Tx FIFO interrupt enable */
-#define SSP_SSCR1_LBM (1U << 2)/* loopback mode enable */
-#define SSP_SSCR1_SPO (1U << 3)/* Moto SPI SSCLK pol. (1 = high) */
-#define SSP_SSCR1_SPH (1U << 4)/* Moto SPI SSCLK phase:
- 0 = inactive full at start,
- 1/2 at end of frame
- 1 = inactive 1/2 at start,
- full at end of frame */
-#define SSP_SSCR1_MWDS (1U << 5)/* Microwire data size:
- 0 = 8 bit
- 1 = 16 bit */
-#define SSP_SSCR1_TFT (((x) - 1) << 6) /* Tx FIFO threshold */
-#define SSP_SSCR1_RFT (((x) - 1) << 10)/* Rx FIFO threshold */
-#define SSP_SSCR1_EFWR (1U << 14)/* enab. FIFO write/read */
-#define SSP_SSCR1_STRF (1U << 15)/* FIFO write/read FIFO select:
- 0 = Tx FIFO
- 1 = Rx FIFO */
-
-#define SSP_SSSR_TNF (1U << 2)/* Tx FIFO not full */
-#define SSP_SSSR_RNE (1U << 3)/* Rx FIFO not empty */
-#define SSP_SSSR_BSY (1U << 4)/* SSP is busy */
-#define SSP_SSSR_TFS (1U << 5)/* Tx FIFO service request */
-#define SSP_SSSR_RFS (1U << 6)/* Rx FIFO service request */
-#define SSP_SSSR_ROR (1U << 7)/* Rx FIFO overrun */
-#define SSP_SSSR_TFL(x) (((x) >> 8) & 0xf) /* Tx FIFO level */
-#define SSP_SSSR_RFL(x) (((x) >> 12) & 0xf)/* Rx FIFO level */
-
-#define SSP_SSITR_TTFS (1U << 5)/* Test Tx FIFO service */
-#define SSP_SSITR_TRFS (1U << 6)/* Test Rx FIFO service */
-#define SSP_SSITR_TROR (1U << 7)/* Test Rx overrun */
-
-#endif /* CPU_XSCALE_80321 */
/*
* Peripheral Bus Interface Unit
diff --git a/sys/arm/xscale/i80321/i80321var.h b/sys/arm/xscale/i8134x/i80321var.h
index 0fead25..0fead25 100644
--- a/sys/arm/xscale/i80321/i80321var.h
+++ b/sys/arm/xscale/i8134x/i80321var.h
diff --git a/sys/arm/xscale/ixp425/avila_machdep.c b/sys/arm/xscale/ixp425/avila_machdep.c
index e033e13..f8632e1 100644
--- a/sys/arm/xscale/ixp425/avila_machdep.c
+++ b/sys/arm/xscale/ixp425/avila_machdep.c
@@ -353,7 +353,7 @@ initarm(struct arm_boot_params *abp)
xscale_cache_clean_addr = 0xff000000U;
cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
- setttb(kernel_l1pt.pv_pa);
+ cpu_setttb(kernel_l1pt.pv_pa);
cpu_tlb_flushID();
cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
@@ -370,7 +370,7 @@ initarm(struct arm_boot_params *abp)
/*
* We must now clean the cache again....
* Cleaning may be done by reading new data to displace any
- * dirty data in the cache. This will have happened in setttb()
+ * dirty data in the cache. This will have happened in cpu_setttb()
* but since we are boot strapping the addresses used for the read
* may have just been remapped and thus the cache could be out
* of sync. A re-clean after the switch will cure this.
diff --git a/sys/arm/xscale/pxa/pxa_machdep.c b/sys/arm/xscale/pxa/pxa_machdep.c
index 5cc8d46..2bbb835 100644
--- a/sys/arm/xscale/pxa/pxa_machdep.c
+++ b/sys/arm/xscale/pxa/pxa_machdep.c
@@ -267,7 +267,7 @@ initarm(struct arm_boot_params *abp)
xscale_cache_clean_addr = 0xff000000U;
cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
- setttb(kernel_l1pt.pv_pa);
+ cpu_setttb(kernel_l1pt.pv_pa);
cpu_tlb_flushID();
cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
@@ -284,7 +284,7 @@ initarm(struct arm_boot_params *abp)
/*
* We must now clean the cache again....
* Cleaning may be done by reading new data to displace any
- * dirty data in the cache. This will have happened in setttb()
+ * dirty data in the cache. This will have happened in cpu_setttb()
* but since we are boot strapping the addresses used for the read
* may have just been remapped and thus the cache could be out
* of sync. A re-clean after the switch will cure this.
diff --git a/sys/arm64/arm64/locore.S b/sys/arm64/arm64/locore.S
index 9909a42..87abee1 100644
--- a/sys/arm64/arm64/locore.S
+++ b/sys/arm64/arm64/locore.S
@@ -628,11 +628,11 @@ tcr_early:
sctlr_set:
/* Bits to set */
.quad (SCTLR_UCI | SCTLR_nTWE | SCTLR_nTWI | SCTLR_UCT | SCTLR_DZE | \
- SCTLR_I | SCTLR_SED | SCTLR_C | SCTLR_M)
+ SCTLR_I | SCTLR_SED | SCTLR_SA0 | SCTLR_SA | SCTLR_C | SCTLR_M)
sctlr_clear:
/* Bits to clear */
.quad (SCTLR_EE | SCTLR_EOE | SCTLR_WXN | SCTLR_UMA | SCTLR_ITD | \
- SCTLR_THEE | SCTLR_CP15BEN | SCTLR_SA0 | SCTLR_SA | SCTLR_A)
+ SCTLR_THEE | SCTLR_CP15BEN | SCTLR_A)
.globl abort
abort:
diff --git a/sys/arm64/arm64/trap.c b/sys/arm64/arm64/trap.c
index 89d6d0c..10e3f41 100644
--- a/sys/arm64/arm64/trap.c
+++ b/sys/arm64/arm64/trap.c
@@ -374,6 +374,10 @@ do_el0_sync(struct trapframe *frame)
case EXCP_UNKNOWN:
el0_excp_unknown(frame);
break;
+ case EXCP_SP_ALIGN:
+ call_trapsignal(td, SIGBUS, BUS_ADRALN, (void *)frame->tf_sp);
+ userret(td, frame);
+ break;
case EXCP_PC_ALIGN:
call_trapsignal(td, SIGBUS, BUS_ADRALN, (void *)frame->tf_elr);
userret(td, frame);
diff --git a/sys/arm64/arm64/uma_machdep.c b/sys/arm64/arm64/uma_machdep.c
index 9b9df5c..a9dae0f 100644
--- a/sys/arm64/arm64/uma_machdep.c
+++ b/sys/arm64/arm64/uma_machdep.c
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/systm.h>
+#include <sys/taskqueue.h>
#include <vm/vm.h>
#include <vm/vm_page.h>
#include <vm/vm_pageout.h>
diff --git a/sys/arm64/arm64/vm_machdep.c b/sys/arm64/arm64/vm_machdep.c
index 6794b1b4..3b68914 100644
--- a/sys/arm64/arm64/vm_machdep.c
+++ b/sys/arm64/arm64/vm_machdep.c
@@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sf_buf.h>
#include <sys/signal.h>
#include <sys/unistd.h>
+#include <sys/taskqueue.h>
#include <vm/vm.h>
#include <vm/vm_page.h>
diff --git a/sys/arm64/include/kdb.h b/sys/arm64/include/kdb.h
index e4f4f70..2f7306e 100644
--- a/sys/arm64/include/kdb.h
+++ b/sys/arm64/include/kdb.h
@@ -43,6 +43,8 @@ void kdb_cpu_set_singlestep(void);
static __inline void
kdb_cpu_sync_icache(unsigned char *addr, size_t size)
{
+
+ cpu_icache_sync_range((vm_offset_t)addr, size);
}
static __inline void
diff --git a/sys/boot/common/load_elf.c b/sys/boot/common/load_elf.c
index 0ff1a15..3207f73 100644
--- a/sys/boot/common/load_elf.c
+++ b/sys/boot/common/load_elf.c
@@ -886,7 +886,7 @@ __elfN(parse_modmetadata)(struct preloaded_file *fp, elf_file_t ef,
error = __elfN(reloc_ptr)(fp, ef, v, &md, sizeof(md));
if (error == EOPNOTSUPP) {
md.md_cval += ef->off;
- md.md_data = (void *)((uintptr_t)md.md_data + ef->off);
+ md.md_data = (void *)((uintptr_t)md.md_data + (uintptr_t)ef->off);
} else if (error != 0)
return (error);
#endif
diff --git a/sys/boot/efi/boot1/boot1.c b/sys/boot/efi/boot1/boot1.c
index c326c79..1161b0a 100644
--- a/sys/boot/efi/boot1/boot1.c
+++ b/sys/boot/efi/boot1/boot1.c
@@ -50,9 +50,6 @@ static const boot_module_t *boot_modules[] =
void putchar(int c);
EFI_STATUS efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE* Xsystab);
-static void try_load(const boot_module_t* mod);
-static EFI_STATUS probe_handle(EFI_HANDLE h);
-
EFI_SYSTEM_TABLE *systab;
EFI_BOOT_SERVICES *bs;
static EFI_HANDLE *image;
@@ -85,20 +82,300 @@ Free(void *buf, const char *file __unused, int line __unused)
}
/*
- * This function only returns if it fails to load the kernel. If it
- * succeeds, it simply boots the kernel.
+ * nodes_match returns TRUE if the imgpath isn't NULL and the nodes match,
+ * FALSE otherwise.
*/
-void
-try_load(const boot_module_t *mod)
+static BOOLEAN
+nodes_match(EFI_DEVICE_PATH *imgpath, EFI_DEVICE_PATH *devpath)
+{
+ int len;
+
+ if (imgpath == NULL || imgpath->Type != devpath->Type ||
+ imgpath->SubType != devpath->SubType)
+ return (FALSE);
+
+ len = DevicePathNodeLength(imgpath);
+ if (len != DevicePathNodeLength(devpath))
+ return (FALSE);
+
+ return (memcmp(imgpath, devpath, (size_t)len) == 0);
+}
+
+/*
+ * device_paths_match returns TRUE if the imgpath isn't NULL and all nodes
+ * in imgpath and devpath match up to their respect occurances of a media
+ * node, FALSE otherwise.
+ */
+static BOOLEAN
+device_paths_match(EFI_DEVICE_PATH *imgpath, EFI_DEVICE_PATH *devpath)
+{
+
+ if (imgpath == NULL)
+ return (FALSE);
+
+ while (!IsDevicePathEnd(imgpath) && !IsDevicePathEnd(devpath)) {
+ if (IsDevicePathType(imgpath, MEDIA_DEVICE_PATH) &&
+ IsDevicePathType(devpath, MEDIA_DEVICE_PATH))
+ return (TRUE);
+
+ if (!nodes_match(imgpath, devpath))
+ return (FALSE);
+
+ imgpath = NextDevicePathNode(imgpath);
+ devpath = NextDevicePathNode(devpath);
+ }
+
+ return (FALSE);
+}
+
+/*
+ * devpath_last returns the last non-path end node in devpath.
+ */
+static EFI_DEVICE_PATH *
+devpath_last(EFI_DEVICE_PATH *devpath)
+{
+
+ while (!IsDevicePathEnd(NextDevicePathNode(devpath)))
+ devpath = NextDevicePathNode(devpath);
+
+ return (devpath);
+}
+
+/*
+ * devpath_node_str is a basic output method for a devpath node which
+ * only understands a subset of the available sub types.
+ *
+ * If we switch to UEFI 2.x then we should update it to use:
+ * EFI_DEVICE_PATH_TO_TEXT_PROTOCOL.
+ */
+static int
+devpath_node_str(char *buf, size_t size, EFI_DEVICE_PATH *devpath)
+{
+
+ switch (devpath->Type) {
+ case MESSAGING_DEVICE_PATH:
+ switch (devpath->SubType) {
+ case MSG_ATAPI_DP: {
+ ATAPI_DEVICE_PATH *atapi;
+
+ atapi = (ATAPI_DEVICE_PATH *)(void *)devpath;
+ return snprintf(buf, size, "ata(%s,%s,0x%x)",
+ (atapi->PrimarySecondary == 1) ? "Sec" : "Pri",
+ (atapi->SlaveMaster == 1) ? "Slave" : "Master",
+ atapi->Lun);
+ }
+ case MSG_USB_DP: {
+ USB_DEVICE_PATH *usb;
+
+ usb = (USB_DEVICE_PATH *)devpath;
+ return snprintf(buf, size, "usb(0x%02x,0x%02x)",
+ usb->ParentPortNumber, usb->InterfaceNumber);
+ }
+ case MSG_SCSI_DP: {
+ SCSI_DEVICE_PATH *scsi;
+
+ scsi = (SCSI_DEVICE_PATH *)(void *)devpath;
+ return snprintf(buf, size, "scsi(0x%02x,0x%02x)",
+ scsi->Pun, scsi->Lun);
+ }
+ case MSG_SATA_DP: {
+ SATA_DEVICE_PATH *sata;
+
+ sata = (SATA_DEVICE_PATH *)(void *)devpath;
+ return snprintf(buf, size, "sata(0x%x,0x%x,0x%x)",
+ sata->HBAPortNumber, sata->PortMultiplierPortNumber,
+ sata->Lun);
+ }
+ default:
+ return snprintf(buf, size, "msg(0x%02x)",
+ devpath->SubType);
+ }
+ break;
+ case HARDWARE_DEVICE_PATH:
+ switch (devpath->SubType) {
+ case HW_PCI_DP: {
+ PCI_DEVICE_PATH *pci;
+
+ pci = (PCI_DEVICE_PATH *)devpath;
+ return snprintf(buf, size, "pci(0x%02x,0x%02x)",
+ pci->Device, pci->Function);
+ }
+ default:
+ return snprintf(buf, size, "hw(0x%02x)",
+ devpath->SubType);
+ }
+ break;
+ case ACPI_DEVICE_PATH: {
+ ACPI_HID_DEVICE_PATH *acpi;
+
+ acpi = (ACPI_HID_DEVICE_PATH *)(void *)devpath;
+ if ((acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
+ switch (EISA_ID_TO_NUM(acpi->HID)) {
+ case 0x0a03:
+ return snprintf(buf, size, "pciroot(0x%x)",
+ acpi->UID);
+ case 0x0a08:
+ return snprintf(buf, size, "pcieroot(0x%x)",
+ acpi->UID);
+ case 0x0604:
+ return snprintf(buf, size, "floppy(0x%x)",
+ acpi->UID);
+ case 0x0301:
+ return snprintf(buf, size, "keyboard(0x%x)",
+ acpi->UID);
+ case 0x0501:
+ return snprintf(buf, size, "serial(0x%x)",
+ acpi->UID);
+ case 0x0401:
+ return snprintf(buf, size, "parallelport(0x%x)",
+ acpi->UID);
+ default:
+ return snprintf(buf, size, "acpi(pnp%04x,0x%x)",
+ EISA_ID_TO_NUM(acpi->HID), acpi->UID);
+ }
+ }
+
+ return snprintf(buf, size, "acpi(0x%08x,0x%x)", acpi->HID,
+ acpi->UID);
+ }
+ case MEDIA_DEVICE_PATH:
+ switch (devpath->SubType) {
+ case MEDIA_CDROM_DP: {
+ CDROM_DEVICE_PATH *cdrom;
+
+ cdrom = (CDROM_DEVICE_PATH *)(void *)devpath;
+ return snprintf(buf, size, "cdrom(%x)",
+ cdrom->BootEntry);
+ }
+ case MEDIA_HARDDRIVE_DP: {
+ HARDDRIVE_DEVICE_PATH *hd;
+
+ hd = (HARDDRIVE_DEVICE_PATH *)(void *)devpath;
+ return snprintf(buf, size, "hd(%x)",
+ hd->PartitionNumber);
+ }
+ default:
+ return snprintf(buf, size, "media(0x%02x)",
+ devpath->SubType);
+ }
+ case BBS_DEVICE_PATH:
+ return snprintf(buf, size, "bbs(0x%02x)", devpath->SubType);
+ case END_DEVICE_PATH_TYPE:
+ return (0);
+ }
+
+ return snprintf(buf, size, "type(0x%02x, 0x%02x)", devpath->Type,
+ devpath->SubType);
+}
+
+/*
+ * devpath_strlcat appends a text description of devpath to buf but not more
+ * than size - 1 characters followed by NUL-terminator.
+ */
+int
+devpath_strlcat(char *buf, size_t size, EFI_DEVICE_PATH *devpath)
+{
+ size_t len, used;
+ const char *sep;
+
+ sep = "";
+ used = 0;
+ while (!IsDevicePathEnd(devpath)) {
+ len = snprintf(buf, size - used, "%s", sep);
+ used += len;
+ if (used > size)
+ return (used);
+ buf += len;
+
+ len = devpath_node_str(buf, size - used, devpath);
+ used += len;
+ if (used > size)
+ return (used);
+ buf += len;
+ devpath = NextDevicePathNode(devpath);
+ sep = ":";
+ }
+
+ return (used);
+}
+
+/*
+ * devpath_str is convenience method which returns the text description of
+ * devpath using a static buffer, so it isn't thread safe!
+ */
+char *
+devpath_str(EFI_DEVICE_PATH *devpath)
+{
+ static char buf[256];
+
+ devpath_strlcat(buf, sizeof(buf), devpath);
+
+ return buf;
+}
+
+/*
+ * load_loader attempts to load the loader image data.
+ *
+ * It tries each module and its respective devices, identified by mod->probe,
+ * in order until a successful load occurs at which point it returns EFI_SUCCESS
+ * and EFI_NOT_FOUND otherwise.
+ *
+ * Only devices which have preferred matching the preferred parameter are tried.
+ */
+static EFI_STATUS
+load_loader(const boot_module_t **modp, dev_info_t **devinfop, void **bufp,
+ size_t *bufsize, BOOLEAN preferred)
{
- size_t bufsize, cmdsize;
- void *buf;
+ UINTN i;
+ dev_info_t *dev;
+ const boot_module_t *mod;
+
+ for (i = 0; i < NUM_BOOT_MODULES; i++) {
+ if (boot_modules[i] == NULL)
+ continue;
+ mod = boot_modules[i];
+ for (dev = mod->devices(); dev != NULL; dev = dev->next) {
+ if (dev->preferred != preferred)
+ continue;
+
+ if (mod->load(PATH_LOADER_EFI, dev, bufp, bufsize) ==
+ EFI_SUCCESS) {
+ *devinfop = dev;
+ *modp = mod;
+ return (EFI_SUCCESS);
+ }
+ }
+ }
+
+ return (EFI_NOT_FOUND);
+}
+
+/*
+ * try_boot only returns if it fails to load the loader. If it succeeds
+ * it simply boots, otherwise it returns the status of last EFI call.
+ */
+static EFI_STATUS
+try_boot()
+{
+ size_t bufsize, loadersize, cmdsize;
+ void *buf, *loaderbuf;
char *cmd;
dev_info_t *dev;
+ const boot_module_t *mod;
EFI_HANDLE loaderhandle;
EFI_LOADED_IMAGE *loaded_image;
EFI_STATUS status;
+ status = load_loader(&mod, &dev, &loaderbuf, &loadersize, TRUE);
+ if (status != EFI_SUCCESS) {
+ status = load_loader(&mod, &dev, &loaderbuf, &loadersize,
+ FALSE);
+ if (status != EFI_SUCCESS) {
+ printf("Failed to load '%s'\n", PATH_LOADER_EFI);
+ return (status);
+ }
+ }
+
/*
* Read in and parse the command line from /boot.config or /boot/config,
* if present. We'll pass it the next stage via a simple ASCII
@@ -111,67 +388,183 @@ try_load(const boot_module_t *mod)
*/
cmd = NULL;
cmdsize = 0;
- status = mod->load(PATH_DOTCONFIG, &dev, &buf, &bufsize);
+ status = mod->load(PATH_DOTCONFIG, dev, &buf, &bufsize);
if (status == EFI_NOT_FOUND)
- status = mod->load(PATH_CONFIG, &dev, &buf, &bufsize);
+ status = mod->load(PATH_CONFIG, dev, &buf, &bufsize);
if (status == EFI_SUCCESS) {
cmdsize = bufsize + 1;
cmd = malloc(cmdsize);
- if (cmd == NULL) {
- free(buf);
- return;
- }
+ if (cmd == NULL)
+ goto errout;
memcpy(cmd, buf, bufsize);
cmd[bufsize] = '\0';
free(buf);
+ buf = NULL;
}
- status = mod->load(PATH_LOADER_EFI, &dev, &buf, &bufsize);
- if (status == EFI_NOT_FOUND)
- return;
-
- if (status != EFI_SUCCESS) {
- printf("%s failed to load %s (%lu)\n", mod->name,
- PATH_LOADER_EFI, EFI_ERROR_CODE(status));
- return;
- }
-
- if ((status = bs->LoadImage(TRUE, image, dev->devpath, buf, bufsize,
- &loaderhandle)) != EFI_SUCCESS) {
+ if ((status = bs->LoadImage(TRUE, image, devpath_last(dev->devpath),
+ loaderbuf, loadersize, &loaderhandle)) != EFI_SUCCESS) {
printf("Failed to load image provided by %s, size: %zu, (%lu)\n",
mod->name, bufsize, EFI_ERROR_CODE(status));
- return;
+ goto errout;
}
- if (cmd != NULL)
- printf(" command args: %s\n", cmd);
-
if ((status = bs->HandleProtocol(loaderhandle, &LoadedImageGUID,
(VOID**)&loaded_image)) != EFI_SUCCESS) {
printf("Failed to query LoadedImage provided by %s (%lu)\n",
mod->name, EFI_ERROR_CODE(status));
- return;
+ goto errout;
}
+ if (cmd != NULL)
+ printf(" command args: %s\n", cmd);
+
loaded_image->DeviceHandle = dev->devhandle;
loaded_image->LoadOptionsSize = cmdsize;
loaded_image->LoadOptions = cmd;
+ DPRINTF("Starting '%s' in 5 seconds...", PATH_LOADER_EFI);
+ DSTALL(1000000);
+ DPRINTF(".");
+ DSTALL(1000000);
+ DPRINTF(".");
+ DSTALL(1000000);
+ DPRINTF(".");
+ DSTALL(1000000);
+ DPRINTF(".");
+ DSTALL(1000000);
+ DPRINTF(".\n");
+
if ((status = bs->StartImage(loaderhandle, NULL, NULL)) !=
EFI_SUCCESS) {
printf("Failed to start image provided by %s (%lu)\n",
mod->name, EFI_ERROR_CODE(status));
- free(cmd);
loaded_image->LoadOptionsSize = 0;
loaded_image->LoadOptions = NULL;
- return;
}
+
+errout:
+ if (cmd != NULL)
+ free(cmd);
+ if (buf != NULL)
+ free(buf);
+ if (loaderbuf != NULL)
+ free(loaderbuf);
+
+ return (status);
+}
+
+/*
+ * probe_handle determines if the passed handle represents a logical partition
+ * if it does it uses each module in order to probe it and if successful it
+ * returns EFI_SUCCESS.
+ */
+static EFI_STATUS
+probe_handle(EFI_HANDLE h, EFI_DEVICE_PATH *imgpath, BOOLEAN *preferred)
+{
+ dev_info_t *devinfo;
+ EFI_BLOCK_IO *blkio;
+ EFI_DEVICE_PATH *devpath;
+ EFI_STATUS status;
+ UINTN i;
+
+ /* Figure out if we're dealing with an actual partition. */
+ status = bs->HandleProtocol(h, &DevicePathGUID, (void **)&devpath);
+ if (status == EFI_UNSUPPORTED)
+ return (status);
+
+ if (status != EFI_SUCCESS) {
+ DPRINTF("\nFailed to query DevicePath (%lu)\n",
+ EFI_ERROR_CODE(status));
+ return (status);
+ }
+
+ DPRINTF("probing: %s\n", devpath_str(devpath));
+
+ status = bs->HandleProtocol(h, &BlockIoProtocolGUID, (void **)&blkio);
+ if (status == EFI_UNSUPPORTED)
+ return (status);
+
+ if (status != EFI_SUCCESS) {
+ DPRINTF("\nFailed to query BlockIoProtocol (%lu)\n",
+ EFI_ERROR_CODE(status));
+ return (status);
+ }
+
+ if (!blkio->Media->LogicalPartition)
+ return (EFI_UNSUPPORTED);
+
+ *preferred = device_paths_match(imgpath, devpath);
+
+ /* Run through each module, see if it can load this partition */
+ for (i = 0; i < NUM_BOOT_MODULES; i++) {
+ if (boot_modules[i] == NULL)
+ continue;
+
+ if ((status = bs->AllocatePool(EfiLoaderData,
+ sizeof(*devinfo), (void **)&devinfo)) !=
+ EFI_SUCCESS) {
+ DPRINTF("\nFailed to allocate devinfo (%lu)\n",
+ EFI_ERROR_CODE(status));
+ continue;
+ }
+ devinfo->dev = blkio;
+ devinfo->devpath = devpath;
+ devinfo->devhandle = h;
+ devinfo->devdata = NULL;
+ devinfo->preferred = *preferred;
+ devinfo->next = NULL;
+
+ status = boot_modules[i]->probe(devinfo);
+ if (status == EFI_SUCCESS)
+ return (EFI_SUCCESS);
+ (void)bs->FreePool(devinfo);
+ }
+
+ return (EFI_UNSUPPORTED);
+}
+
+/*
+ * probe_handle_status calls probe_handle and outputs the returned status
+ * of the call.
+ */
+static void
+probe_handle_status(EFI_HANDLE h, EFI_DEVICE_PATH *imgpath)
+{
+ EFI_STATUS status;
+ BOOLEAN preferred;
+
+ status = probe_handle(h, imgpath, &preferred);
+
+ DPRINTF("probe: ");
+ switch (status) {
+ case EFI_UNSUPPORTED:
+ printf(".");
+ DPRINTF(" not supported\n");
+ break;
+ case EFI_SUCCESS:
+ if (preferred) {
+ printf("%c", '*');
+ DPRINTF(" supported (preferred)\n");
+ } else {
+ printf("%c", '+');
+ DPRINTF(" supported\n");
+ }
+ break;
+ default:
+ printf("x");
+ DPRINTF(" error (%lu)\n", EFI_ERROR_CODE(status));
+ break;
+ }
+ DSTALL(500000);
}
EFI_STATUS
efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab)
{
EFI_HANDLE *handles;
+ EFI_LOADED_IMAGE *img;
+ EFI_DEVICE_PATH *imgpath;
EFI_STATUS status;
EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL;
SIMPLE_TEXT_OUTPUT_INTERFACE *conout = NULL;
@@ -254,20 +647,22 @@ efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab)
/* Scan all partitions, probing with all modules. */
nhandles = hsize / sizeof(*handles);
printf(" Probing %zu block devices...", nhandles);
- for (i = 0; i < nhandles; i++) {
- status = probe_handle(handles[i]);
- switch (status) {
- case EFI_UNSUPPORTED:
- printf(".");
- break;
- case EFI_SUCCESS:
- printf("+");
- break;
- default:
- printf("x");
- break;
- }
+ DPRINTF("\n");
+
+ /* Determine the devpath of our image so we can prefer it. */
+ status = bs->HandleProtocol(image, &LoadedImageGUID, (VOID**)&img);
+ imgpath = NULL;
+ if (status == EFI_SUCCESS) {
+ status = bs->HandleProtocol(img->DeviceHandle, &DevicePathGUID,
+ (void **)&imgpath);
+ if (status != EFI_SUCCESS)
+ DPRINTF("Failed to get image DevicePath (%lu)\n",
+ EFI_ERROR_CODE(status));
+ DPRINTF("boot1 imagepath: %s\n", devpath_str(imgpath));
}
+
+ for (i = 0; i < nhandles; i++)
+ probe_handle_status(handles[i], imgpath);
printf(" done\n");
/* Status summary. */
@@ -278,78 +673,15 @@ efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab)
}
}
- /* Select a partition to boot by trying each module in order. */
- for (i = 0; i < NUM_BOOT_MODULES; i++)
- if (boot_modules[i] != NULL)
- try_load(boot_modules[i]);
+ try_boot();
/* If we get here, we're out of luck... */
panic("No bootable partitions found!");
}
-static EFI_STATUS
-probe_handle(EFI_HANDLE h)
-{
- dev_info_t *devinfo;
- EFI_BLOCK_IO *blkio;
- EFI_DEVICE_PATH *devpath;
- EFI_STATUS status;
- UINTN i;
-
- /* Figure out if we're dealing with an actual partition. */
- status = bs->HandleProtocol(h, &DevicePathGUID, (void **)&devpath);
- if (status == EFI_UNSUPPORTED)
- return (status);
-
- if (status != EFI_SUCCESS) {
- DPRINTF("\nFailed to query DevicePath (%lu)\n",
- EFI_ERROR_CODE(status));
- return (status);
- }
-
- while (!IsDevicePathEnd(NextDevicePathNode(devpath)))
- devpath = NextDevicePathNode(devpath);
-
- status = bs->HandleProtocol(h, &BlockIoProtocolGUID, (void **)&blkio);
- if (status == EFI_UNSUPPORTED)
- return (status);
-
- if (status != EFI_SUCCESS) {
- DPRINTF("\nFailed to query BlockIoProtocol (%lu)\n",
- EFI_ERROR_CODE(status));
- return (status);
- }
-
- if (!blkio->Media->LogicalPartition)
- return (EFI_UNSUPPORTED);
-
- /* Run through each module, see if it can load this partition */
- for (i = 0; i < NUM_BOOT_MODULES; i++) {
- if (boot_modules[i] == NULL)
- continue;
-
- if ((status = bs->AllocatePool(EfiLoaderData,
- sizeof(*devinfo), (void **)&devinfo)) !=
- EFI_SUCCESS) {
- DPRINTF("\nFailed to allocate devinfo (%lu)\n",
- EFI_ERROR_CODE(status));
- continue;
- }
- devinfo->dev = blkio;
- devinfo->devpath = devpath;
- devinfo->devhandle = h;
- devinfo->devdata = NULL;
- devinfo->next = NULL;
-
- status = boot_modules[i]->probe(devinfo);
- if (status == EFI_SUCCESS)
- return (EFI_SUCCESS);
- (void)bs->FreePool(devinfo);
- }
-
- return (EFI_UNSUPPORTED);
-}
-
+/*
+ * add_device adds a device to the passed devinfo list.
+ */
void
add_device(dev_info_t **devinfop, dev_info_t *devinfo)
{
diff --git a/sys/boot/efi/boot1/boot_module.h b/sys/boot/efi/boot1/boot_module.h
index 2c158f6..296d5a6 100644
--- a/sys/boot/efi/boot1/boot_module.h
+++ b/sys/boot/efi/boot1/boot_module.h
@@ -36,9 +36,11 @@
#include <eficonsctl.h>
#ifdef EFI_DEBUG
-#define DPRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
+#define DPRINTF(fmt, args...) printf(fmt, ##args)
+#define DSTALL(d) bs->Stall(d)
#else
#define DPRINTF(fmt, ...) {}
+#define DSTALL(d) {}
#endif
/* EFI device info */
@@ -48,6 +50,7 @@ typedef struct dev_info
EFI_DEVICE_PATH *devpath;
EFI_HANDLE *devhandle;
void *devdata;
+ BOOLEAN preferred;
struct dev_info *next;
} dev_info_t;
@@ -75,19 +78,21 @@ typedef struct boot_module_t
/*
* load should select the best out of a set of devices that probe
- * indicated were loadable and load it.
+ * indicated were loadable and load the specified file.
*
* Return codes:
* EFI_SUCCESS = The module can handle the device.
* EFI_NOT_FOUND = The module can not handle the device.
* Other = The module encountered an error.
*/
- EFI_STATUS (*load)(const char *loader_path, dev_info_t **devinfo,
+ EFI_STATUS (*load)(const char *filepath, dev_info_t *devinfo,
void **buf, size_t *bufsize);
/* status outputs information about the probed devices. */
void (*status)();
+ /* valid devices as found by probe. */
+ dev_info_t *(*devices)();
} boot_module_t;
/* Standard boot modules. */
@@ -107,4 +112,6 @@ extern int vsnprintf(char *str, size_t sz, const char *fmt, va_list ap);
extern EFI_SYSTEM_TABLE *systab;
extern EFI_BOOT_SERVICES *bs;
+extern int devpath_strlcat(char *buf, size_t size, EFI_DEVICE_PATH *devpath);
+extern char *devpath_str(EFI_DEVICE_PATH *devpath);
#endif
diff --git a/sys/boot/efi/boot1/ufs_module.c b/sys/boot/efi/boot1/ufs_module.c
index 07c7152..63087ea 100644
--- a/sys/boot/efi/boot1/ufs_module.c
+++ b/sys/boot/efi/boot1/ufs_module.c
@@ -93,7 +93,7 @@ probe(dev_info_t* dev)
}
static EFI_STATUS
-try_load(dev_info_t *dev, const char *loader_path, void **bufp, size_t *bufsize)
+load(const char *filepath, dev_info_t *dev, void **bufp, size_t *bufsize)
{
ufs_ino_t ino;
EFI_STATUS status;
@@ -101,59 +101,46 @@ try_load(dev_info_t *dev, const char *loader_path, void **bufp, size_t *bufsize)
ssize_t read;
void *buf;
- if (init_dev(dev) < 0)
+ DPRINTF("Loading '%s' from %s\n", filepath, devpath_str(dev->devpath));
+
+ if (init_dev(dev) < 0) {
+ DPRINTF("Failed to init device\n");
return (EFI_UNSUPPORTED);
+ }
- if ((ino = lookup(loader_path)) == 0)
+ if ((ino = lookup(filepath)) == 0) {
+ DPRINTF("Failed to lookup '%s' (file not found?)\n", filepath);
return (EFI_NOT_FOUND);
+ }
if (fsread_size(ino, NULL, 0, &size) < 0 || size <= 0) {
- printf("Failed to read size of '%s' ino: %d\n", loader_path,
- ino);
+ printf("Failed to read size of '%s' ino: %d\n", filepath, ino);
return (EFI_INVALID_PARAMETER);
}
if ((status = bs->AllocatePool(EfiLoaderData, size, &buf)) !=
EFI_SUCCESS) {
- printf("Failed to allocate read buffer (%lu)\n",
- EFI_ERROR_CODE(status));
+ printf("Failed to allocate read buffer %zu for '%s' (%lu)\n",
+ size, filepath, EFI_ERROR_CODE(status));
return (status);
}
read = fsread(ino, buf, size);
if ((size_t)read != size) {
- printf("Failed to read '%s' (%zd != %zu)\n", loader_path, read,
+ printf("Failed to read '%s' (%zd != %zu)\n", filepath, read,
size);
(void)bs->FreePool(buf);
return (EFI_INVALID_PARAMETER);
}
+ DPRINTF("Load complete\n");
+
*bufp = buf;
*bufsize = size;
return (EFI_SUCCESS);
}
-static EFI_STATUS
-load(const char *loader_path, dev_info_t **devinfop, void **buf,
- size_t *bufsize)
-{
- dev_info_t *dev;
- EFI_STATUS status;
-
- for (dev = devices; dev != NULL; dev = dev->next) {
- status = try_load(dev, loader_path, buf, bufsize);
- if (status == EFI_SUCCESS) {
- *devinfop = dev;
- return (EFI_SUCCESS);
- } else if (status != EFI_NOT_FOUND) {
- return (status);
- }
- }
-
- return (EFI_NOT_FOUND);
-}
-
static void
status()
{
@@ -176,10 +163,18 @@ status()
}
}
+static dev_info_t *
+_devices()
+{
+
+ return (devices);
+}
+
const boot_module_t ufs_module =
{
.name = "UFS",
.probe = probe,
.load = load,
- .status = status
+ .status = status,
+ .devices = _devices
};
diff --git a/sys/boot/efi/boot1/zfs_module.c b/sys/boot/efi/boot1/zfs_module.c
index 96eec33..925f0b2 100644
--- a/sys/boot/efi/boot1/zfs_module.c
+++ b/sys/boot/efi/boot1/zfs_module.c
@@ -91,7 +91,7 @@ probe(dev_info_t *dev)
}
static EFI_STATUS
-try_load(dev_info_t *devinfo, const char *loader_path, void **bufp, size_t *bufsize)
+load(const char *filepath, dev_info_t *devinfo, void **bufp, size_t *bufsize)
{
spa_t *spa;
struct zfsmount zfsmount;
@@ -102,32 +102,41 @@ try_load(dev_info_t *devinfo, const char *loader_path, void **bufp, size_t *bufs
EFI_STATUS status;
spa = devinfo->devdata;
- if (zfs_spa_init(spa) != 0) {
- /* Init failed, don't report this loudly. */
+
+ DPRINTF("load: '%s' spa: '%s', devpath: %s\n", filepath, spa->spa_name,
+ devpath_str(devinfo->devpath));
+
+ if ((err = zfs_spa_init(spa)) != 0) {
+ DPRINTF("Failed to load pool '%s' (%d)\n", spa->spa_name, err);
return (EFI_NOT_FOUND);
}
- if (zfs_mount(spa, 0, &zfsmount) != 0) {
- /* Mount failed, don't report this loudly. */
+ if ((err = zfs_mount(spa, 0, &zfsmount)) != 0) {
+ DPRINTF("Failed to mount pool '%s' (%d)\n", spa->spa_name, err);
return (EFI_NOT_FOUND);
}
- if ((err = zfs_lookup(&zfsmount, loader_path, &dn)) != 0) {
- printf("Failed to lookup %s on pool %s (%d)\n", loader_path,
+ if ((err = zfs_lookup(&zfsmount, filepath, &dn)) != 0) {
+ if (err == ENOENT) {
+ DPRINTF("Failed to find '%s' on pool '%s' (%d)\n",
+ filepath, spa->spa_name, err);
+ return (EFI_NOT_FOUND);
+ }
+ printf("Failed to lookup '%s' on pool '%s' (%d)\n", filepath,
spa->spa_name, err);
return (EFI_INVALID_PARAMETER);
}
if ((err = zfs_dnode_stat(spa, &dn, &st)) != 0) {
- printf("Failed to lookup %s on pool %s (%d)\n", loader_path,
+ printf("Failed to stat '%s' on pool '%s' (%d)\n", filepath,
spa->spa_name, err);
return (EFI_INVALID_PARAMETER);
}
if ((status = bs->AllocatePool(EfiLoaderData, (UINTN)st.st_size, &buf))
!= EFI_SUCCESS) {
- printf("Failed to allocate load buffer for pool %s (%lu)\n",
- spa->spa_name, EFI_ERROR_CODE(status));
+ printf("Failed to allocate load buffer %zd for pool '%s' for '%s' "
+ "(%lu)\n", st.st_size, spa->spa_name, filepath, EFI_ERROR_CODE(status));
return (EFI_INVALID_PARAMETER);
}
@@ -144,26 +153,6 @@ try_load(dev_info_t *devinfo, const char *loader_path, void **bufp, size_t *bufs
return (EFI_SUCCESS);
}
-static EFI_STATUS
-load(const char *loader_path, dev_info_t **devinfop, void **bufp,
- size_t *bufsize)
-{
- dev_info_t *devinfo;
- EFI_STATUS status;
-
- for (devinfo = devices; devinfo != NULL; devinfo = devinfo->next) {
- status = try_load(devinfo, loader_path, bufp, bufsize);
- if (status == EFI_SUCCESS) {
- *devinfop = devinfo;
- return (EFI_SUCCESS);
- } else if (status != EFI_NOT_FOUND) {
- return (status);
- }
- }
-
- return (EFI_NOT_FOUND);
-}
-
static void
status()
{
@@ -189,11 +178,19 @@ init()
zfs_init();
}
+static dev_info_t *
+_devices()
+{
+
+ return (devices);
+}
+
const boot_module_t zfs_module =
{
.name = "ZFS",
.init = init,
.probe = probe,
.load = load,
- .status = status
+ .status = status,
+ .devices = _devices
};
diff --git a/sys/boot/efi/include/efidevp.h b/sys/boot/efi/include/efidevp.h
index f0f49ef..dda79de7 100644
--- a/sys/boot/efi/include/efidevp.h
+++ b/sys/boot/efi/include/efidevp.h
@@ -40,9 +40,7 @@ typedef struct _EFI_DEVICE_PATH {
#define EFI_DP_TYPE_MASK 0x7F
#define EFI_DP_TYPE_UNPACKED 0x80
-//#define END_DEVICE_PATH_TYPE 0xff
#define END_DEVICE_PATH_TYPE 0x7f
-//#define END_DEVICE_PATH_TYPE_UNPACKED 0x7f
#define END_ENTIRE_DEVICE_PATH_SUBTYPE 0xff
#define END_INSTANCE_DEVICE_PATH_SUBTYPE 0x01
@@ -56,8 +54,8 @@ typedef struct _EFI_DEVICE_PATH {
#define DevicePathSubType(a) ( (a)->SubType )
#define DevicePathNodeLength(a) ( ((a)->Length[0]) | ((a)->Length[1] << 8) )
#define NextDevicePathNode(a) ( (EFI_DEVICE_PATH *) ( ((UINT8 *) (a)) + DevicePathNodeLength(a)))
-//#define IsDevicePathEndType(a) ( DevicePathType(a) == END_DEVICE_PATH_TYPE_UNPACKED )
-#define IsDevicePathEndType(a) ( DevicePathType(a) == END_DEVICE_PATH_TYPE )
+#define IsDevicePathType(a, t) ( DevicePathType(a) == t )
+#define IsDevicePathEndType(a) IsDevicePathType(a, END_DEVICE_PATH_TYPE)
#define IsDevicePathEndSubType(a) ( (a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE )
#define IsDevicePathEnd(a) ( IsDevicePathEndType(a) && IsDevicePathEndSubType(a) )
#define IsDevicePathUnpacked(a) ( (a)->Type & EFI_DP_TYPE_UNPACKED )
@@ -285,6 +283,13 @@ typedef struct _UART_DEVICE_PATH {
#define DEVICE_PATH_MESSAGING_VT_UTF8 \
{ 0xad15a0d6, 0x8bec, 0x4acf, {0xa0, 0x73, 0xd0, 0x1d, 0xe7, 0x7e, 0x2d, 0x88} }
+#define MSG_SATA_DP 0x12
+typedef struct _SATA_DEVICE_PATH {
+ EFI_DEVICE_PATH Header;
+ UINT16 HBAPortNumber;
+ UINT16 PortMultiplierPortNumber;
+ UINT16 Lun;
+} SATA_DEVICE_PATH;
#define MEDIA_DEVICE_PATH 0x04
diff --git a/sys/boot/efi/libefi/efinet.c b/sys/boot/efi/libefi/efinet.c
index d9ecdcc..b7888aa 100644
--- a/sys/boot/efi/libefi/efinet.c
+++ b/sys/boot/efi/libefi/efinet.c
@@ -309,8 +309,8 @@ efinet_dev_init()
status = BS->OpenProtocol(h, &sn_guid, (void **)&net,
IH, 0, EFI_OPEN_PROTOCOL_EXCLUSIVE);
if (status != EFI_SUCCESS) {
- printf("Unable to open network interface %d\n", i);
- continue;
+ printf("Unable to open network interface %d for "
+ "exclusive access\n", i);
}
dif->dif_unit = i;
diff --git a/sys/boot/zfs/zfs.c b/sys/boot/zfs/zfs.c
index 8e6d420..bf2fc6f8 100644
--- a/sys/boot/zfs/zfs.c
+++ b/sys/boot/zfs/zfs.c
@@ -722,8 +722,6 @@ init_zfs_bootenv(char *currdev)
currdev[strlen(currdev) - 1] = '\0';
setenv("zfs_be_active", currdev, 1);
setenv("zfs_be_currpage", "1", 1);
- /* Do not overwrite if already set */
- setenv("vfs.root.mountfrom", currdev, 0);
/* Forward past zfs: */
currdev = strchr(currdev, ':');
currdev++;
diff --git a/sys/cam/ata/ata_all.c b/sys/cam/ata/ata_all.c
index d836e42..d5220e8 100644
--- a/sys/cam/ata/ata_all.c
+++ b/sys/cam/ata/ata_all.c
@@ -75,13 +75,18 @@ ata_op_string(struct ata_cmd *cmd)
if (cmd->control & 0x04)
return ("SOFT_RESET");
switch (cmd->command) {
- case 0x00: return ("NOP");
+ case 0x00:
+ switch (cmd->features) {
+ case 0x00: return ("NOP FLUSHQUEUE");
+ case 0x01: return ("NOP AUTOPOLL");
+ }
+ return ("NOP");
case 0x03: return ("CFA_REQUEST_EXTENDED_ERROR");
case 0x06:
switch (cmd->features) {
- case 0x01: return ("DSM TRIM");
- }
- return "DSM";
+ case 0x01: return ("DSM TRIM");
+ }
+ return "DSM";
case 0x08: return ("DEVICE_RESET");
case 0x20: return ("READ");
case 0x24: return ("READ48");
@@ -105,6 +110,12 @@ ata_op_string(struct ata_cmd *cmd)
case 0x3f: return ("WRITE_LOG_EXT");
case 0x40: return ("READ_VERIFY");
case 0x42: return ("READ_VERIFY48");
+ case 0x45:
+ switch (cmd->features) {
+ case 0x55: return ("WRITE_UNCORRECTABLE48 PSEUDO");
+ case 0xaa: return ("WRITE_UNCORRECTABLE48 FLAGGED");
+ }
+ return "WRITE_UNCORRECTABLE48";
case 0x51: return ("CONFIGURE_STREAM");
case 0x60: return ("READ_FPDMA_QUEUED");
case 0x61: return ("WRITE_FPDMA_QUEUED");
@@ -128,7 +139,18 @@ ata_op_string(struct ata_cmd *cmd)
case 0xa0: return ("PACKET");
case 0xa1: return ("ATAPI_IDENTIFY");
case 0xa2: return ("SERVICE");
- case 0xb0: return ("SMART");
+ case 0xb0:
+ switch(cmd->features) {
+ case 0xd0: return ("SMART READ ATTR VALUES");
+ case 0xd1: return ("SMART READ ATTR THRESHOLDS");
+ case 0xd3: return ("SMART SAVE ATTR VALUES");
+ case 0xd4: return ("SMART EXECUTE OFFLINE IMMEDIATE");
+ case 0xd5: return ("SMART READ LOG DATA");
+ case 0xd8: return ("SMART ENABLE OPERATION");
+ case 0xd9: return ("SMART DISABLE OPERATION");
+ case 0xda: return ("SMART RETURN STATUS");
+ }
+ return ("SMART");
case 0xb1: return ("DEVICE CONFIGURATION");
case 0xc0: return ("CFA_ERASE");
case 0xc4: return ("READ_MUL");
@@ -158,18 +180,22 @@ ata_op_string(struct ata_cmd *cmd)
case 0xed: return ("MEDIA_EJECT");
case 0xef:
switch (cmd->features) {
- case 0x03: return ("SETFEATURES SET TRANSFER MODE");
- case 0x02: return ("SETFEATURES ENABLE WCACHE");
- case 0x82: return ("SETFEATURES DISABLE WCACHE");
- case 0x06: return ("SETFEATURES ENABLE PUIS");
- case 0x86: return ("SETFEATURES DISABLE PUIS");
- case 0x07: return ("SETFEATURES SPIN-UP");
- case 0x10: return ("SETFEATURES ENABLE SATA FEATURE");
- case 0x90: return ("SETFEATURES DISABLE SATA FEATURE");
- case 0xaa: return ("SETFEATURES ENABLE RCACHE");
- case 0x55: return ("SETFEATURES DISABLE RCACHE");
- }
- return "SETFEATURES";
+ case 0x03: return ("SETFEATURES SET TRANSFER MODE");
+ case 0x02: return ("SETFEATURES ENABLE WCACHE");
+ case 0x82: return ("SETFEATURES DISABLE WCACHE");
+ case 0x06: return ("SETFEATURES ENABLE PUIS");
+ case 0x86: return ("SETFEATURES DISABLE PUIS");
+ case 0x07: return ("SETFEATURES SPIN-UP");
+ case 0x10: return ("SETFEATURES ENABLE SATA FEATURE");
+ case 0x90: return ("SETFEATURES DISABLE SATA FEATURE");
+ case 0xaa: return ("SETFEATURES ENABLE RCACHE");
+ case 0x55: return ("SETFEATURES DISABLE RCACHE");
+ case 0x5d: return ("SETFEATURES ENABLE RELIRQ");
+ case 0xdd: return ("SETFEATURES DISABLE RELIRQ");
+ case 0x5e: return ("SETFEATURES ENABLE SRVIRQ");
+ case 0xde: return ("SETFEATURES DISABLE SRVIRQ");
+ }
+ return "SETFEATURES";
case 0xf1: return ("SECURITY_SET_PASSWORD");
case 0xf2: return ("SECURITY_UNLOCK");
case 0xf3: return ("SECURITY_ERASE_PREPARE");
diff --git a/sys/cddl/dev/fbt/arm/fbt_isa.c b/sys/cddl/dev/fbt/arm/fbt_isa.c
index 0e948dd..2e0e5a5 100644
--- a/sys/cddl/dev/fbt/arm/fbt_isa.c
+++ b/sys/cddl/dev/fbt/arm/fbt_isa.c
@@ -83,7 +83,7 @@ fbt_patch_tracepoint(fbt_probe_t *fbt, fbt_patchval_t val)
{
*fbt->fbtp_patchpoint = val;
- cpu_icache_sync_range((vm_offset_t)fbt->fbtp_patchpoint, sizeof(val));
+ icache_sync((vm_offset_t)fbt->fbtp_patchpoint, sizeof(val));
}
int
diff --git a/sys/compat/cloudabi/cloudabi_proc.c b/sys/compat/cloudabi/cloudabi_proc.c
index d917337..8d0b6e7 100644
--- a/sys/compat/cloudabi/cloudabi_proc.c
+++ b/sys/compat/cloudabi/cloudabi_proc.c
@@ -75,12 +75,16 @@ int
cloudabi_sys_proc_fork(struct thread *td,
struct cloudabi_sys_proc_fork_args *uap)
{
+ struct fork_req fr;
struct filecaps fcaps = {};
- struct proc *p2;
int error, fd;
cap_rights_init(&fcaps.fc_rights, CAP_FSTAT, CAP_EVENT);
- error = fork1(td, RFFDG | RFPROC | RFPROCDESC, 0, &p2, &fd, 0, &fcaps);
+ bzero(&fr, sizeof(fr));
+ fr.fr_flags = RFFDG | RFPROC | RFPROCDESC;
+ fr.fr_pd_fd = &fd;
+ fr.fr_pd_fcaps = &fcaps;
+ error = fork1(td, &fr);
if (error != 0)
return (error);
/* Return the file descriptor to the parent process. */
diff --git a/sys/compat/linux/linux_fork.c b/sys/compat/linux/linux_fork.c
index d0f73ad..c12f198 100644
--- a/sys/compat/linux/linux_fork.c
+++ b/sys/compat/linux/linux_fork.c
@@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$");
int
linux_fork(struct thread *td, struct linux_fork_args *args)
{
+ struct fork_req fr;
int error;
struct proc *p2;
struct thread *td2;
@@ -73,8 +74,10 @@ linux_fork(struct thread *td, struct linux_fork_args *args)
printf(ARGS(fork, ""));
#endif
- if ((error = fork1(td, RFFDG | RFPROC | RFSTOPPED, 0, &p2, NULL, 0,
- NULL)) != 0)
+ bzero(&fr, sizeof(fr));
+ fr.fr_flags = RFFDG | RFPROC | RFSTOPPED;
+ fr.fr_procp = &p2;
+ if ((error = fork1(td, &fr)) != 0)
return (error);
td2 = FIRST_THREAD_IN_PROC(p2);
@@ -97,6 +100,7 @@ linux_fork(struct thread *td, struct linux_fork_args *args)
int
linux_vfork(struct thread *td, struct linux_vfork_args *args)
{
+ struct fork_req fr;
int error;
struct proc *p2;
struct thread *td2;
@@ -106,8 +110,10 @@ linux_vfork(struct thread *td, struct linux_vfork_args *args)
printf(ARGS(vfork, ""));
#endif
- if ((error = fork1(td, RFFDG | RFPROC | RFMEM | RFPPWAIT | RFSTOPPED,
- 0, &p2, NULL, 0, NULL)) != 0)
+ bzero(&fr, sizeof(fr));
+ fr.fr_flags = RFFDG | RFPROC | RFMEM | RFPPWAIT | RFSTOPPED;
+ fr.fr_procp = &p2;
+ if ((error = fork1(td, &fr)) != 0)
return (error);
td2 = FIRST_THREAD_IN_PROC(p2);
@@ -130,6 +136,7 @@ linux_vfork(struct thread *td, struct linux_vfork_args *args)
static int
linux_clone_proc(struct thread *td, struct linux_clone_args *args)
{
+ struct fork_req fr;
int error, ff = RFPROC | RFSTOPPED;
struct proc *p2;
struct thread *td2;
@@ -170,7 +177,10 @@ linux_clone_proc(struct thread *td, struct linux_clone_args *args)
if (args->flags & LINUX_CLONE_VFORK)
ff |= RFPPWAIT;
- error = fork1(td, ff, 0, &p2, NULL, 0, NULL);
+ bzero(&fr, sizeof(fr));
+ fr.fr_flags = ff;
+ fr.fr_procp = &p2;
+ error = fork1(td, &fr);
if (error)
return (error);
diff --git a/sys/conf/files.arm b/sys/conf/files.arm
index 9f3a6bf..bc5d8a3 100644
--- a/sys/conf/files.arm
+++ b/sys/conf/files.arm
@@ -14,14 +14,14 @@ arm/arm/cpufunc_asm.S standard
arm/arm/cpufunc_asm_arm9.S optional cpu_arm9 | cpu_arm9e
arm/arm/cpufunc_asm_arm11.S optional cpu_arm1176
arm/arm/cpufunc_asm_arm11x6.S optional cpu_arm1176
-arm/arm/cpufunc_asm_armv4.S optional cpu_arm9 | cpu_arm9e | cpu_fa526 | cpu_xscale_80321 | cpu_xscale_pxa2x0 | cpu_xscale_ixp425 | cpu_xscale_80219 | cpu_xscale_81342
+arm/arm/cpufunc_asm_armv4.S optional cpu_arm9 | cpu_arm9e | cpu_fa526 | cpu_xscale_pxa2x0 | cpu_xscale_ixp425 | cpu_xscale_81342
arm/arm/cpufunc_asm_armv5_ec.S optional cpu_arm9e
arm/arm/cpufunc_asm_armv6.S optional cpu_arm1176
arm/arm/cpufunc_asm_armv7.S optional cpu_cortexa | cpu_krait | cpu_mv_pj4b
arm/arm/cpufunc_asm_fa526.S optional cpu_fa526
arm/arm/cpufunc_asm_pj4b.S optional cpu_mv_pj4b
arm/arm/cpufunc_asm_sheeva.S optional cpu_arm9e
-arm/arm/cpufunc_asm_xscale.S optional cpu_xscale_80321 | cpu_xscale_pxa2x0 | cpu_xscale_ixp425 | cpu_xscale_80219 | cpu_xscale_81342
+arm/arm/cpufunc_asm_xscale.S optional cpu_xscale_pxa2x0 | cpu_xscale_ixp425 | cpu_xscale_81342
arm/arm/cpufunc_asm_xscale_c3.S optional cpu_xscale_81342
arm/arm/cpuinfo.c standard
arm/arm/cpu_asm-v6.S optional armv6
diff --git a/sys/conf/options b/sys/conf/options
index c7cd5818..f1b2af4 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -918,6 +918,7 @@ VNET_DEBUG opt_global.h
# Common Flash Interface (CFI) options
CFI_SUPPORT_STRATAFLASH opt_cfi.h
CFI_ARMEDANDDANGEROUS opt_cfi.h
+CFI_HARDWAREBYTESWAP opt_cfi.h
# Sound options
SND_DEBUG opt_snd.h
diff --git a/sys/conf/options.arm b/sys/conf/options.arm
index ef66413..7beae5b 100644
--- a/sys/conf/options.arm
+++ b/sys/conf/options.arm
@@ -15,8 +15,6 @@ CPU_CORTEXA opt_global.h
CPU_KRAIT opt_global.h
CPU_FA526 opt_global.h
CPU_MV_PJ4B opt_global.h
-CPU_XSCALE_80219 opt_global.h
-CPU_XSCALE_80321 opt_global.h
CPU_XSCALE_81342 opt_global.h
CPU_XSCALE_IXP425 opt_global.h
CPU_XSCALE_IXP435 opt_global.h
diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c
index 753e8e5..e325f6e 100644
--- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c
+++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c
@@ -48,6 +48,7 @@
#include <vm/vm_phys.h>
#include <machine/bus.h>
+#include <machine/cpu.h>
#include <arm/broadcom/bcm2835/bcm2835_mbox.h>
#include <arm/broadcom/bcm2835/bcm2835_vcbus.h>
@@ -411,6 +412,7 @@ create_pagelist(char __user *buf, size_t count, unsigned short type,
int run, addridx, actual_pages;
int err;
vm_paddr_t pagelist_phys;
+ vm_paddr_t pa;
offset = (vm_offset_t)buf & (PAGE_SIZE - 1);
num_pages = (count + offset + PAGE_SIZE - 1) / PAGE_SIZE;
@@ -533,7 +535,8 @@ create_pagelist(char __user *buf, size_t count, unsigned short type,
(fragments - g_fragments_base)/g_fragment_size;
}
- cpu_dcache_wbinv_range((vm_offset_t)buf, count);
+ pa = pmap_extract(PCPU_GET(curpmap), (vm_offset_t)buf);
+ dcache_wbinv_poc((vm_offset_t)buf, pa, count);
bus_dmamap_sync(bi->pagelist_dma_tag, bi->pagelist_dma_map, BUS_DMASYNC_PREWRITE);
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index 118e38e..8cefa9e 100644
--- a/sys/dev/ata/ata-all.c
+++ b/sys/dev/ata/ata-all.c
@@ -496,7 +496,18 @@ ata_cmd2str(struct ata_request *request)
}
} else {
switch (request->u.ata.command) {
- case 0x00: return ("NOP");
+ case 0x00:
+ switch (request->u.ata.feature) {
+ case 0x00: return ("NOP FLUSHQUEUE");
+ case 0x01: return ("NOP AUTOPOLL");
+ }
+ return ("NOP");
+ case 0x03: return ("CFA_REQUEST_EXTENDED_ERROR");
+ case 0x06:
+ switch (request->u.ata.feature) {
+ case 0x01: return ("DSM TRIM");
+ }
+ return "DSM";
case 0x08: return ("DEVICE_RESET");
case 0x20: return ("READ");
case 0x24: return ("READ48");
@@ -504,18 +515,65 @@ ata_cmd2str(struct ata_request *request)
case 0x26: return ("READ_DMA_QUEUED48");
case 0x27: return ("READ_NATIVE_MAX_ADDRESS48");
case 0x29: return ("READ_MUL48");
+ case 0x2a: return ("READ_STREAM_DMA48");
+ case 0x2b: return ("READ_STREAM48");
+ case 0x2f: return ("READ_LOG_EXT");
case 0x30: return ("WRITE");
case 0x34: return ("WRITE48");
case 0x35: return ("WRITE_DMA48");
case 0x36: return ("WRITE_DMA_QUEUED48");
case 0x37: return ("SET_MAX_ADDRESS48");
case 0x39: return ("WRITE_MUL48");
+ case 0x3a: return ("WRITE_STREAM_DMA48");
+ case 0x3b: return ("WRITE_STREAM48");
+ case 0x3d: return ("WRITE_DMA_FUA48");
+ case 0x3e: return ("WRITE_DMA_QUEUED_FUA48");
+ case 0x3f: return ("WRITE_LOG_EXT");
+ case 0x40: return ("READ_VERIFY");
+ case 0x42: return ("READ_VERIFY48");
+ case 0x45:
+ switch (request->u.ata.feature) {
+ case 0x55: return ("WRITE_UNCORRECTABLE48 PSEUDO");
+ case 0xaa: return ("WRITE_UNCORRECTABLE48 FLAGGED");
+ }
+ return "WRITE_UNCORRECTABLE48";
+ case 0x51: return ("CONFIGURE_STREAM");
+ case 0x60: return ("READ_FPDMA_QUEUED");
+ case 0x61: return ("WRITE_FPDMA_QUEUED");
+ case 0x63: return ("NCQ_NON_DATA");
+ case 0x64: return ("SEND_FPDMA_QUEUED");
+ case 0x65: return ("RECEIVE_FPDMA_QUEUED");
+ case 0x67:
+ if (request->u.ata.feature == 0xec)
+ return ("SEP_ATTN IDENTIFY");
+ switch (request->u.ata.lba) {
+ case 0x00: return ("SEP_ATTN READ BUFFER");
+ case 0x02: return ("SEP_ATTN RECEIVE DIAGNOSTIC RESULTS");
+ case 0x80: return ("SEP_ATTN WRITE BUFFER");
+ case 0x82: return ("SEP_ATTN SEND DIAGNOSTIC");
+ }
+ return ("SEP_ATTN");
case 0x70: return ("SEEK");
- case 0xa0: return ("PACKET_CMD");
+ case 0x87: return ("CFA_TRANSLATE_SECTOR");
+ case 0x90: return ("EXECUTE_DEVICE_DIAGNOSTIC");
+ case 0x92: return ("DOWNLOAD_MICROCODE");
+ case 0xa0: return ("PACKET");
case 0xa1: return ("ATAPI_IDENTIFY");
case 0xa2: return ("SERVICE");
- case 0xb0: return ("SMART");
- case 0xc0: return ("CFA ERASE");
+ case 0xb0:
+ switch(request->u.ata.feature) {
+ case 0xd0: return ("SMART READ ATTR VALUES");
+ case 0xd1: return ("SMART READ ATTR THRESHOLDS");
+ case 0xd3: return ("SMART SAVE ATTR VALUES");
+ case 0xd4: return ("SMART EXECUTE OFFLINE IMMEDIATE");
+ case 0xd5: return ("SMART READ LOG DATA");
+ case 0xd8: return ("SMART ENABLE OPERATION");
+ case 0xd9: return ("SMART DISABLE OPERATION");
+ case 0xda: return ("SMART RETURN STATUS");
+ }
+ return ("SMART");
+ case 0xb1: return ("DEVICE CONFIGURATION");
+ case 0xc0: return ("CFA_ERASE");
case 0xc4: return ("READ_MUL");
case 0xc5: return ("WRITE_MUL");
case 0xc6: return ("SET_MULTI");
@@ -523,22 +581,48 @@ ata_cmd2str(struct ata_request *request)
case 0xc8: return ("READ_DMA");
case 0xca: return ("WRITE_DMA");
case 0xcc: return ("WRITE_DMA_QUEUED");
+ case 0xcd: return ("CFA_WRITE_MULTIPLE_WITHOUT_ERASE");
+ case 0xce: return ("WRITE_MUL_FUA48");
+ case 0xd1: return ("CHECK_MEDIA_CARD_TYPE");
+ case 0xda: return ("GET_MEDIA_STATUS");
+ case 0xde: return ("MEDIA_LOCK");
+ case 0xdf: return ("MEDIA_UNLOCK");
+ case 0xe0: return ("STANDBY_IMMEDIATE");
+ case 0xe1: return ("IDLE_IMMEDIATE");
+ case 0xe2: return ("STANDBY");
+ case 0xe3: return ("IDLE");
+ case 0xe4: return ("READ_BUFFER/PM");
+ case 0xe5: return ("CHECK_POWER_MODE");
case 0xe6: return ("SLEEP");
case 0xe7: return ("FLUSHCACHE");
+ case 0xe8: return ("WRITE_PM");
case 0xea: return ("FLUSHCACHE48");
case 0xec: return ("ATA_IDENTIFY");
+ case 0xed: return ("MEDIA_EJECT");
case 0xef:
switch (request->u.ata.feature) {
case 0x03: return ("SETFEATURES SET TRANSFER MODE");
case 0x02: return ("SETFEATURES ENABLE WCACHE");
case 0x82: return ("SETFEATURES DISABLE WCACHE");
+ case 0x06: return ("SETFEATURES ENABLE PUIS");
+ case 0x86: return ("SETFEATURES DISABLE PUIS");
+ case 0x07: return ("SETFEATURES SPIN-UP");
+ case 0x10: return ("SETFEATURES ENABLE SATA FEATURE");
+ case 0x90: return ("SETFEATURES DISABLE SATA FEATURE");
case 0xaa: return ("SETFEATURES ENABLE RCACHE");
case 0x55: return ("SETFEATURES DISABLE RCACHE");
+ case 0x5d: return ("SETFEATURES ENABLE RELIRQ");
+ case 0xdd: return ("SETFEATURES DISABLE RELIRQ");
+ case 0x5e: return ("SETFEATURES ENABLE SRVIRQ");
+ case 0xde: return ("SETFEATURES DISABLE SRVIRQ");
}
- sprintf(buffer, "SETFEATURES 0x%02x",
- request->u.ata.feature);
- return (buffer);
- case 0xf5: return ("SECURITY_FREE_LOCK");
+ return "SETFEATURES";
+ case 0xf1: return ("SECURITY_SET_PASSWORD");
+ case 0xf2: return ("SECURITY_UNLOCK");
+ case 0xf3: return ("SECURITY_ERASE_PREPARE");
+ case 0xf4: return ("SECURITY_ERASE_UNIT");
+ case 0xf5: return ("SECURITY_FREEZE_LOCK");
+ case 0xf6: return ("SECURITY_DISABLE_PASSWORD");
case 0xf8: return ("READ_NATIVE_MAX_ADDRESS");
case 0xf9: return ("SET_MAX_ADDRESS");
}
diff --git a/sys/dev/cfi/cfi_core.c b/sys/dev/cfi/cfi_core.c
index 5150b77..d292e1a 100644
--- a/sys/dev/cfi/cfi_core.c
+++ b/sys/dev/cfi/cfi_core.c
@@ -99,11 +99,17 @@ cfi_read(struct cfi_softc *sc, u_int ofs)
break;
case 2:
sval = bus_space_read_2(sc->sc_tag, sc->sc_handle, ofs);
+#ifdef CFI_HARDWAREBYTESWAP
+ val = sval;
+#else
val = le16toh(sval);
+#endif
break;
case 4:
val = bus_space_read_4(sc->sc_tag, sc->sc_handle, ofs);
+#ifndef CFI_HARDWAREBYTESWAP
val = le32toh(val);
+#endif
break;
default:
val = ~0;
@@ -122,10 +128,19 @@ cfi_write(struct cfi_softc *sc, u_int ofs, u_int val)
bus_space_write_1(sc->sc_tag, sc->sc_handle, ofs, val);
break;
case 2:
+#ifdef CFI_HARDWAREBYTESWAP
+ bus_space_write_2(sc->sc_tag, sc->sc_handle, ofs, val);
+#else
bus_space_write_2(sc->sc_tag, sc->sc_handle, ofs, htole16(val));
+
+#endif
break;
case 4:
+#ifdef CFI_HARDWAREBYTESWAP
+ bus_space_write_4(sc->sc_tag, sc->sc_handle, ofs, val);
+#else
bus_space_write_4(sc->sc_tag, sc->sc_handle, ofs, htole32(val));
+#endif
break;
}
}
diff --git a/sys/dev/cxgb/cxgb_sge.c b/sys/dev/cxgb/cxgb_sge.c
index d70a948..2cfad26 100644
--- a/sys/dev/cxgb/cxgb_sge.c
+++ b/sys/dev/cxgb/cxgb_sge.c
@@ -738,7 +738,7 @@ refill_fl(adapter_t *sc, struct sge_fl *q, int n)
cl, q->buf_size, refill_fl_cb, &cb_arg, 0);
if (err != 0 || cb_arg.error) {
- if (q->zone == zone_pack)
+ if (q->zone != zone_pack)
uma_zfree(q->zone, cl);
m_free(m);
goto done;
diff --git a/sys/dev/e1000/e1000_80003es2lan.c b/sys/dev/e1000/e1000_80003es2lan.c
index b948bb4..e7c42d5 100644
--- a/sys/dev/e1000/e1000_80003es2lan.c
+++ b/sys/dev/e1000/e1000_80003es2lan.c
@@ -851,11 +851,17 @@ static s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw)
e1000_release_phy_80003es2lan(hw);
/* Disable IBIST slave mode (far-end loopback) */
- e1000_read_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_INBAND_PARAM,
- &kum_reg_data);
- kum_reg_data |= E1000_KMRNCTRLSTA_IBIST_DISABLE;
- e1000_write_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_INBAND_PARAM,
- kum_reg_data);
+ ret_val = e1000_read_kmrn_reg_80003es2lan(hw,
+ E1000_KMRNCTRLSTA_INBAND_PARAM, &kum_reg_data);
+ if (!ret_val) {
+ kum_reg_data |= E1000_KMRNCTRLSTA_IBIST_DISABLE;
+ ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
+ E1000_KMRNCTRLSTA_INBAND_PARAM,
+ kum_reg_data);
+ if (ret_val)
+ DEBUGOUT("Error disabling far-end loopback\n");
+ } else
+ DEBUGOUT("Error disabling far-end loopback\n");
ret_val = e1000_get_auto_rd_done_generic(hw);
if (ret_val)
@@ -911,11 +917,18 @@ static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw)
return ret_val;
/* Disable IBIST slave mode (far-end loopback) */
- e1000_read_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_INBAND_PARAM,
- &kum_reg_data);
- kum_reg_data |= E1000_KMRNCTRLSTA_IBIST_DISABLE;
- e1000_write_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_INBAND_PARAM,
- kum_reg_data);
+ ret_val =
+ e1000_read_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_INBAND_PARAM,
+ &kum_reg_data);
+ if (!ret_val) {
+ kum_reg_data |= E1000_KMRNCTRLSTA_IBIST_DISABLE;
+ ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
+ E1000_KMRNCTRLSTA_INBAND_PARAM,
+ kum_reg_data);
+ if (ret_val)
+ DEBUGOUT("Error disabling far-end loopback\n");
+ } else
+ DEBUGOUT("Error disabling far-end loopback\n");
/* Set the transmit descriptor write-back policy */
reg_data = E1000_READ_REG(hw, E1000_TXDCTL(0));
diff --git a/sys/dev/e1000/e1000_82540.c b/sys/dev/e1000/e1000_82540.c
index 68f92c6..2d03b8f 100644
--- a/sys/dev/e1000/e1000_82540.c
+++ b/sys/dev/e1000/e1000_82540.c
@@ -66,7 +66,7 @@ static s32 e1000_read_mac_addr_82540(struct e1000_hw *hw);
static s32 e1000_init_phy_params_82540(struct e1000_hw *hw)
{
struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val = E1000_SUCCESS;
+ s32 ret_val;
phy->addr = 1;
phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
@@ -329,7 +329,7 @@ static s32 e1000_init_hw_82540(struct e1000_hw *hw)
{
struct e1000_mac_info *mac = &hw->mac;
u32 txdctl, ctrl_ext;
- s32 ret_val = E1000_SUCCESS;
+ s32 ret_val;
u16 i;
DEBUGFUNC("e1000_init_hw_82540");
@@ -411,7 +411,7 @@ static s32 e1000_init_hw_82540(struct e1000_hw *hw)
static s32 e1000_setup_copper_link_82540(struct e1000_hw *hw)
{
u32 ctrl;
- s32 ret_val = E1000_SUCCESS;
+ s32 ret_val;
u16 data;
DEBUGFUNC("e1000_setup_copper_link_82540");
@@ -498,7 +498,7 @@ out:
**/
static s32 e1000_adjust_serdes_amplitude_82540(struct e1000_hw *hw)
{
- s32 ret_val = E1000_SUCCESS;
+ s32 ret_val;
u16 nvm_data;
DEBUGFUNC("e1000_adjust_serdes_amplitude_82540");
@@ -528,7 +528,7 @@ out:
**/
static s32 e1000_set_vco_speed_82540(struct e1000_hw *hw)
{
- s32 ret_val = E1000_SUCCESS;
+ s32 ret_val;
u16 default_page = 0;
u16 phy_data;
diff --git a/sys/dev/e1000/e1000_82541.c b/sys/dev/e1000/e1000_82541.c
index 5961555..55d51087 100644
--- a/sys/dev/e1000/e1000_82541.c
+++ b/sys/dev/e1000/e1000_82541.c
@@ -85,7 +85,7 @@ static const u16 e1000_igp_cable_length_table[] = {
static s32 e1000_init_phy_params_82541(struct e1000_hw *hw)
{
struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val = E1000_SUCCESS;
+ s32 ret_val;
DEBUGFUNC("e1000_init_phy_params_82541");
@@ -295,7 +295,7 @@ void e1000_init_function_pointers_82541(struct e1000_hw *hw)
**/
static s32 e1000_reset_hw_82541(struct e1000_hw *hw)
{
- u32 ledctl, ctrl, icr, manc;
+ u32 ledctl, ctrl, manc;
DEBUGFUNC("e1000_reset_hw_82541");
@@ -317,6 +317,7 @@ static s32 e1000_reset_hw_82541(struct e1000_hw *hw)
/* Must reset the Phy before resetting the MAC */
if ((hw->mac.type == e1000_82541) || (hw->mac.type == e1000_82547)) {
E1000_WRITE_REG(hw, E1000_CTRL, (ctrl | E1000_CTRL_PHY_RST));
+ E1000_WRITE_FLUSH(hw);
msec_delay(5);
}
@@ -359,7 +360,7 @@ static s32 e1000_reset_hw_82541(struct e1000_hw *hw)
E1000_WRITE_REG(hw, E1000_IMC, 0xFFFFFFFF);
/* Clear any pending interrupt events. */
- icr = E1000_READ_REG(hw, E1000_ICR);
+ E1000_READ_REG(hw, E1000_ICR);
return E1000_SUCCESS;
}
diff --git a/sys/dev/e1000/e1000_82542.c b/sys/dev/e1000/e1000_82542.c
index b2d676e..4cca9b2 100644
--- a/sys/dev/e1000/e1000_82542.c
+++ b/sys/dev/e1000/e1000_82542.c
@@ -317,7 +317,7 @@ static s32 e1000_init_hw_82542(struct e1000_hw *hw)
static s32 e1000_setup_link_82542(struct e1000_hw *hw)
{
struct e1000_mac_info *mac = &hw->mac;
- s32 ret_val = E1000_SUCCESS;
+ s32 ret_val;
DEBUGFUNC("e1000_setup_link_82542");
@@ -565,7 +565,7 @@ static void e1000_clear_hw_cntrs_82542(struct e1000_hw *hw)
*
* Reads the device MAC address from the EEPROM and stores the value.
**/
-static s32 e1000_read_mac_addr_82542(struct e1000_hw *hw)
+s32 e1000_read_mac_addr_82542(struct e1000_hw *hw)
{
s32 ret_val = E1000_SUCCESS;
u16 offset, nvm_data, i;
diff --git a/sys/dev/e1000/e1000_82543.c b/sys/dev/e1000/e1000_82543.c
index b9a53bd..474387d 100644
--- a/sys/dev/e1000/e1000_82543.c
+++ b/sys/dev/e1000/e1000_82543.c
@@ -900,7 +900,7 @@ static s32 e1000_phy_hw_reset_82543(struct e1000_hw *hw)
**/
static s32 e1000_reset_hw_82543(struct e1000_hw *hw)
{
- u32 ctrl, icr;
+ u32 ctrl;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_reset_hw_82543");
@@ -942,7 +942,7 @@ static s32 e1000_reset_hw_82543(struct e1000_hw *hw)
/* Masking off and clearing any pending interrupts */
E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
- icr = E1000_READ_REG(hw, E1000_ICR);
+ E1000_READ_REG(hw, E1000_ICR);
return ret_val;
}
diff --git a/sys/dev/e1000/e1000_82571.h b/sys/dev/e1000/e1000_82571.h
index 1d7718e..8e5ca56 100644
--- a/sys/dev/e1000/e1000_82571.h
+++ b/sys/dev/e1000/e1000_82571.h
@@ -50,9 +50,10 @@
#define E1000_EIAC_82574 0x000DC /* Ext. Interrupt Auto Clear - RW */
#define E1000_EIAC_MASK_82574 0x01F00000
-#define E1000_NVM_INIT_CTRL2_MNGM 0x6000 /* Manageability Operation Mode mask */
+#define E1000_IVAR_INT_ALLOC_VALID 0x8
-#define E1000_RXCFGL 0x0B634 /* TimeSync Rx EtherType & Msg Type Reg - RW */
+/* Manageability Operation Mode mask */
+#define E1000_NVM_INIT_CTRL2_MNGM 0x6000
#define E1000_BASE1000T_STATUS 10
#define E1000_IDLE_ERROR_COUNT_MASK 0xFF
diff --git a/sys/dev/e1000/e1000_82575.c b/sys/dev/e1000/e1000_82575.c
index 10653f8..38770a3 100644
--- a/sys/dev/e1000/e1000_82575.c
+++ b/sys/dev/e1000/e1000_82575.c
@@ -278,6 +278,11 @@ static s32 e1000_init_phy_params_82575(struct e1000_hw *hw)
if (ret_val)
goto out;
}
+ if (phy->id == M88E1543_E_PHY_ID) {
+ ret_val = e1000_initialize_M88E1543_phy(hw);
+ if (ret_val)
+ goto out;
+ }
break;
case IGP03E1000_E_PHY_ID:
case IGP04E1000_E_PHY_ID:
@@ -1235,7 +1240,7 @@ static s32 e1000_check_for_link_media_swap(struct e1000_hw *hw)
DEBUGFUNC("e1000_check_for_link_media_swap");
- /* Check the copper medium. */
+ /* Check for copper. */
ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 0);
if (ret_val)
return ret_val;
@@ -1247,7 +1252,7 @@ static s32 e1000_check_for_link_media_swap(struct e1000_hw *hw)
if (data & E1000_M88E1112_STATUS_LINK)
port = E1000_MEDIA_PORT_COPPER;
- /* Check the other medium. */
+ /* Check for other. */
ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 1);
if (ret_val)
return ret_val;
@@ -1256,11 +1261,6 @@ static s32 e1000_check_for_link_media_swap(struct e1000_hw *hw)
if (ret_val)
return ret_val;
- /* reset page to 0 */
- ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 0);
- if (ret_val)
- return ret_val;
-
if (data & E1000_M88E1112_STATUS_LINK)
port = E1000_MEDIA_PORT_OTHER;
@@ -1268,8 +1268,20 @@ static s32 e1000_check_for_link_media_swap(struct e1000_hw *hw)
if (port && (hw->dev_spec._82575.media_port != port)) {
hw->dev_spec._82575.media_port = port;
hw->dev_spec._82575.media_changed = TRUE;
+ }
+
+ if (port == E1000_MEDIA_PORT_COPPER) {
+ /* reset page to 0 */
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 0);
+ if (ret_val)
+ return ret_val;
+ e1000_check_for_link_82575(hw);
} else {
- ret_val = e1000_check_for_link_82575(hw);
+ e1000_check_for_link_82575(hw);
+ /* reset page to 0 */
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 0);
+ if (ret_val)
+ return ret_val;
}
return E1000_SUCCESS;
@@ -2136,7 +2148,13 @@ void e1000_rx_fifo_flush_82575(struct e1000_hw *hw)
u32 rctl, rlpml, rxdctl[4], rfctl, temp_rctl, rx_enabled;
int i, ms_wait;
- DEBUGFUNC("e1000_rx_fifo_workaround_82575");
+ DEBUGFUNC("e1000_rx_fifo_flush_82575");
+
+ /* disable IPv6 options as per hardware errata */
+ rfctl = E1000_READ_REG(hw, E1000_RFCTL);
+ rfctl |= E1000_RFCTL_IPV6_EX_DIS;
+ E1000_WRITE_REG(hw, E1000_RFCTL, rfctl);
+
if (hw->mac.type != e1000_82575 ||
!(E1000_READ_REG(hw, E1000_MANC) & E1000_MANC_RCV_TCO_EN))
return;
@@ -2164,7 +2182,6 @@ void e1000_rx_fifo_flush_82575(struct e1000_hw *hw)
* incoming packets are rejected. Set enable and wait 2ms so that
* any packet that was coming in as RCTL.EN was set is flushed
*/
- rfctl = E1000_READ_REG(hw, E1000_RFCTL);
E1000_WRITE_REG(hw, E1000_RFCTL, rfctl & ~E1000_RFCTL_LEF);
rlpml = E1000_READ_REG(hw, E1000_RLPML);
@@ -2806,7 +2823,7 @@ s32 e1000_read_emi_reg(struct e1000_hw *hw, u16 addr, u16 *data)
* e1000_initialize_M88E1512_phy - Initialize M88E1512 PHY
* @hw: pointer to the HW structure
*
- * Initialize Marverl 1512 to work correctly with Avoton.
+ * Initialize Marvell 1512 to work correctly with Avoton.
**/
s32 e1000_initialize_M88E1512_phy(struct e1000_hw *hw)
{
@@ -2892,13 +2909,114 @@ out:
}
/**
+ * e1000_initialize_M88E1543_phy - Initialize M88E1543 PHY
+ * @hw: pointer to the HW structure
+ *
+ * Initialize Marvell 1543 to work correctly with Avoton.
+ **/
+s32 e1000_initialize_M88E1543_phy(struct e1000_hw *hw)
+{
+ struct e1000_phy_info *phy = &hw->phy;
+ s32 ret_val = E1000_SUCCESS;
+
+ DEBUGFUNC("e1000_initialize_M88E1543_phy");
+
+ /* Check if this is correct PHY. */
+ if (phy->id != M88E1543_E_PHY_ID)
+ goto out;
+
+ /* Switch to PHY page 0xFF. */
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x00FF);
+ if (ret_val)
+ goto out;
+
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0x214B);
+ if (ret_val)
+ goto out;
+
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2144);
+ if (ret_val)
+ goto out;
+
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0x0C28);
+ if (ret_val)
+ goto out;
+
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2146);
+ if (ret_val)
+ goto out;
+
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0xB233);
+ if (ret_val)
+ goto out;
+
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x214D);
+ if (ret_val)
+ goto out;
+
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0xDC0C);
+ if (ret_val)
+ goto out;
+
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2159);
+ if (ret_val)
+ goto out;
+
+ /* Switch to PHY page 0xFB. */
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x00FB);
+ if (ret_val)
+ goto out;
+
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_3, 0xC00D);
+ if (ret_val)
+ goto out;
+
+ /* Switch to PHY page 0x12. */
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x12);
+ if (ret_val)
+ goto out;
+
+ /* Change mode to SGMII-to-Copper */
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1512_MODE, 0x8001);
+ if (ret_val)
+ goto out;
+
+ /* Switch to PHY page 1. */
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x1);
+ if (ret_val)
+ goto out;
+
+ /* Change mode to 1000BASE-X/SGMII and autoneg enable; reset */
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1543_FIBER_CTRL, 0x9140);
+ if (ret_val)
+ goto out;
+
+ /* Return the PHY to page 0. */
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0);
+ if (ret_val)
+ goto out;
+
+ ret_val = phy->ops.commit(hw);
+ if (ret_val) {
+ DEBUGOUT("Error committing the PHY changes\n");
+ return ret_val;
+ }
+
+ msec_delay(1000);
+out:
+ return ret_val;
+}
+
+/**
* e1000_set_eee_i350 - Enable/disable EEE support
* @hw: pointer to the HW structure
+ * @adv1g: boolean flag enabling 1G EEE advertisement
+ * @adv100m: boolean flag enabling 100M EEE advertisement
*
* Enable/disable EEE based on setting in dev_spec structure.
*
**/
-s32 e1000_set_eee_i350(struct e1000_hw *hw)
+s32 e1000_set_eee_i350(struct e1000_hw *hw, bool adv1G, bool adv100M)
{
u32 ipcnfg, eeer;
@@ -2914,7 +3032,16 @@ s32 e1000_set_eee_i350(struct e1000_hw *hw)
if (!(hw->dev_spec._82575.eee_disable)) {
u32 eee_su = E1000_READ_REG(hw, E1000_EEE_SU);
- ipcnfg |= (E1000_IPCNFG_EEE_1G_AN | E1000_IPCNFG_EEE_100M_AN);
+ if (adv100M)
+ ipcnfg |= E1000_IPCNFG_EEE_100M_AN;
+ else
+ ipcnfg &= ~E1000_IPCNFG_EEE_100M_AN;
+
+ if (adv1G)
+ ipcnfg |= E1000_IPCNFG_EEE_1G_AN;
+ else
+ ipcnfg &= ~E1000_IPCNFG_EEE_1G_AN;
+
eeer |= (E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN |
E1000_EEER_LPI_FC);
@@ -2938,11 +3065,13 @@ out:
/**
* e1000_set_eee_i354 - Enable/disable EEE support
* @hw: pointer to the HW structure
+ * @adv1g: boolean flag enabling 1G EEE advertisement
+ * @adv100m: boolean flag enabling 100M EEE advertisement
*
* Enable/disable EEE legacy mode based on setting in dev_spec structure.
*
**/
-s32 e1000_set_eee_i354(struct e1000_hw *hw)
+s32 e1000_set_eee_i354(struct e1000_hw *hw, bool adv1G, bool adv100M)
{
struct e1000_phy_info *phy = &hw->phy;
s32 ret_val = E1000_SUCCESS;
@@ -2984,8 +3113,16 @@ s32 e1000_set_eee_i354(struct e1000_hw *hw)
if (ret_val)
goto out;
- phy_data |= E1000_EEE_ADV_100_SUPPORTED |
- E1000_EEE_ADV_1000_SUPPORTED;
+ if (adv100M)
+ phy_data |= E1000_EEE_ADV_100_SUPPORTED;
+ else
+ phy_data &= ~E1000_EEE_ADV_100_SUPPORTED;
+
+ if (adv1G)
+ phy_data |= E1000_EEE_ADV_1000_SUPPORTED;
+ else
+ phy_data &= ~E1000_EEE_ADV_1000_SUPPORTED;
+
ret_val = e1000_write_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
E1000_EEE_ADV_DEV_I354,
phy_data);
diff --git a/sys/dev/e1000/e1000_82575.h b/sys/dev/e1000/e1000_82575.h
index 503fdce..45fe132 100644
--- a/sys/dev/e1000/e1000_82575.h
+++ b/sys/dev/e1000/e1000_82575.h
@@ -495,10 +495,11 @@ void e1000_rlpml_set_vf(struct e1000_hw *, u16);
s32 e1000_promisc_set_vf(struct e1000_hw *, enum e1000_promisc_type type);
u16 e1000_rxpbs_adjust_82580(u32 data);
s32 e1000_read_emi_reg(struct e1000_hw *hw, u16 addr, u16 *data);
-s32 e1000_set_eee_i350(struct e1000_hw *);
-s32 e1000_set_eee_i354(struct e1000_hw *);
+s32 e1000_set_eee_i350(struct e1000_hw *hw, bool adv1G, bool adv100M);
+s32 e1000_set_eee_i354(struct e1000_hw *hw, bool adv1G, bool adv100M);
s32 e1000_get_eee_status_i354(struct e1000_hw *, bool *);
s32 e1000_initialize_M88E1512_phy(struct e1000_hw *hw);
+s32 e1000_initialize_M88E1543_phy(struct e1000_hw *hw);
/* I2C SDA and SCL timing parameters for standard mode */
#define E1000_I2C_T_HD_STA 4
diff --git a/sys/dev/e1000/e1000_api.c b/sys/dev/e1000/e1000_api.c
index 5db22db..28379cc 100644
--- a/sys/dev/e1000/e1000_api.c
+++ b/sys/dev/e1000/e1000_api.c
@@ -299,6 +299,13 @@ s32 e1000_set_mac_type(struct e1000_hw *hw)
case E1000_DEV_ID_PCH_I218_V3:
mac->type = e1000_pch_lpt;
break;
+ case E1000_DEV_ID_PCH_SPT_I219_LM:
+ case E1000_DEV_ID_PCH_SPT_I219_V:
+ case E1000_DEV_ID_PCH_SPT_I219_LM2:
+ case E1000_DEV_ID_PCH_SPT_I219_V2:
+ case E1000_DEV_ID_PCH_LBG_I219_LM3:
+ mac->type = e1000_pch_spt;
+ break;
case E1000_DEV_ID_82575EB_COPPER:
case E1000_DEV_ID_82575EB_FIBER_SERDES:
case E1000_DEV_ID_82575GB_QUAD_COPPER:
@@ -449,6 +456,7 @@ s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device)
case e1000_pchlan:
case e1000_pch2lan:
case e1000_pch_lpt:
+ case e1000_pch_spt:
e1000_init_function_pointers_ich8lan(hw);
break;
case e1000_82575:
diff --git a/sys/dev/e1000/e1000_defines.h b/sys/dev/e1000/e1000_defines.h
index 9472ca4..e33fe0f 100644
--- a/sys/dev/e1000/e1000_defines.h
+++ b/sys/dev/e1000/e1000_defines.h
@@ -197,6 +197,8 @@
#define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */
#define E1000_RCTL_DTYP_PS 0x00000400 /* Packet Split descriptor */
#define E1000_RCTL_RDMTS_HALF 0x00000000 /* Rx desc min thresh size */
+#define E1000_RCTL_RDMTS_HEX 0x00010000
+#define E1000_RCTL_RDMTS1_HEX E1000_RCTL_RDMTS_HEX
#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */
#define E1000_RCTL_MO_3 0x00003000 /* multicast offset 15:4 */
#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */
@@ -753,6 +755,12 @@
#define E1000_TSYNCTXCTL_VALID 0x00000001 /* Tx timestamp valid */
#define E1000_TSYNCTXCTL_ENABLED 0x00000010 /* enable Tx timestamping */
+/* HH Time Sync */
+#define E1000_TSYNCTXCTL_MAX_ALLOWED_DLY_MASK 0x0000F000 /* max delay */
+#define E1000_TSYNCTXCTL_SYNC_COMP_ERR 0x20000000 /* sync err */
+#define E1000_TSYNCTXCTL_SYNC_COMP 0x40000000 /* sync complete */
+#define E1000_TSYNCTXCTL_START_SYNC 0x80000000 /* initiate sync */
+
#define E1000_TSYNCRXCTL_VALID 0x00000001 /* Rx timestamp valid */
#define E1000_TSYNCRXCTL_TYPE_MASK 0x0000000E /* Rx type mask */
#define E1000_TSYNCRXCTL_TYPE_L2_V2 0x00
@@ -849,6 +857,7 @@
#define E1000_M88E1543_PAGE_ADDR 0x16 /* Page Offset Register */
#define E1000_M88E1543_EEE_CTRL_1 0x0
#define E1000_M88E1543_EEE_CTRL_1_MS 0x0001 /* EEE Master/Slave */
+#define E1000_M88E1543_FIBER_CTRL 0x0 /* Fiber Control Register */
#define E1000_EEE_ADV_DEV_I354 7
#define E1000_EEE_ADV_ADDR_I354 60
#define E1000_EEE_ADV_100_SUPPORTED (1 << 1) /* 100BaseTx EEE Supported */
@@ -1020,9 +1029,7 @@
/* NVM Addressing bits based on type 0=small, 1=large */
#define E1000_EECD_ADDR_BITS 0x00000400
#define E1000_EECD_TYPE 0x00002000 /* NVM Type (1-SPI, 0-Microwire) */
-#ifndef E1000_NVM_GRANT_ATTEMPTS
#define E1000_NVM_GRANT_ATTEMPTS 1000 /* NVM # attempts to gain grant */
-#endif
#define E1000_EECD_AUTO_RD 0x00000200 /* NVM Auto Read done */
#define E1000_EECD_SIZE_EX_MASK 0x00007800 /* NVM Size */
#define E1000_EECD_SIZE_EX_SHIFT 11
diff --git a/sys/dev/e1000/e1000_hw.h b/sys/dev/e1000/e1000_hw.h
index 8ae4b20..1792e14 100644
--- a/sys/dev/e1000/e1000_hw.h
+++ b/sys/dev/e1000/e1000_hw.h
@@ -137,6 +137,11 @@ struct e1000_hw;
#define E1000_DEV_ID_PCH_I218_V2 0x15A1
#define E1000_DEV_ID_PCH_I218_LM3 0x15A2 /* Wildcat Point PCH */
#define E1000_DEV_ID_PCH_I218_V3 0x15A3 /* Wildcat Point PCH */
+#define E1000_DEV_ID_PCH_SPT_I219_LM 0x156F /* Sunrise Point PCH */
+#define E1000_DEV_ID_PCH_SPT_I219_V 0x1570 /* Sunrise Point PCH */
+#define E1000_DEV_ID_PCH_SPT_I219_LM2 0x15B7 /* Sunrise Point-H PCH */
+#define E1000_DEV_ID_PCH_SPT_I219_V2 0x15B8 /* Sunrise Point-H PCH */
+#define E1000_DEV_ID_PCH_LBG_I219_LM3 0x15B9 /* LEWISBURG PCH */
#define E1000_DEV_ID_82576 0x10C9
#define E1000_DEV_ID_82576_FIBER 0x10E6
#define E1000_DEV_ID_82576_SERDES 0x10E7
@@ -222,6 +227,7 @@ enum e1000_mac_type {
e1000_pchlan,
e1000_pch2lan,
e1000_pch_lpt,
+ e1000_pch_spt,
e1000_82575,
e1000_82576,
e1000_82580,
@@ -805,7 +811,7 @@ struct e1000_mac_info {
enum e1000_serdes_link_state serdes_link_state;
bool serdes_has_link;
bool tx_pkt_filtering;
- u32 max_frame_size;
+ u32 max_frame_size;
};
struct e1000_phy_info {
diff --git a/sys/dev/e1000/e1000_i210.c b/sys/dev/e1000/e1000_i210.c
index 563f11a..cd8d7c7 100644
--- a/sys/dev/e1000/e1000_i210.c
+++ b/sys/dev/e1000/e1000_i210.c
@@ -883,6 +883,35 @@ static s32 e1000_pll_workaround_i210(struct e1000_hw *hw)
}
/**
+ * e1000_get_cfg_done_i210 - Read config done bit
+ * @hw: pointer to the HW structure
+ *
+ * Read the management control register for the config done bit for
+ * completion status. NOTE: silicon which is EEPROM-less will fail trying
+ * to read the config done bit, so an error is *ONLY* logged and returns
+ * E1000_SUCCESS. If we were to return with error, EEPROM-less silicon
+ * would not be able to be reset or change link.
+ **/
+static s32 e1000_get_cfg_done_i210(struct e1000_hw *hw)
+{
+ s32 timeout = PHY_CFG_TIMEOUT;
+ u32 mask = E1000_NVM_CFG_DONE_PORT_0;
+
+ DEBUGFUNC("e1000_get_cfg_done_i210");
+
+ while (timeout) {
+ if (E1000_READ_REG(hw, E1000_EEMNGCTL_I210) & mask)
+ break;
+ msec_delay(1);
+ timeout--;
+ }
+ if (!timeout)
+ DEBUGOUT("MNG configuration cycle has not completed.\n");
+
+ return E1000_SUCCESS;
+}
+
+/**
* e1000_init_hw_i210 - Init hw for I210/I211
* @hw: pointer to the HW structure
*
@@ -899,6 +928,7 @@ s32 e1000_init_hw_i210(struct e1000_hw *hw)
if (ret_val != E1000_SUCCESS)
return ret_val;
}
+ hw->phy.ops.get_cfg_done = e1000_get_cfg_done_i210;
ret_val = e1000_init_hw_82575(hw);
return ret_val;
}
diff --git a/sys/dev/e1000/e1000_ich8lan.c b/sys/dev/e1000/e1000_ich8lan.c
index 75fcade..9b9a090 100644
--- a/sys/dev/e1000/e1000_ich8lan.c
+++ b/sys/dev/e1000/e1000_ich8lan.c
@@ -92,10 +92,13 @@ static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw,
bool active);
static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset,
u16 words, u16 *data);
+static s32 e1000_read_nvm_spt(struct e1000_hw *hw, u16 offset, u16 words,
+ u16 *data);
static s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset,
u16 words, u16 *data);
static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw);
static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw);
+static s32 e1000_update_nvm_checksum_spt(struct e1000_hw *hw);
static s32 e1000_valid_led_default_ich8lan(struct e1000_hw *hw,
u16 *data);
static s32 e1000_id_led_init_pchlan(struct e1000_hw *hw);
@@ -123,6 +126,14 @@ static s32 e1000_read_flash_byte_ich8lan(struct e1000_hw *hw,
u32 offset, u8 *data);
static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
u8 size, u16 *data);
+static s32 e1000_read_flash_data32_ich8lan(struct e1000_hw *hw, u32 offset,
+ u32 *data);
+static s32 e1000_read_flash_dword_ich8lan(struct e1000_hw *hw,
+ u32 offset, u32 *data);
+static s32 e1000_write_flash_data32_ich8lan(struct e1000_hw *hw,
+ u32 offset, u32 data);
+static s32 e1000_retry_write_flash_dword_ich8lan(struct e1000_hw *hw,
+ u32 offset, u32 dword);
static s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw,
u32 offset, u16 *data);
static s32 e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw,
@@ -232,16 +243,21 @@ static bool e1000_phy_is_accessible_pchlan(struct e1000_hw *hw)
if (ret_val)
return FALSE;
out:
- if (hw->mac.type == e1000_pch_lpt) {
- /* Unforce SMBus mode in PHY */
- hw->phy.ops.read_reg_locked(hw, CV_SMB_CTRL, &phy_reg);
- phy_reg &= ~CV_SMB_CTRL_FORCE_SMBUS;
- hw->phy.ops.write_reg_locked(hw, CV_SMB_CTRL, phy_reg);
+ if ((hw->mac.type == e1000_pch_lpt) ||
+ (hw->mac.type == e1000_pch_spt)) {
+ /* Only unforce SMBus if ME is not active */
+ if (!(E1000_READ_REG(hw, E1000_FWSM) &
+ E1000_ICH_FWSM_FW_VALID)) {
+ /* Unforce SMBus mode in PHY */
+ hw->phy.ops.read_reg_locked(hw, CV_SMB_CTRL, &phy_reg);
+ phy_reg &= ~CV_SMB_CTRL_FORCE_SMBUS;
+ hw->phy.ops.write_reg_locked(hw, CV_SMB_CTRL, phy_reg);
- /* Unforce SMBus mode in MAC */
- mac_reg = E1000_READ_REG(hw, E1000_CTRL_EXT);
- mac_reg &= ~E1000_CTRL_EXT_FORCE_SMBUS;
- E1000_WRITE_REG(hw, E1000_CTRL_EXT, mac_reg);
+ /* Unforce SMBus mode in MAC */
+ mac_reg = E1000_READ_REG(hw, E1000_CTRL_EXT);
+ mac_reg &= ~E1000_CTRL_EXT_FORCE_SMBUS;
+ E1000_WRITE_REG(hw, E1000_CTRL_EXT, mac_reg);
+ }
}
return TRUE;
@@ -328,6 +344,7 @@ static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw)
*/
switch (hw->mac.type) {
case e1000_pch_lpt:
+ case e1000_pch_spt:
if (e1000_phy_is_accessible_pchlan(hw))
break;
@@ -475,6 +492,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
/* fall-through */
case e1000_pch2lan:
case e1000_pch_lpt:
+ case e1000_pch_spt:
/* In case the PHY needs to be in mdio slow mode,
* set slow mode and try to get the PHY id again.
*/
@@ -617,36 +635,57 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw)
struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
u32 gfpreg, sector_base_addr, sector_end_addr;
u16 i;
+ u32 nvm_size;
DEBUGFUNC("e1000_init_nvm_params_ich8lan");
- /* Can't read flash registers if the register set isn't mapped. */
nvm->type = e1000_nvm_flash_sw;
- if (!hw->flash_address) {
- DEBUGOUT("ERROR: Flash registers not mapped\n");
- return -E1000_ERR_CONFIG;
- }
- gfpreg = E1000_READ_FLASH_REG(hw, ICH_FLASH_GFPREG);
+ if (hw->mac.type == e1000_pch_spt) {
+ /* in SPT, gfpreg doesn't exist. NVM size is taken from the
+ * STRAP register. This is because in SPT the GbE Flash region
+ * is no longer accessed through the flash registers. Instead,
+ * the mechanism has changed, and the Flash region access
+ * registers are now implemented in GbE memory space.
+ */
+ nvm->flash_base_addr = 0;
+ nvm_size =
+ (((E1000_READ_REG(hw, E1000_STRAP) >> 1) & 0x1F) + 1)
+ * NVM_SIZE_MULTIPLIER;
+ nvm->flash_bank_size = nvm_size / 2;
+ /* Adjust to word count */
+ nvm->flash_bank_size /= sizeof(u16);
+ /* Set the base address for flash register access */
+ hw->flash_address = hw->hw_addr + E1000_FLASH_BASE_ADDR;
+ } else {
+ /* Can't read flash registers if register set isn't mapped. */
+ if (!hw->flash_address) {
+ DEBUGOUT("ERROR: Flash registers not mapped\n");
+ return -E1000_ERR_CONFIG;
+ }
- /* sector_X_addr is a "sector"-aligned address (4096 bytes)
- * Add 1 to sector_end_addr since this sector is included in
- * the overall size.
- */
- sector_base_addr = gfpreg & FLASH_GFPREG_BASE_MASK;
- sector_end_addr = ((gfpreg >> 16) & FLASH_GFPREG_BASE_MASK) + 1;
+ gfpreg = E1000_READ_FLASH_REG(hw, ICH_FLASH_GFPREG);
- /* flash_base_addr is byte-aligned */
- nvm->flash_base_addr = sector_base_addr << FLASH_SECTOR_ADDR_SHIFT;
+ /* sector_X_addr is a "sector"-aligned address (4096 bytes)
+ * Add 1 to sector_end_addr since this sector is included in
+ * the overall size.
+ */
+ sector_base_addr = gfpreg & FLASH_GFPREG_BASE_MASK;
+ sector_end_addr = ((gfpreg >> 16) & FLASH_GFPREG_BASE_MASK) + 1;
- /* find total size of the NVM, then cut in half since the total
- * size represents two separate NVM banks.
- */
- nvm->flash_bank_size = ((sector_end_addr - sector_base_addr)
- << FLASH_SECTOR_ADDR_SHIFT);
- nvm->flash_bank_size /= 2;
- /* Adjust to word count */
- nvm->flash_bank_size /= sizeof(u16);
+ /* flash_base_addr is byte-aligned */
+ nvm->flash_base_addr = sector_base_addr
+ << FLASH_SECTOR_ADDR_SHIFT;
+
+ /* find total size of the NVM, then cut in half since the total
+ * size represents two separate NVM banks.
+ */
+ nvm->flash_bank_size = ((sector_end_addr - sector_base_addr)
+ << FLASH_SECTOR_ADDR_SHIFT);
+ nvm->flash_bank_size /= 2;
+ /* Adjust to word count */
+ nvm->flash_bank_size /= sizeof(u16);
+ }
nvm->word_size = E1000_SHADOW_RAM_WORDS;
@@ -662,8 +701,13 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw)
/* Function Pointers */
nvm->ops.acquire = e1000_acquire_nvm_ich8lan;
nvm->ops.release = e1000_release_nvm_ich8lan;
- nvm->ops.read = e1000_read_nvm_ich8lan;
- nvm->ops.update = e1000_update_nvm_checksum_ich8lan;
+ if (hw->mac.type == e1000_pch_spt) {
+ nvm->ops.read = e1000_read_nvm_spt;
+ nvm->ops.update = e1000_update_nvm_checksum_spt;
+ } else {
+ nvm->ops.read = e1000_read_nvm_ich8lan;
+ nvm->ops.update = e1000_update_nvm_checksum_ich8lan;
+ }
nvm->ops.valid_led_default = e1000_valid_led_default_ich8lan;
nvm->ops.validate = e1000_validate_nvm_checksum_ich8lan;
nvm->ops.write = e1000_write_nvm_ich8lan;
@@ -681,9 +725,6 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw)
static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw)
{
struct e1000_mac_info *mac = &hw->mac;
-#if defined(QV_RELEASE) || !defined(NO_PCH_LPT_B0_SUPPORT)
- u16 pci_cfg;
-#endif /* QV_RELEASE || !defined(NO_PCH_LPT_B0_SUPPORT) */
DEBUGFUNC("e1000_init_mac_params_ich8lan");
@@ -752,15 +793,12 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw)
mac->ops.rar_set = e1000_rar_set_pch2lan;
/* fall-through */
case e1000_pch_lpt:
+ case e1000_pch_spt:
/* multicast address update for pch2 */
mac->ops.update_mc_addr_list =
e1000_update_mc_addr_list_pch2lan;
+ /* fall-through */
case e1000_pchlan:
-#if defined(QV_RELEASE) || !defined(NO_PCH_LPT_B0_SUPPORT)
- /* save PCH revision_id */
- e1000_read_pci_cfg(hw, E1000_PCI_REVISION_ID_REG, &pci_cfg);
- hw->revision_id = (u8)(pci_cfg &= 0x000F);
-#endif /* QV_RELEASE || !defined(NO_PCH_LPT_B0_SUPPORT) */
/* check management mode */
mac->ops.check_mng_mode = e1000_check_mng_mode_pchlan;
/* ID LED init */
@@ -777,7 +815,8 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw)
break;
}
- if (mac->type == e1000_pch_lpt) {
+ if ((mac->type == e1000_pch_lpt) ||
+ (mac->type == e1000_pch_spt)) {
mac->rar_entry_count = E1000_PCH_LPT_RAR_ENTRIES;
mac->ops.rar_set = e1000_rar_set_pch_lpt;
mac->ops.setup_physical_interface = e1000_setup_copper_link_pch_lpt;
@@ -1007,8 +1046,9 @@ release:
/* clear FEXTNVM6 bit 8 on link down or 10/100 */
fextnvm6 &= ~E1000_FEXTNVM6_REQ_PLL_CLK;
- if (!link || ((status & E1000_STATUS_SPEED_100) &&
- (status & E1000_STATUS_FD)))
+ if ((hw->phy.revision > 5) || !link ||
+ ((status & E1000_STATUS_SPEED_100) &&
+ (status & E1000_STATUS_FD)))
goto update_fextnvm6;
ret_val = hw->phy.ops.read_reg(hw, I217_INBAND_CTRL, &reg);
@@ -1221,6 +1261,7 @@ s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx)
u32 mac_reg;
s32 ret_val = E1000_SUCCESS;
u16 phy_reg;
+ u16 oem_reg = 0;
if ((hw->mac.type < e1000_pch_lpt) ||
(hw->device_id == E1000_DEV_ID_PCH_LPT_I217_LM) ||
@@ -1276,6 +1317,25 @@ s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx)
mac_reg |= E1000_CTRL_EXT_FORCE_SMBUS;
E1000_WRITE_REG(hw, E1000_CTRL_EXT, mac_reg);
+ /* Si workaround for ULP entry flow on i127/rev6 h/w. Enable
+ * LPLU and disable Gig speed when entering ULP
+ */
+ if ((hw->phy.type == e1000_phy_i217) && (hw->phy.revision == 6)) {
+ ret_val = e1000_read_phy_reg_hv_locked(hw, HV_OEM_BITS,
+ &oem_reg);
+ if (ret_val)
+ goto release;
+
+ phy_reg = oem_reg;
+ phy_reg |= HV_OEM_BITS_LPLU | HV_OEM_BITS_GBE_DIS;
+
+ ret_val = e1000_write_phy_reg_hv_locked(hw, HV_OEM_BITS,
+ phy_reg);
+
+ if (ret_val)
+ goto release;
+ }
+
/* Set Inband ULP Exit, Reset to SMBus mode and
* Disable SMBus Release on PERST# in PHY
*/
@@ -1287,10 +1347,15 @@ s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx)
if (to_sx) {
if (E1000_READ_REG(hw, E1000_WUFC) & E1000_WUFC_LNKC)
phy_reg |= I218_ULP_CONFIG1_WOL_HOST;
+ else
+ phy_reg &= ~I218_ULP_CONFIG1_WOL_HOST;
phy_reg |= I218_ULP_CONFIG1_STICKY_ULP;
+ phy_reg &= ~I218_ULP_CONFIG1_INBAND_EXIT;
} else {
phy_reg |= I218_ULP_CONFIG1_INBAND_EXIT;
+ phy_reg &= ~I218_ULP_CONFIG1_STICKY_ULP;
+ phy_reg &= ~I218_ULP_CONFIG1_WOL_HOST;
}
e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg);
@@ -1302,6 +1367,15 @@ s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx)
/* Commit ULP changes in PHY by starting auto ULP configuration */
phy_reg |= I218_ULP_CONFIG1_START;
e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg);
+
+ if ((hw->phy.type == e1000_phy_i217) && (hw->phy.revision == 6) &&
+ to_sx && (E1000_READ_REG(hw, E1000_STATUS) & E1000_STATUS_LU)) {
+ ret_val = e1000_write_phy_reg_hv_locked(hw, HV_OEM_BITS,
+ oem_reg);
+ if (ret_val)
+ goto release;
+ }
+
release:
hw->phy.ops.release(hw);
out:
@@ -1352,10 +1426,10 @@ s32 e1000_disable_ulp_lpt_lp(struct e1000_hw *hw, bool force)
E1000_WRITE_REG(hw, E1000_H2ME, mac_reg);
}
- /* Poll up to 100msec for ME to clear ULP_CFG_DONE */
+ /* Poll up to 300msec for ME to clear ULP_CFG_DONE. */
while (E1000_READ_REG(hw, E1000_FWSM) &
E1000_FWSM_ULP_CFG_DONE) {
- if (i++ == 10) {
+ if (i++ == 30) {
ret_val = -E1000_ERR_PHY;
goto out;
}
@@ -1429,6 +1503,8 @@ s32 e1000_disable_ulp_lpt_lp(struct e1000_hw *hw, bool force)
I218_ULP_CONFIG1_RESET_TO_SMBUS |
I218_ULP_CONFIG1_WOL_HOST |
I218_ULP_CONFIG1_INBAND_EXIT |
+ I218_ULP_CONFIG1_EN_ULP_LANPHYPC |
+ I218_ULP_CONFIG1_DIS_CLR_STICKY_ON_PERST |
I218_ULP_CONFIG1_DISABLE_SMB_PERST);
e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg);
@@ -1467,7 +1543,8 @@ out:
static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
{
struct e1000_mac_info *mac = &hw->mac;
- s32 ret_val;
+ s32 ret_val, tipg_reg = 0;
+ u16 emi_addr, emi_val = 0;
bool link;
u16 phy_reg;
@@ -1500,35 +1577,119 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
* the IPG and reduce Rx latency in the PHY.
*/
if (((hw->mac.type == e1000_pch2lan) ||
- (hw->mac.type == e1000_pch_lpt)) && link) {
- u32 reg;
- reg = E1000_READ_REG(hw, E1000_STATUS);
- if (!(reg & (E1000_STATUS_FD | E1000_STATUS_SPEED_MASK))) {
- u16 emi_addr;
+ (hw->mac.type == e1000_pch_lpt) ||
+ (hw->mac.type == e1000_pch_spt)) && link) {
+ u16 speed, duplex;
- reg = E1000_READ_REG(hw, E1000_TIPG);
- reg &= ~E1000_TIPG_IPGT_MASK;
- reg |= 0xFF;
- E1000_WRITE_REG(hw, E1000_TIPG, reg);
+ e1000_get_speed_and_duplex_copper_generic(hw, &speed, &duplex);
+ tipg_reg = E1000_READ_REG(hw, E1000_TIPG);
+ tipg_reg &= ~E1000_TIPG_IPGT_MASK;
+ if (duplex == HALF_DUPLEX && speed == SPEED_10) {
+ tipg_reg |= 0xFF;
/* Reduce Rx latency in analog PHY */
- ret_val = hw->phy.ops.acquire(hw);
- if (ret_val)
- return ret_val;
+ emi_val = 0;
+ } else if (hw->mac.type == e1000_pch_spt &&
+ duplex == FULL_DUPLEX && speed != SPEED_1000) {
+ tipg_reg |= 0xC;
+ emi_val = 1;
+ } else {
+ /* Roll back the default values */
+ tipg_reg |= 0x08;
+ emi_val = 1;
+ }
+
+ E1000_WRITE_REG(hw, E1000_TIPG, tipg_reg);
- if (hw->mac.type == e1000_pch2lan)
- emi_addr = I82579_RX_CONFIG;
+ ret_val = hw->phy.ops.acquire(hw);
+ if (ret_val)
+ return ret_val;
+
+ if (hw->mac.type == e1000_pch2lan)
+ emi_addr = I82579_RX_CONFIG;
+ else
+ emi_addr = I217_RX_CONFIG;
+ ret_val = e1000_write_emi_reg_locked(hw, emi_addr, emi_val);
+
+ if (hw->mac.type == e1000_pch_lpt ||
+ hw->mac.type == e1000_pch_spt) {
+ u16 phy_reg;
+
+ hw->phy.ops.read_reg_locked(hw, I217_PLL_CLOCK_GATE_REG,
+ &phy_reg);
+ phy_reg &= ~I217_PLL_CLOCK_GATE_MASK;
+ if (speed == SPEED_100 || speed == SPEED_10)
+ phy_reg |= 0x3E8;
else
- emi_addr = I217_RX_CONFIG;
- ret_val = e1000_write_emi_reg_locked(hw, emi_addr, 0);
+ phy_reg |= 0xFA;
+ hw->phy.ops.write_reg_locked(hw,
+ I217_PLL_CLOCK_GATE_REG,
+ phy_reg);
+ }
+ hw->phy.ops.release(hw);
- hw->phy.ops.release(hw);
+ if (ret_val)
+ return ret_val;
- if (ret_val)
- return ret_val;
+ if (hw->mac.type == e1000_pch_spt) {
+ u16 data;
+ u16 ptr_gap;
+
+ if (speed == SPEED_1000) {
+ ret_val = hw->phy.ops.acquire(hw);
+ if (ret_val)
+ return ret_val;
+
+ ret_val = hw->phy.ops.read_reg_locked(hw,
+ PHY_REG(776, 20),
+ &data);
+ if (ret_val) {
+ hw->phy.ops.release(hw);
+ return ret_val;
+ }
+
+ ptr_gap = (data & (0x3FF << 2)) >> 2;
+ if (ptr_gap < 0x18) {
+ data &= ~(0x3FF << 2);
+ data |= (0x18 << 2);
+ ret_val =
+ hw->phy.ops.write_reg_locked(hw,
+ PHY_REG(776, 20), data);
+ }
+ hw->phy.ops.release(hw);
+ if (ret_val)
+ return ret_val;
+ } else {
+ ret_val = hw->phy.ops.acquire(hw);
+ if (ret_val)
+ return ret_val;
+
+ ret_val = hw->phy.ops.write_reg_locked(hw,
+ PHY_REG(776, 20),
+ 0xC023);
+ hw->phy.ops.release(hw);
+ if (ret_val)
+ return ret_val;
+
+ }
}
}
+ /* I217 Packet Loss issue:
+ * ensure that FEXTNVM4 Beacon Duration is set correctly
+ * on power up.
+ * Set the Beacon Duration for I217 to 8 usec
+ */
+ if ((hw->mac.type == e1000_pch_lpt) ||
+ (hw->mac.type == e1000_pch_spt)) {
+ u32 mac_reg;
+
+ mac_reg = E1000_READ_REG(hw, E1000_FEXTNVM4);
+ mac_reg &= ~E1000_FEXTNVM4_BEACON_DURATION_MASK;
+ mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_8USEC;
+ E1000_WRITE_REG(hw, E1000_FEXTNVM4, mac_reg);
+ }
+
/* Work-around I218 hang issue */
if ((hw->device_id == E1000_DEV_ID_PCH_LPTLP_I218_LM) ||
(hw->device_id == E1000_DEV_ID_PCH_LPTLP_I218_V) ||
@@ -1538,7 +1699,8 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
if (ret_val)
return ret_val;
}
- if (hw->mac.type == e1000_pch_lpt) {
+ if ((hw->mac.type == e1000_pch_lpt) ||
+ (hw->mac.type == e1000_pch_spt)) {
/* Set platform power management values for
* Latency Tolerance Reporting (LTR)
* Optimized Buffer Flush/Fill (OBFF)
@@ -1551,6 +1713,19 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
/* Clear link partner's EEE ability */
hw->dev_spec.ich8lan.eee_lp_ability = 0;
+ /* FEXTNVM6 K1-off workaround */
+ if (hw->mac.type == e1000_pch_spt) {
+ u32 pcieanacfg = E1000_READ_REG(hw, E1000_PCIEANACFG);
+ u32 fextnvm6 = E1000_READ_REG(hw, E1000_FEXTNVM6);
+
+ if (pcieanacfg & E1000_FEXTNVM6_K1_OFF_ENABLE)
+ fextnvm6 |= E1000_FEXTNVM6_K1_OFF_ENABLE;
+ else
+ fextnvm6 &= ~E1000_FEXTNVM6_K1_OFF_ENABLE;
+
+ E1000_WRITE_REG(hw, E1000_FEXTNVM6, fextnvm6);
+ }
+
if (!link)
return E1000_SUCCESS; /* No link detected */
@@ -1644,6 +1819,7 @@ void e1000_init_function_pointers_ich8lan(struct e1000_hw *hw)
case e1000_pchlan:
case e1000_pch2lan:
case e1000_pch_lpt:
+ case e1000_pch_spt:
hw->phy.ops.init_params = e1000_init_phy_params_pchlan;
break;
default:
@@ -2026,7 +2202,7 @@ static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw)
continue;
}
blocked = FALSE;
- } while (blocked && (i++ < 10));
+ } while (blocked && (i++ < 30));
return blocked ? E1000_BLK_PHY_RESET : E1000_SUCCESS;
}
@@ -2107,6 +2283,7 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
case e1000_pchlan:
case e1000_pch2lan:
case e1000_pch_lpt:
+ case e1000_pch_spt:
sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M;
break;
default:
@@ -3216,12 +3393,47 @@ static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank)
struct e1000_nvm_info *nvm = &hw->nvm;
u32 bank1_offset = nvm->flash_bank_size * sizeof(u16);
u32 act_offset = E1000_ICH_NVM_SIG_WORD * 2 + 1;
+ u32 nvm_dword = 0;
u8 sig_byte = 0;
s32 ret_val;
DEBUGFUNC("e1000_valid_nvm_bank_detect_ich8lan");
switch (hw->mac.type) {
+ case e1000_pch_spt:
+ bank1_offset = nvm->flash_bank_size;
+ act_offset = E1000_ICH_NVM_SIG_WORD;
+
+ /* set bank to 0 in case flash read fails */
+ *bank = 0;
+
+ /* Check bank 0 */
+ ret_val = e1000_read_flash_dword_ich8lan(hw, act_offset,
+ &nvm_dword);
+ if (ret_val)
+ return ret_val;
+ sig_byte = (u8)((nvm_dword & 0xFF00) >> 8);
+ if ((sig_byte & E1000_ICH_NVM_VALID_SIG_MASK) ==
+ E1000_ICH_NVM_SIG_VALUE) {
+ *bank = 0;
+ return E1000_SUCCESS;
+ }
+
+ /* Check bank 1 */
+ ret_val = e1000_read_flash_dword_ich8lan(hw, act_offset +
+ bank1_offset,
+ &nvm_dword);
+ if (ret_val)
+ return ret_val;
+ sig_byte = (u8)((nvm_dword & 0xFF00) >> 8);
+ if ((sig_byte & E1000_ICH_NVM_VALID_SIG_MASK) ==
+ E1000_ICH_NVM_SIG_VALUE) {
+ *bank = 1;
+ return E1000_SUCCESS;
+ }
+
+ DEBUGOUT("ERROR: No valid NVM bank present\n");
+ return -E1000_ERR_NVM;
case e1000_ich8lan:
case e1000_ich9lan:
eecd = E1000_READ_REG(hw, E1000_EECD);
@@ -3269,6 +3481,99 @@ static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank)
}
/**
+ * e1000_read_nvm_spt - NVM access for SPT
+ * @hw: pointer to the HW structure
+ * @offset: The offset (in bytes) of the word(s) to read.
+ * @words: Size of data to read in words.
+ * @data: pointer to the word(s) to read at offset.
+ *
+ * Reads a word(s) from the NVM
+ **/
+static s32 e1000_read_nvm_spt(struct e1000_hw *hw, u16 offset, u16 words,
+ u16 *data)
+{
+ struct e1000_nvm_info *nvm = &hw->nvm;
+ struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
+ u32 act_offset;
+ s32 ret_val = E1000_SUCCESS;
+ u32 bank = 0;
+ u32 dword = 0;
+ u16 offset_to_read;
+ u16 i;
+
+ DEBUGFUNC("e1000_read_nvm_spt");
+
+ if ((offset >= nvm->word_size) || (words > nvm->word_size - offset) ||
+ (words == 0)) {
+ DEBUGOUT("nvm parameter(s) out of bounds\n");
+ ret_val = -E1000_ERR_NVM;
+ goto out;
+ }
+
+ nvm->ops.acquire(hw);
+
+ ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank);
+ if (ret_val != E1000_SUCCESS) {
+ DEBUGOUT("Could not detect valid bank, assuming bank 0\n");
+ bank = 0;
+ }
+
+ act_offset = (bank) ? nvm->flash_bank_size : 0;
+ act_offset += offset;
+
+ ret_val = E1000_SUCCESS;
+
+ for (i = 0; i < words; i += 2) {
+ if (words - i == 1) {
+ if (dev_spec->shadow_ram[offset+i].modified) {
+ data[i] = dev_spec->shadow_ram[offset+i].value;
+ } else {
+ offset_to_read = act_offset + i -
+ ((act_offset + i) % 2);
+ ret_val =
+ e1000_read_flash_dword_ich8lan(hw,
+ offset_to_read,
+ &dword);
+ if (ret_val)
+ break;
+ if ((act_offset + i) % 2 == 0)
+ data[i] = (u16)(dword & 0xFFFF);
+ else
+ data[i] = (u16)((dword >> 16) & 0xFFFF);
+ }
+ } else {
+ offset_to_read = act_offset + i;
+ if (!(dev_spec->shadow_ram[offset+i].modified) ||
+ !(dev_spec->shadow_ram[offset+i+1].modified)) {
+ ret_val =
+ e1000_read_flash_dword_ich8lan(hw,
+ offset_to_read,
+ &dword);
+ if (ret_val)
+ break;
+ }
+ if (dev_spec->shadow_ram[offset+i].modified)
+ data[i] = dev_spec->shadow_ram[offset+i].value;
+ else
+ data[i] = (u16) (dword & 0xFFFF);
+ if (dev_spec->shadow_ram[offset+i].modified)
+ data[i+1] =
+ dev_spec->shadow_ram[offset+i+1].value;
+ else
+ data[i+1] = (u16) (dword >> 16 & 0xFFFF);
+ }
+ }
+
+ nvm->ops.release(hw);
+
+out:
+ if (ret_val)
+ DEBUGOUT1("NVM read error: %d\n", ret_val);
+
+ return ret_val;
+}
+
+/**
* e1000_read_nvm_ich8lan - Read word(s) from the NVM
* @hw: pointer to the HW structure
* @offset: The offset (in bytes) of the word(s) to read.
@@ -3355,7 +3660,11 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw)
/* Clear FCERR and DAEL in hw status by writing 1 */
hsfsts.hsf_status.flcerr = 1;
hsfsts.hsf_status.dael = 1;
- E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFSTS, hsfsts.regval);
+ if (hw->mac.type == e1000_pch_spt)
+ E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS,
+ hsfsts.regval & 0xFFFF);
+ else
+ E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFSTS, hsfsts.regval);
/* Either we should have a hardware SPI cycle in progress
* bit to check against, in order to start a new cycle or
@@ -3371,7 +3680,12 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw)
* Begin by setting Flash Cycle Done.
*/
hsfsts.hsf_status.flcdone = 1;
- E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFSTS, hsfsts.regval);
+ if (hw->mac.type == e1000_pch_spt)
+ E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS,
+ hsfsts.regval & 0xFFFF);
+ else
+ E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFSTS,
+ hsfsts.regval);
ret_val = E1000_SUCCESS;
} else {
s32 i;
@@ -3393,8 +3707,12 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw)
* now set the Flash Cycle Done.
*/
hsfsts.hsf_status.flcdone = 1;
- E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFSTS,
- hsfsts.regval);
+ if (hw->mac.type == e1000_pch_spt)
+ E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS,
+ hsfsts.regval & 0xFFFF);
+ else
+ E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFSTS,
+ hsfsts.regval);
} else {
DEBUGOUT("Flash controller busy, cannot get access\n");
}
@@ -3419,10 +3737,17 @@ static s32 e1000_flash_cycle_ich8lan(struct e1000_hw *hw, u32 timeout)
DEBUGFUNC("e1000_flash_cycle_ich8lan");
/* Start a cycle by writing 1 in Flash Cycle Go in Hw Flash Control */
- hsflctl.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFCTL);
+ if (hw->mac.type == e1000_pch_spt)
+ hsflctl.regval = E1000_READ_FLASH_REG(hw, ICH_FLASH_HSFSTS)>>16;
+ else
+ hsflctl.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFCTL);
hsflctl.hsf_ctrl.flcgo = 1;
- E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFCTL, hsflctl.regval);
+ if (hw->mac.type == e1000_pch_spt)
+ E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS,
+ hsflctl.regval << 16);
+ else
+ E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFCTL, hsflctl.regval);
/* wait till FDONE bit is set to 1 */
do {
@@ -3439,6 +3764,29 @@ static s32 e1000_flash_cycle_ich8lan(struct e1000_hw *hw, u32 timeout)
}
/**
+ * e1000_read_flash_dword_ich8lan - Read dword from flash
+ * @hw: pointer to the HW structure
+ * @offset: offset to data location
+ * @data: pointer to the location for storing the data
+ *
+ * Reads the flash dword at offset into data. Offset is converted
+ * to bytes before read.
+ **/
+static s32 e1000_read_flash_dword_ich8lan(struct e1000_hw *hw, u32 offset,
+ u32 *data)
+{
+ DEBUGFUNC("e1000_read_flash_dword_ich8lan");
+
+ if (!data)
+ return -E1000_ERR_NVM;
+
+ /* Must convert word offset into bytes. */
+ offset <<= 1;
+
+ return e1000_read_flash_data32_ich8lan(hw, offset, data);
+}
+
+/**
* e1000_read_flash_word_ich8lan - Read word from flash
* @hw: pointer to the HW structure
* @offset: offset to data location
@@ -3475,7 +3823,13 @@ static s32 e1000_read_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset,
s32 ret_val;
u16 word = 0;
- ret_val = e1000_read_flash_data_ich8lan(hw, offset, 1, &word);
+ /* In SPT, only 32 bits access is supported,
+ * so this function should not be called.
+ */
+ if (hw->mac.type == e1000_pch_spt)
+ return -E1000_ERR_NVM;
+ else
+ ret_val = e1000_read_flash_data_ich8lan(hw, offset, 1, &word);
if (ret_val)
return ret_val;
@@ -3561,6 +3915,83 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
return ret_val;
}
+/**
+ * e1000_read_flash_data32_ich8lan - Read dword from NVM
+ * @hw: pointer to the HW structure
+ * @offset: The offset (in bytes) of the dword to read.
+ * @data: Pointer to the dword to store the value read.
+ *
+ * Reads a byte or word from the NVM using the flash access registers.
+ **/
+static s32 e1000_read_flash_data32_ich8lan(struct e1000_hw *hw, u32 offset,
+ u32 *data)
+{
+ union ich8_hws_flash_status hsfsts;
+ union ich8_hws_flash_ctrl hsflctl;
+ u32 flash_linear_addr;
+ s32 ret_val = -E1000_ERR_NVM;
+ u8 count = 0;
+
+ DEBUGFUNC("e1000_read_flash_data_ich8lan");
+
+ if (offset > ICH_FLASH_LINEAR_ADDR_MASK ||
+ hw->mac.type != e1000_pch_spt)
+ return -E1000_ERR_NVM;
+ flash_linear_addr = ((ICH_FLASH_LINEAR_ADDR_MASK & offset) +
+ hw->nvm.flash_base_addr);
+
+ do {
+ usec_delay(1);
+ /* Steps */
+ ret_val = e1000_flash_cycle_init_ich8lan(hw);
+ if (ret_val != E1000_SUCCESS)
+ break;
+ /* In SPT, This register is in Lan memory space, not flash.
+ * Therefore, only 32 bit access is supported
+ */
+ hsflctl.regval = E1000_READ_FLASH_REG(hw, ICH_FLASH_HSFSTS)>>16;
+
+ /* 0b/1b corresponds to 1 or 2 byte size, respectively. */
+ hsflctl.hsf_ctrl.fldbcount = sizeof(u32) - 1;
+ hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_READ;
+ /* In SPT, This register is in Lan memory space, not flash.
+ * Therefore, only 32 bit access is supported
+ */
+ E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS,
+ (u32)hsflctl.regval << 16);
+ E1000_WRITE_FLASH_REG(hw, ICH_FLASH_FADDR, flash_linear_addr);
+
+ ret_val = e1000_flash_cycle_ich8lan(hw,
+ ICH_FLASH_READ_COMMAND_TIMEOUT);
+
+ /* Check if FCERR is set to 1, if set to 1, clear it
+ * and try the whole sequence a few more times, else
+ * read in (shift in) the Flash Data0, the order is
+ * least significant byte first msb to lsb
+ */
+ if (ret_val == E1000_SUCCESS) {
+ *data = E1000_READ_FLASH_REG(hw, ICH_FLASH_FDATA0);
+ break;
+ } else {
+ /* If we've gotten here, then things are probably
+ * completely hosed, but if the error condition is
+ * detected, it won't hurt to give it another try...
+ * ICH_FLASH_CYCLE_REPEAT_COUNT times.
+ */
+ hsfsts.regval = E1000_READ_FLASH_REG16(hw,
+ ICH_FLASH_HSFSTS);
+ if (hsfsts.hsf_status.flcerr) {
+ /* Repeat for some time before giving up. */
+ continue;
+ } else if (!hsfsts.hsf_status.flcdone) {
+ DEBUGOUT("Timeout error - flash cycle did not complete.\n");
+ break;
+ }
+ }
+ } while (count++ < ICH_FLASH_CYCLE_REPEAT_COUNT);
+
+ return ret_val;
+}
/**
* e1000_write_nvm_ich8lan - Write word(s) to the NVM
@@ -3599,6 +4030,175 @@ static s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
}
/**
+ * e1000_update_nvm_checksum_spt - Update the checksum for NVM
+ * @hw: pointer to the HW structure
+ *
+ * The NVM checksum is updated by calling the generic update_nvm_checksum,
+ * which writes the checksum to the shadow ram. The changes in the shadow
+ * ram are then committed to the EEPROM by processing each bank at a time
+ * checking for the modified bit and writing only the pending changes.
+ * After a successful commit, the shadow ram is cleared and is ready for
+ * future writes.
+ **/
+static s32 e1000_update_nvm_checksum_spt(struct e1000_hw *hw)
+{
+ struct e1000_nvm_info *nvm = &hw->nvm;
+ struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
+ u32 i, act_offset, new_bank_offset, old_bank_offset, bank;
+ s32 ret_val;
+ u32 dword = 0;
+
+ DEBUGFUNC("e1000_update_nvm_checksum_spt");
+
+ ret_val = e1000_update_nvm_checksum_generic(hw);
+ if (ret_val)
+ goto out;
+
+ if (nvm->type != e1000_nvm_flash_sw)
+ goto out;
+
+ nvm->ops.acquire(hw);
+
+ /* We're writing to the opposite bank so if we're on bank 1,
+ * write to bank 0 etc. We also need to erase the segment that
+ * is going to be written
+ */
+ ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank);
+ if (ret_val != E1000_SUCCESS) {
+ DEBUGOUT("Could not detect valid bank, assuming bank 0\n");
+ bank = 0;
+ }
+
+ if (bank == 0) {
+ new_bank_offset = nvm->flash_bank_size;
+ old_bank_offset = 0;
+ ret_val = e1000_erase_flash_bank_ich8lan(hw, 1);
+ if (ret_val)
+ goto release;
+ } else {
+ old_bank_offset = nvm->flash_bank_size;
+ new_bank_offset = 0;
+ ret_val = e1000_erase_flash_bank_ich8lan(hw, 0);
+ if (ret_val)
+ goto release;
+ }
+ for (i = 0; i < E1000_SHADOW_RAM_WORDS; i += 2) {
+ /* Determine whether to write the value stored
+ * in the other NVM bank or a modified value stored
+ * in the shadow RAM
+ */
+ ret_val = e1000_read_flash_dword_ich8lan(hw,
+ i + old_bank_offset,
+ &dword);
+
+ if (dev_spec->shadow_ram[i].modified) {
+ dword &= 0xffff0000;
+ dword |= (dev_spec->shadow_ram[i].value & 0xffff);
+ }
+ if (dev_spec->shadow_ram[i + 1].modified) {
+ dword &= 0x0000ffff;
+ dword |= ((dev_spec->shadow_ram[i + 1].value & 0xffff)
+ << 16);
+ }
+ if (ret_val)
+ break;
+
+ /* If the word is 0x13, then make sure the signature bits
+ * (15:14) are 11b until the commit has completed.
+ * This will allow us to write 10b which indicates the
+ * signature is valid. We want to do this after the write
+ * has completed so that we don't mark the segment valid
+ * while the write is still in progress
+ */
+ if (i == E1000_ICH_NVM_SIG_WORD - 1)
+ dword |= E1000_ICH_NVM_SIG_MASK << 16;
+
+ /* Convert offset to bytes. */
+ act_offset = (i + new_bank_offset) << 1;
+
+ usec_delay(100);
+
+ /* Write the data to the new bank. Offset in words*/
+ act_offset = i + new_bank_offset;
+ ret_val = e1000_retry_write_flash_dword_ich8lan(hw, act_offset,
+ dword);
+ if (ret_val)
+ break;
+ }
+
+ /* Don't bother writing the segment valid bits if sector
+ * programming failed.
+ */
+ if (ret_val) {
+ DEBUGOUT("Flash commit failed.\n");
+ goto release;
+ }
+
+ /* Finally validate the new segment by setting bit 15:14
+ * to 10b in word 0x13 , this can be done without an
+ * erase as well since these bits are 11 to start with
+ * and we need to change bit 14 to 0b
+ */
+ act_offset = new_bank_offset + E1000_ICH_NVM_SIG_WORD;
+
+ /*offset in words but we read dword*/
+ --act_offset;
+ ret_val = e1000_read_flash_dword_ich8lan(hw, act_offset, &dword);
+
+ if (ret_val)
+ goto release;
+
+ dword &= 0xBFFFFFFF;
+ ret_val = e1000_retry_write_flash_dword_ich8lan(hw, act_offset, dword);
+
+ if (ret_val)
+ goto release;
+
+ /* And invalidate the previously valid segment by setting
+ * its signature word (0x13) high_byte to 0b. This can be
+ * done without an erase because flash erase sets all bits
+ * to 1's. We can write 1's to 0's without an erase
+ */
+ act_offset = (old_bank_offset + E1000_ICH_NVM_SIG_WORD) * 2 + 1;
+
+ /* offset in words but we read dword*/
+ act_offset = old_bank_offset + E1000_ICH_NVM_SIG_WORD - 1;
+ ret_val = e1000_read_flash_dword_ich8lan(hw, act_offset, &dword);
+
+ if (ret_val)
+ goto release;
+
+ dword &= 0x00FFFFFF;
+ ret_val = e1000_retry_write_flash_dword_ich8lan(hw, act_offset, dword);
+
+ if (ret_val)
+ goto release;
+
+ /* Great! Everything worked, we can now clear the cached entries. */
+ for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) {
+ dev_spec->shadow_ram[i].modified = FALSE;
+ dev_spec->shadow_ram[i].value = 0xFFFF;
+ }
+
+release:
+ nvm->ops.release(hw);
+
+ /* Reload the EEPROM, or else modifications will not appear
+ * until after the next adapter reset.
+ */
+ if (!ret_val) {
+ nvm->ops.reload(hw);
+ msec_delay(10);
+ }
+
+out:
+ if (ret_val)
+ DEBUGOUT1("NVM update error: %d\n", ret_val);
+
+ return ret_val;
+}
+
+/**
* e1000_update_nvm_checksum_ich8lan - Update the checksum for NVM
* @hw: pointer to the HW structure
*
@@ -3775,6 +4375,7 @@ static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw)
*/
switch (hw->mac.type) {
case e1000_pch_lpt:
+ case e1000_pch_spt:
word = NVM_COMPAT;
valid_csum_mask = NVM_COMPAT_VALID_CSUM;
break;
@@ -3822,8 +4423,13 @@ static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
DEBUGFUNC("e1000_write_ich8_data");
- if (size < 1 || size > 2 || offset > ICH_FLASH_LINEAR_ADDR_MASK)
- return -E1000_ERR_NVM;
+ if (hw->mac.type == e1000_pch_spt) {
+ if (size != 4 || offset > ICH_FLASH_LINEAR_ADDR_MASK)
+ return -E1000_ERR_NVM;
+ } else {
+ if (size < 1 || size > 2 || offset > ICH_FLASH_LINEAR_ADDR_MASK)
+ return -E1000_ERR_NVM;
+ }
flash_linear_addr = ((ICH_FLASH_LINEAR_ADDR_MASK & offset) +
hw->nvm.flash_base_addr);
@@ -3834,12 +4440,29 @@ static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
ret_val = e1000_flash_cycle_init_ich8lan(hw);
if (ret_val != E1000_SUCCESS)
break;
- hsflctl.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFCTL);
+ /* In SPT, This register is in Lan memory space, not
+ * flash. Therefore, only 32 bit access is supported
+ */
+ if (hw->mac.type == e1000_pch_spt)
+ hsflctl.regval =
+ E1000_READ_FLASH_REG(hw, ICH_FLASH_HSFSTS)>>16;
+ else
+ hsflctl.regval =
+ E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFCTL);
/* 0b/1b corresponds to 1 or 2 byte size, respectively. */
hsflctl.hsf_ctrl.fldbcount = size - 1;
hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_WRITE;
- E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFCTL, hsflctl.regval);
+ /* In SPT, This register is in Lan memory space,
+ * not flash. Therefore, only 32 bit access is
+ * supported
+ */
+ if (hw->mac.type == e1000_pch_spt)
+ E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS,
+ hsflctl.regval << 16);
+ else
+ E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFCTL,
+ hsflctl.regval);
E1000_WRITE_FLASH_REG(hw, ICH_FLASH_FADDR, flash_linear_addr);
@@ -3877,6 +4500,94 @@ static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
return ret_val;
}
+/**
+* e1000_write_flash_data32_ich8lan - Writes 4 bytes to the NVM
+* @hw: pointer to the HW structure
+* @offset: The offset (in bytes) of the dwords to read.
+* @data: The 4 bytes to write to the NVM.
+*
+* Writes one/two/four bytes to the NVM using the flash access registers.
+**/
+static s32 e1000_write_flash_data32_ich8lan(struct e1000_hw *hw, u32 offset,
+ u32 data)
+{
+ union ich8_hws_flash_status hsfsts;
+ union ich8_hws_flash_ctrl hsflctl;
+ u32 flash_linear_addr;
+ s32 ret_val;
+ u8 count = 0;
+
+ DEBUGFUNC("e1000_write_flash_data32_ich8lan");
+
+ if (hw->mac.type == e1000_pch_spt) {
+ if (offset > ICH_FLASH_LINEAR_ADDR_MASK)
+ return -E1000_ERR_NVM;
+ }
+ flash_linear_addr = ((ICH_FLASH_LINEAR_ADDR_MASK & offset) +
+ hw->nvm.flash_base_addr);
+ do {
+ usec_delay(1);
+ /* Steps */
+ ret_val = e1000_flash_cycle_init_ich8lan(hw);
+ if (ret_val != E1000_SUCCESS)
+ break;
+
+ /* In SPT, This register is in Lan memory space, not
+ * flash. Therefore, only 32 bit access is supported
+ */
+ if (hw->mac.type == e1000_pch_spt)
+ hsflctl.regval = E1000_READ_FLASH_REG(hw,
+ ICH_FLASH_HSFSTS)
+ >> 16;
+ else
+ hsflctl.regval = E1000_READ_FLASH_REG16(hw,
+ ICH_FLASH_HSFCTL);
+
+ hsflctl.hsf_ctrl.fldbcount = sizeof(u32) - 1;
+ hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_WRITE;
+
+ /* In SPT, This register is in Lan memory space,
+ * not flash. Therefore, only 32 bit access is
+ * supported
+ */
+ if (hw->mac.type == e1000_pch_spt)
+ E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS,
+ hsflctl.regval << 16);
+ else
+ E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFCTL,
+ hsflctl.regval);
+
+ E1000_WRITE_FLASH_REG(hw, ICH_FLASH_FADDR, flash_linear_addr);
+
+ E1000_WRITE_FLASH_REG(hw, ICH_FLASH_FDATA0, data);
+
+ /* check if FCERR is set to 1 , if set to 1, clear it
+ * and try the whole sequence a few more times else done
+ */
+ ret_val = e1000_flash_cycle_ich8lan(hw,
+ ICH_FLASH_WRITE_COMMAND_TIMEOUT);
+
+ if (ret_val == E1000_SUCCESS)
+ break;
+
+ /* If we're here, then things are most likely
+ * completely hosed, but if the error condition
+ * is detected, it won't hurt to give it another
+ * try...ICH_FLASH_CYCLE_REPEAT_COUNT times.
+ */
+ hsfsts.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFSTS);
+
+ if (hsfsts.hsf_status.flcerr)
+ /* Repeat for some time before giving up. */
+ continue;
+ if (!hsfsts.hsf_status.flcdone) {
+ DEBUGOUT("Timeout error - flash cycle did not complete.\n");
+ break;
+ }
+ } while (count++ < ICH_FLASH_CYCLE_REPEAT_COUNT);
+
+ return ret_val;
+}
/**
* e1000_write_flash_byte_ich8lan - Write a single byte to NVM
@@ -3896,7 +4607,42 @@ static s32 e1000_write_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset,
return e1000_write_flash_data_ich8lan(hw, offset, 1, word);
}
+/**
+* e1000_retry_write_flash_dword_ich8lan - Writes a dword to NVM
+* @hw: pointer to the HW structure
+* @offset: The offset of the word to write.
+* @dword: The dword to write to the NVM.
+*
+* Writes a single dword to the NVM using the flash access registers.
+* Goes through a retry algorithm before giving up.
+**/
+static s32 e1000_retry_write_flash_dword_ich8lan(struct e1000_hw *hw,
+ u32 offset, u32 dword)
+{
+ s32 ret_val;
+ u16 program_retries;
+
+ DEBUGFUNC("e1000_retry_write_flash_dword_ich8lan");
+
+ /* Must convert word offset into bytes. */
+ offset <<= 1;
+
+ ret_val = e1000_write_flash_data32_ich8lan(hw, offset, dword);
+ if (!ret_val)
+ return ret_val;
+ for (program_retries = 0; program_retries < 100; program_retries++) {
+ DEBUGOUT2("Retrying Byte %8.8X at offset %u\n", dword, offset);
+ usec_delay(100);
+ ret_val = e1000_write_flash_data32_ich8lan(hw, offset, dword);
+ if (ret_val == E1000_SUCCESS)
+ break;
+ }
+ if (program_retries == 100)
+ return -E1000_ERR_NVM;
+
+ return E1000_SUCCESS;
+}
/**
* e1000_retry_write_flash_byte_ich8lan - Writes a single byte to NVM
@@ -4006,12 +4752,22 @@ static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank)
/* Write a value 11 (block Erase) in Flash
* Cycle field in hw flash control
*/
- hsflctl.regval =
- E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFCTL);
+ if (hw->mac.type == e1000_pch_spt)
+ hsflctl.regval =
+ E1000_READ_FLASH_REG(hw,
+ ICH_FLASH_HSFSTS)>>16;
+ else
+ hsflctl.regval =
+ E1000_READ_FLASH_REG16(hw,
+ ICH_FLASH_HSFCTL);
hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_ERASE;
- E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFCTL,
- hsflctl.regval);
+ if (hw->mac.type == e1000_pch_spt)
+ E1000_WRITE_FLASH_REG(hw, ICH_FLASH_HSFSTS,
+ hsflctl.regval << 16);
+ else
+ E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFCTL,
+ hsflctl.regval);
/* Write the last 24 bits of an index within the
* block into Flash Linear address field in Flash
@@ -4444,7 +5200,8 @@ static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw)
E1000_WRITE_REG(hw, E1000_RFCTL, reg);
/* Enable ECC on Lynxpoint */
- if (hw->mac.type == e1000_pch_lpt) {
+ if ((hw->mac.type == e1000_pch_lpt) ||
+ (hw->mac.type == e1000_pch_spt)) {
reg = E1000_READ_REG(hw, E1000_PBECCSTS);
reg |= E1000_PBECCSTS_ECC_ENABLE;
E1000_WRITE_REG(hw, E1000_PBECCSTS, reg);
@@ -4876,7 +5633,8 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw)
if ((device_id == E1000_DEV_ID_PCH_LPTLP_I218_LM) ||
(device_id == E1000_DEV_ID_PCH_LPTLP_I218_V) ||
(device_id == E1000_DEV_ID_PCH_I218_LM3) ||
- (device_id == E1000_DEV_ID_PCH_I218_V3)) {
+ (device_id == E1000_DEV_ID_PCH_I218_V3) ||
+ (hw->mac.type == e1000_pch_spt)) {
u32 fextnvm6 = E1000_READ_REG(hw, E1000_FEXTNVM6);
E1000_WRITE_REG(hw, E1000_FEXTNVM6,
@@ -4992,18 +5750,18 @@ out:
* the PHY.
* On i217, setup Intel Rapid Start Technology.
**/
-void e1000_resume_workarounds_pchlan(struct e1000_hw *hw)
+u32 e1000_resume_workarounds_pchlan(struct e1000_hw *hw)
{
s32 ret_val;
DEBUGFUNC("e1000_resume_workarounds_pchlan");
if (hw->mac.type < e1000_pch2lan)
- return;
+ return E1000_SUCCESS;
ret_val = e1000_init_phy_workarounds_pchlan(hw);
if (ret_val) {
DEBUGOUT1("Failed to init PHY flow ret_val=%d\n", ret_val);
- return;
+ return ret_val;
}
/* For i217 Intel Rapid Start Technology support when the system
@@ -5017,7 +5775,7 @@ void e1000_resume_workarounds_pchlan(struct e1000_hw *hw)
ret_val = hw->phy.ops.acquire(hw);
if (ret_val) {
DEBUGOUT("Failed to setup iRST\n");
- return;
+ return ret_val;
}
/* Clear Auto Enable LPI after link up */
@@ -5051,7 +5809,9 @@ release:
if (ret_val)
DEBUGOUT1("Error %d in resume workarounds\n", ret_val);
hw->phy.ops.release(hw);
+ return ret_val;
}
+ return E1000_SUCCESS;
}
/**
diff --git a/sys/dev/e1000/e1000_ich8lan.h b/sys/dev/e1000/e1000_ich8lan.h
index 9cb79c0..edc1dd1 100644
--- a/sys/dev/e1000/e1000_ich8lan.h
+++ b/sys/dev/e1000/e1000_ich8lan.h
@@ -107,9 +107,23 @@
#define E1000_FEXTNVM6_REQ_PLL_CLK 0x00000100
#define E1000_FEXTNVM6_ENABLE_K1_ENTRY_CONDITION 0x00000200
-
+#define E1000_FEXTNVM6_K1_OFF_ENABLE 0x80000000
+/* bit for disabling packet buffer read */
+#define E1000_FEXTNVM7_DISABLE_PB_READ 0x00040000
+#define E1000_FEXTNVM7_SIDE_CLK_UNGATE 0x00000004
#define E1000_FEXTNVM7_DISABLE_SMB_PERST 0x00000020
-
+#define E1000_FEXTNVM9_IOSFSB_CLKGATE_DIS 0x00000800
+#define E1000_FEXTNVM9_IOSFSB_CLKREQ_DIS 0x00001000
+#define E1000_FEXTNVM11_DISABLE_PB_READ 0x00000200
+#define E1000_FEXTNVM11_DISABLE_MULR_FIX 0x00002000
+
+/* bit24: RXDCTL thresholds granularity: 0 - cache lines, 1 - descriptors */
+#define E1000_RXDCTL_THRESH_UNIT_DESC 0x01000000
+
+#define NVM_SIZE_MULTIPLIER 4096 /*multiplier for NVMS field*/
+#define E1000_FLASH_BASE_ADDR 0xE000 /*offset of NVM access regs*/
+#define E1000_CTRL_EXT_NVMVS 0x3 /*NVM valid sector */
+#define E1000_TARC0_CB_MULTIQ_3_REQ (1 << 28 | 1 << 29)
#define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL
#define E1000_ICH_RAR_ENTRIES 7
@@ -171,6 +185,8 @@
#define E1000_NVM_K1_CONFIG 0x1B /* NVM K1 Config Word */
#define E1000_NVM_K1_ENABLE 0x1 /* NVM Enable K1 bit */
+#define K1_ENTRY_LATENCY 0
+#define K1_MIN_TIME 1
/* SMBus Control Phy Register */
#define CV_SMB_CTRL PHY_REG(769, 23)
@@ -184,6 +200,10 @@
#define I218_ULP_CONFIG1_INBAND_EXIT 0x0020 /* Inband on ULP exit */
#define I218_ULP_CONFIG1_WOL_HOST 0x0040 /* WoL Host on ULP exit */
#define I218_ULP_CONFIG1_RESET_TO_SMBUS 0x0100 /* Reset to SMBus mode */
+/* enable ULP even if when phy powered down via lanphypc */
+#define I218_ULP_CONFIG1_EN_ULP_LANPHYPC 0x0400
+/* disable clear of sticky ULP on PERST */
+#define I218_ULP_CONFIG1_DIS_CLR_STICKY_ON_PERST 0x0800
#define I218_ULP_CONFIG1_DISABLE_SMB_PERST 0x1000 /* Disable on PERST# */
/* SMBus Address Phy Register */
@@ -222,6 +242,9 @@
#define HV_PM_CTRL_PLL_STOP_IN_K1_GIGA 0x100
#define HV_PM_CTRL_K1_ENABLE 0x4000
+#define I217_PLL_CLOCK_GATE_REG PHY_REG(772, 28)
+#define I217_PLL_CLOCK_GATE_MASK 0x07FF
+
#define SW_FLAG_TIMEOUT 1000 /* SW Semaphore flag timeout in ms */
/* Inband Control */
@@ -302,15 +325,12 @@
#define E1000_SVCR_OFF_TIMER_SHIFT 16
#define E1000_SVT_OFF_HWM_MASK 0x0000001F
-#if defined(QV_RELEASE) || !defined(NO_PCH_LPT_B0_SUPPORT)
-#define E1000_PCI_REVISION_ID_REG 0x08
-#endif /* defined(QV_RELEASE) || !defined(NO_PCH_LPT_B0_SUPPORT) */
void e1000_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw,
bool state);
void e1000_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw);
void e1000_gig_downshift_workaround_ich8lan(struct e1000_hw *hw);
void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw);
-void e1000_resume_workarounds_pchlan(struct e1000_hw *hw);
+u32 e1000_resume_workarounds_pchlan(struct e1000_hw *hw);
s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable);
void e1000_copy_rx_addrs_to_phy_ich8lan(struct e1000_hw *hw);
s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable);
diff --git a/sys/dev/e1000/e1000_mac.h b/sys/dev/e1000/e1000_mac.h
index 1daed9b..ef9789b 100644
--- a/sys/dev/e1000/e1000_mac.h
+++ b/sys/dev/e1000/e1000_mac.h
@@ -36,9 +36,7 @@
#define _E1000_MAC_H_
void e1000_init_mac_ops_generic(struct e1000_hw *hw);
-#ifndef E1000_REMOVED
#define E1000_REMOVED(a) (0)
-#endif /* E1000_REMOVED */
void e1000_null_mac_generic(struct e1000_hw *hw);
s32 e1000_null_ops_generic(struct e1000_hw *hw);
s32 e1000_null_link_info(struct e1000_hw *hw, u16 *s, u16 *d);
diff --git a/sys/dev/e1000/e1000_mbx.c b/sys/dev/e1000/e1000_mbx.c
index d9fb9ac..1de19a4 100644
--- a/sys/dev/e1000/e1000_mbx.c
+++ b/sys/dev/e1000/e1000_mbx.c
@@ -426,15 +426,21 @@ static s32 e1000_check_for_rst_vf(struct e1000_hw *hw,
static s32 e1000_obtain_mbx_lock_vf(struct e1000_hw *hw)
{
s32 ret_val = -E1000_ERR_MBX;
+ int count = 10;
DEBUGFUNC("e1000_obtain_mbx_lock_vf");
- /* Take ownership of the buffer */
- E1000_WRITE_REG(hw, E1000_V2PMAILBOX(0), E1000_V2PMAILBOX_VFU);
+ do {
+ /* Take ownership of the buffer */
+ E1000_WRITE_REG(hw, E1000_V2PMAILBOX(0), E1000_V2PMAILBOX_VFU);
- /* reserve mailbox for vf use */
- if (e1000_read_v2p_mailbox(hw) & E1000_V2PMAILBOX_VFU)
- ret_val = E1000_SUCCESS;
+ /* reserve mailbox for vf use */
+ if (e1000_read_v2p_mailbox(hw) & E1000_V2PMAILBOX_VFU) {
+ ret_val = E1000_SUCCESS;
+ break;
+ }
+ usec_delay(1000);
+ } while (count-- > 0);
return ret_val;
}
@@ -639,18 +645,26 @@ static s32 e1000_obtain_mbx_lock_pf(struct e1000_hw *hw, u16 vf_number)
{
s32 ret_val = -E1000_ERR_MBX;
u32 p2v_mailbox;
+ int count = 10;
DEBUGFUNC("e1000_obtain_mbx_lock_pf");
- /* Take ownership of the buffer */
- E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU);
+ do {
+ /* Take ownership of the buffer */
+ E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number),
+ E1000_P2VMAILBOX_PFU);
- /* reserve mailbox for vf use */
- p2v_mailbox = E1000_READ_REG(hw, E1000_P2VMAILBOX(vf_number));
- if (p2v_mailbox & E1000_P2VMAILBOX_PFU)
- ret_val = E1000_SUCCESS;
+ /* reserve mailbox for pf use */
+ p2v_mailbox = E1000_READ_REG(hw, E1000_P2VMAILBOX(vf_number));
+ if (p2v_mailbox & E1000_P2VMAILBOX_PFU) {
+ ret_val = E1000_SUCCESS;
+ break;
+ }
+ usec_delay(1000);
+ } while (count-- > 0);
return ret_val;
+
}
/**
diff --git a/sys/dev/e1000/e1000_nvm.h b/sys/dev/e1000/e1000_nvm.h
index 31f2180..64a4083 100644
--- a/sys/dev/e1000/e1000_nvm.h
+++ b/sys/dev/e1000/e1000_nvm.h
@@ -35,12 +35,10 @@
#ifndef _E1000_NVM_H_
#define _E1000_NVM_H_
-#if !defined(NO_READ_PBA_RAW) || !defined(NO_WRITE_PBA_RAW)
struct e1000_pba {
u16 word[2];
u16 *pba_block;
};
-#endif
void e1000_init_nvm_ops_generic(struct e1000_hw *hw);
diff --git a/sys/dev/e1000/e1000_osdep.h b/sys/dev/e1000/e1000_osdep.h
index fc46f48..c0bf418 100644
--- a/sys/dev/e1000/e1000_osdep.h
+++ b/sys/dev/e1000/e1000_osdep.h
@@ -60,24 +60,24 @@
#define ASSERT(x) if(!(x)) panic("EM: x")
#define usec_delay(x) DELAY(x)
-#define usec_delay_irq(x) DELAY(x)
+#define usec_delay_irq(x) usec_delay(x)
#define msec_delay(x) DELAY(1000*(x))
#define msec_delay_irq(x) DELAY(1000*(x))
-#define DEBUGFUNC(F) DEBUGOUT(F);
-#define DEBUGOUT(S) do {} while (0)
-#define DEBUGOUT1(S,A) do {} while (0)
-#define DEBUGOUT2(S,A,B) do {} while (0)
-#define DEBUGOUT3(S,A,B,C) do {} while (0)
-#define DEBUGOUT7(S,A,B,C,D,E,F,G) do {} while (0)
+/* Enable/disable debugging statements in shared code */
+#define DBG 0
+
+#define DEBUGOUT(...) \
+ do { if (DBG) printf(__VA_ARGS__); } while (0)
+#define DEBUGOUT1(...) DEBUGOUT(__VA_ARGS__)
+#define DEBUGOUT2(...) DEBUGOUT(__VA_ARGS__)
+#define DEBUGOUT3(...) DEBUGOUT(__VA_ARGS__)
+#define DEBUGOUT7(...) DEBUGOUT(__VA_ARGS__)
+#define DEBUGFUNC(F) DEBUGOUT(F "\n")
#define STATIC static
#define FALSE 0
#define TRUE 1
-#ifndef __bool_true_false_are_defined
-#define false FALSE
-#define true TRUE
-#endif
#define CMD_MEM_WRT_INVALIDATE 0x0010 /* BIT_4 */
#define PCI_COMMAND_REGISTER PCIR_COMMAND
@@ -99,9 +99,6 @@ typedef int64_t s64;
typedef int32_t s32;
typedef int16_t s16;
typedef int8_t s8;
-#ifndef __bool_true_false_are_defined
-typedef boolean_t bool;
-#endif
#define __le16 u16
#define __le32 u32
diff --git a/sys/dev/e1000/e1000_phy.c b/sys/dev/e1000/e1000_phy.c
index 0c8ccd2..b2bec3e 100644
--- a/sys/dev/e1000/e1000_phy.c
+++ b/sys/dev/e1000/e1000_phy.c
@@ -1827,9 +1827,9 @@ s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw)
phy_data);
if (ret_val)
return ret_val;
- }
- DEBUGOUT1("M88E1000 PSCR: %X\n", phy_data);
+ DEBUGOUT1("M88E1000 PSCR: %X\n", phy_data);
+ }
ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data);
if (ret_val)
@@ -3429,14 +3429,12 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
u16 *data, bool read, bool page_set)
{
s32 ret_val;
- u16 reg, page;
+ u16 reg = BM_PHY_REG_NUM(offset);
+ u16 page = BM_PHY_REG_PAGE(offset);
u16 phy_reg = 0;
DEBUGFUNC("e1000_access_phy_wakeup_reg_bm");
- reg = BM_PHY_REG_NUM(offset);
- page = BM_PHY_REG_PAGE(offset);
-
/* Gig must be disabled for MDIO accesses to Host Wakeup reg page */
if ((hw->mac.type == e1000_pchlan) &&
(!(E1000_READ_REG(hw, E1000_PHY_CTRL) & E1000_PHY_CTRL_GBE_DISABLE)))
diff --git a/sys/dev/e1000/e1000_regs.h b/sys/dev/e1000/e1000_regs.h
index 7c81a89..37d7017 100644
--- a/sys/dev/e1000/e1000_regs.h
+++ b/sys/dev/e1000/e1000_regs.h
@@ -65,6 +65,9 @@
#define E1000_FEXTNVM4 0x00024 /* Future Extended NVM 4 - RW */
#define E1000_FEXTNVM6 0x00010 /* Future Extended NVM 6 - RW */
#define E1000_FEXTNVM7 0x000E4 /* Future Extended NVM 7 - RW */
+#define E1000_FEXTNVM9 0x5BB4 /* Future Extended NVM 9 - RW */
+#define E1000_FEXTNVM11 0x5BBC /* Future Extended NVM 11 - RW */
+#define E1000_PCIEANACFG 0x00F18 /* PCIE Analog Config */
#define E1000_FCT 0x00030 /* Flow Control Type - RW */
#define E1000_CONNSW 0x00034 /* Copper/Fiber switch control - RW */
#define E1000_VET 0x00038 /* VLAN Ether Type - RW */
@@ -107,7 +110,9 @@
#define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */
#define E1000_PBS 0x01008 /* Packet Buffer Size */
#define E1000_PBECCSTS 0x0100C /* Packet Buffer ECC Status - RW */
+#define E1000_IOSFPC 0x00F28 /* TX corrupted data */
#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */
+#define E1000_EEMNGCTL_I210 0x01010 /* i210 MNG EEprom Mode Control */
#define E1000_EEARBC 0x01024 /* EEPROM Auto Read Bus Control */
#define E1000_EEARBC_I210 0x12024 /* EEPROM Auto Read Bus Control */
#define E1000_FLASHT 0x01028 /* FLASH Timer Register */
@@ -588,6 +593,10 @@
#define E1000_TIMADJL 0x0B60C /* Time sync time adjustment offset Low - RW */
#define E1000_TIMADJH 0x0B610 /* Time sync time adjustment offset High - RW */
#define E1000_TSAUXC 0x0B640 /* Timesync Auxiliary Control register */
+#define E1000_SYSSTMPL 0x0B648 /* HH Timesync system stamp low register */
+#define E1000_SYSSTMPH 0x0B64C /* HH Timesync system stamp hi register */
+#define E1000_PLTSTMPL 0x0B640 /* HH Timesync platform stamp low register */
+#define E1000_PLTSTMPH 0x0B644 /* HH Timesync platform stamp hi register */
#define E1000_SYSTIMR 0x0B6F8 /* System time register Residue */
#define E1000_TSICR 0x0B66C /* Interrupt Cause Register */
#define E1000_TSIM 0x0B674 /* Interrupt Mask Register */
diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c
index b6c98b1..1f6746c 100644
--- a/sys/dev/e1000/if_em.c
+++ b/sys/dev/e1000/if_em.c
@@ -96,14 +96,9 @@
#include "if_em.h"
/*********************************************************************
- * Set this to one to display debug statistics
- *********************************************************************/
-int em_display_debug_stats = 0;
-
-/*********************************************************************
* Driver version:
*********************************************************************/
-char em_driver_version[] = "7.4.2";
+char em_driver_version[] = "7.6.1-k";
/*********************************************************************
* PCI Device ID Table
@@ -191,6 +186,13 @@ static em_vendor_info_t em_vendor_info_array[] =
{ 0x8086, E1000_DEV_ID_PCH_I218_V2, PCI_ANY_ID, PCI_ANY_ID, 0},
{ 0x8086, E1000_DEV_ID_PCH_I218_LM3, PCI_ANY_ID, PCI_ANY_ID, 0},
{ 0x8086, E1000_DEV_ID_PCH_I218_V3, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_PCH_SPT_I219_LM, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_PCH_SPT_I219_V, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_PCH_SPT_I219_LM2,
+ PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_PCH_SPT_I219_V2, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_PCH_LBG_I219_LM3,
+ PCI_ANY_ID, PCI_ANY_ID, 0},
/* required last entry */
{ 0, 0, 0, 0, 0}
};
@@ -238,6 +240,7 @@ static void em_free_pci_resources(struct adapter *);
static void em_local_timer(void *);
static void em_reset(struct adapter *);
static int em_setup_interface(device_t, struct adapter *);
+static void em_flush_desc_rings(struct adapter *);
static void em_setup_transmit_structures(struct adapter *);
static void em_initialize_transmit_unit(struct adapter *);
@@ -577,10 +580,25 @@ em_attach(device_t dev)
adapter->osdep.flash_bus_space_handle =
rman_get_bushandle(adapter->flash);
}
+ /*
+ ** In the new SPT device flash is not a
+ ** seperate BAR, rather it is also in BAR0,
+ ** so use the same tag and an offset handle for the
+ ** FLASH read/write macros in the shared code.
+ */
+ else if (hw->mac.type == e1000_pch_spt) {
+ adapter->osdep.flash_bus_space_tag =
+ adapter->osdep.mem_bus_space_tag;
+ adapter->osdep.flash_bus_space_handle =
+ adapter->osdep.mem_bus_space_handle
+ + E1000_FLASH_BASE_ADDR;
+ }
/* Do Shared Code initialization */
- if (e1000_setup_init_funcs(hw, TRUE)) {
- device_printf(dev, "Setup of Shared code failed\n");
+ error = e1000_setup_init_funcs(hw, TRUE);
+ if (error) {
+ device_printf(dev, "Setup of Shared code failed, error %d\n",
+ error);
error = ENXIO;
goto err_pci;
}
@@ -1170,6 +1188,7 @@ em_ioctl(if_t ifp, u_long command, caddr_t data)
case e1000_ich10lan:
case e1000_pch2lan:
case e1000_pch_lpt:
+ case e1000_pch_spt:
case e1000_82574:
case e1000_82583:
case e1000_80003es2lan: /* 9K Jumbo Frame size */
@@ -2359,6 +2378,8 @@ em_update_link_status(struct adapter *adapter)
switch (hw->phy.media_type) {
case e1000_media_type_copper:
if (hw->mac.get_link_status) {
+ if (hw->mac.type == e1000_pch_spt)
+ msec_delay(50);
/* Do the work to read phy */
e1000_check_for_link(hw);
link_check = !hw->mac.get_link_status;
@@ -2450,6 +2471,10 @@ em_stop(void *arg)
EM_TX_UNLOCK(txr);
}
+ /* I219 needs some special flushing to avoid hangs */
+ if (adapter->hw.mac.type == e1000_pch_spt)
+ em_flush_desc_rings(adapter);
+
e1000_reset_hw(&adapter->hw);
E1000_WRITE_REG(&adapter->hw, E1000_WUC, 0);
@@ -2869,6 +2894,116 @@ msi:
}
+/*
+** The 3 following flush routines are used as a workaround in the
+** I219 client parts and only for them.
+**
+** em_flush_tx_ring - remove all descriptors from the tx_ring
+**
+** We want to clear all pending descriptors from the TX ring.
+** zeroing happens when the HW reads the regs. We assign the ring itself as
+** the data of the next descriptor. We don't care about the data we are about
+** to reset the HW.
+*/
+static void
+em_flush_tx_ring(struct adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ struct tx_ring *txr = adapter->tx_rings;
+ struct e1000_tx_desc *txd;
+ u32 tctl, txd_lower = E1000_TXD_CMD_IFCS;
+ u16 size = 512;
+
+ tctl = E1000_READ_REG(hw, E1000_TCTL);
+ E1000_WRITE_REG(hw, E1000_TCTL, tctl | E1000_TCTL_EN);
+
+ txd = &txr->tx_base[txr->next_avail_desc++];
+ if (txr->next_avail_desc == adapter->num_tx_desc)
+ txr->next_avail_desc = 0;
+
+ /* Just use the ring as a dummy buffer addr */
+ txd->buffer_addr = txr->txdma.dma_paddr;
+ txd->lower.data = htole32(txd_lower | size);
+ txd->upper.data = 0;
+
+ /* flush descriptors to memory before notifying the HW */
+ wmb();
+
+ E1000_WRITE_REG(hw, E1000_TDT(0), txr->next_avail_desc);
+ mb();
+ usec_delay(250);
+}
+
+/*
+** em_flush_rx_ring - remove all descriptors from the rx_ring
+**
+** Mark all descriptors in the RX ring as consumed and disable the rx ring
+*/
+static void
+em_flush_rx_ring(struct adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 rctl, rxdctl;
+
+ rctl = E1000_READ_REG(hw, E1000_RCTL);
+ E1000_WRITE_REG(hw, E1000_RCTL, rctl & ~E1000_RCTL_EN);
+ E1000_WRITE_FLUSH(hw);
+ usec_delay(150);
+
+ rxdctl = E1000_READ_REG(hw, E1000_RXDCTL(0));
+ /* zero the lower 14 bits (prefetch and host thresholds) */
+ rxdctl &= 0xffffc000;
+ /*
+ * update thresholds: prefetch threshold to 31, host threshold to 1
+ * and make sure the granularity is "descriptors" and not "cache lines"
+ */
+ rxdctl |= (0x1F | (1 << 8) | E1000_RXDCTL_THRESH_UNIT_DESC);
+ E1000_WRITE_REG(hw, E1000_RXDCTL(0), rxdctl);
+
+ /* momentarily enable the RX ring for the changes to take effect */
+ E1000_WRITE_REG(hw, E1000_RCTL, rctl | E1000_RCTL_EN);
+ E1000_WRITE_FLUSH(hw);
+ usec_delay(150);
+ E1000_WRITE_REG(hw, E1000_RCTL, rctl & ~E1000_RCTL_EN);
+}
+
+/*
+** em_flush_desc_rings - remove all descriptors from the descriptor rings
+**
+** In i219, the descriptor rings must be emptied before resetting the HW
+** or before changing the device state to D3 during runtime (runtime PM).
+**
+** Failure to do this will cause the HW to enter a unit hang state which can
+** only be released by PCI reset on the device
+**
+*/
+static void
+em_flush_desc_rings(struct adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ device_t dev = adapter->dev;
+ u16 hang_state;
+ u32 fext_nvm11, tdlen;
+
+ /* First, disable MULR fix in FEXTNVM11 */
+ fext_nvm11 = E1000_READ_REG(hw, E1000_FEXTNVM11);
+ fext_nvm11 |= E1000_FEXTNVM11_DISABLE_MULR_FIX;
+ E1000_WRITE_REG(hw, E1000_FEXTNVM11, fext_nvm11);
+
+ /* do nothing if we're not in faulty state, or if the queue is empty */
+ tdlen = E1000_READ_REG(hw, E1000_TDLEN(0));
+ hang_state = pci_read_config(dev, PCICFG_DESC_RING_STATUS, 2);
+ if (!(hang_state & FLUSH_DESC_REQUIRED) || !tdlen)
+ return;
+ em_flush_tx_ring(adapter);
+
+ /* recheck, maybe the fault is caused by the rx ring */
+ hang_state = pci_read_config(dev, PCICFG_DESC_RING_STATUS, 2);
+ if (hang_state & FLUSH_DESC_REQUIRED)
+ em_flush_rx_ring(adapter);
+}
+
+
/*********************************************************************
*
* Initialize the hardware to a configuration
@@ -2930,6 +3065,7 @@ em_reset(struct adapter *adapter)
case e1000_pchlan:
case e1000_pch2lan:
case e1000_pch_lpt:
+ case e1000_pch_spt:
pba = E1000_PBA_26K;
break;
default:
@@ -2988,6 +3124,7 @@ em_reset(struct adapter *adapter)
break;
case e1000_pch2lan:
case e1000_pch_lpt:
+ case e1000_pch_spt:
hw->fc.high_water = 0x5C20;
hw->fc.low_water = 0x5048;
hw->fc.pause_time = 0x0650;
@@ -3012,6 +3149,10 @@ em_reset(struct adapter *adapter)
break;
}
+ /* I219 needs some special flushing to avoid hangs */
+ if (hw->mac.type == e1000_pch_spt)
+ em_flush_desc_rings(adapter);
+
/* Issue a global reset */
e1000_reset_hw(hw);
E1000_WRITE_REG(hw, E1000_WUC, 0);
@@ -3608,6 +3749,15 @@ em_initialize_transmit_unit(struct adapter *adapter)
/* This write will effectively turn on the transmit unit. */
E1000_WRITE_REG(&adapter->hw, E1000_TCTL, tctl);
+ if (hw->mac.type == e1000_pch_spt) {
+ u32 reg;
+ reg = E1000_READ_REG(hw, E1000_IOSFPC);
+ reg |= E1000_RCTL_RDMTS_HEX;
+ E1000_WRITE_REG(hw, E1000_IOSFPC, reg);
+ reg = E1000_READ_REG(hw, E1000_TARC(0));
+ reg |= E1000_TARC0_CB_MULTIQ_3_REQ;
+ E1000_WRITE_REG(hw, E1000_TARC(0), reg);
+ }
}
diff --git a/sys/dev/e1000/if_em.h b/sys/dev/e1000/if_em.h
index 362df49..3b280b3 100644
--- a/sys/dev/e1000/if_em.h
+++ b/sys/dev/e1000/if_em.h
@@ -218,6 +218,9 @@
#define EM_TX_HUNG 0x80000000
#define EM_TX_MAXTRIES 10
+#define PCICFG_DESC_RING_STATUS 0xe4
+#define FLUSH_DESC_REQUIRED 0x100
+
/*
* TDBA/RDBA should be aligned on 16 byte boundary. But TDLEN/RDLEN should be
* multiple of 128 bytes. So we align TDBA/RDBA on 128 byte boundary. This will
diff --git a/sys/dev/e1000/if_igb.c b/sys/dev/e1000/if_igb.c
index 5be7836..c84dfc2 100644
--- a/sys/dev/e1000/if_igb.c
+++ b/sys/dev/e1000/if_igb.c
@@ -47,7 +47,7 @@
/*********************************************************************
* Driver version:
*********************************************************************/
-char igb_driver_version[] = "2.5.2";
+char igb_driver_version[] = "2.5.3-k";
/*********************************************************************
@@ -551,9 +551,9 @@ igb_attach(device_t dev)
"Disable Energy Efficient Ethernet");
if (adapter->hw.phy.media_type == e1000_media_type_copper) {
if (adapter->hw.mac.type == e1000_i354)
- e1000_set_eee_i354(&adapter->hw);
+ e1000_set_eee_i354(&adapter->hw, TRUE, TRUE);
else
- e1000_set_eee_i350(&adapter->hw);
+ e1000_set_eee_i350(&adapter->hw, TRUE, TRUE);
}
}
@@ -1277,6 +1277,9 @@ igb_init_locked(struct adapter *adapter)
if (ifp->if_capenable & IFCAP_TSO)
ifp->if_hwassist |= CSUM_TSO;
+ /* Clear bad data from Rx FIFOs */
+ e1000_rx_fifo_flush_82575(&adapter->hw);
+
/* Configure for OS presence */
igb_init_manageability(adapter);
@@ -1304,7 +1307,6 @@ igb_init_locked(struct adapter *adapter)
return;
}
igb_initialize_receive_units(adapter);
- e1000_rx_fifo_flush_82575(&adapter->hw);
/* Enable VLAN support */
if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING)
@@ -1341,9 +1343,9 @@ igb_init_locked(struct adapter *adapter)
/* Set Energy Efficient Ethernet */
if (adapter->hw.phy.media_type == e1000_media_type_copper) {
if (adapter->hw.mac.type == e1000_i354)
- e1000_set_eee_i354(&adapter->hw);
+ e1000_set_eee_i354(&adapter->hw, TRUE, TRUE);
else
- e1000_set_eee_i350(&adapter->hw);
+ e1000_set_eee_i350(&adapter->hw, TRUE, TRUE);
}
}
diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c
index 7f46573..3f56f12 100644
--- a/sys/dev/hwpmc/hwpmc_mod.c
+++ b/sys/dev/hwpmc/hwpmc_mod.c
@@ -1009,14 +1009,14 @@ pmc_attach_one_process(struct proc *p, struct pmc *pm)
/* issue an attach event to a configured log file */
if (pm->pm_owner->po_flags & PMC_PO_OWNS_LOGFILE) {
- pmc_getfilename(p->p_textvp, &fullpath, &freepath);
if (p->p_flag & P_KTHREAD) {
fullpath = kernelname;
freepath = NULL;
- } else
+ } else {
+ pmc_getfilename(p->p_textvp, &fullpath, &freepath);
pmclog_process_pmcattach(pm, p->p_pid, fullpath);
- if (freepath)
- free(freepath, M_TEMP);
+ }
+ free(freepath, M_TEMP);
if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
pmc_log_process_mappings(pm->pm_owner, p);
}
diff --git a/sys/dev/hyperv/include/hyperv.h b/sys/dev/hyperv/include/hyperv.h
index 852e14e..8e2ca57 100644
--- a/sys/dev/hyperv/include/hyperv.h
+++ b/sys/dev/hyperv/include/hyperv.h
@@ -908,30 +908,6 @@ int hv_vmbus_channel_teardown_gpdal(
struct hv_vmbus_channel* vmbus_select_outgoing_channel(struct hv_vmbus_channel *promary);
-/*
- * Work abstraction defines
- */
-typedef struct hv_work_queue {
- struct taskqueue* queue;
- struct proc* proc;
- struct sema* work_sema;
-} hv_work_queue;
-
-typedef struct hv_work_item {
- struct task work;
- void (*callback)(void *);
- void* context;
- hv_work_queue* wq;
-} hv_work_item;
-
-struct hv_work_queue* hv_work_queue_create(char* name);
-
-void hv_work_queue_close(struct hv_work_queue* wq);
-
-int hv_queue_work_item(
- hv_work_queue* wq,
- void (*callback)(void *),
- void* context);
/**
* @brief Get physical address from virtual
*/
@@ -952,8 +928,8 @@ typedef struct hv_vmbus_service {
hv_guid guid; /* Hyper-V GUID */
char *name; /* name of service */
boolean_t enabled; /* service enabled */
- hv_work_queue *work_queue; /* background work queue */
-
+ void* context;
+ struct task task;
/*
* function to initialize service
*/
@@ -963,6 +939,11 @@ typedef struct hv_vmbus_service {
* function to process Hyper-V messages
*/
void (*callback)(void *);
+
+ /*
+ * function to uninitilize service
+ */
+ int (*uninit)(struct hv_vmbus_service *);
} hv_vmbus_service;
extern uint8_t* receive_buffer[];
diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.c b/sys/dev/hyperv/netvsc/hv_net_vsc.c
index 8bf34a8..cd60b4969 100644
--- a/sys/dev/hyperv/netvsc/hv_net_vsc.c
+++ b/sys/dev/hyperv/netvsc/hv_net_vsc.c
@@ -74,10 +74,7 @@ hv_nv_alloc_net_device(struct hv_device *device)
netvsc_dev *net_dev;
hn_softc_t *sc = device_get_softc(device->device);
- net_dev = malloc(sizeof(netvsc_dev), M_NETVSC, M_NOWAIT | M_ZERO);
- if (net_dev == NULL) {
- return (NULL);
- }
+ net_dev = malloc(sizeof(netvsc_dev), M_NETVSC, M_WAITOK | M_ZERO);
net_dev->dev = device;
net_dev->destroy = FALSE;
@@ -136,15 +133,15 @@ hv_nv_get_next_send_section(netvsc_dev *net_dev)
int i;
for (i = 0; i < bitsmap_words; i++) {
- idx = ffs(~bitsmap[i]);
+ idx = ffsl(~bitsmap[i]);
if (0 == idx)
continue;
idx--;
- if (i * BITS_PER_LONG + idx >= net_dev->send_section_count)
- return (ret);
+ KASSERT(i * BITS_PER_LONG + idx < net_dev->send_section_count,
+ ("invalid i %d and idx %lu", i, idx));
- if (synch_test_and_set_bit(idx, &bitsmap[i]))
+ if (atomic_testandset_long(&bitsmap[i], idx))
continue;
ret = i * BITS_PER_LONG + idx;
@@ -224,11 +221,7 @@ hv_nv_init_rx_buffer_with_net_vsp(struct hv_device *device)
init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.num_sections;
net_dev->rx_sections = malloc(net_dev->rx_section_count *
- sizeof(nvsp_1_rx_buf_section), M_NETVSC, M_NOWAIT);
- if (net_dev->rx_sections == NULL) {
- ret = EINVAL;
- goto cleanup;
- }
+ sizeof(nvsp_1_rx_buf_section), M_NETVSC, M_WAITOK);
memcpy(net_dev->rx_sections,
init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.sections,
net_dev->rx_section_count * sizeof(nvsp_1_rx_buf_section));
@@ -326,11 +319,7 @@ hv_nv_init_send_buffer_with_net_vsp(struct hv_device *device)
BITS_PER_LONG);
net_dev->send_section_bitsmap =
malloc(net_dev->bitsmap_words * sizeof(long), M_NETVSC,
- M_NOWAIT | M_ZERO);
- if (NULL == net_dev->send_section_bitsmap) {
- ret = ENOMEM;
- goto cleanup;
- }
+ M_WAITOK | M_ZERO);
goto exit;
@@ -789,8 +778,27 @@ hv_nv_on_send_completion(netvsc_dev *net_dev,
if (NULL != net_vsc_pkt) {
if (net_vsc_pkt->send_buf_section_idx !=
NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX) {
- synch_change_bit(net_vsc_pkt->send_buf_section_idx,
- net_dev->send_section_bitsmap);
+ u_long mask;
+ int idx;
+
+ idx = net_vsc_pkt->send_buf_section_idx /
+ BITS_PER_LONG;
+ KASSERT(idx < net_dev->bitsmap_words,
+ ("invalid section index %u",
+ net_vsc_pkt->send_buf_section_idx));
+ mask = 1UL <<
+ (net_vsc_pkt->send_buf_section_idx %
+ BITS_PER_LONG);
+
+ KASSERT(net_dev->send_section_bitsmap[idx] &
+ mask,
+ ("index bitmap 0x%lx, section index %u, "
+ "bitmap idx %d, bitmask 0x%lx",
+ net_dev->send_section_bitsmap[idx],
+ net_vsc_pkt->send_buf_section_idx,
+ idx, mask));
+ atomic_clear_long(
+ &net_dev->send_section_bitsmap[idx], mask);
}
/* Notify the layer above us */
diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.h b/sys/dev/hyperv/netvsc/hv_net_vsc.h
index c190340..4f52e0d 100644
--- a/sys/dev/hyperv/netvsc/hv_net_vsc.h
+++ b/sys/dev/hyperv/netvsc/hv_net_vsc.h
@@ -1015,6 +1015,7 @@ typedef struct hn_softc {
bus_dma_tag_t hn_tx_rndis_dtag;
int hn_tx_chimney_size;
int hn_tx_chimney_max;
+ uint64_t hn_csum_assist;
struct mtx hn_txlist_spin;
struct hn_txdesc_list hn_txlist;
@@ -1022,6 +1023,7 @@ typedef struct hn_softc {
int hn_txdesc_avail;
int hn_txeof;
+ int hn_sched_tx;
int hn_direct_tx_size;
struct taskqueue *hn_tx_taskq;
struct task hn_start_task;
@@ -1030,11 +1032,12 @@ typedef struct hn_softc {
struct lro_ctrl hn_lro;
int hn_lro_hiwat;
- /* Trust tcp segments verification on host side */
- int hn_trust_hosttcp;
+ /* Trust csum verification on host side */
+ int hn_trust_hcsum; /* HN_TRUST_HCSUM_ */
u_long hn_csum_ip;
u_long hn_csum_tcp;
+ u_long hn_csum_udp;
u_long hn_csum_trusted;
u_long hn_lro_tried;
u_long hn_small_pkts;
@@ -1045,6 +1048,9 @@ typedef struct hn_softc {
u_long hn_tx_chimney;
} hn_softc_t;
+#define HN_TRUST_HCSUM_IP 0x0001
+#define HN_TRUST_HCSUM_TCP 0x0002
+#define HN_TRUST_HCSUM_UDP 0x0004
/*
* Externs
diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
index ab88e36..be43bf4 100644
--- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
+++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
@@ -132,6 +132,8 @@ __FBSDID("$FreeBSD$");
/* YYY should get it from the underlying channel */
#define HN_TX_DESC_CNT 512
+#define HN_LROENT_CNT_DEF 128
+
#define HN_RNDIS_MSG_LEN \
(sizeof(rndis_msg) + \
RNDIS_VLAN_PPI_SIZE + \
@@ -167,14 +169,12 @@ struct hn_txdesc {
#define HN_TXD_FLAG_DMAMAP 0x2
/*
- * A unified flag for all outbound check sum flags is useful,
- * and it helps avoiding unnecessary check sum calculation in
- * network forwarding scenario.
+ * Only enable UDP checksum offloading when it is on 2012R2 or
+ * later. UDP checksum offloading doesn't work on earlier
+ * Windows releases.
*/
-#define HV_CSUM_FOR_OUTBOUND \
- (CSUM_IP|CSUM_IP_UDP|CSUM_IP_TCP|CSUM_IP_SCTP|CSUM_IP_TSO| \
- CSUM_IP_ISCSI|CSUM_IP6_UDP|CSUM_IP6_TCP|CSUM_IP6_SCTP| \
- CSUM_IP6_TSO|CSUM_IP6_ISCSI)
+#define HN_CSUM_ASSIST_WIN8 (CSUM_TCP)
+#define HN_CSUM_ASSIST (CSUM_IP | CSUM_UDP | CSUM_TCP)
/* XXX move to netinet/tcp_lro.h */
#define HN_LRO_HIWAT_MAX 65535
@@ -212,6 +212,14 @@ int hv_promisc_mode = 0; /* normal mode by default */
static int hn_trust_hosttcp = 1;
TUNABLE_INT("dev.hn.trust_hosttcp", &hn_trust_hosttcp);
+/* Trust udp datagrams verification on host side. */
+static int hn_trust_hostudp = 1;
+TUNABLE_INT("dev.hn.trust_hostudp", &hn_trust_hostudp);
+
+/* Trust ip packets verification on host side. */
+static int hn_trust_hostip = 1;
+TUNABLE_INT("dev.hn.trust_hostip", &hn_trust_hostip);
+
#if __FreeBSD_version >= 1100045
/* Limit TSO burst size */
static int hn_tso_maxlen = 0;
@@ -226,6 +234,13 @@ TUNABLE_INT("dev.hn.tx_chimney_size", &hn_tx_chimney_size);
static int hn_direct_tx_size = HN_DIRECT_TX_SIZE_DEF;
TUNABLE_INT("dev.hn.direct_tx_size", &hn_direct_tx_size);
+#if defined(INET) || defined(INET6)
+#if __FreeBSD_version >= 1100095
+static int hn_lro_entry_count = HN_LROENT_CNT_DEF;
+TUNABLE_INT("dev.hn.lro_entry_count", &hn_lro_entry_count);
+#endif
+#endif
+
/*
* Forward declarations
*/
@@ -241,12 +256,14 @@ static void hn_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr);
#ifdef HN_LRO_HIWAT
static int hn_lro_hiwat_sysctl(SYSCTL_HANDLER_ARGS);
#endif
+static int hn_trust_hcsum_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_tx_chimney_size_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_check_iplen(const struct mbuf *, int);
static int hn_create_tx_ring(struct hn_softc *sc);
static void hn_destroy_tx_ring(struct hn_softc *sc);
static void hn_start_taskfunc(void *xsc, int pending);
static void hn_txeof_taskfunc(void *xsc, int pending);
+static int hn_encap(struct hn_softc *, struct hn_txdesc *, struct mbuf **);
static __inline void
hn_set_lro_hiwat(struct hn_softc *sc, int hiwat)
@@ -257,62 +274,6 @@ hn_set_lro_hiwat(struct hn_softc *sc, int hiwat)
#endif
}
-/*
- * NetVsc get message transport protocol type
- */
-static uint32_t get_transport_proto_type(struct mbuf *m_head)
-{
- uint32_t ret_val = TRANSPORT_TYPE_NOT_IP;
- uint16_t ether_type = 0;
- int ether_len = 0;
- struct ether_vlan_header *eh;
-#ifdef INET
- struct ip *iph;
-#endif
-#ifdef INET6
- struct ip6_hdr *ip6;
-#endif
-
- eh = mtod(m_head, struct ether_vlan_header*);
- if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
- ether_len = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
- ether_type = eh->evl_proto;
- } else {
- ether_len = ETHER_HDR_LEN;
- ether_type = eh->evl_encap_proto;
- }
-
- switch (ntohs(ether_type)) {
-#ifdef INET6
- case ETHERTYPE_IPV6:
- ip6 = (struct ip6_hdr *)(m_head->m_data + ether_len);
-
- if (IPPROTO_TCP == ip6->ip6_nxt) {
- ret_val = TRANSPORT_TYPE_IPV6_TCP;
- } else if (IPPROTO_UDP == ip6->ip6_nxt) {
- ret_val = TRANSPORT_TYPE_IPV6_UDP;
- }
- break;
-#endif
-#ifdef INET
- case ETHERTYPE_IP:
- iph = (struct ip *)(m_head->m_data + ether_len);
-
- if (IPPROTO_TCP == iph->ip_p) {
- ret_val = TRANSPORT_TYPE_IPV4_TCP;
- } else if (IPPROTO_UDP == iph->ip_p) {
- ret_val = TRANSPORT_TYPE_IPV4_UDP;
- }
- break;
-#endif
- default:
- ret_val = TRANSPORT_TYPE_NOT_IP;
- break;
- }
-
- return (ret_val);
-}
-
static int
hn_ifmedia_upd(struct ifnet *ifp __unused)
{
@@ -383,6 +344,11 @@ netvsc_attach(device_t dev)
#if __FreeBSD_version >= 1100045
int tso_maxlen;
#endif
+#if defined(INET) || defined(INET6)
+#if __FreeBSD_version >= 1100095
+ int lroent_cnt;
+#endif
+#endif
sc = device_get_softc(dev);
if (sc == NULL) {
@@ -393,8 +359,13 @@ netvsc_attach(device_t dev)
sc->hn_unit = unit;
sc->hn_dev = dev;
sc->hn_lro_hiwat = HN_LRO_HIWAT_DEF;
- sc->hn_trust_hosttcp = hn_trust_hosttcp;
sc->hn_direct_tx_size = hn_direct_tx_size;
+ if (hn_trust_hosttcp)
+ sc->hn_trust_hcsum |= HN_TRUST_HCSUM_TCP;
+ if (hn_trust_hostudp)
+ sc->hn_trust_hcsum |= HN_TRUST_HCSUM_UDP;
+ if (hn_trust_hostip)
+ sc->hn_trust_hcsum |= HN_TRUST_HCSUM_IP;
sc->hn_tx_taskq = taskqueue_create_fast("hn_tx", M_WAITOK,
taskqueue_thread_enqueue, &sc->hn_tx_taskq);
@@ -444,15 +415,12 @@ netvsc_attach(device_t dev)
ifp->if_capenable |=
IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_TSO |
IFCAP_LRO;
- /*
- * Only enable UDP checksum offloading when it is on 2012R2 or
- * later. UDP checksum offloading doesn't work on earlier
- * Windows releases.
- */
+
if (hv_vmbus_protocal_version >= HV_VMBUS_VERSION_WIN8_1)
- ifp->if_hwassist = CSUM_TCP | CSUM_UDP | CSUM_TSO;
+ sc->hn_csum_assist = HN_CSUM_ASSIST;
else
- ifp->if_hwassist = CSUM_TCP | CSUM_TSO;
+ sc->hn_csum_assist = HN_CSUM_ASSIST_WIN8;
+ ifp->if_hwassist = sc->hn_csum_assist | CSUM_TSO;
error = hv_rf_on_device_add(device_ctx, &device_info);
if (error)
@@ -463,9 +431,17 @@ netvsc_attach(device_t dev)
}
#if defined(INET) || defined(INET6)
+#if __FreeBSD_version >= 1100095
+ lroent_cnt = hn_lro_entry_count;
+ if (lroent_cnt < TCP_LRO_ENTRIES)
+ lroent_cnt = TCP_LRO_ENTRIES;
+ tcp_lro_init_args(&sc->hn_lro, ifp, lroent_cnt, 0);
+ device_printf(dev, "LRO: entry count %d\n", lroent_cnt);
+#else
tcp_lro_init(&sc->hn_lro);
/* Driver private LRO settings */
sc->hn_lro.ifp = ifp;
+#endif
#ifdef HN_LRO_HIWAT
sc->hn_lro.lro_hiwat = sc->hn_lro_hiwat;
#endif
@@ -509,17 +485,30 @@ netvsc_attach(device_t dev)
CTLTYPE_INT | CTLFLAG_RW, sc, 0, hn_lro_hiwat_sysctl,
"I", "LRO high watermark");
#endif
- SYSCTL_ADD_INT(ctx, child, OID_AUTO, "trust_hosttcp",
- CTLFLAG_RW, &sc->hn_trust_hosttcp, 0,
+ SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "trust_hosttcp",
+ CTLTYPE_INT | CTLFLAG_RW, sc, HN_TRUST_HCSUM_TCP,
+ hn_trust_hcsum_sysctl, "I",
"Trust tcp segement verification on host side, "
"when csum info is missing");
+ SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "trust_hostudp",
+ CTLTYPE_INT | CTLFLAG_RW, sc, HN_TRUST_HCSUM_UDP,
+ hn_trust_hcsum_sysctl, "I",
+ "Trust udp datagram verification on host side, "
+ "when csum info is missing");
+ SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "trust_hostip",
+ CTLTYPE_INT | CTLFLAG_RW, sc, HN_TRUST_HCSUM_IP,
+ hn_trust_hcsum_sysctl, "I",
+ "Trust ip packet verification on host side, "
+ "when csum info is missing");
SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "csum_ip",
CTLFLAG_RW, &sc->hn_csum_ip, "RXCSUM IP");
SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "csum_tcp",
CTLFLAG_RW, &sc->hn_csum_tcp, "RXCSUM TCP");
+ SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "csum_udp",
+ CTLFLAG_RW, &sc->hn_csum_udp, "RXCSUM UDP");
SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "csum_trusted",
CTLFLAG_RW, &sc->hn_csum_trusted,
- "# of TCP segements that we trust host's csum verification");
+ "# of packets that we trust host's csum verification");
SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "small_pkts",
CTLFLAG_RW, &sc->hn_small_pkts, "# of small packets received");
SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "no_txdescs",
@@ -545,6 +534,10 @@ netvsc_attach(device_t dev)
SYSCTL_ADD_INT(ctx, child, OID_AUTO, "direct_tx_size",
CTLFLAG_RW, &sc->hn_direct_tx_size, 0,
"Size of the packet for direct transmission");
+ SYSCTL_ADD_INT(ctx, child, OID_AUTO, "sched_tx",
+ CTLFLAG_RW, &sc->hn_sched_tx, 0,
+ "Always schedule transmission "
+ "instead of doing direct transmission");
if (unit == 0) {
struct sysctl_ctx_list *dc_ctx;
@@ -562,6 +555,14 @@ netvsc_attach(device_t dev)
CTLFLAG_RD, &hn_trust_hosttcp, 0,
"Trust tcp segement verification on host side, "
"when csum info is missing (global setting)");
+ SYSCTL_ADD_INT(dc_ctx, dc_child, OID_AUTO, "trust_hostudp",
+ CTLFLAG_RD, &hn_trust_hostudp, 0,
+ "Trust udp datagram verification on host side, "
+ "when csum info is missing (global setting)");
+ SYSCTL_ADD_INT(dc_ctx, dc_child, OID_AUTO, "trust_hostip",
+ CTLFLAG_RD, &hn_trust_hostip, 0,
+ "Trust ip packet verification on host side, "
+ "when csum info is missing (global setting)");
SYSCTL_ADD_INT(dc_ctx, dc_child, OID_AUTO, "tx_chimney_size",
CTLFLAG_RD, &hn_tx_chimney_size, 0,
"Chimney send packet size limit");
@@ -572,6 +573,12 @@ netvsc_attach(device_t dev)
SYSCTL_ADD_INT(dc_ctx, dc_child, OID_AUTO, "direct_tx_size",
CTLFLAG_RD, &hn_direct_tx_size, 0,
"Size of the packet for direct transmission");
+#if defined(INET) || defined(INET6)
+#if __FreeBSD_version >= 1100095
+ SYSCTL_ADD_INT(dc_ctx, dc_child, OID_AUTO, "lro_entry_count",
+ CTLFLAG_RD, &hn_lro_entry_count, 0, "LRO entry count");
+#endif
+#endif
}
return (0);
@@ -761,6 +768,15 @@ void
netvsc_channel_rollup(struct hv_device *device_ctx)
{
struct hn_softc *sc = device_get_softc(device_ctx->device);
+#if defined(INET) || defined(INET6)
+ struct lro_ctrl *lro = &sc->hn_lro;
+ struct lro_entry *queued;
+
+ while ((queued = SLIST_FIRST(&lro->lro_active)) != NULL) {
+ SLIST_REMOVE_HEAD(&lro->lro_active, next);
+ tcp_lro_flush(lro, queued);
+ }
+#endif
if (!sc->hn_txeof)
return;
@@ -770,177 +786,94 @@ netvsc_channel_rollup(struct hv_device *device_ctx)
}
/*
- * Start a transmit of one or more packets
+ * NOTE:
+ * This this function fails, then both txd and m_head0 will be freed
*/
static int
-hn_start_locked(struct ifnet *ifp, int len)
+hn_encap(struct hn_softc *sc, struct hn_txdesc *txd, struct mbuf **m_head0)
{
- hn_softc_t *sc = ifp->if_softc;
- struct hv_device *device_ctx = vmbus_get_devctx(sc->hn_dev);
- netvsc_dev *net_dev = sc->net_dev;
- struct ether_vlan_header *eh;
+ bus_dma_segment_t segs[HN_TX_DATA_SEGCNT_MAX];
+ int error, nsegs, i;
+ struct mbuf *m_head = *m_head0;
+ netvsc_packet *packet;
rndis_msg *rndis_mesg;
rndis_packet *rndis_pkt;
rndis_per_packet_info *rppi;
- ndis_8021q_info *rppi_vlan_info;
- rndis_tcp_ip_csum_info *csum_info;
- rndis_tcp_tso_info *tso_info;
- int ether_len;
- uint32_t rndis_msg_size = 0;
- uint32_t trans_proto_type;
+ uint32_t rndis_msg_size;
- if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
- IFF_DRV_RUNNING)
- return 0;
+ packet = &txd->netvsc_pkt;
+ packet->is_data_pkt = TRUE;
+ packet->tot_data_buf_len = m_head->m_pkthdr.len;
- while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
- bus_dma_segment_t segs[HN_TX_DATA_SEGCNT_MAX];
- int error, nsegs, i, send_failed = 0;
- struct hn_txdesc *txd;
- netvsc_packet *packet;
- struct mbuf *m_head;
-
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
- if (m_head == NULL)
- break;
+ /*
+ * extension points to the area reserved for the
+ * rndis_filter_packet, which is placed just after
+ * the netvsc_packet (and rppi struct, if present;
+ * length is updated later).
+ */
+ rndis_mesg = txd->rndis_msg;
+ /* XXX not necessary */
+ memset(rndis_mesg, 0, HN_RNDIS_MSG_LEN);
+ rndis_mesg->ndis_msg_type = REMOTE_NDIS_PACKET_MSG;
- if (len > 0 && m_head->m_pkthdr.len > len) {
- /*
- * This sending could be time consuming; let callers
- * dispatch this packet sending (and sending of any
- * following up packets) to tx taskqueue.
- */
- IF_PREPEND(&ifp->if_snd, m_head);
- return 1;
- }
+ rndis_pkt = &rndis_mesg->msg.packet;
+ rndis_pkt->data_offset = sizeof(rndis_packet);
+ rndis_pkt->data_length = packet->tot_data_buf_len;
+ rndis_pkt->per_pkt_info_offset = sizeof(rndis_packet);
- txd = hn_txdesc_get(sc);
- if (txd == NULL) {
- sc->hn_no_txdescs++;
- IF_PREPEND(&ifp->if_snd, m_head);
- atomic_set_int(&ifp->if_drv_flags, IFF_DRV_OACTIVE);
- break;
- }
+ rndis_msg_size = RNDIS_MESSAGE_SIZE(rndis_packet);
- packet = &txd->netvsc_pkt;
- packet->is_data_pkt = TRUE;
- /* Initialize it from the mbuf */
- packet->tot_data_buf_len = m_head->m_pkthdr.len;
+ if (m_head->m_flags & M_VLANTAG) {
+ ndis_8021q_info *rppi_vlan_info;
- /*
- * extension points to the area reserved for the
- * rndis_filter_packet, which is placed just after
- * the netvsc_packet (and rppi struct, if present;
- * length is updated later).
- */
- rndis_mesg = txd->rndis_msg;
- /* XXX not necessary */
- memset(rndis_mesg, 0, HN_RNDIS_MSG_LEN);
- rndis_mesg->ndis_msg_type = REMOTE_NDIS_PACKET_MSG;
+ rndis_msg_size += RNDIS_VLAN_PPI_SIZE;
+ rppi = hv_set_rppi_data(rndis_mesg, RNDIS_VLAN_PPI_SIZE,
+ ieee_8021q_info);
- rndis_pkt = &rndis_mesg->msg.packet;
- rndis_pkt->data_offset = sizeof(rndis_packet);
- rndis_pkt->data_length = packet->tot_data_buf_len;
- rndis_pkt->per_pkt_info_offset = sizeof(rndis_packet);
+ rppi_vlan_info = (ndis_8021q_info *)((uint8_t *)rppi +
+ rppi->per_packet_info_offset);
+ rppi_vlan_info->u1.s1.vlan_id =
+ m_head->m_pkthdr.ether_vtag & 0xfff;
+ }
- rndis_msg_size = RNDIS_MESSAGE_SIZE(rndis_packet);
+ if (m_head->m_pkthdr.csum_flags & CSUM_TSO) {
+ rndis_tcp_tso_info *tso_info;
+ struct ether_vlan_header *eh;
+ int ether_len;
/*
- * If the Hyper-V infrastructure needs to embed a VLAN tag,
- * initialize netvsc_packet and rppi struct values as needed.
+ * XXX need m_pullup and use mtodo
*/
- if (m_head->m_flags & M_VLANTAG) {
- /*
- * set up some additional fields so the Hyper-V infrastructure will stuff the VLAN tag
- * into the frame.
- */
- rndis_msg_size += RNDIS_VLAN_PPI_SIZE;
-
- rppi = hv_set_rppi_data(rndis_mesg, RNDIS_VLAN_PPI_SIZE,
- ieee_8021q_info);
-
- /* VLAN info immediately follows rppi struct */
- rppi_vlan_info = (ndis_8021q_info *)((char*)rppi +
- rppi->per_packet_info_offset);
- /* FreeBSD does not support CFI or priority */
- rppi_vlan_info->u1.s1.vlan_id =
- m_head->m_pkthdr.ether_vtag & 0xfff;
- }
-
- /* Only check the flags for outbound and ignore the ones for inbound */
- if (0 == (m_head->m_pkthdr.csum_flags & HV_CSUM_FOR_OUTBOUND)) {
- goto pre_send;
- }
-
eh = mtod(m_head, struct ether_vlan_header*);
- if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
+ if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN))
ether_len = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
- } else {
+ else
ether_len = ETHER_HDR_LEN;
- }
-
- trans_proto_type = get_transport_proto_type(m_head);
- if (TRANSPORT_TYPE_NOT_IP == trans_proto_type) {
- goto pre_send;
- }
- /*
- * TSO packet needless to setup the send side checksum
- * offload.
- */
- if (m_head->m_pkthdr.csum_flags & CSUM_TSO) {
- goto do_tso;
- }
-
- /* setup checksum offload */
- rndis_msg_size += RNDIS_CSUM_PPI_SIZE;
- rppi = hv_set_rppi_data(rndis_mesg, RNDIS_CSUM_PPI_SIZE,
- tcpip_chksum_info);
- csum_info = (rndis_tcp_ip_csum_info *)((char*)rppi +
- rppi->per_packet_info_offset);
-
- if (trans_proto_type & (TYPE_IPV4 << 16)) {
- csum_info->xmit.is_ipv4 = 1;
- } else {
- csum_info->xmit.is_ipv6 = 1;
- }
-
- if (trans_proto_type & TYPE_TCP) {
- csum_info->xmit.tcp_csum = 1;
- csum_info->xmit.tcp_header_offset = 0;
- } else if (trans_proto_type & TYPE_UDP) {
- csum_info->xmit.udp_csum = 1;
- }
-
- goto pre_send;
-
-do_tso:
- /* setup TCP segmentation offload */
rndis_msg_size += RNDIS_TSO_PPI_SIZE;
rppi = hv_set_rppi_data(rndis_mesg, RNDIS_TSO_PPI_SIZE,
tcp_large_send_info);
-
- tso_info = (rndis_tcp_tso_info *)((char *)rppi +
+
+ tso_info = (rndis_tcp_tso_info *)((uint8_t *)rppi +
rppi->per_packet_info_offset);
tso_info->lso_v2_xmit.type =
RNDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE;
-
+
#ifdef INET
- if (trans_proto_type & (TYPE_IPV4 << 16)) {
+ if (m_head->m_pkthdr.csum_flags & CSUM_IP_TSO) {
struct ip *ip =
(struct ip *)(m_head->m_data + ether_len);
unsigned long iph_len = ip->ip_hl << 2;
struct tcphdr *th =
(struct tcphdr *)((caddr_t)ip + iph_len);
-
+
tso_info->lso_v2_xmit.ip_version =
RNDIS_TCP_LARGE_SEND_OFFLOAD_IPV4;
ip->ip_len = 0;
ip->ip_sum = 0;
-
+
th->th_sum = in_pseudo(ip->ip_src.s_addr,
- ip->ip_dst.s_addr,
- htons(IPPROTO_TCP));
+ ip->ip_dst.s_addr, htons(IPPROTO_TCP));
}
#endif
#if defined(INET6) && defined(INET)
@@ -948,8 +881,8 @@ do_tso:
#endif
#ifdef INET6
{
- struct ip6_hdr *ip6 =
- (struct ip6_hdr *)(m_head->m_data + ether_len);
+ struct ip6_hdr *ip6 = (struct ip6_hdr *)
+ (m_head->m_data + ether_len);
struct tcphdr *th = (struct tcphdr *)(ip6 + 1);
tso_info->lso_v2_xmit.ip_version =
@@ -960,98 +893,163 @@ do_tso:
#endif
tso_info->lso_v2_xmit.tcp_header_offset = 0;
tso_info->lso_v2_xmit.mss = m_head->m_pkthdr.tso_segsz;
+ } else if (m_head->m_pkthdr.csum_flags & sc->hn_csum_assist) {
+ rndis_tcp_ip_csum_info *csum_info;
-pre_send:
- rndis_mesg->msg_len = packet->tot_data_buf_len + rndis_msg_size;
- packet->tot_data_buf_len = rndis_mesg->msg_len;
-
- /* send packet with send buffer */
- if (packet->tot_data_buf_len < sc->hn_tx_chimney_size) {
- uint32_t send_buf_section_idx;
-
- send_buf_section_idx =
- hv_nv_get_next_send_section(net_dev);
- if (send_buf_section_idx !=
- NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX) {
- uint8_t *dest = ((uint8_t *)net_dev->send_buf +
- (send_buf_section_idx *
- net_dev->send_section_size));
-
- memcpy(dest, rndis_mesg, rndis_msg_size);
- dest += rndis_msg_size;
-
- m_copydata(m_head, 0, m_head->m_pkthdr.len,
- dest);
-
- packet->send_buf_section_idx =
- send_buf_section_idx;
- packet->send_buf_section_size =
- packet->tot_data_buf_len;
- packet->page_buf_count = 0;
- sc->hn_tx_chimney++;
- goto do_send;
- }
- }
-
- error = hn_txdesc_dmamap_load(sc, txd, &m_head, segs, &nsegs);
- if (error) {
- int freed;
+ rndis_msg_size += RNDIS_CSUM_PPI_SIZE;
+ rppi = hv_set_rppi_data(rndis_mesg, RNDIS_CSUM_PPI_SIZE,
+ tcpip_chksum_info);
+ csum_info = (rndis_tcp_ip_csum_info *)((uint8_t *)rppi +
+ rppi->per_packet_info_offset);
- /*
- * This mbuf is not linked w/ the txd yet, so free
- * it now.
- */
- m_freem(m_head);
- freed = hn_txdesc_put(sc, txd);
- KASSERT(freed != 0,
- ("fail to free txd upon txdma error"));
+ csum_info->xmit.is_ipv4 = 1;
+ if (m_head->m_pkthdr.csum_flags & CSUM_IP)
+ csum_info->xmit.ip_header_csum = 1;
- sc->hn_txdma_failed++;
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
- continue;
+ if (m_head->m_pkthdr.csum_flags & CSUM_TCP) {
+ csum_info->xmit.tcp_csum = 1;
+ csum_info->xmit.tcp_header_offset = 0;
+ } else if (m_head->m_pkthdr.csum_flags & CSUM_UDP) {
+ csum_info->xmit.udp_csum = 1;
}
+ }
+
+ rndis_mesg->msg_len = packet->tot_data_buf_len + rndis_msg_size;
+ packet->tot_data_buf_len = rndis_mesg->msg_len;
- packet->page_buf_count = nsegs +
- HV_RF_NUM_TX_RESERVED_PAGE_BUFS;
+ /*
+ * Chimney send, if the packet could fit into one chimney buffer.
+ */
+ if (packet->tot_data_buf_len < sc->hn_tx_chimney_size) {
+ netvsc_dev *net_dev = sc->net_dev;
+ uint32_t send_buf_section_idx;
+
+ send_buf_section_idx =
+ hv_nv_get_next_send_section(net_dev);
+ if (send_buf_section_idx !=
+ NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX) {
+ uint8_t *dest = ((uint8_t *)net_dev->send_buf +
+ (send_buf_section_idx *
+ net_dev->send_section_size));
+
+ memcpy(dest, rndis_mesg, rndis_msg_size);
+ dest += rndis_msg_size;
+ m_copydata(m_head, 0, m_head->m_pkthdr.len, dest);
+
+ packet->send_buf_section_idx = send_buf_section_idx;
+ packet->send_buf_section_size =
+ packet->tot_data_buf_len;
+ packet->page_buf_count = 0;
+ sc->hn_tx_chimney++;
+ goto done;
+ }
+ }
- /* send packet with page buffer */
- packet->page_buffers[0].pfn = atop(txd->rndis_msg_paddr);
- packet->page_buffers[0].offset =
- txd->rndis_msg_paddr & PAGE_MASK;
- packet->page_buffers[0].length = rndis_msg_size;
+ error = hn_txdesc_dmamap_load(sc, txd, &m_head, segs, &nsegs);
+ if (error) {
+ int freed;
/*
- * Fill the page buffers with mbuf info starting at index
- * HV_RF_NUM_TX_RESERVED_PAGE_BUFS.
+ * This mbuf is not linked w/ the txd yet, so free it now.
*/
- for (i = 0; i < nsegs; ++i) {
- hv_vmbus_page_buffer *pb = &packet->page_buffers[
- i + HV_RF_NUM_TX_RESERVED_PAGE_BUFS];
+ m_freem(m_head);
+ *m_head0 = NULL;
- pb->pfn = atop(segs[i].ds_addr);
- pb->offset = segs[i].ds_addr & PAGE_MASK;
- pb->length = segs[i].ds_len;
- }
+ freed = hn_txdesc_put(sc, txd);
+ KASSERT(freed != 0,
+ ("fail to free txd upon txdma error"));
- packet->send_buf_section_idx =
- NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX;
- packet->send_buf_section_size = 0;
+ sc->hn_txdma_failed++;
+ if_inc_counter(sc->hn_ifp, IFCOUNTER_OERRORS, 1);
+ return error;
+ }
+ *m_head0 = m_head;
+
+ packet->page_buf_count = nsegs + HV_RF_NUM_TX_RESERVED_PAGE_BUFS;
+
+ /* send packet with page buffer */
+ packet->page_buffers[0].pfn = atop(txd->rndis_msg_paddr);
+ packet->page_buffers[0].offset = txd->rndis_msg_paddr & PAGE_MASK;
+ packet->page_buffers[0].length = rndis_msg_size;
-do_send:
- txd->m = m_head;
+ /*
+ * Fill the page buffers with mbuf info starting at index
+ * HV_RF_NUM_TX_RESERVED_PAGE_BUFS.
+ */
+ for (i = 0; i < nsegs; ++i) {
+ hv_vmbus_page_buffer *pb = &packet->page_buffers[
+ i + HV_RF_NUM_TX_RESERVED_PAGE_BUFS];
+
+ pb->pfn = atop(segs[i].ds_addr);
+ pb->offset = segs[i].ds_addr & PAGE_MASK;
+ pb->length = segs[i].ds_len;
+ }
+
+ packet->send_buf_section_idx =
+ NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX;
+ packet->send_buf_section_size = 0;
+done:
+ txd->m = m_head;
+
+ /* Set the completion routine */
+ packet->compl.send.on_send_completion = netvsc_xmit_completion;
+ packet->compl.send.send_completion_context = packet;
+ packet->compl.send.send_completion_tid = (uint64_t)(uintptr_t)txd;
+
+ return 0;
+}
+
+/*
+ * Start a transmit of one or more packets
+ */
+static int
+hn_start_locked(struct ifnet *ifp, int len)
+{
+ struct hn_softc *sc = ifp->if_softc;
+ struct hv_device *device_ctx = vmbus_get_devctx(sc->hn_dev);
+
+ if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
+ IFF_DRV_RUNNING)
+ return 0;
+
+ while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
+ int error, send_failed = 0;
+ struct hn_txdesc *txd;
+ struct mbuf *m_head;
+
+ IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
+ if (m_head == NULL)
+ break;
+
+ if (len > 0 && m_head->m_pkthdr.len > len) {
+ /*
+ * This sending could be time consuming; let callers
+ * dispatch this packet sending (and sending of any
+ * following up packets) to tx taskqueue.
+ */
+ IF_PREPEND(&ifp->if_snd, m_head);
+ return 1;
+ }
- /* Set the completion routine */
- packet->compl.send.on_send_completion = netvsc_xmit_completion;
- packet->compl.send.send_completion_context = packet;
- packet->compl.send.send_completion_tid =
- (uint64_t)(uintptr_t)txd;
+ txd = hn_txdesc_get(sc);
+ if (txd == NULL) {
+ sc->hn_no_txdescs++;
+ IF_PREPEND(&ifp->if_snd, m_head);
+ atomic_set_int(&ifp->if_drv_flags, IFF_DRV_OACTIVE);
+ break;
+ }
+ error = hn_encap(sc, txd, &m_head);
+ if (error) {
+ /* Both txd and m_head are freed */
+ continue;
+ }
again:
/*
* Make sure that txd is not freed before ETHER_BPF_MTAP.
*/
hn_txdesc_hold(txd);
- error = hv_nv_on_send(device_ctx, packet);
+ error = hv_nv_on_send(device_ctx, &txd->netvsc_pkt);
if (!error) {
ETHER_BPF_MTAP(ifp, m_head);
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
@@ -1191,7 +1189,7 @@ netvsc_recv(struct hv_device *device_ctx, netvsc_packet *packet,
struct mbuf *m_new;
struct ifnet *ifp;
device_t dev = device_ctx->device;
- int size, do_lro = 0;
+ int size, do_lro = 0, do_csum = 1;
if (sc == NULL) {
return (0); /* TODO: KYS how can this be! */
@@ -1239,21 +1237,28 @@ netvsc_recv(struct hv_device *device_ctx, netvsc_packet *packet,
}
m_new->m_pkthdr.rcvif = ifp;
+ if (__predict_false((ifp->if_capenable & IFCAP_RXCSUM) == 0))
+ do_csum = 0;
+
/* receive side checksum offload */
- if (NULL != csum_info) {
+ if (csum_info != NULL) {
/* IP csum offload */
- if (csum_info->receive.ip_csum_succeeded) {
+ if (csum_info->receive.ip_csum_succeeded && do_csum) {
m_new->m_pkthdr.csum_flags |=
(CSUM_IP_CHECKED | CSUM_IP_VALID);
sc->hn_csum_ip++;
}
- /* TCP csum offload */
- if (csum_info->receive.tcp_csum_succeeded) {
+ /* TCP/UDP csum offload */
+ if ((csum_info->receive.tcp_csum_succeeded ||
+ csum_info->receive.udp_csum_succeeded) && do_csum) {
m_new->m_pkthdr.csum_flags |=
(CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
m_new->m_pkthdr.csum_data = 0xffff;
- sc->hn_csum_tcp++;
+ if (csum_info->receive.tcp_csum_succeeded)
+ sc->hn_csum_tcp++;
+ else
+ sc->hn_csum_udp++;
}
if (csum_info->receive.ip_csum_succeeded &&
@@ -1284,7 +1289,8 @@ netvsc_recv(struct hv_device *device_ctx, netvsc_packet *packet,
pr = hn_check_iplen(m_new, hoff);
if (pr == IPPROTO_TCP) {
- if (sc->hn_trust_hosttcp) {
+ if (do_csum &&
+ (sc->hn_trust_hcsum & HN_TRUST_HCSUM_TCP)) {
sc->hn_csum_trusted++;
m_new->m_pkthdr.csum_flags |=
(CSUM_IP_CHECKED | CSUM_IP_VALID |
@@ -1293,6 +1299,20 @@ netvsc_recv(struct hv_device *device_ctx, netvsc_packet *packet,
}
/* Rely on SW csum verification though... */
do_lro = 1;
+ } else if (pr == IPPROTO_UDP) {
+ if (do_csum &&
+ (sc->hn_trust_hcsum & HN_TRUST_HCSUM_UDP)) {
+ sc->hn_csum_trusted++;
+ m_new->m_pkthdr.csum_flags |=
+ (CSUM_IP_CHECKED | CSUM_IP_VALID |
+ CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
+ m_new->m_pkthdr.csum_data = 0xffff;
+ }
+ } else if (pr != IPPROTO_DONE && do_csum &&
+ (sc->hn_trust_hcsum & HN_TRUST_HCSUM_IP)) {
+ sc->hn_csum_trusted++;
+ m_new->m_pkthdr.csum_flags |=
+ (CSUM_IP_CHECKED | CSUM_IP_VALID);
}
}
}
@@ -1331,18 +1351,8 @@ skip:
}
void
-netvsc_recv_rollup(struct hv_device *device_ctx)
+netvsc_recv_rollup(struct hv_device *device_ctx __unused)
{
-#if defined(INET) || defined(INET6)
- hn_softc_t *sc = device_get_softc(device_ctx->device);
- struct lro_ctrl *lro = &sc->hn_lro;
- struct lro_entry *queued;
-
- while ((queued = SLIST_FIRST(&lro->lro_active)) != NULL) {
- SLIST_REMOVE_HEAD(&lro->lro_active, next);
- tcp_lro_flush(lro, queued);
- }
-#endif
}
/*
@@ -1506,47 +1516,40 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
error = 0;
break;
case SIOCSIFCAP:
+ NV_LOCK(sc);
+
mask = ifr->ifr_reqcap ^ ifp->if_capenable;
if (mask & IFCAP_TXCSUM) {
- if (IFCAP_TXCSUM & ifp->if_capenable) {
- ifp->if_capenable &= ~IFCAP_TXCSUM;
- ifp->if_hwassist &= ~(CSUM_TCP | CSUM_UDP);
- } else {
- ifp->if_capenable |= IFCAP_TXCSUM;
- /*
- * Only enable UDP checksum offloading on
- * Windows Server 2012R2 or later releases.
- */
- if (hv_vmbus_protocal_version >=
- HV_VMBUS_VERSION_WIN8_1) {
- ifp->if_hwassist |=
- (CSUM_TCP | CSUM_UDP);
- } else {
- ifp->if_hwassist |= CSUM_TCP;
- }
- }
+ ifp->if_capenable ^= IFCAP_TXCSUM;
+ if (ifp->if_capenable & IFCAP_TXCSUM)
+ ifp->if_hwassist |= sc->hn_csum_assist;
+ else
+ ifp->if_hwassist &= ~sc->hn_csum_assist;
}
- if (mask & IFCAP_RXCSUM) {
- if (IFCAP_RXCSUM & ifp->if_capenable) {
- ifp->if_capenable &= ~IFCAP_RXCSUM;
- } else {
- ifp->if_capenable |= IFCAP_RXCSUM;
- }
- }
+ if (mask & IFCAP_RXCSUM)
+ ifp->if_capenable ^= IFCAP_RXCSUM;
+
if (mask & IFCAP_LRO)
ifp->if_capenable ^= IFCAP_LRO;
if (mask & IFCAP_TSO4) {
ifp->if_capenable ^= IFCAP_TSO4;
- ifp->if_hwassist ^= CSUM_IP_TSO;
+ if (ifp->if_capenable & IFCAP_TSO4)
+ ifp->if_hwassist |= CSUM_IP_TSO;
+ else
+ ifp->if_hwassist &= ~CSUM_IP_TSO;
}
if (mask & IFCAP_TSO6) {
ifp->if_capenable ^= IFCAP_TSO6;
- ifp->if_hwassist ^= CSUM_IP6_TSO;
+ if (ifp->if_capenable & IFCAP_TSO6)
+ ifp->if_hwassist |= CSUM_IP6_TSO;
+ else
+ ifp->if_hwassist &= ~CSUM_IP6_TSO;
}
+ NV_UNLOCK(sc);
error = 0;
break;
case SIOCADDMULTI:
@@ -1603,9 +1606,11 @@ hn_stop(hn_softc_t *sc)
static void
hn_start(struct ifnet *ifp)
{
- hn_softc_t *sc;
+ struct hn_softc *sc = ifp->if_softc;
+
+ if (sc->hn_sched_tx)
+ goto do_sched;
- sc = ifp->if_softc;
if (NV_TRYLOCK(sc)) {
int sched;
@@ -1614,15 +1619,18 @@ hn_start(struct ifnet *ifp)
if (!sched)
return;
}
+do_sched:
taskqueue_enqueue_fast(sc->hn_tx_taskq, &sc->hn_start_task);
}
static void
hn_start_txeof(struct ifnet *ifp)
{
- hn_softc_t *sc;
+ struct hn_softc *sc = ifp->if_softc;
+
+ if (sc->hn_sched_tx)
+ goto do_sched;
- sc = ifp->if_softc;
if (NV_TRYLOCK(sc)) {
int sched;
@@ -1634,6 +1642,7 @@ hn_start_txeof(struct ifnet *ifp)
&sc->hn_start_task);
}
} else {
+do_sched:
/*
* Release the OACTIVE earlier, with the hope, that
* others could catch up. The task will clear the
@@ -1735,6 +1744,30 @@ hn_lro_hiwat_sysctl(SYSCTL_HANDLER_ARGS)
#endif /* HN_LRO_HIWAT */
static int
+hn_trust_hcsum_sysctl(SYSCTL_HANDLER_ARGS)
+{
+ struct hn_softc *sc = arg1;
+ int hcsum = arg2;
+ int on, error;
+
+ on = 0;
+ if (sc->hn_trust_hcsum & hcsum)
+ on = 1;
+
+ error = sysctl_handle_int(oidp, &on, 0, req);
+ if (error || req->newptr == NULL)
+ return error;
+
+ NV_LOCK(sc);
+ if (on)
+ sc->hn_trust_hcsum |= hcsum;
+ else
+ sc->hn_trust_hcsum &= ~hcsum;
+ NV_UNLOCK(sc);
+ return 0;
+}
+
+static int
hn_tx_chimney_size_sysctl(SYSCTL_HANDLER_ARGS)
{
struct hn_softc *sc = arg1;
diff --git a/sys/dev/hyperv/netvsc/hv_rndis_filter.c b/sys/dev/hyperv/netvsc/hv_rndis_filter.c
index dfd0b47..9fb78ee 100644
--- a/sys/dev/hyperv/netvsc/hv_rndis_filter.c
+++ b/sys/dev/hyperv/netvsc/hv_rndis_filter.c
@@ -135,12 +135,9 @@ hv_get_rndis_device(void)
{
rndis_device *device;
- device = malloc(sizeof(rndis_device), M_NETVSC, M_NOWAIT | M_ZERO);
- if (device == NULL) {
- return (NULL);
- }
+ device = malloc(sizeof(rndis_device), M_NETVSC, M_WAITOK | M_ZERO);
- mtx_init(&device->req_lock, "HV-FRL", NULL, MTX_SPIN | MTX_RECURSE);
+ mtx_init(&device->req_lock, "HV-FRL", NULL, MTX_DEF);
/* Same effect as STAILQ_HEAD_INITIALIZER() static initializer */
STAILQ_INIT(&device->myrequest_list);
@@ -171,10 +168,7 @@ hv_rndis_request(rndis_device *device, uint32_t message_type,
rndis_msg *rndis_mesg;
rndis_set_request *set;
- request = malloc(sizeof(rndis_request), M_NETVSC, M_NOWAIT | M_ZERO);
- if (request == NULL) {
- return (NULL);
- }
+ request = malloc(sizeof(rndis_request), M_NETVSC, M_WAITOK | M_ZERO);
sema_init(&request->wait_sema, 0, "rndis sema");
@@ -193,9 +187,9 @@ hv_rndis_request(rndis_device *device, uint32_t message_type,
set->request_id += 1;
/* Add to the request list */
- mtx_lock_spin(&device->req_lock);
+ mtx_lock(&device->req_lock);
STAILQ_INSERT_TAIL(&device->myrequest_list, request, mylist_entry);
- mtx_unlock_spin(&device->req_lock);
+ mtx_unlock(&device->req_lock);
return (request);
}
@@ -206,14 +200,14 @@ hv_rndis_request(rndis_device *device, uint32_t message_type,
static inline void
hv_put_rndis_request(rndis_device *device, rndis_request *request)
{
- mtx_lock_spin(&device->req_lock);
+ mtx_lock(&device->req_lock);
/* Fixme: Has O(n) performance */
/*
* XXXKYS: Use Doubly linked lists.
*/
STAILQ_REMOVE(&device->myrequest_list, request, rndis_request_,
mylist_entry);
- mtx_unlock_spin(&device->req_lock);
+ mtx_unlock(&device->req_lock);
sema_destroy(&request->wait_sema);
free(request, M_NETVSC);
@@ -270,7 +264,7 @@ hv_rf_receive_response(rndis_device *device, rndis_msg *response)
rndis_request *next_request;
boolean_t found = FALSE;
- mtx_lock_spin(&device->req_lock);
+ mtx_lock(&device->req_lock);
request = STAILQ_FIRST(&device->myrequest_list);
while (request != NULL) {
/*
@@ -285,7 +279,7 @@ hv_rf_receive_response(rndis_device *device, rndis_msg *response)
next_request = STAILQ_NEXT(request, mylist_entry);
request = next_request;
}
- mtx_unlock_spin(&device->req_lock);
+ mtx_unlock(&device->req_lock);
if (found) {
if (response->msg_len <= sizeof(rndis_msg)) {
diff --git a/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c b/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c
index 098c8c9..9683ad8 100644
--- a/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c
+++ b/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c
@@ -1524,13 +1524,12 @@ static void
storvsc_destroy_bounce_buffer(struct sglist *sgl)
{
struct hv_sgl_node *sgl_node = NULL;
-
- sgl_node = LIST_FIRST(&g_hv_sgl_page_pool.in_use_sgl_list);
- LIST_REMOVE(sgl_node, link);
- if (NULL == sgl_node) {
+ if (LIST_EMPTY(&g_hv_sgl_page_pool.in_use_sgl_list)) {
printf("storvsc error: not enough in use sgl\n");
return;
}
+ sgl_node = LIST_FIRST(&g_hv_sgl_page_pool.in_use_sgl_list);
+ LIST_REMOVE(sgl_node, link);
sgl_node->sgl_data = sgl;
LIST_INSERT_HEAD(&g_hv_sgl_page_pool.free_sgl_list, sgl_node, link);
}
@@ -1556,12 +1555,12 @@ storvsc_create_bounce_buffer(uint16_t seg_count, int write)
struct hv_sgl_node *sgl_node = NULL;
/* get struct sglist from free_sgl_list */
- sgl_node = LIST_FIRST(&g_hv_sgl_page_pool.free_sgl_list);
- LIST_REMOVE(sgl_node, link);
- if (NULL == sgl_node) {
+ if (LIST_EMPTY(&g_hv_sgl_page_pool.free_sgl_list)) {
printf("storvsc error: not enough free sgl\n");
return NULL;
}
+ sgl_node = LIST_FIRST(&g_hv_sgl_page_pool.free_sgl_list);
+ LIST_REMOVE(sgl_node, link);
bounce_sgl = sgl_node->sgl_data;
LIST_INSERT_HEAD(&g_hv_sgl_page_pool.in_use_sgl_list, sgl_node, link);
diff --git a/sys/dev/hyperv/utilities/hv_kvp.c b/sys/dev/hyperv/utilities/hv_kvp.c
index 58d565c4..86e037a 100644
--- a/sys/dev/hyperv/utilities/hv_kvp.c
+++ b/sys/dev/hyperv/utilities/hv_kvp.c
@@ -98,7 +98,7 @@ static d_poll_t hv_kvp_dev_daemon_poll;
static int hv_kvp_req_in_progress(void);
static void hv_kvp_transaction_init(uint32_t, hv_vmbus_channel *, uint64_t, uint8_t *);
static void hv_kvp_send_msg_to_daemon(void);
-static void hv_kvp_process_request(void *context);
+static void hv_kvp_process_request(void *context, int pending);
/* hv_kvp character device structure */
static struct cdevsw hv_kvp_cdevsw =
@@ -123,9 +123,6 @@ static struct selinfo hv_kvp_selinfo;
*/
static struct {
- /* Pre-allocated work item for queue */
- hv_work_item work_item;
-
/* Unless specified the pending mutex should be
* used to alter the values of the following paramters:
* 1. req_in_progress
@@ -642,7 +639,7 @@ hv_kvp_send_msg_to_daemon(void)
* and interact with daemon
*/
static void
-hv_kvp_process_request(void *context)
+hv_kvp_process_request(void *context, int pending)
{
uint8_t *kvp_buf;
hv_vmbus_channel *channel = context;
@@ -756,23 +753,18 @@ hv_kvp_callback(void *context)
uint64_t pending_cnt = 0;
if (kvp_globals.register_done == false) {
-
kvp_globals.channelp = context;
+ TASK_INIT(&service_table[HV_KVP].task, 0, hv_kvp_process_request, context);
} else {
-
mtx_lock(&kvp_globals.pending_mutex);
kvp_globals.pending_reqs = kvp_globals.pending_reqs + 1;
pending_cnt = kvp_globals.pending_reqs;
mtx_unlock(&kvp_globals.pending_mutex);
if (pending_cnt == 1) {
hv_kvp_log_info("%s: Queuing work item\n", __func__);
- hv_queue_work_item(
- service_table[HV_KVP].work_queue,
- hv_kvp_process_request,
- context
- );
+ taskqueue_enqueue(taskqueue_thread, &service_table[HV_KVP].task);
}
- }
+ }
}
@@ -977,26 +969,13 @@ int
hv_kvp_init(hv_vmbus_service *srv)
{
int error = 0;
- hv_work_queue *work_queue = NULL;
-
- memset(&kvp_globals, 0, sizeof(kvp_globals));
- work_queue = hv_work_queue_create("KVP Service");
- if (work_queue == NULL) {
- hv_kvp_log_info("%s: Work queue alloc failed\n", __func__);
- error = ENOMEM;
- hv_kvp_log_error("%s: ENOMEM\n", __func__);
- goto Finish;
- }
- srv->work_queue = work_queue;
+ memset(&kvp_globals, 0, sizeof(kvp_globals));
error = hv_kvp_dev_init();
mtx_init(&kvp_globals.pending_mutex, "hv-kvp pending mutex",
- NULL, MTX_DEF);
- kvp_globals.pending_reqs = 0;
-
+ NULL, MTX_DEF);
-Finish:
return (error);
}
diff --git a/sys/dev/hyperv/utilities/hv_util.c b/sys/dev/hyperv/utilities/hv_util.c
index dc4b1e2..38054ca 100644
--- a/sys/dev/hyperv/utilities/hv_util.c
+++ b/sys/dev/hyperv/utilities/hv_util.c
@@ -52,6 +52,8 @@ static void hv_heartbeat_cb(void *context);
static void hv_timesync_cb(void *context);
static int hv_timesync_init(hv_vmbus_service *serv);
+static int hv_timesync_uninit(hv_vmbus_service *serv);
+static void hv_set_host_time(void *context, int pending);
/*
* Note: GUID codes below are predefined by the host hypervisor
@@ -73,6 +75,7 @@ hv_vmbus_service service_table[] = {
.enabled = TRUE,
.init = hv_timesync_init,
.callback = hv_timesync_cb,
+ .uninit = hv_timesync_uninit,
},
/* Heartbeat Service */
@@ -111,10 +114,16 @@ struct hv_ictimesync_data {
static int
hv_timesync_init(hv_vmbus_service *serv)
{
+ void *time_msg = malloc(sizeof(time_sync_data), M_DEVBUF, M_WAITOK);
+ TASK_INIT(&serv->task, 1, hv_set_host_time, time_msg);
+ return (0);
+}
- serv->work_queue = hv_work_queue_create("Time Sync");
- if (serv->work_queue == NULL)
- return (ENOMEM);
+static int
+hv_timesync_uninit(hv_vmbus_service *serv)
+{
+ taskqueue_drain(taskqueue_thread, &serv->task);
+ free(serv->task.ta_context, M_DEVBUF);
return (0);
}
@@ -152,9 +161,9 @@ hv_negotiate_version(
* Set host time based on time sync message from host
*/
static void
-hv_set_host_time(void *context)
+hv_set_host_time(void *context, int pending)
{
- time_sync_data* time_msg = (time_sync_data*) context;
+ time_sync_data* time_msg = (time_sync_data*) context;
uint64_t hosttime = time_msg->data;
struct timespec guest_ts, host_ts;
uint64_t host_tns;
@@ -166,7 +175,7 @@ hv_set_host_time(void *context)
host_ts.tv_nsec = (long)(host_tns%HV_NANO_SEC_PER_SEC);
nanotime(&guest_ts);
-
+
diff = (int64_t)host_ts.tv_sec - (int64_t)guest_ts.tv_sec;
/*
@@ -175,12 +184,7 @@ hv_set_host_time(void *context)
if (diff > 5 || diff < -5) {
error = kern_clock_settime(curthread, CLOCK_REALTIME,
&host_ts);
- }
-
- /*
- * Free the hosttime that was allocated in hv_adj_guesttime()
- */
- free(time_msg, M_DEVBUF);
+ }
}
/**
@@ -197,23 +201,13 @@ hv_set_host_time(void *context)
static inline
void hv_adj_guesttime(uint64_t hosttime, uint8_t flags)
{
- time_sync_data* time_msg;
-
- time_msg = malloc(sizeof(time_sync_data), M_DEVBUF, M_NOWAIT);
+ time_sync_data* time_msg = service_table[HV_TIME_SYNCH].task.ta_context;
- if (time_msg == NULL)
- return;
-
time_msg->data = hosttime;
- if ((flags & HV_ICTIMESYNCFLAG_SYNC) != 0) {
- hv_queue_work_item(service_table[HV_TIME_SYNCH].work_queue,
- hv_set_host_time, time_msg);
- } else if ((flags & HV_ICTIMESYNCFLAG_SAMPLE) != 0) {
- hv_queue_work_item(service_table[HV_TIME_SYNCH].work_queue,
- hv_set_host_time, time_msg);
- } else {
- free(time_msg, M_DEVBUF);
+ if (((flags & HV_ICTIMESYNCFLAG_SYNC) != 0) ||
+ ((flags & HV_ICTIMESYNCFLAG_SAMPLE) != 0)) {
+ taskqueue_enqueue(taskqueue_thread, &service_table[HV_TIME_SYNCH].task);
}
}
@@ -452,19 +446,14 @@ hv_util_detach(device_t dev)
service = device_get_softc(dev);
receive_buffer_offset = service - &service_table[0];
- if (service->work_queue != NULL)
- hv_work_queue_close(service->work_queue);
+ if (service->uninit != NULL)
+ service->uninit(service);
free(receive_buffer[receive_buffer_offset], M_DEVBUF);
receive_buffer[receive_buffer_offset] = NULL;
return (0);
}
-static void
-hv_util_init(void)
-{
-}
-
static int
hv_util_modevent(module_t mod, int event, void *arg)
{
@@ -495,6 +484,3 @@ static devclass_t util_devclass;
DRIVER_MODULE(hv_utils, vmbus, util_driver, util_devclass, hv_util_modevent, 0);
MODULE_VERSION(hv_utils, 1);
MODULE_DEPEND(hv_utils, vmbus, 1, 1, 1);
-
-SYSINIT(hv_util_initx, SI_SUB_KTHREAD_IDLE, SI_ORDER_MIDDLE + 1,
- hv_util_init, NULL);
diff --git a/sys/dev/hyperv/vmbus/hv_channel.c b/sys/dev/hyperv/vmbus/hv_channel.c
index 762ace4..af7395b 100644
--- a/sys/dev/hyperv/vmbus/hv_channel.c
+++ b/sys/dev/hyperv/vmbus/hv_channel.c
@@ -68,9 +68,7 @@ vmbus_channel_set_event(hv_vmbus_channel *channel)
+ ((channel->offer_msg.child_rel_id >> 5))));
monitor_page = (hv_vmbus_monitor_page *)
- hv_vmbus_g_connection.monitor_pages;
-
- monitor_page++; /* Get the child to parent monitor page */
+ hv_vmbus_g_connection.monitor_page_2;
synch_set_bit(channel->monitor_bit,
(uint32_t *)&monitor_page->
diff --git a/sys/dev/hyperv/vmbus/hv_channel_mgmt.c b/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
index 93008aa..21f7d95 100644
--- a/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
+++ b/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
@@ -36,8 +36,10 @@
*/
static void vmbus_channel_on_offer(hv_vmbus_channel_msg_header* hdr);
+static void vmbus_channel_on_offer_internal(void* context);
static void vmbus_channel_on_open_result(hv_vmbus_channel_msg_header* hdr);
static void vmbus_channel_on_offer_rescind(hv_vmbus_channel_msg_header* hdr);
+static void vmbus_channel_on_offer_rescind_internal(void* context);
static void vmbus_channel_on_gpadl_created(hv_vmbus_channel_msg_header* hdr);
static void vmbus_channel_on_gpadl_torndown(hv_vmbus_channel_msg_header* hdr);
static void vmbus_channel_on_offers_delivered(hv_vmbus_channel_msg_header* hdr);
@@ -49,41 +51,46 @@ static void vmbus_channel_on_version_response(hv_vmbus_channel_msg_header* hdr);
hv_vmbus_channel_msg_table_entry
g_channel_message_table[HV_CHANNEL_MESSAGE_COUNT] = {
{ HV_CHANNEL_MESSAGE_INVALID,
- 0, NULL },
+ NULL },
{ HV_CHANNEL_MESSAGE_OFFER_CHANNEL,
- 0, vmbus_channel_on_offer },
+ vmbus_channel_on_offer },
{ HV_CHANNEL_MESSAGE_RESCIND_CHANNEL_OFFER,
- 0, vmbus_channel_on_offer_rescind },
+ vmbus_channel_on_offer_rescind },
{ HV_CHANNEL_MESSAGE_REQUEST_OFFERS,
- 0, NULL },
+ NULL },
{ HV_CHANNEL_MESSAGE_ALL_OFFERS_DELIVERED,
- 1, vmbus_channel_on_offers_delivered },
+ vmbus_channel_on_offers_delivered },
{ HV_CHANNEL_MESSAGE_OPEN_CHANNEL,
- 0, NULL },
+ NULL },
{ HV_CHANNEL_MESSAGE_OPEN_CHANNEL_RESULT,
- 1, vmbus_channel_on_open_result },
+ vmbus_channel_on_open_result },
{ HV_CHANNEL_MESSAGE_CLOSE_CHANNEL,
- 0, NULL },
+ NULL },
{ HV_CHANNEL_MESSAGEL_GPADL_HEADER,
- 0, NULL },
+ NULL },
{ HV_CHANNEL_MESSAGE_GPADL_BODY,
- 0, NULL },
+ NULL },
{ HV_CHANNEL_MESSAGE_GPADL_CREATED,
- 1, vmbus_channel_on_gpadl_created },
+ vmbus_channel_on_gpadl_created },
{ HV_CHANNEL_MESSAGE_GPADL_TEARDOWN,
- 0, NULL },
+ NULL },
{ HV_CHANNEL_MESSAGE_GPADL_TORNDOWN,
- 1, vmbus_channel_on_gpadl_torndown },
+ vmbus_channel_on_gpadl_torndown },
{ HV_CHANNEL_MESSAGE_REL_ID_RELEASED,
- 0, NULL },
+ NULL },
{ HV_CHANNEL_MESSAGE_INITIATED_CONTACT,
- 0, NULL },
+ NULL },
{ HV_CHANNEL_MESSAGE_VERSION_RESPONSE,
- 1, vmbus_channel_on_version_response },
+ vmbus_channel_on_version_response },
{ HV_CHANNEL_MESSAGE_UNLOAD,
- 0, NULL }
+ NULL }
};
+typedef struct hv_work_item {
+ struct task work;
+ void (*callback)(void *);
+ void* context;
+} hv_work_item;
/**
* Implementation of the work abstraction.
@@ -93,120 +100,30 @@ work_item_callback(void *work, int pending)
{
struct hv_work_item *w = (struct hv_work_item *)work;
- /*
- * Serialize work execution.
- */
- if (w->wq->work_sema != NULL) {
- sema_wait(w->wq->work_sema);
- }
-
w->callback(w->context);
- if (w->wq->work_sema != NULL) {
- sema_post(w->wq->work_sema);
- }
-
free(w, M_DEVBUF);
}
-struct hv_work_queue*
-hv_work_queue_create(char* name)
-{
- static unsigned int qid = 0;
- char qname[64];
- int pri;
- struct hv_work_queue* wq;
-
- wq = malloc(sizeof(struct hv_work_queue), M_DEVBUF, M_NOWAIT | M_ZERO);
- KASSERT(wq != NULL, ("Error VMBUS: Failed to allocate work_queue\n"));
- if (wq == NULL)
- return (NULL);
-
- /*
- * We use work abstraction to handle messages
- * coming from the host and these are typically offers.
- * Some FreeBsd drivers appear to have a concurrency issue
- * where probe/attach needs to be serialized. We ensure that
- * by having only one thread process work elements in a
- * specific queue by serializing work execution.
- *
- */
- if (strcmp(name, "vmbusQ") == 0) {
- pri = PI_DISK;
- } else { /* control */
- pri = PI_NET;
- /*
- * Initialize semaphore for this queue by pointing
- * to the globale semaphore used for synchronizing all
- * control messages.
- */
- wq->work_sema = &hv_vmbus_g_connection.control_sema;
- }
-
- sprintf(qname, "hv_%s_%u", name, qid);
-
- /*
- * Fixme: FreeBSD 8.2 has a different prototype for
- * taskqueue_create(), and for certain other taskqueue functions.
- * We need to research the implications of these changes.
- * Fixme: Not sure when the changes were introduced.
- */
- wq->queue = taskqueue_create(qname, M_NOWAIT, taskqueue_thread_enqueue,
- &wq->queue
- #if __FreeBSD_version < 800000
- , &wq->proc
- #endif
- );
-
- if (wq->queue == NULL) {
- free(wq, M_DEVBUF);
- return (NULL);
- }
-
- if (taskqueue_start_threads(&wq->queue, 1, pri, "%s taskq", qname)) {
- taskqueue_free(wq->queue);
- free(wq, M_DEVBUF);
- return (NULL);
- }
-
- qid++;
-
- return (wq);
-}
-
-void
-hv_work_queue_close(struct hv_work_queue *wq)
-{
- /*
- * KYS: Need to drain the taskqueue
- * before we close the hv_work_queue.
- */
- /*KYS: taskqueue_drain(wq->tq, ); */
- taskqueue_free(wq->queue);
- free(wq, M_DEVBUF);
-}
-
/**
* @brief Create work item
*/
-int
+static int
hv_queue_work_item(
- struct hv_work_queue *wq,
void (*callback)(void *), void *context)
{
struct hv_work_item *w = malloc(sizeof(struct hv_work_item),
- M_DEVBUF, M_NOWAIT | M_ZERO);
+ M_DEVBUF, M_NOWAIT);
KASSERT(w != NULL, ("Error VMBUS: Failed to allocate WorkItem\n"));
if (w == NULL)
return (ENOMEM);
w->callback = callback;
w->context = context;
- w->wq = wq;
TASK_INIT(&w->work, 0, work_item_callback, w);
- return (taskqueue_enqueue(wq->queue, &w->work));
+ return (taskqueue_enqueue(taskqueue_thread, &w->work));
}
@@ -221,10 +138,7 @@ hv_vmbus_allocate_channel(void)
channel = (hv_vmbus_channel*) malloc(
sizeof(hv_vmbus_channel),
M_DEVBUF,
- M_NOWAIT | M_ZERO);
- KASSERT(channel != NULL, ("Error VMBUS: Failed to allocate channel!"));
- if (channel == NULL)
- return (NULL);
+ M_WAITOK | M_ZERO);
mtx_init(&channel->inbound_lock, "channel inbound", NULL, MTX_DEF);
mtx_init(&channel->sc_lock, "vmbus multi channel", NULL, MTX_DEF);
@@ -235,16 +149,6 @@ hv_vmbus_allocate_channel(void)
}
/**
- * @brief Release the vmbus channel object itself
- */
-static inline void
-ReleaseVmbusChannel(void *context)
-{
- hv_vmbus_channel* channel = (hv_vmbus_channel*) context;
- free(channel, M_DEVBUF);
-}
-
-/**
* @brief Release the resources used by the vmbus channel object
*/
void
@@ -252,13 +156,8 @@ hv_vmbus_free_vmbus_channel(hv_vmbus_channel* channel)
{
mtx_destroy(&channel->sc_lock);
mtx_destroy(&channel->inbound_lock);
- /*
- * We have to release the channel's workqueue/thread in
- * the vmbus's workqueue/thread context
- * ie we can't destroy ourselves
- */
- hv_queue_work_item(hv_vmbus_g_connection.work_queue,
- ReleaseVmbusChannel, (void *) channel);
+
+ free(channel, M_DEVBUF);
}
/**
@@ -456,7 +355,7 @@ static void
vmbus_channel_on_offer(hv_vmbus_channel_msg_header* hdr)
{
hv_vmbus_channel_offer_channel* offer;
- hv_vmbus_channel* new_channel;
+ hv_vmbus_channel_offer_channel* copied;
offer = (hv_vmbus_channel_offer_channel*) hdr;
@@ -466,10 +365,25 @@ vmbus_channel_on_offer(hv_vmbus_channel_msg_header* hdr)
guidType = &offer->offer.interface_type;
guidInstance = &offer->offer.interface_instance;
+ // copy offer data
+ copied = malloc(sizeof(*copied), M_DEVBUF, M_NOWAIT);
+ if (copied == NULL) {
+ printf("fail to allocate memory\n");
+ return;
+ }
+
+ memcpy(copied, hdr, sizeof(*copied));
+ hv_queue_work_item(vmbus_channel_on_offer_internal, copied);
+}
+
+static void
+vmbus_channel_on_offer_internal(void* context)
+{
+ hv_vmbus_channel* new_channel;
+
+ hv_vmbus_channel_offer_channel* offer = (hv_vmbus_channel_offer_channel*)context;
/* Allocate the channel object and save this offer */
new_channel = hv_vmbus_allocate_channel();
- if (new_channel == NULL)
- return;
/*
* By default we setup state to enable batched
@@ -509,6 +423,8 @@ vmbus_channel_on_offer(hv_vmbus_channel_msg_header* hdr)
new_channel->monitor_bit = (uint8_t) offer->monitor_id % 32;
vmbus_channel_process_offer(new_channel);
+
+ free(offer, M_DEVBUF);
}
/**
@@ -526,13 +442,20 @@ vmbus_channel_on_offer_rescind(hv_vmbus_channel_msg_header* hdr)
rescind = (hv_vmbus_channel_rescind_offer*) hdr;
channel = hv_vmbus_g_connection.channels[rescind->child_rel_id];
- if (channel == NULL)
+ if (channel == NULL)
return;
- hv_vmbus_child_device_unregister(channel->device);
- mtx_lock(&hv_vmbus_g_connection.channel_lock);
+ hv_queue_work_item(vmbus_channel_on_offer_rescind_internal, channel);
hv_vmbus_g_connection.channels[rescind->child_rel_id] = NULL;
- mtx_unlock(&hv_vmbus_g_connection.channel_lock);
+}
+
+static void
+vmbus_channel_on_offer_rescind_internal(void *context)
+{
+ hv_vmbus_channel* channel;
+
+ channel = (hv_vmbus_channel*)context;
+ hv_vmbus_child_device_unregister(channel->device);
}
/**
@@ -709,35 +632,6 @@ vmbus_channel_on_version_response(hv_vmbus_channel_msg_header* hdr)
}
/**
- * @brief Handler for channel protocol messages.
- *
- * This is invoked in the vmbus worker thread context.
- */
-void
-hv_vmbus_on_channel_message(void *context)
-{
- hv_vmbus_message* msg;
- hv_vmbus_channel_msg_header* hdr;
- int size;
-
- msg = (hv_vmbus_message*) context;
- hdr = (hv_vmbus_channel_msg_header*) msg->u.payload;
- size = msg->header.payload_size;
-
- if (hdr->message_type >= HV_CHANNEL_MESSAGE_COUNT) {
- free(msg, M_DEVBUF);
- return;
- }
-
- if (g_channel_message_table[hdr->message_type].messageHandler) {
- g_channel_message_table[hdr->message_type].messageHandler(hdr);
- }
-
- /* Free the msg that was allocated in VmbusOnMsgDPC() */
- free(msg, M_DEVBUF);
-}
-
-/**
* @brief Send a request to get all our pending offers.
*/
int
@@ -762,8 +656,7 @@ hv_vmbus_request_channel_offers(void)
ret = hv_vmbus_post_message(msg, sizeof(hv_vmbus_channel_msg_header));
- if (msg_info)
- free(msg_info, M_DEVBUF);
+ free(msg_info, M_DEVBUF);
return (ret);
}
diff --git a/sys/dev/hyperv/vmbus/hv_connection.c b/sys/dev/hyperv/vmbus/hv_connection.c
index 05b1612..e60c557 100644
--- a/sys/dev/hyperv/vmbus/hv_connection.c
+++ b/sys/dev/hyperv/vmbus/hv_connection.c
@@ -86,12 +86,10 @@ hv_vmbus_negotiate_version(hv_vmbus_channel_msg_info *msg_info,
hv_vmbus_g_connection.interrupt_page);
msg->monitor_page_1 = hv_get_phys_addr(
- hv_vmbus_g_connection.monitor_pages);
+ hv_vmbus_g_connection.monitor_page_1);
- msg->monitor_page_2 =
- hv_get_phys_addr(
- ((uint8_t *) hv_vmbus_g_connection.monitor_pages
- + PAGE_SIZE));
+ msg->monitor_page_2 = hv_get_phys_addr(
+ hv_vmbus_g_connection.monitor_page_2);
/**
* Add to list before we send the request since we may receive the
@@ -164,8 +162,6 @@ hv_vmbus_connect(void) {
* Initialize the vmbus connection
*/
hv_vmbus_g_connection.connect_state = HV_CONNECTING;
- hv_vmbus_g_connection.work_queue = hv_work_queue_create("vmbusQ");
- sema_init(&hv_vmbus_g_connection.control_sema, 1, "control_sema");
TAILQ_INIT(&hv_vmbus_g_connection.channel_msg_anchor);
mtx_init(&hv_vmbus_g_connection.channel_msg_lock, "vmbus channel msg",
@@ -179,18 +175,9 @@ hv_vmbus_connect(void) {
* Setup the vmbus event connection for channel interrupt abstraction
* stuff
*/
- hv_vmbus_g_connection.interrupt_page = contigmalloc(
+ hv_vmbus_g_connection.interrupt_page = malloc(
PAGE_SIZE, M_DEVBUF,
- M_NOWAIT | M_ZERO, 0UL,
- BUS_SPACE_MAXADDR,
- PAGE_SIZE, 0);
- KASSERT(hv_vmbus_g_connection.interrupt_page != NULL,
- ("Error VMBUS: malloc failed to allocate Channel"
- " Request Event message!"));
- if (hv_vmbus_g_connection.interrupt_page == NULL) {
- ret = ENOMEM;
- goto cleanup;
- }
+ M_WAITOK | M_ZERO);
hv_vmbus_g_connection.recv_interrupt_page =
hv_vmbus_g_connection.interrupt_page;
@@ -203,31 +190,19 @@ hv_vmbus_connect(void) {
* Set up the monitor notification facility. The 1st page for
* parent->child and the 2nd page for child->parent
*/
- hv_vmbus_g_connection.monitor_pages = contigmalloc(
- 2 * PAGE_SIZE,
+ hv_vmbus_g_connection.monitor_page_1 = malloc(
+ PAGE_SIZE,
M_DEVBUF,
- M_NOWAIT | M_ZERO,
- 0UL,
- BUS_SPACE_MAXADDR,
+ M_WAITOK | M_ZERO);
+ hv_vmbus_g_connection.monitor_page_2 = malloc(
PAGE_SIZE,
- 0);
- KASSERT(hv_vmbus_g_connection.monitor_pages != NULL,
- ("Error VMBUS: malloc failed to allocate Monitor Pages!"));
- if (hv_vmbus_g_connection.monitor_pages == NULL) {
- ret = ENOMEM;
- goto cleanup;
- }
+ M_DEVBUF,
+ M_WAITOK | M_ZERO);
msg_info = (hv_vmbus_channel_msg_info*)
malloc(sizeof(hv_vmbus_channel_msg_info) +
sizeof(hv_vmbus_channel_initiate_contact),
- M_DEVBUF, M_NOWAIT | M_ZERO);
- KASSERT(msg_info != NULL,
- ("Error VMBUS: malloc failed for Initiate Contact message!"));
- if (msg_info == NULL) {
- ret = ENOMEM;
- goto cleanup;
- }
+ M_DEVBUF, M_WAITOK | M_ZERO);
hv_vmbus_g_connection.channels = malloc(sizeof(hv_vmbus_channel*) *
HV_CHANNEL_MAX_COUNT,
@@ -269,8 +244,6 @@ hv_vmbus_connect(void) {
hv_vmbus_g_connection.connect_state = HV_DISCONNECTED;
- hv_work_queue_close(hv_vmbus_g_connection.work_queue);
- sema_destroy(&hv_vmbus_g_connection.control_sema);
mtx_destroy(&hv_vmbus_g_connection.channel_lock);
mtx_destroy(&hv_vmbus_g_connection.channel_msg_lock);
@@ -282,13 +255,8 @@ hv_vmbus_connect(void) {
hv_vmbus_g_connection.interrupt_page = NULL;
}
- if (hv_vmbus_g_connection.monitor_pages != NULL) {
- contigfree(
- hv_vmbus_g_connection.monitor_pages,
- 2 * PAGE_SIZE,
- M_DEVBUF);
- hv_vmbus_g_connection.monitor_pages = NULL;
- }
+ free(hv_vmbus_g_connection.monitor_page_1, M_DEVBUF);
+ free(hv_vmbus_g_connection.monitor_page_2, M_DEVBUF);
if (msg_info) {
sema_destroy(&msg_info->wait_sema);
@@ -305,32 +273,19 @@ hv_vmbus_connect(void) {
int
hv_vmbus_disconnect(void) {
int ret = 0;
- hv_vmbus_channel_unload* msg;
-
- msg = malloc(sizeof(hv_vmbus_channel_unload),
- M_DEVBUF, M_NOWAIT | M_ZERO);
- KASSERT(msg != NULL,
- ("Error VMBUS: malloc failed to allocate Channel Unload Msg!"));
- if (msg == NULL)
- return (ENOMEM);
+ hv_vmbus_channel_unload msg;
- msg->message_type = HV_CHANNEL_MESSAGE_UNLOAD;
-
- ret = hv_vmbus_post_message(msg, sizeof(hv_vmbus_channel_unload));
+ msg.message_type = HV_CHANNEL_MESSAGE_UNLOAD;
+ ret = hv_vmbus_post_message(&msg, sizeof(hv_vmbus_channel_unload));
contigfree(hv_vmbus_g_connection.interrupt_page, PAGE_SIZE, M_DEVBUF);
mtx_destroy(&hv_vmbus_g_connection.channel_msg_lock);
- hv_work_queue_close(hv_vmbus_g_connection.work_queue);
- sema_destroy(&hv_vmbus_g_connection.control_sema);
-
free(hv_vmbus_g_connection.channels, M_DEVBUF);
hv_vmbus_g_connection.connect_state = HV_DISCONNECTED;
- free(msg, M_DEVBUF);
-
return (ret);
}
diff --git a/sys/dev/hyperv/vmbus/hv_hv.c b/sys/dev/hyperv/vmbus/hv_hv.c
index ca5641f..6afc2b8 100644
--- a/sys/dev/hyperv/vmbus/hv_hv.c
+++ b/sys/dev/hyperv/vmbus/hv_hv.c
@@ -189,11 +189,7 @@ hv_vmbus_init(void)
* See if the hypercall page is already set
*/
hypercall_msr.as_uint64_t = rdmsr(HV_X64_MSR_HYPERCALL);
- virt_addr = malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT | M_ZERO);
- KASSERT(virt_addr != NULL,
- ("Error VMBUS: malloc failed to allocate page during init!"));
- if (virt_addr == NULL)
- goto cleanup;
+ virt_addr = malloc(PAGE_SIZE, M_DEVBUF, M_WAITOK | M_ZERO);
hypercall_msr.u.enable = 1;
hypercall_msr.u.guest_physical_address =
diff --git a/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c b/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
index 7eac116..8a1e412 100644
--- a/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
+++ b/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
@@ -83,8 +83,6 @@ vmbus_msg_swintr(void *arg)
hv_vmbus_channel_msg_table_entry *entry;
hv_vmbus_channel_msg_type msg_type;
hv_vmbus_message* msg;
- hv_vmbus_message* copied;
- static bool warned = false;
cpu = (int)(long)arg;
KASSERT(cpu <= mp_maxid, ("VMBUS: vmbus_msg_swintr: "
@@ -100,31 +98,15 @@ vmbus_msg_swintr(void *arg)
hdr = (hv_vmbus_channel_msg_header *)msg->u.payload;
msg_type = hdr->message_type;
- if (msg_type >= HV_CHANNEL_MESSAGE_COUNT && !warned) {
- warned = true;
+ if (msg_type >= HV_CHANNEL_MESSAGE_COUNT) {
printf("VMBUS: unknown message type = %d\n", msg_type);
goto handled;
}
entry = &g_channel_message_table[msg_type];
- if (entry->handler_no_sleep)
+ if (entry->messageHandler)
entry->messageHandler(hdr);
- else {
-
- copied = malloc(sizeof(hv_vmbus_message),
- M_DEVBUF, M_NOWAIT);
- KASSERT(copied != NULL,
- ("Error VMBUS: malloc failed to allocate"
- " hv_vmbus_message!"));
- if (copied == NULL)
- continue;
-
- memcpy(copied, msg, sizeof(hv_vmbus_message));
- hv_queue_work_item(hv_vmbus_g_connection.work_queue,
- hv_vmbus_on_channel_message,
- copied);
- }
handled:
msg->header.message_type = HV_MESSAGE_TYPE_NONE;
@@ -309,12 +291,7 @@ hv_vmbus_child_device_create(
* Allocate the new child device
*/
child_dev = malloc(sizeof(hv_device), M_DEVBUF,
- M_NOWAIT | M_ZERO);
- KASSERT(child_dev != NULL,
- ("Error VMBUS: malloc failed to allocate hv_device!"));
-
- if (child_dev == NULL)
- return (NULL);
+ M_WAITOK | M_ZERO);
child_dev->channel = channel;
memcpy(&child_dev->class_id, &type, sizeof(hv_guid));
@@ -566,12 +543,7 @@ vmbus_bus_init(void)
*/
for(i = 0; i < 2; i++) {
setup_args.page_buffers[2 * j + i] =
- malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT | M_ZERO);
- if (setup_args.page_buffers[2 * j + i] == NULL) {
- KASSERT(setup_args.page_buffers[2 * j + i] != NULL,
- ("Error VMBUS: malloc failed!"));
- goto cleanup1;
- }
+ malloc(PAGE_SIZE, M_DEVBUF, M_WAITOK | M_ZERO);
}
}
diff --git a/sys/dev/hyperv/vmbus/hv_vmbus_priv.h b/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
index 538ab1e..5f62072 100644
--- a/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
+++ b/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
@@ -350,7 +350,8 @@ typedef struct {
* notification and 2nd is child->parent
* notification
*/
- void *monitor_pages;
+ void *monitor_page_1;
+ void *monitor_page_2;
TAILQ_HEAD(, hv_vmbus_channel_msg_info) channel_msg_anchor;
struct mtx channel_msg_lock;
/**
@@ -362,10 +363,8 @@ typedef struct {
/**
* channel table for fast lookup through id.
- */
+ */
hv_vmbus_channel **channels;
- hv_vmbus_handle work_queue;
- struct sema control_sema;
} hv_vmbus_connection;
typedef union {
@@ -632,7 +631,6 @@ typedef void (*vmbus_msg_handler)(hv_vmbus_channel_msg_header *msg);
typedef struct hv_vmbus_channel_msg_table_entry {
hv_vmbus_channel_msg_type messageType;
- bool handler_no_sleep; /* true: the handler doesn't sleep */
vmbus_msg_handler messageHandler;
} hv_vmbus_channel_msg_table_entry;
@@ -682,7 +680,6 @@ uint32_t hv_ring_buffer_read_end(
hv_vmbus_channel* hv_vmbus_allocate_channel(void);
void hv_vmbus_free_vmbus_channel(hv_vmbus_channel *channel);
-void hv_vmbus_on_channel_message(void *context);
int hv_vmbus_request_channel_offers(void);
void hv_vmbus_release_unattached_channels(void);
int hv_vmbus_init(void);
diff --git a/sys/dev/ixgbe/if_ix.c b/sys/dev/ixgbe/if_ix.c
index c6a5084..f0e218f 100644
--- a/sys/dev/ixgbe/if_ix.c
+++ b/sys/dev/ixgbe/if_ix.c
@@ -1017,6 +1017,7 @@ static void
ixgbe_set_if_hwassist(struct adapter *adapter)
{
struct ifnet *ifp = adapter->ifp;
+ struct ixgbe_hw *hw = &adapter->hw;
ifp->if_hwassist = 0;
#if __FreeBSD_version >= 1000000
@@ -1024,18 +1025,21 @@ ixgbe_set_if_hwassist(struct adapter *adapter)
ifp->if_hwassist |= CSUM_IP_TSO;
if (ifp->if_capenable & IFCAP_TSO6)
ifp->if_hwassist |= CSUM_IP6_TSO;
- if (ifp->if_capenable & IFCAP_TXCSUM)
- ifp->if_hwassist |= (CSUM_IP | CSUM_IP_UDP | CSUM_IP_TCP |
- CSUM_IP_SCTP);
- if (ifp->if_capenable & IFCAP_TXCSUM_IPV6)
- ifp->if_hwassist |= (CSUM_IP6_UDP | CSUM_IP6_TCP |
- CSUM_IP6_SCTP);
+ if (ifp->if_capenable & IFCAP_TXCSUM) {
+ ifp->if_hwassist |= (CSUM_IP | CSUM_IP_UDP | CSUM_IP_TCP);
+ if (hw->mac.type != ixgbe_mac_82598EB)
+ ifp->if_hwassist |= CSUM_IP_SCTP;
+ }
+ if (ifp->if_capenable & IFCAP_TXCSUM_IPV6) {
+ ifp->if_hwassist |= (CSUM_IP6_UDP | CSUM_IP6_TCP);
+ if (hw->mac.type != ixgbe_mac_82598EB)
+ ifp->if_hwassist |= CSUM_IP6_SCTP;
+ }
#else
if (ifp->if_capenable & IFCAP_TSO)
ifp->if_hwassist |= CSUM_TSO;
if (ifp->if_capenable & IFCAP_TXCSUM) {
ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP);
- struct ixgbe_hw *hw = &adapter->hw;
if (hw->mac.type != ixgbe_mac_82598EB)
ifp->if_hwassist |= CSUM_SCTP;
}
diff --git a/sys/dev/mps/mps.c b/sys/dev/mps/mps.c
index 4080fc6..5f18341 100644
--- a/sys/dev/mps/mps.c
+++ b/sys/dev/mps/mps.c
@@ -1476,6 +1476,14 @@ mps_setup_sysctl(struct mps_softc *sc)
OID_AUTO, "spinup_wait_time", CTLFLAG_RD,
&sc->spinup_wait_time, DEFAULT_SPINUP_WAIT, "seconds to wait for "
"spinup after SATA ID error");
+
+ SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
+ OID_AUTO, "mapping_table_dump", CTLTYPE_STRING | CTLFLAG_RD, sc, 0,
+ mps_mapping_dump, "A", "Mapping Table Dump");
+
+ SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
+ OID_AUTO, "encl_table_dump", CTLTYPE_STRING | CTLFLAG_RD, sc, 0,
+ mps_mapping_encl_dump, "A", "Enclosure Table Dump");
}
int
diff --git a/sys/dev/mps/mps_mapping.c b/sys/dev/mps/mps_mapping.c
index d96f33c..351625b 100644
--- a/sys/dev/mps/mps_mapping.c
+++ b/sys/dev/mps/mps_mapping.c
@@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <sys/endian.h>
#include <sys/sysctl.h>
+#include <sys/sbuf.h>
#include <sys/eventhandler.h>
#include <sys/uio.h>
#include <machine/bus.h>
@@ -2263,3 +2264,61 @@ out:
if (sc->pending_map_events)
sc->pending_map_events--;
}
+
+int
+mps_mapping_dump(SYSCTL_HANDLER_ARGS)
+{
+ struct mps_softc *sc;
+ struct dev_mapping_table *mt_entry;
+ struct sbuf sbuf;
+ int i, error;
+
+ sc = (struct mps_softc *)arg1;
+
+ error = sysctl_wire_old_buffer(req, 0);
+ if (error != 0)
+ return (error);
+ sbuf_new_for_sysctl(&sbuf, NULL, 128, req);
+
+ sbuf_printf(&sbuf, "\nindex physical_id handle id\n");
+ for (i = 0; i < sc->max_devices; i++) {
+ mt_entry = &sc->mapping_table[i];
+ if (mt_entry->physical_id == 0)
+ continue;
+ sbuf_printf(&sbuf, "%4d %jx %04x %hd\n",
+ i, mt_entry->physical_id, mt_entry->dev_handle,
+ mt_entry->id);
+ }
+ error = sbuf_finish(&sbuf);
+ sbuf_delete(&sbuf);
+ return (error);
+}
+
+int
+mps_mapping_encl_dump(SYSCTL_HANDLER_ARGS)
+{
+ struct mps_softc *sc;
+ struct enc_mapping_table *enc_entry;
+ struct sbuf sbuf;
+ int i, error;
+
+ sc = (struct mps_softc *)arg1;
+
+ error = sysctl_wire_old_buffer(req, 0);
+ if (error != 0)
+ return (error);
+ sbuf_new_for_sysctl(&sbuf, NULL, 128, req);
+
+ sbuf_printf(&sbuf, "\nindex enclosure_id handle map_index\n");
+ for (i = 0; i < sc->max_enclosures; i++) {
+ enc_entry = &sc->enclosure_table[i];
+ if (enc_entry->enclosure_id == 0)
+ continue;
+ sbuf_printf(&sbuf, "%4d %jx %04x %d\n",
+ i, enc_entry->enclosure_id, enc_entry->enc_handle,
+ enc_entry->start_index);
+ }
+ error = sbuf_finish(&sbuf);
+ sbuf_delete(&sbuf);
+ return (error);
+}
diff --git a/sys/dev/mps/mpsvar.h b/sys/dev/mps/mpsvar.h
index 96bb4e1..0cb51a0 100644
--- a/sys/dev/mps/mpsvar.h
+++ b/sys/dev/mps/mpsvar.h
@@ -756,6 +756,8 @@ void mps_mapping_enclosure_dev_status_change_event(struct mps_softc *,
Mpi2EventDataSasEnclDevStatusChange_t *event_data);
void mps_mapping_ir_config_change_event(struct mps_softc *sc,
Mpi2EventDataIrConfigChangeList_t *event_data);
+int mps_mapping_dump(SYSCTL_HANDLER_ARGS);
+int mps_mapping_encl_dump(SYSCTL_HANDLER_ARGS);
void mpssas_evt_handler(struct mps_softc *sc, uintptr_t data,
MPI2_EVENT_NOTIFICATION_REPLY *event);
diff --git a/sys/fs/cd9660/cd9660_vfsops.c b/sys/fs/cd9660/cd9660_vfsops.c
index a1f8780..983b869 100644
--- a/sys/fs/cd9660/cd9660_vfsops.c
+++ b/sys/fs/cd9660/cd9660_vfsops.c
@@ -741,8 +741,7 @@ cd9660_vget_internal(mp, ino, flags, vpp, relocated, isodir)
if (off + isonum_711(isodir->length) >
imp->logical_block_size) {
vput(vp);
- if (bp != 0)
- brelse(bp);
+ brelse(bp);
printf("fhtovp: directory crosses block boundary %d[off=%d/len=%d]\n",
off +isonum_711(isodir->length), off,
isonum_711(isodir->length));
diff --git a/sys/fs/ext2fs/ext2_inode_cnv.c b/sys/fs/ext2fs/ext2_inode_cnv.c
index 78679cf..d62e9ba 100644
--- a/sys/fs/ext2fs/ext2_inode_cnv.c
+++ b/sys/fs/ext2fs/ext2_inode_cnv.c
@@ -149,11 +149,13 @@ ext2_i2ei(struct inode *ip, struct ext2fs_dinode *ei)
ei->e2di_atime = ip->i_atime;
ei->e2di_mtime = ip->i_mtime;
ei->e2di_ctime = ip->i_ctime;
- ei->e2di_ctime_extra = NSEC_TO_XTIME(ip->i_ctimensec);
- ei->e2di_mtime_extra = NSEC_TO_XTIME(ip->i_mtimensec);
- ei->e2di_atime_extra = NSEC_TO_XTIME(ip->i_atimensec);
- ei->e2di_crtime = ip->i_birthtime;
- ei->e2di_crtime_extra = NSEC_TO_XTIME(ip->i_birthnsec);
+ if (E2DI_HAS_XTIME(ip)) {
+ ei->e2di_ctime_extra = NSEC_TO_XTIME(ip->i_ctimensec);
+ ei->e2di_mtime_extra = NSEC_TO_XTIME(ip->i_mtimensec);
+ ei->e2di_atime_extra = NSEC_TO_XTIME(ip->i_atimensec);
+ ei->e2di_crtime = ip->i_birthtime;
+ ei->e2di_crtime_extra = NSEC_TO_XTIME(ip->i_birthnsec);
+ }
ei->e2di_flags = 0;
ei->e2di_flags |= (ip->i_flags & SF_APPEND) ? EXT2_APPEND: 0;
ei->e2di_flags |= (ip->i_flags & SF_IMMUTABLE) ? EXT2_IMMUTABLE: 0;
diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c
index 5a2a6a9..74a7e32 100644
--- a/sys/fs/msdosfs/msdosfs_vnops.c
+++ b/sys/fs/msdosfs/msdosfs_vnops.c
@@ -941,14 +941,10 @@ msdosfs_rename(struct vop_rename_args *ap)
int error;
u_long cn, pcl;
daddr_t bn;
- struct denode *fddep; /* from file's parent directory */
struct msdosfsmount *pmp;
struct direntry *dotdotp;
struct buf *bp;
- fddep = VTODE(ap->a_fdvp);
- pmp = fddep->de_pmp;
-
pmp = VFSTOMSDOSFS(fdvp->v_mount);
#ifdef DIAGNOSTIC
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index 8a7a11a..43d4800 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -258,7 +258,7 @@ __elfN(get_brandinfo)(struct image_params *imgp, const char *interp,
int interp_name_len, int32_t *osrel)
{
const Elf_Ehdr *hdr = (const Elf_Ehdr *)imgp->image_header;
- Elf_Brandinfo *bi;
+ Elf_Brandinfo *bi, *bi_m;
boolean_t ret;
int i;
@@ -270,6 +270,7 @@ __elfN(get_brandinfo)(struct image_params *imgp, const char *interp,
*/
/* Look for an ".note.ABI-tag" ELF section */
+ bi_m = NULL;
for (i = 0; i < MAX_BRANDS; i++) {
bi = elf_brand_list[i];
if (bi == NULL)
@@ -280,10 +281,28 @@ __elfN(get_brandinfo)(struct image_params *imgp, const char *interp,
/* Give brand a chance to veto check_note's guess */
if (ret && bi->header_supported)
ret = bi->header_supported(imgp);
+ /*
+ * If note checker claimed the binary, but the
+ * interpreter path in the image does not
+ * match default one for the brand, try to
+ * search for other brands with the same
+ * interpreter. Either there is better brand
+ * with the right interpreter, or, failing
+ * this, we return first brand which accepted
+ * our note and, optionally, header.
+ */
+ if (ret && bi_m == NULL && (strlen(bi->interp_path) +
+ 1 != interp_name_len || strncmp(interp,
+ bi->interp_path, interp_name_len) != 0)) {
+ bi_m = bi;
+ ret = 0;
+ }
if (ret)
return (bi);
}
}
+ if (bi_m != NULL)
+ return (bi_m);
/* If the executable has a brand, search for it in the brand list. */
for (i = 0; i < MAX_BRANDS; i++) {
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index 8d5580b..d5f8f4d 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -828,12 +828,15 @@ start_init(void *dummy)
static void
create_init(const void *udata __unused)
{
+ struct fork_req fr;
struct ucred *newcred, *oldcred;
struct thread *td;
int error;
- error = fork1(&thread0, RFFDG | RFPROC | RFSTOPPED, 0, &initproc,
- NULL, 0, NULL);
+ bzero(&fr, sizeof(fr));
+ fr.fr_flags = RFFDG | RFPROC | RFSTOPPED;
+ fr.fr_procp = &initproc;
+ error = fork1(&thread0, &fr);
if (error)
panic("cannot fork init: %d\n", error);
KASSERT(initproc->p_pid == 1, ("create_init: initproc->p_pid != 1"));
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index e7d7276..9abe08c 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -101,12 +101,15 @@ struct fork_args {
int
sys_fork(struct thread *td, struct fork_args *uap)
{
- int error;
- struct proc *p2;
+ struct fork_req fr;
+ int error, pid;
- error = fork1(td, RFFDG | RFPROC, 0, &p2, NULL, 0, NULL);
+ bzero(&fr, sizeof(fr));
+ fr.fr_flags = RFFDG | RFPROC;
+ fr.fr_pidp = &pid;
+ error = fork1(td, &fr);
if (error == 0) {
- td->td_retval[0] = p2->p_pid;
+ td->td_retval[0] = pid;
td->td_retval[1] = 0;
}
return (error);
@@ -114,22 +117,24 @@ sys_fork(struct thread *td, struct fork_args *uap)
/* ARGUSED */
int
-sys_pdfork(td, uap)
- struct thread *td;
- struct pdfork_args *uap;
+sys_pdfork(struct thread *td, struct pdfork_args *uap)
{
- int error, fd;
- struct proc *p2;
-
+ struct fork_req fr;
+ int error, fd, pid;
+
+ bzero(&fr, sizeof(fr));
+ fr.fr_flags = RFFDG | RFPROC | RFPROCDESC;
+ fr.fr_pidp = &pid;
+ fr.fr_pd_fd = &fd;
+ fr.fr_pd_flags = uap->flags;
/*
* It is necessary to return fd by reference because 0 is a valid file
* descriptor number, and the child needs to be able to distinguish
* itself from the parent using the return value.
*/
- error = fork1(td, RFFDG | RFPROC | RFPROCDESC, 0, &p2,
- &fd, uap->flags, NULL);
+ error = fork1(td, &fr);
if (error == 0) {
- td->td_retval[0] = p2->p_pid;
+ td->td_retval[0] = pid;
td->td_retval[1] = 0;
error = copyout(&fd, uap->fdp, sizeof(fd));
}
@@ -140,13 +145,15 @@ sys_pdfork(td, uap)
int
sys_vfork(struct thread *td, struct vfork_args *uap)
{
- int error, flags;
- struct proc *p2;
+ struct fork_req fr;
+ int error, pid;
- flags = RFFDG | RFPROC | RFPPWAIT | RFMEM;
- error = fork1(td, flags, 0, &p2, NULL, 0, NULL);
+ bzero(&fr, sizeof(fr));
+ fr.fr_flags = RFFDG | RFPROC | RFPPWAIT | RFMEM;
+ fr.fr_pidp = &pid;
+ error = fork1(td, &fr);
if (error == 0) {
- td->td_retval[0] = p2->p_pid;
+ td->td_retval[0] = pid;
td->td_retval[1] = 0;
}
return (error);
@@ -155,17 +162,20 @@ sys_vfork(struct thread *td, struct vfork_args *uap)
int
sys_rfork(struct thread *td, struct rfork_args *uap)
{
- struct proc *p2;
- int error;
+ struct fork_req fr;
+ int error, pid;
/* Don't allow kernel-only flags. */
if ((uap->flags & RFKERNELONLY) != 0)
return (EINVAL);
AUDIT_ARG_FFLAGS(uap->flags);
- error = fork1(td, uap->flags, 0, &p2, NULL, 0, NULL);
+ bzero(&fr, sizeof(fr));
+ fr.fr_flags = uap->flags;
+ fr.fr_pidp = &pid;
+ error = fork1(td, &fr);
if (error == 0) {
- td->td_retval[0] = p2 ? p2->p_pid : 0;
+ td->td_retval[0] = pid;
td->td_retval[1] = 0;
}
return (error);
@@ -366,11 +376,11 @@ fail:
}
static void
-do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2,
- struct vmspace *vm2, int pdflags)
+do_fork(struct thread *td, struct fork_req *fr, struct proc *p2, struct thread *td2,
+ struct vmspace *vm2, struct file *fp_procdesc)
{
struct proc *p1, *pptr;
- int p2_held, trypid;
+ int trypid;
struct filedesc *fd;
struct filedesc_to_leader *fdtol;
struct sigacts *newsigacts;
@@ -378,10 +388,9 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2,
sx_assert(&proctree_lock, SX_SLOCKED);
sx_assert(&allproc_lock, SX_XLOCKED);
- p2_held = 0;
p1 = td->td_proc;
- trypid = fork_findpid(flags);
+ trypid = fork_findpid(fr->fr_flags);
sx_sunlock(&proctree_lock);
@@ -414,7 +423,7 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2,
/*
* Malloc things while we don't hold any locks.
*/
- if (flags & RFSIGSHARE)
+ if (fr->fr_flags & RFSIGSHARE)
newsigacts = NULL;
else
newsigacts = sigacts_alloc();
@@ -422,10 +431,10 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2,
/*
* Copy filedesc.
*/
- if (flags & RFCFDG) {
+ if (fr->fr_flags & RFCFDG) {
fd = fdinit(p1->p_fd, false);
fdtol = NULL;
- } else if (flags & RFFDG) {
+ } else if (fr->fr_flags & RFFDG) {
fd = fdcopy(p1->p_fd);
fdtol = NULL;
} else {
@@ -433,7 +442,7 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2,
if (p1->p_fdtol == NULL)
p1->p_fdtol = filedesc_to_leader_alloc(NULL, NULL,
p1->p_leader);
- if ((flags & RFTHREAD) != 0) {
+ if ((fr->fr_flags & RFTHREAD) != 0) {
/*
* Shared file descriptor table, and shared
* process leaders.
@@ -501,16 +510,16 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2,
vm_domain_policy_localcopy(&p2->p_vm_dom_policy,
&p1->p_vm_dom_policy);
- if (flags & RFSIGSHARE) {
+ if (fr->fr_flags & RFSIGSHARE) {
p2->p_sigacts = sigacts_hold(p1->p_sigacts);
} else {
sigacts_copy(newsigacts, p1->p_sigacts);
p2->p_sigacts = newsigacts;
}
- if (flags & RFTSIGZMB)
- p2->p_sigparent = RFTSIGNUM(flags);
- else if (flags & RFLINUXTHPN)
+ if (fr->fr_flags & RFTSIGZMB)
+ p2->p_sigparent = RFTSIGNUM(fr->fr_flags);
+ else if (fr->fr_flags & RFLINUXTHPN)
p2->p_sigparent = SIGUSR1;
else
p2->p_sigparent = SIGCHLD;
@@ -543,7 +552,7 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2,
/*
* Set up linkage for kernel based threading.
*/
- if ((flags & RFTHREAD) != 0) {
+ if ((fr->fr_flags & RFTHREAD) != 0) {
mtx_lock(&ppeers_lock);
p2->p_peers = p1->p_peers;
p1->p_peers = p2;
@@ -590,7 +599,7 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2,
if (p1->p_session->s_ttyvp != NULL && p1->p_flag & P_CONTROLT)
p2->p_flag |= P_CONTROLT;
SESS_UNLOCK(p1->p_session);
- if (flags & RFPPWAIT)
+ if (fr->fr_flags & RFPPWAIT)
p2->p_flag |= P_PPWAIT;
p2->p_pgrp = p1->p_pgrp;
@@ -624,7 +633,7 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2,
* of init. This effectively disassociates the child from the
* parent.
*/
- if ((flags & RFNOWAIT) != 0) {
+ if ((fr->fr_flags & RFNOWAIT) != 0) {
pptr = p1->p_reaper;
p2->p_reaper = pptr;
} else {
@@ -652,13 +661,13 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2,
* Finish creating the child process. It will return via a different
* execution path later. (ie: directly into user mode)
*/
- vm_forkproc(td, p2, td2, vm2, flags);
+ vm_forkproc(td, p2, td2, vm2, fr->fr_flags);
- if (flags == (RFFDG | RFPROC)) {
+ if (fr->fr_flags == (RFFDG | RFPROC)) {
PCPU_INC(cnt.v_forks);
PCPU_ADD(cnt.v_forkpages, p2->p_vmspace->vm_dsize +
p2->p_vmspace->vm_ssize);
- } else if (flags == (RFFDG | RFPROC | RFPPWAIT | RFMEM)) {
+ } else if (fr->fr_flags == (RFFDG | RFPROC | RFPPWAIT | RFMEM)) {
PCPU_INC(cnt.v_vforks);
PCPU_ADD(cnt.v_vforkpages, p2->p_vmspace->vm_dsize +
p2->p_vmspace->vm_ssize);
@@ -677,14 +686,14 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2,
* can happen that might cause that process to need the descriptor.
* However, don't do this until after fork(2) can no longer fail.
*/
- if (flags & RFPROCDESC)
- procdesc_new(p2, pdflags);
+ if (fr->fr_flags & RFPROCDESC)
+ procdesc_new(p2, fr->fr_pd_flags);
/*
* Both processes are set up, now check if any loadable modules want
* to adjust anything.
*/
- EVENTHANDLER_INVOKE(process_fork, p1, p2, flags);
+ EVENTHANDLER_INVOKE(process_fork, p1, p2, fr->fr_flags);
/*
* Set the child start time and mark the process as being complete.
@@ -703,9 +712,14 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2,
* this only after p_state is PRS_NORMAL since the fasttrap module will
* use pfind() later on.
*/
- if ((flags & RFMEM) == 0 && dtrace_fasttrap_fork)
+ if ((fr->fr_flags & RFMEM) == 0 && dtrace_fasttrap_fork)
dtrace_fasttrap_fork(p1, p2);
#endif
+ /*
+ * Hold the process so that it cannot exit after we make it runnable,
+ * but before we wait for the debugger.
+ */
+ _PHOLD(p2);
if ((p1->p_flag & (P_TRACED | P_FOLLOWFORK)) == (P_TRACED |
P_FOLLOWFORK)) {
/*
@@ -718,24 +732,12 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2,
td->td_dbgflags |= TDB_FORK;
td->td_dbg_forked = p2->p_pid;
td2->td_dbgflags |= TDB_STOPATFORK;
- _PHOLD(p2);
- p2_held = 1;
}
- if (flags & RFPPWAIT) {
+ if (fr->fr_flags & RFPPWAIT) {
td->td_pflags |= TDP_RFPPWAIT;
td->td_rfppwait_p = p2;
}
PROC_UNLOCK(p2);
- if ((flags & RFSTOPPED) == 0) {
- /*
- * If RFSTOPPED not requested, make child runnable and
- * add to run queue.
- */
- thread_lock(td2);
- TD_SET_CAN_RUN(td2);
- sched_add(td2, SRQ_BORING);
- thread_unlock(td2);
- }
/*
* Now can be swapped.
@@ -747,22 +749,41 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2,
* Tell any interested parties about the new process.
*/
knote_fork(&p1->p_klist, p2->p_pid);
- SDT_PROBE3(proc, , , create, p2, p1, flags);
+ SDT_PROBE3(proc, , , create, p2, p1, fr->fr_flags);
+ if (fr->fr_flags & RFPROCDESC) {
+ procdesc_finit(p2->p_procdesc, fp_procdesc);
+ fdrop(fp_procdesc, td);
+ }
+
+ if ((fr->fr_flags & RFSTOPPED) == 0) {
+ /*
+ * If RFSTOPPED not requested, make child runnable and
+ * add to run queue.
+ */
+ thread_lock(td2);
+ TD_SET_CAN_RUN(td2);
+ sched_add(td2, SRQ_BORING);
+ thread_unlock(td2);
+ if (fr->fr_pidp != NULL)
+ *fr->fr_pidp = p2->p_pid;
+ } else {
+ *fr->fr_procp = p2;
+ }
+
+ PROC_LOCK(p2);
/*
* Wait until debugger is attached to child.
*/
- PROC_LOCK(p2);
- while ((td2->td_dbgflags & TDB_STOPATFORK) != 0)
+ while (td2->td_proc == p2 && (td2->td_dbgflags & TDB_STOPATFORK) != 0)
cv_wait(&p2->p_dbgwait, &p2->p_mtx);
- if (p2_held)
- _PRELE(p2);
+ _PRELE(p2);
+ racct_proc_fork_done(p2);
PROC_UNLOCK(p2);
}
int
-fork1(struct thread *td, int flags, int pages, struct proc **procp,
- int *procdescp, int pdflags, struct filecaps *fcaps)
+fork1(struct thread *td, struct fork_req *fr)
{
struct proc *p1, *newproc;
struct thread *td2;
@@ -772,6 +793,15 @@ fork1(struct thread *td, int flags, int pages, struct proc **procp,
int error, nprocs_new, ok;
static int curfail;
static struct timeval lastfail;
+ int flags, pages;
+
+ flags = fr->fr_flags;
+ pages = fr->fr_pages;
+
+ if ((flags & RFSTOPPED) != 0)
+ MPASS(fr->fr_procp != NULL && fr->fr_pidp == NULL);
+ else
+ MPASS(fr->fr_procp == NULL);
/* Check for the undefined or unimplemented flags. */
if ((flags & ~(RFFLAGS | RFTSIGFLAGS(RFTSIGMASK))) != 0)
@@ -795,7 +825,7 @@ fork1(struct thread *td, int flags, int pages, struct proc **procp,
return (EINVAL);
/* Must provide a place to put a procdesc if creating one. */
- if (procdescp == NULL)
+ if (fr->fr_pd_fd == NULL)
return (EINVAL);
}
@@ -806,7 +836,10 @@ fork1(struct thread *td, int flags, int pages, struct proc **procp,
* certain parts of a process from itself.
*/
if ((flags & RFPROC) == 0) {
- *procp = NULL;
+ if (fr->fr_procp != NULL)
+ *fr->fr_procp = NULL;
+ else if (fr->fr_pidp != NULL)
+ *fr->fr_pidp = 0;
return (fork_norfproc(td, flags));
}
@@ -845,7 +878,8 @@ fork1(struct thread *td, int flags, int pages, struct proc **procp,
* later.
*/
if (flags & RFPROCDESC) {
- error = falloc_caps(td, &fp_procdesc, procdescp, 0, fcaps);
+ error = falloc_caps(td, &fp_procdesc, fr->fr_pd_fd, 0,
+ fr->fr_pd_fcaps);
if (error != 0)
goto fail2;
}
@@ -933,17 +967,7 @@ fork1(struct thread *td, int flags, int pages, struct proc **procp,
lim_cur(td, RLIMIT_NPROC));
}
if (ok) {
- do_fork(td, flags, newproc, td2, vm2, pdflags);
-
- /*
- * Return child proc pointer to parent.
- */
- *procp = newproc;
- if (flags & RFPROCDESC) {
- procdesc_finit(newproc->p_procdesc, fp_procdesc);
- fdrop(fp_procdesc, td);
- }
- racct_proc_fork_done(newproc);
+ do_fork(td, fr, newproc, td2, vm2, fp_procdesc);
return (0);
}
@@ -962,7 +986,7 @@ fail2:
vmspace_free(vm2);
uma_zfree(proc_zone, newproc);
if ((flags & RFPROCDESC) != 0 && fp_procdesc != NULL) {
- fdclose(td, fp_procdesc, *procdescp);
+ fdclose(td, fp_procdesc, *fr->fr_pd_fd);
fdrop(fp_procdesc, td);
}
atomic_add_int(&nprocs, -1);
diff --git a/sys/kern/kern_kthread.c b/sys/kern/kern_kthread.c
index 2072dc7..9cca255 100644
--- a/sys/kern/kern_kthread.c
+++ b/sys/kern/kern_kthread.c
@@ -80,6 +80,7 @@ int
kproc_create(void (*func)(void *), void *arg,
struct proc **newpp, int flags, int pages, const char *fmt, ...)
{
+ struct fork_req fr;
int error;
va_list ap;
struct thread *td;
@@ -88,8 +89,11 @@ kproc_create(void (*func)(void *), void *arg,
if (!proc0.p_stats)
panic("kproc_create called too soon");
- error = fork1(&thread0, RFMEM | RFFDG | RFPROC | RFSTOPPED | flags,
- pages, &p2, NULL, 0, NULL);
+ bzero(&fr, sizeof(fr));
+ fr.fr_flags = RFMEM | RFFDG | RFPROC | RFSTOPPED | flags;
+ fr.fr_pages = pages;
+ fr.fr_procp = &p2;
+ error = fork1(&thread0, &fr);
if (error)
return error;
diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c
index e7c81d6..f7c67f2 100644
--- a/sys/kern/kern_malloc.c
+++ b/sys/kern/kern_malloc.c
@@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$");
#include <sys/proc.h>
#include <sys/sbuf.h>
#include <sys/sysctl.h>
+#include <sys/taskqueue.h>
#include <sys/time.h>
#include <sys/vmem.h>
diff --git a/sys/kern/kern_mbuf.c b/sys/kern/kern_mbuf.c
index a864c94..5596439 100644
--- a/sys/kern/kern_mbuf.c
+++ b/sys/kern/kern_mbuf.c
@@ -52,7 +52,6 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_page.h>
#include <vm/vm_map.h>
#include <vm/uma.h>
-#include <vm/uma_int.h>
#include <vm/uma_dbg.h>
/*
@@ -275,12 +274,6 @@ uma_zone_t zone_jumbo16;
uma_zone_t zone_ext_refcnt;
/*
- * Callout to assist us in freeing mbufs.
- */
-static struct callout mb_reclaim_callout;
-static struct mtx mb_reclaim_callout_mtx;
-
-/*
* Local prototypes.
*/
static int mb_ctor_mbuf(void *, int, void *, int);
@@ -292,9 +285,8 @@ static void mb_dtor_pack(void *, int, void *);
static int mb_zinit_pack(void *, int, int);
static void mb_zfini_pack(void *, int);
-static void mb_reclaim(void *);
+static void mb_reclaim(uma_zone_t, int);
static void *mbuf_jumbo_alloc(uma_zone_t, vm_size_t, uint8_t *, int);
-static void mb_maxaction(uma_zone_t);
/* Ensure that MSIZE is a power of 2. */
CTASSERT((((MSIZE - 1) ^ MSIZE) + 1) >> 1 == MSIZE);
@@ -320,7 +312,7 @@ mbuf_init(void *dummy)
if (nmbufs > 0)
nmbufs = uma_zone_set_max(zone_mbuf, nmbufs);
uma_zone_set_warning(zone_mbuf, "kern.ipc.nmbufs limit reached");
- uma_zone_set_maxaction(zone_mbuf, mb_maxaction);
+ uma_zone_set_maxaction(zone_mbuf, mb_reclaim);
zone_clust = uma_zcreate(MBUF_CLUSTER_MEM_NAME, MCLBYTES,
mb_ctor_clust, mb_dtor_clust,
@@ -333,7 +325,7 @@ mbuf_init(void *dummy)
if (nmbclusters > 0)
nmbclusters = uma_zone_set_max(zone_clust, nmbclusters);
uma_zone_set_warning(zone_clust, "kern.ipc.nmbclusters limit reached");
- uma_zone_set_maxaction(zone_clust, mb_maxaction);
+ uma_zone_set_maxaction(zone_clust, mb_reclaim);
zone_pack = uma_zsecond_create(MBUF_PACKET_MEM_NAME, mb_ctor_pack,
mb_dtor_pack, mb_zinit_pack, mb_zfini_pack, zone_mbuf);
@@ -350,7 +342,7 @@ mbuf_init(void *dummy)
if (nmbjumbop > 0)
nmbjumbop = uma_zone_set_max(zone_jumbop, nmbjumbop);
uma_zone_set_warning(zone_jumbop, "kern.ipc.nmbjumbop limit reached");
- uma_zone_set_maxaction(zone_jumbop, mb_maxaction);
+ uma_zone_set_maxaction(zone_jumbop, mb_reclaim);
zone_jumbo9 = uma_zcreate(MBUF_JUMBO9_MEM_NAME, MJUM9BYTES,
mb_ctor_clust, mb_dtor_clust,
@@ -364,7 +356,7 @@ mbuf_init(void *dummy)
if (nmbjumbo9 > 0)
nmbjumbo9 = uma_zone_set_max(zone_jumbo9, nmbjumbo9);
uma_zone_set_warning(zone_jumbo9, "kern.ipc.nmbjumbo9 limit reached");
- uma_zone_set_maxaction(zone_jumbo9, mb_maxaction);
+ uma_zone_set_maxaction(zone_jumbo9, mb_reclaim);
zone_jumbo16 = uma_zcreate(MBUF_JUMBO16_MEM_NAME, MJUM16BYTES,
mb_ctor_clust, mb_dtor_clust,
@@ -378,20 +370,13 @@ mbuf_init(void *dummy)
if (nmbjumbo16 > 0)
nmbjumbo16 = uma_zone_set_max(zone_jumbo16, nmbjumbo16);
uma_zone_set_warning(zone_jumbo16, "kern.ipc.nmbjumbo16 limit reached");
- uma_zone_set_maxaction(zone_jumbo16, mb_maxaction);
+ uma_zone_set_maxaction(zone_jumbo16, mb_reclaim);
zone_ext_refcnt = uma_zcreate(MBUF_EXTREFCNT_MEM_NAME, sizeof(u_int),
NULL, NULL,
NULL, NULL,
UMA_ALIGN_PTR, UMA_ZONE_ZINIT);
- /* uma_prealloc() goes here... */
-
- /* Initialize the mb_reclaim() callout. */
- mtx_init(&mb_reclaim_callout_mtx, "mb_reclaim_callout_mtx", NULL,
- MTX_DEF);
- callout_init(&mb_reclaim_callout, 1);
-
/*
* Hook event handler for low-memory situation, used to
* drain protocols and push data back to the caches (UMA
@@ -678,81 +663,23 @@ m_pkthdr_init(struct mbuf *m, int how)
}
/*
- * This is the protocol drain routine.
+ * This is the protocol drain routine. Called by UMA whenever any of the
+ * mbuf zones is closed to its limit.
*
* No locks should be held when this is called. The drain routines have to
* presently acquire some locks which raises the possibility of lock order
* reversal.
*/
static void
-mb_reclaim(void *junk)
+mb_reclaim(uma_zone_t zone __unused, int pending __unused)
{
struct domain *dp;
struct protosw *pr;
- WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK | WARN_PANIC, NULL,
- "mb_reclaim()");
+ WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK | WARN_PANIC, NULL, __func__);
for (dp = domains; dp != NULL; dp = dp->dom_next)
for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
if (pr->pr_drain != NULL)
(*pr->pr_drain)();
}
-
-/*
- * This is the function called by the mb_reclaim_callout, which is
- * used when we hit the maximum for a zone.
- *
- * (See mb_maxaction() below.)
- */
-static void
-mb_reclaim_timer(void *junk __unused)
-{
-
- mtx_lock(&mb_reclaim_callout_mtx);
-
- /*
- * Avoid running this function extra times by skipping this invocation
- * if the callout has already been rescheduled.
- */
- if (callout_pending(&mb_reclaim_callout) ||
- !callout_active(&mb_reclaim_callout)) {
- mtx_unlock(&mb_reclaim_callout_mtx);
- return;
- }
- mtx_unlock(&mb_reclaim_callout_mtx);
-
- mb_reclaim(NULL);
-
- mtx_lock(&mb_reclaim_callout_mtx);
- callout_deactivate(&mb_reclaim_callout);
- mtx_unlock(&mb_reclaim_callout_mtx);
-}
-
-/*
- * This function is called when we hit the maximum for a zone.
- *
- * At that point, we want to call the protocol drain routine to free up some
- * mbufs. However, we will use the callout routines to schedule this to
- * occur in another thread. (The thread calling this function holds the
- * zone lock.)
- */
-static void
-mb_maxaction(uma_zone_t zone __unused)
-{
-
- /*
- * If we can't immediately obtain the lock, either the callout
- * is currently running, or another thread is scheduling the
- * callout.
- */
- if (!mtx_trylock(&mb_reclaim_callout_mtx))
- return;
-
- /* If not already scheduled/running, schedule the callout. */
- if (!callout_active(&mb_reclaim_callout)) {
- callout_reset(&mb_reclaim_callout, 1, mb_reclaim_timer, NULL);
- }
-
- mtx_unlock(&mb_reclaim_callout_mtx);
-}
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index a4f8576..729d7f0 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -2983,6 +2983,12 @@ static SYSCTL_NODE(_kern_proc, KERN_PROC_SIGTRAMP, sigtramp, CTLFLAG_RD |
int allproc_gen;
+/*
+ * stop_all_proc() purpose is to stop all process which have usermode,
+ * except current process for obvious reasons. This makes it somewhat
+ * unreliable when invoked from multithreaded process. The service
+ * must not be user-callable anyway.
+ */
void
stop_all_proc(void)
{
@@ -2991,17 +2997,6 @@ stop_all_proc(void)
bool restart, seen_stopped, seen_exiting, stopped_some;
cp = curproc;
- /*
- * stop_all_proc() assumes that all process which have
- * usermode must be stopped, except current process, for
- * obvious reasons. Since other threads in the process
- * establishing global stop could unstop something, disable
- * calls from multithreaded processes as precaution. The
- * service must not be user-callable anyway.
- */
- KASSERT((cp->p_flag & P_HADTHREADS) == 0 ||
- (cp->p_flag & P_KTHREAD) != 0, ("mt stop_all_proc"));
-
allproc_loop:
sx_xlock(&allproc_lock);
gen = allproc_gen;
@@ -3088,7 +3083,7 @@ resume_all_proc(void)
sx_xunlock(&allproc_lock);
}
-#define TOTAL_STOP_DEBUG 1
+/* #define TOTAL_STOP_DEBUG 1 */
#ifdef TOTAL_STOP_DEBUG
volatile static int ap_resume;
#include <sys/mount.h>
diff --git a/sys/kern/kern_racct.c b/sys/kern/kern_racct.c
index 0c7c0c4..ce7e2a4 100644
--- a/sys/kern/kern_racct.c
+++ b/sys/kern/kern_racct.c
@@ -957,16 +957,15 @@ void
racct_proc_fork_done(struct proc *child)
{
+ PROC_LOCK_ASSERT(child, MA_OWNED);
#ifdef RCTL
if (!racct_enable)
return;
- PROC_LOCK(child);
mtx_lock(&racct_lock);
rctl_enforce(child, RACCT_NPROC, 0);
rctl_enforce(child, RACCT_NTHR, 0);
mtx_unlock(&racct_lock);
- PROC_UNLOCK(child);
#endif
}
diff --git a/sys/kern/sysv_sem.c b/sys/kern/sysv_sem.c
index d9324f4..22616b9 100644
--- a/sys/kern/sysv_sem.c
+++ b/sys/kern/sysv_sem.c
@@ -867,6 +867,11 @@ sys_semget(struct thread *td, struct semget_args *uap)
}
if (semid < seminfo.semmni) {
DPRINTF(("found public key\n"));
+ if ((semflg & IPC_CREAT) && (semflg & IPC_EXCL)) {
+ DPRINTF(("not exclusive\n"));
+ error = EEXIST;
+ goto done2;
+ }
if ((error = ipcperm(td, &sema[semid].u.sem_perm,
semflg & 0700))) {
goto done2;
@@ -876,11 +881,6 @@ sys_semget(struct thread *td, struct semget_args *uap)
error = EINVAL;
goto done2;
}
- if ((semflg & IPC_CREAT) && (semflg & IPC_EXCL)) {
- DPRINTF(("not exclusive\n"));
- error = EEXIST;
- goto done2;
- }
#ifdef MAC
error = mac_sysvsem_check_semget(cred, &sema[semid]);
if (error != 0)
diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c
index 14a66c3..5b2083c 100644
--- a/sys/kern/vfs_aio.c
+++ b/sys/kern/vfs_aio.c
@@ -196,7 +196,7 @@ typedef struct oaiocb {
} oaiocb_t;
/*
- * Below is a key of locks used to protect each member of struct aiocblist
+ * Below is a key of locks used to protect each member of struct kaiocb
* aioliojob and kaioinfo and any backends.
*
* * - need not protected
@@ -219,10 +219,10 @@ typedef struct oaiocb {
* daemons.
*/
-struct aiocblist {
- TAILQ_ENTRY(aiocblist) list; /* (b) internal list of for backend */
- TAILQ_ENTRY(aiocblist) plist; /* (a) list of jobs for each backend */
- TAILQ_ENTRY(aiocblist) allist; /* (a) list of all jobs in proc */
+struct kaiocb {
+ TAILQ_ENTRY(kaiocb) list; /* (b) internal list of for backend */
+ TAILQ_ENTRY(kaiocb) plist; /* (a) list of jobs for each backend */
+ TAILQ_ENTRY(kaiocb) allist; /* (a) list of all jobs in proc */
int jobflags; /* (a) job flags */
int jobstate; /* (b) job state */
int inputcharge; /* (*) input blockes */
@@ -235,7 +235,7 @@ struct aiocblist {
struct ucred *cred; /* (*) active credential when created */
struct file *fd_file; /* (*) pointer to file structure */
struct aioliojob *lio; /* (*) optional lio job */
- struct aiocb *uuaiocb; /* (*) pointer in userspace of aiocb */
+ struct aiocb *ujob; /* (*) pointer in userspace of aiocb */
struct knlist klist; /* (a) list of knotes */
struct aiocb uaiocb; /* (*) kernel I/O control block */
ksiginfo_t ksi; /* (a) realtime signal info */
@@ -244,10 +244,10 @@ struct aiocblist {
};
/* jobflags */
-#define AIOCBLIST_DONE 0x01
-#define AIOCBLIST_BUFDONE 0x02
-#define AIOCBLIST_RUNDOWN 0x04
-#define AIOCBLIST_CHECKSYNC 0x08
+#define KAIOCB_DONE 0x01
+#define KAIOCB_BUFDONE 0x02
+#define KAIOCB_RUNDOWN 0x04
+#define KAIOCB_CHECKSYNC 0x08
/*
* AIO process info
@@ -289,12 +289,12 @@ struct kaioinfo {
int kaio_count; /* (a) size of AIO queue */
int kaio_ballowed_count; /* (*) maximum number of buffers */
int kaio_buffer_count; /* (a) number of physio buffers */
- TAILQ_HEAD(,aiocblist) kaio_all; /* (a) all AIOs in a process */
- TAILQ_HEAD(,aiocblist) kaio_done; /* (a) done queue for process */
+ TAILQ_HEAD(,kaiocb) kaio_all; /* (a) all AIOs in a process */
+ TAILQ_HEAD(,kaiocb) kaio_done; /* (a) done queue for process */
TAILQ_HEAD(,aioliojob) kaio_liojoblist; /* (a) list of lio jobs */
- TAILQ_HEAD(,aiocblist) kaio_jobqueue; /* (a) job queue for process */
- TAILQ_HEAD(,aiocblist) kaio_bufqueue; /* (a) buffer job queue */
- TAILQ_HEAD(,aiocblist) kaio_syncqueue; /* (a) queue for aio_fsync */
+ TAILQ_HEAD(,kaiocb) kaio_jobqueue; /* (a) job queue for process */
+ TAILQ_HEAD(,kaiocb) kaio_bufqueue; /* (a) buffer job queue */
+ TAILQ_HEAD(,kaiocb) kaio_syncqueue; /* (a) queue for aio_fsync */
struct task kaio_task; /* (*) task to kick aio processes */
};
@@ -323,28 +323,28 @@ struct aiocb_ops {
static TAILQ_HEAD(,aioproc) aio_freeproc; /* (c) Idle daemons */
static struct sema aio_newproc_sem;
static struct mtx aio_job_mtx;
-static TAILQ_HEAD(,aiocblist) aio_jobs; /* (c) Async job list */
+static TAILQ_HEAD(,kaiocb) aio_jobs; /* (c) Async job list */
static struct unrhdr *aiod_unr;
void aio_init_aioinfo(struct proc *p);
static int aio_onceonly(void);
-static int aio_free_entry(struct aiocblist *aiocbe);
-static void aio_process_rw(struct aiocblist *aiocbe);
-static void aio_process_sync(struct aiocblist *aiocbe);
-static void aio_process_mlock(struct aiocblist *aiocbe);
+static int aio_free_entry(struct kaiocb *job);
+static void aio_process_rw(struct kaiocb *job);
+static void aio_process_sync(struct kaiocb *job);
+static void aio_process_mlock(struct kaiocb *job);
static int aio_newproc(int *);
-int aio_aqueue(struct thread *td, struct aiocb *job,
+int aio_aqueue(struct thread *td, struct aiocb *ujob,
struct aioliojob *lio, int type, struct aiocb_ops *ops);
static void aio_physwakeup(struct bio *bp);
static void aio_proc_rundown(void *arg, struct proc *p);
static void aio_proc_rundown_exec(void *arg, struct proc *p,
struct image_params *imgp);
-static int aio_qphysio(struct proc *p, struct aiocblist *iocb);
+static int aio_qphysio(struct proc *p, struct kaiocb *job);
static void aio_daemon(void *param);
static void aio_swake_cb(struct socket *, struct sockbuf *);
static int aio_unload(void);
-static void aio_bio_done_notify(struct proc *userp,
- struct aiocblist *aiocbe, int type);
+static void aio_bio_done_notify(struct proc *userp, struct kaiocb *job,
+ int type);
#define DONE_BUF 1
#define DONE_QUEUE 2
static int aio_kick(struct proc *userp);
@@ -488,7 +488,7 @@ aio_onceonly(void)
NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
aiop_zone = uma_zcreate("AIOP", sizeof(struct aioproc), NULL,
NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
- aiocb_zone = uma_zcreate("AIOCB", sizeof(struct aiocblist), NULL, NULL,
+ aiocb_zone = uma_zcreate("AIOCB", sizeof(struct kaiocb), NULL, NULL,
NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
aiol_zone = uma_zcreate("AIOL", AIO_LISTIO_MAX*sizeof(intptr_t) , NULL,
NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
@@ -625,29 +625,29 @@ aio_sendsig(struct proc *p, struct sigevent *sigev, ksiginfo_t *ksi)
* restart the queue scan.
*/
static int
-aio_free_entry(struct aiocblist *aiocbe)
+aio_free_entry(struct kaiocb *job)
{
struct kaioinfo *ki;
struct aioliojob *lj;
struct proc *p;
- p = aiocbe->userproc;
+ p = job->userproc;
MPASS(curproc == p);
ki = p->p_aioinfo;
MPASS(ki != NULL);
AIO_LOCK_ASSERT(ki, MA_OWNED);
- MPASS(aiocbe->jobstate == JOBST_JOBFINISHED);
+ MPASS(job->jobstate == JOBST_JOBFINISHED);
atomic_subtract_int(&num_queue_count, 1);
ki->kaio_count--;
MPASS(ki->kaio_count >= 0);
- TAILQ_REMOVE(&ki->kaio_done, aiocbe, plist);
- TAILQ_REMOVE(&ki->kaio_all, aiocbe, allist);
+ TAILQ_REMOVE(&ki->kaio_done, job, plist);
+ TAILQ_REMOVE(&ki->kaio_all, job, allist);
- lj = aiocbe->lio;
+ lj = job->lio;
if (lj) {
lj->lioj_count--;
lj->lioj_finished_count--;
@@ -663,14 +663,14 @@ aio_free_entry(struct aiocblist *aiocbe)
}
}
- /* aiocbe is going away, we need to destroy any knotes */
- knlist_delete(&aiocbe->klist, curthread, 1);
+ /* job is going away, we need to destroy any knotes */
+ knlist_delete(&job->klist, curthread, 1);
PROC_LOCK(p);
- sigqueue_take(&aiocbe->ksi);
+ sigqueue_take(&job->ksi);
PROC_UNLOCK(p);
- MPASS(aiocbe->bp == NULL);
- aiocbe->jobstate = JOBST_NULL;
+ MPASS(job->bp == NULL);
+ job->jobstate = JOBST_NULL;
AIO_UNLOCK(ki);
/*
@@ -682,7 +682,7 @@ aio_free_entry(struct aiocblist *aiocbe)
* another process.
*
* Currently, all the callers of this function call it to remove
- * an aiocblist from the current process' job list either via a
+ * a kaiocb from the current process' job list either via a
* syscall or due to the current process calling exit() or
* execve(). Thus, we know that p == curproc. We also know that
* curthread can't exit since we are curthread.
@@ -693,10 +693,10 @@ aio_free_entry(struct aiocblist *aiocbe)
* at open time, but this is already true of file descriptors in
* a multithreaded process.
*/
- if (aiocbe->fd_file)
- fdrop(aiocbe->fd_file, curthread);
- crfree(aiocbe->cred);
- uma_zfree(aiocb_zone, aiocbe);
+ if (job->fd_file)
+ fdrop(job->fd_file, curthread);
+ crfree(job->cred);
+ uma_zfree(aiocb_zone, job);
AIO_LOCK(ki);
return (0);
@@ -717,7 +717,7 @@ aio_proc_rundown(void *arg, struct proc *p)
{
struct kaioinfo *ki;
struct aioliojob *lj;
- struct aiocblist *cbe, *cbn;
+ struct kaiocb *job, *jobn;
struct file *fp;
struct socket *so;
int remove;
@@ -737,30 +737,30 @@ restart:
* Try to cancel all pending requests. This code simulates
* aio_cancel on all pending I/O requests.
*/
- TAILQ_FOREACH_SAFE(cbe, &ki->kaio_jobqueue, plist, cbn) {
+ TAILQ_FOREACH_SAFE(job, &ki->kaio_jobqueue, plist, jobn) {
remove = 0;
mtx_lock(&aio_job_mtx);
- if (cbe->jobstate == JOBST_JOBQGLOBAL) {
- TAILQ_REMOVE(&aio_jobs, cbe, list);
+ if (job->jobstate == JOBST_JOBQGLOBAL) {
+ TAILQ_REMOVE(&aio_jobs, job, list);
remove = 1;
- } else if (cbe->jobstate == JOBST_JOBQSOCK) {
- fp = cbe->fd_file;
+ } else if (job->jobstate == JOBST_JOBQSOCK) {
+ fp = job->fd_file;
MPASS(fp->f_type == DTYPE_SOCKET);
so = fp->f_data;
- TAILQ_REMOVE(&so->so_aiojobq, cbe, list);
+ TAILQ_REMOVE(&so->so_aiojobq, job, list);
remove = 1;
- } else if (cbe->jobstate == JOBST_JOBQSYNC) {
- TAILQ_REMOVE(&ki->kaio_syncqueue, cbe, list);
+ } else if (job->jobstate == JOBST_JOBQSYNC) {
+ TAILQ_REMOVE(&ki->kaio_syncqueue, job, list);
remove = 1;
}
mtx_unlock(&aio_job_mtx);
if (remove) {
- cbe->jobstate = JOBST_JOBFINISHED;
- cbe->uaiocb._aiocb_private.status = -1;
- cbe->uaiocb._aiocb_private.error = ECANCELED;
- TAILQ_REMOVE(&ki->kaio_jobqueue, cbe, plist);
- aio_bio_done_notify(p, cbe, DONE_QUEUE);
+ job->jobstate = JOBST_JOBFINISHED;
+ job->uaiocb._aiocb_private.status = -1;
+ job->uaiocb._aiocb_private.error = ECANCELED;
+ TAILQ_REMOVE(&ki->kaio_jobqueue, job, plist);
+ aio_bio_done_notify(p, job, DONE_QUEUE);
}
}
@@ -773,8 +773,8 @@ restart:
}
/* Free all completed I/O requests. */
- while ((cbe = TAILQ_FIRST(&ki->kaio_done)) != NULL)
- aio_free_entry(cbe);
+ while ((job = TAILQ_FIRST(&ki->kaio_done)) != NULL)
+ aio_free_entry(job);
while ((lj = TAILQ_FIRST(&ki->kaio_liojoblist)) != NULL) {
if (lj->lioj_count == 0) {
@@ -799,27 +799,27 @@ restart:
/*
* Select a job to run (called by an AIO daemon).
*/
-static struct aiocblist *
+static struct kaiocb *
aio_selectjob(struct aioproc *aiop)
{
- struct aiocblist *aiocbe;
+ struct kaiocb *job;
struct kaioinfo *ki;
struct proc *userp;
mtx_assert(&aio_job_mtx, MA_OWNED);
- TAILQ_FOREACH(aiocbe, &aio_jobs, list) {
- userp = aiocbe->userproc;
+ TAILQ_FOREACH(job, &aio_jobs, list) {
+ userp = job->userproc;
ki = userp->p_aioinfo;
if (ki->kaio_active_count < ki->kaio_maxactive_count) {
- TAILQ_REMOVE(&aio_jobs, aiocbe, list);
+ TAILQ_REMOVE(&aio_jobs, job, list);
/* Account for currently active jobs. */
ki->kaio_active_count++;
- aiocbe->jobstate = JOBST_JOBRUNNING;
+ job->jobstate = JOBST_JOBRUNNING;
break;
}
}
- return (aiocbe);
+ return (job);
}
/*
@@ -857,7 +857,7 @@ drop:
* XXX I don't think it works well for socket, pipe, and fifo.
*/
static void
-aio_process_rw(struct aiocblist *aiocbe)
+aio_process_rw(struct kaiocb *job)
{
struct ucred *td_savedcred;
struct thread *td;
@@ -871,15 +871,15 @@ aio_process_rw(struct aiocblist *aiocbe)
int oublock_st, oublock_end;
int inblock_st, inblock_end;
- KASSERT(aiocbe->uaiocb.aio_lio_opcode == LIO_READ ||
- aiocbe->uaiocb.aio_lio_opcode == LIO_WRITE,
- ("%s: opcode %d", __func__, aiocbe->uaiocb.aio_lio_opcode));
+ KASSERT(job->uaiocb.aio_lio_opcode == LIO_READ ||
+ job->uaiocb.aio_lio_opcode == LIO_WRITE,
+ ("%s: opcode %d", __func__, job->uaiocb.aio_lio_opcode));
td = curthread;
td_savedcred = td->td_ucred;
- td->td_ucred = aiocbe->cred;
- cb = &aiocbe->uaiocb;
- fp = aiocbe->fd_file;
+ td->td_ucred = job->cred;
+ cb = &job->uaiocb;
+ fp = job->fd_file;
aiov.iov_base = (void *)(uintptr_t)cb->aio_buf;
aiov.iov_len = cb->aio_nbytes;
@@ -913,8 +913,8 @@ aio_process_rw(struct aiocblist *aiocbe)
inblock_end = td->td_ru.ru_inblock;
oublock_end = td->td_ru.ru_oublock;
- aiocbe->inputcharge = inblock_end - inblock_st;
- aiocbe->outputcharge = oublock_end - oublock_st;
+ job->inputcharge = inblock_end - inblock_st;
+ job->outputcharge = oublock_end - oublock_st;
if ((error) && (auio.uio_resid != cnt)) {
if (error == ERESTART || error == EINTR || error == EWOULDBLOCK)
@@ -927,9 +927,9 @@ aio_process_rw(struct aiocblist *aiocbe)
sigpipe = 0;
}
if (sigpipe) {
- PROC_LOCK(aiocbe->userproc);
- kern_psignal(aiocbe->userproc, SIGPIPE);
- PROC_UNLOCK(aiocbe->userproc);
+ PROC_LOCK(job->userproc);
+ kern_psignal(job->userproc, SIGPIPE);
+ PROC_UNLOCK(job->userproc);
}
}
}
@@ -941,18 +941,18 @@ aio_process_rw(struct aiocblist *aiocbe)
}
static void
-aio_process_sync(struct aiocblist *aiocbe)
+aio_process_sync(struct kaiocb *job)
{
struct thread *td = curthread;
struct ucred *td_savedcred = td->td_ucred;
- struct aiocb *cb = &aiocbe->uaiocb;
- struct file *fp = aiocbe->fd_file;
+ struct aiocb *cb = &job->uaiocb;
+ struct file *fp = job->fd_file;
int error = 0;
- KASSERT(aiocbe->uaiocb.aio_lio_opcode == LIO_SYNC,
- ("%s: opcode %d", __func__, aiocbe->uaiocb.aio_lio_opcode));
+ KASSERT(job->uaiocb.aio_lio_opcode == LIO_SYNC,
+ ("%s: opcode %d", __func__, job->uaiocb.aio_lio_opcode));
- td->td_ucred = aiocbe->cred;
+ td->td_ucred = job->cred;
if (fp->f_vnode != NULL)
error = aio_fsync_vnode(td, fp->f_vnode);
cb->_aiocb_private.error = error;
@@ -961,31 +961,31 @@ aio_process_sync(struct aiocblist *aiocbe)
}
static void
-aio_process_mlock(struct aiocblist *aiocbe)
+aio_process_mlock(struct kaiocb *job)
{
- struct aiocb *cb = &aiocbe->uaiocb;
+ struct aiocb *cb = &job->uaiocb;
int error;
- KASSERT(aiocbe->uaiocb.aio_lio_opcode == LIO_MLOCK,
- ("%s: opcode %d", __func__, aiocbe->uaiocb.aio_lio_opcode));
+ KASSERT(job->uaiocb.aio_lio_opcode == LIO_MLOCK,
+ ("%s: opcode %d", __func__, job->uaiocb.aio_lio_opcode));
- error = vm_mlock(aiocbe->userproc, aiocbe->cred,
+ error = vm_mlock(job->userproc, job->cred,
__DEVOLATILE(void *, cb->aio_buf), cb->aio_nbytes);
cb->_aiocb_private.error = error;
cb->_aiocb_private.status = 0;
}
static void
-aio_bio_done_notify(struct proc *userp, struct aiocblist *aiocbe, int type)
+aio_bio_done_notify(struct proc *userp, struct kaiocb *job, int type)
{
struct aioliojob *lj;
struct kaioinfo *ki;
- struct aiocblist *scb, *scbn;
+ struct kaiocb *sjob, *sjobn;
int lj_done;
ki = userp->p_aioinfo;
AIO_LOCK_ASSERT(ki, MA_OWNED);
- lj = aiocbe->lio;
+ lj = job->lio;
lj_done = 0;
if (lj) {
lj->lioj_finished_count++;
@@ -993,21 +993,21 @@ aio_bio_done_notify(struct proc *userp, struct aiocblist *aiocbe, int type)
lj_done = 1;
}
if (type == DONE_QUEUE) {
- aiocbe->jobflags |= AIOCBLIST_DONE;
+ job->jobflags |= KAIOCB_DONE;
} else {
- aiocbe->jobflags |= AIOCBLIST_BUFDONE;
+ job->jobflags |= KAIOCB_BUFDONE;
}
- TAILQ_INSERT_TAIL(&ki->kaio_done, aiocbe, plist);
- aiocbe->jobstate = JOBST_JOBFINISHED;
+ TAILQ_INSERT_TAIL(&ki->kaio_done, job, plist);
+ job->jobstate = JOBST_JOBFINISHED;
if (ki->kaio_flags & KAIO_RUNDOWN)
goto notification_done;
- if (aiocbe->uaiocb.aio_sigevent.sigev_notify == SIGEV_SIGNAL ||
- aiocbe->uaiocb.aio_sigevent.sigev_notify == SIGEV_THREAD_ID)
- aio_sendsig(userp, &aiocbe->uaiocb.aio_sigevent, &aiocbe->ksi);
+ if (job->uaiocb.aio_sigevent.sigev_notify == SIGEV_SIGNAL ||
+ job->uaiocb.aio_sigevent.sigev_notify == SIGEV_THREAD_ID)
+ aio_sendsig(userp, &job->uaiocb.aio_sigevent, &job->ksi);
- KNOTE_LOCKED(&aiocbe->klist, 1);
+ KNOTE_LOCKED(&job->klist, 1);
if (lj_done) {
if (lj->lioj_signal.sigev_notify == SIGEV_KEVENT) {
@@ -1024,16 +1024,16 @@ aio_bio_done_notify(struct proc *userp, struct aiocblist *aiocbe, int type)
}
notification_done:
- if (aiocbe->jobflags & AIOCBLIST_CHECKSYNC) {
- TAILQ_FOREACH_SAFE(scb, &ki->kaio_syncqueue, list, scbn) {
- if (aiocbe->fd_file == scb->fd_file &&
- aiocbe->seqno < scb->seqno) {
- if (--scb->pending == 0) {
+ if (job->jobflags & KAIOCB_CHECKSYNC) {
+ TAILQ_FOREACH_SAFE(sjob, &ki->kaio_syncqueue, list, sjobn) {
+ if (job->fd_file == sjob->fd_file &&
+ job->seqno < sjob->seqno) {
+ if (--sjob->pending == 0) {
mtx_lock(&aio_job_mtx);
- scb->jobstate = JOBST_JOBQGLOBAL;
- TAILQ_REMOVE(&ki->kaio_syncqueue, scb,
+ sjob->jobstate = JOBST_JOBQGLOBAL;
+ TAILQ_REMOVE(&ki->kaio_syncqueue, sjob,
list);
- TAILQ_INSERT_TAIL(&aio_jobs, scb, list);
+ TAILQ_INSERT_TAIL(&aio_jobs, sjob, list);
aio_kick_nowait(userp);
mtx_unlock(&aio_job_mtx);
}
@@ -1047,10 +1047,10 @@ notification_done:
}
static void
-aio_switch_vmspace(struct aiocblist *aiocbe)
+aio_switch_vmspace(struct kaiocb *job)
{
- vmspace_switch_aio(aiocbe->userproc->p_vmspace);
+ vmspace_switch_aio(job->userproc->p_vmspace);
}
/*
@@ -1060,7 +1060,7 @@ aio_switch_vmspace(struct aiocblist *aiocbe)
static void
aio_daemon(void *_id)
{
- struct aiocblist *aiocbe;
+ struct kaiocb *job;
struct aioproc *aiop;
struct kaioinfo *ki;
struct proc *p, *userp;
@@ -1105,28 +1105,28 @@ aio_daemon(void *_id)
/*
* Check for jobs.
*/
- while ((aiocbe = aio_selectjob(aiop)) != NULL) {
+ while ((job = aio_selectjob(aiop)) != NULL) {
mtx_unlock(&aio_job_mtx);
- userp = aiocbe->userproc;
+ userp = job->userproc;
/*
* Connect to process address space for user program.
*/
- aio_switch_vmspace(aiocbe);
+ aio_switch_vmspace(job);
ki = userp->p_aioinfo;
/* Do the I/O function. */
- switch(aiocbe->uaiocb.aio_lio_opcode) {
+ switch(job->uaiocb.aio_lio_opcode) {
case LIO_READ:
case LIO_WRITE:
- aio_process_rw(aiocbe);
+ aio_process_rw(job);
break;
case LIO_SYNC:
- aio_process_sync(aiocbe);
+ aio_process_sync(job);
break;
case LIO_MLOCK:
- aio_process_mlock(aiocbe);
+ aio_process_mlock(job);
break;
}
@@ -1136,8 +1136,8 @@ aio_daemon(void *_id)
mtx_unlock(&aio_job_mtx);
AIO_LOCK(ki);
- TAILQ_REMOVE(&ki->kaio_jobqueue, aiocbe, plist);
- aio_bio_done_notify(userp, aiocbe, DONE_QUEUE);
+ TAILQ_REMOVE(&ki->kaio_jobqueue, job, plist);
+ aio_bio_done_notify(userp, job, DONE_QUEUE);
AIO_UNLOCK(ki);
mtx_lock(&aio_job_mtx);
@@ -1226,7 +1226,7 @@ aio_newproc(int *start)
* duration of this call.
*/
static int
-aio_qphysio(struct proc *p, struct aiocblist *aiocbe)
+aio_qphysio(struct proc *p, struct kaiocb *job)
{
struct aiocb *cb;
struct file *fp;
@@ -1240,8 +1240,8 @@ aio_qphysio(struct proc *p, struct aiocblist *aiocbe)
int error, ref, unmap, poff;
vm_prot_t prot;
- cb = &aiocbe->uaiocb;
- fp = aiocbe->fd_file;
+ cb = &job->uaiocb;
+ fp = job->fd_file;
if (fp == NULL || fp->f_type != DTYPE_VNODE)
return (-1);
@@ -1286,9 +1286,9 @@ aio_qphysio(struct proc *p, struct aiocblist *aiocbe)
goto unref;
}
}
- aiocbe->bp = bp = g_alloc_bio();
+ job->bp = bp = g_alloc_bio();
if (!unmap) {
- aiocbe->pbuf = pbuf = (struct buf *)getpbuf(NULL);
+ job->pbuf = pbuf = (struct buf *)getpbuf(NULL);
BUF_KERNPROC(pbuf);
}
@@ -1296,12 +1296,12 @@ aio_qphysio(struct proc *p, struct aiocblist *aiocbe)
ki->kaio_count++;
if (!unmap)
ki->kaio_buffer_count++;
- lj = aiocbe->lio;
+ lj = job->lio;
if (lj)
lj->lioj_count++;
- TAILQ_INSERT_TAIL(&ki->kaio_bufqueue, aiocbe, plist);
- TAILQ_INSERT_TAIL(&ki->kaio_all, aiocbe, allist);
- aiocbe->jobstate = JOBST_JOBQBUF;
+ TAILQ_INSERT_TAIL(&ki->kaio_bufqueue, job, plist);
+ TAILQ_INSERT_TAIL(&ki->kaio_all, job, allist);
+ job->jobstate = JOBST_JOBQBUF;
cb->_aiocb_private.status = cb->aio_nbytes;
AIO_UNLOCK(ki);
@@ -1312,25 +1312,25 @@ aio_qphysio(struct proc *p, struct aiocblist *aiocbe)
bp->bio_offset = cb->aio_offset;
bp->bio_cmd = cb->aio_lio_opcode == LIO_WRITE ? BIO_WRITE : BIO_READ;
bp->bio_dev = dev;
- bp->bio_caller1 = (void *)aiocbe;
+ bp->bio_caller1 = (void *)job;
prot = VM_PROT_READ;
if (cb->aio_lio_opcode == LIO_READ)
prot |= VM_PROT_WRITE; /* Less backwards than it looks */
- if ((aiocbe->npages = vm_fault_quick_hold_pages(
+ if ((job->npages = vm_fault_quick_hold_pages(
&curproc->p_vmspace->vm_map,
- (vm_offset_t)bp->bio_data, bp->bio_length, prot, aiocbe->pages,
- sizeof(aiocbe->pages)/sizeof(aiocbe->pages[0]))) < 0) {
+ (vm_offset_t)bp->bio_data, bp->bio_length, prot, job->pages,
+ sizeof(job->pages)/sizeof(job->pages[0]))) < 0) {
error = EFAULT;
goto doerror;
}
if (!unmap) {
pmap_qenter((vm_offset_t)pbuf->b_data,
- aiocbe->pages, aiocbe->npages);
+ job->pages, job->npages);
bp->bio_data = pbuf->b_data + poff;
} else {
- bp->bio_ma = aiocbe->pages;
- bp->bio_ma_n = aiocbe->npages;
+ bp->bio_ma = job->pages;
+ bp->bio_ma_n = job->npages;
bp->bio_ma_offset = poff;
bp->bio_data = unmapped_buf;
bp->bio_flags |= BIO_UNMAPPED;
@@ -1347,9 +1347,9 @@ aio_qphysio(struct proc *p, struct aiocblist *aiocbe)
doerror:
AIO_LOCK(ki);
- aiocbe->jobstate = JOBST_NULL;
- TAILQ_REMOVE(&ki->kaio_bufqueue, aiocbe, plist);
- TAILQ_REMOVE(&ki->kaio_all, aiocbe, allist);
+ job->jobstate = JOBST_NULL;
+ TAILQ_REMOVE(&ki->kaio_bufqueue, job, plist);
+ TAILQ_REMOVE(&ki->kaio_all, job, allist);
ki->kaio_count--;
if (!unmap)
ki->kaio_buffer_count--;
@@ -1358,10 +1358,10 @@ doerror:
AIO_UNLOCK(ki);
if (pbuf) {
relpbuf(pbuf, NULL);
- aiocbe->pbuf = NULL;
+ job->pbuf = NULL;
}
g_destroy_bio(bp);
- aiocbe->bp = NULL;
+ job->bp = NULL;
unref:
dev_relthread(dev, ref);
return (error);
@@ -1373,7 +1373,7 @@ unref:
static void
aio_swake_cb(struct socket *so, struct sockbuf *sb)
{
- struct aiocblist *cb, *cbn;
+ struct kaiocb *job, *jobn;
int opcode;
SOCKBUF_LOCK_ASSERT(sb);
@@ -1384,18 +1384,18 @@ aio_swake_cb(struct socket *so, struct sockbuf *sb)
sb->sb_flags &= ~SB_AIO;
mtx_lock(&aio_job_mtx);
- TAILQ_FOREACH_SAFE(cb, &so->so_aiojobq, list, cbn) {
- if (opcode == cb->uaiocb.aio_lio_opcode) {
- if (cb->jobstate != JOBST_JOBQSOCK)
+ TAILQ_FOREACH_SAFE(job, &so->so_aiojobq, list, jobn) {
+ if (opcode == job->uaiocb.aio_lio_opcode) {
+ if (job->jobstate != JOBST_JOBQSOCK)
panic("invalid queue value");
/* XXX
* We don't have actual sockets backend yet,
* so we simply move the requests to the generic
* file I/O backend.
*/
- TAILQ_REMOVE(&so->so_aiojobq, cb, list);
- TAILQ_INSERT_TAIL(&aio_jobs, cb, list);
- aio_kick_nowait(cb->userproc);
+ TAILQ_REMOVE(&so->so_aiojobq, job, list);
+ TAILQ_INSERT_TAIL(&aio_jobs, job, list);
+ aio_kick_nowait(job->userproc);
}
}
mtx_unlock(&aio_job_mtx);
@@ -1515,14 +1515,14 @@ static struct aiocb_ops aiocb_ops_osigevent = {
* technique is done in this code.
*/
int
-aio_aqueue(struct thread *td, struct aiocb *job, struct aioliojob *lj,
+aio_aqueue(struct thread *td, struct aiocb *ujob, struct aioliojob *lj,
int type, struct aiocb_ops *ops)
{
struct proc *p = td->td_proc;
cap_rights_t rights;
struct file *fp;
struct socket *so;
- struct aiocblist *aiocbe, *cb;
+ struct kaiocb *job, *job2;
struct kaioinfo *ki;
struct kevent kev;
struct sockbuf *sb;
@@ -1537,57 +1537,57 @@ aio_aqueue(struct thread *td, struct aiocb *job, struct aioliojob *lj,
ki = p->p_aioinfo;
- ops->store_status(job, -1);
- ops->store_error(job, 0);
- ops->store_kernelinfo(job, -1);
+ ops->store_status(ujob, -1);
+ ops->store_error(ujob, 0);
+ ops->store_kernelinfo(ujob, -1);
if (num_queue_count >= max_queue_count ||
ki->kaio_count >= ki->kaio_qallowed_count) {
- ops->store_error(job, EAGAIN);
+ ops->store_error(ujob, EAGAIN);
return (EAGAIN);
}
- aiocbe = uma_zalloc(aiocb_zone, M_WAITOK | M_ZERO);
- knlist_init_mtx(&aiocbe->klist, AIO_MTX(ki));
+ job = uma_zalloc(aiocb_zone, M_WAITOK | M_ZERO);
+ knlist_init_mtx(&job->klist, AIO_MTX(ki));
- error = ops->copyin(job, &aiocbe->uaiocb);
+ error = ops->copyin(ujob, &job->uaiocb);
if (error) {
- ops->store_error(job, error);
- uma_zfree(aiocb_zone, aiocbe);
+ ops->store_error(ujob, error);
+ uma_zfree(aiocb_zone, job);
return (error);
}
/* XXX: aio_nbytes is later casted to signed types. */
- if (aiocbe->uaiocb.aio_nbytes > INT_MAX) {
- uma_zfree(aiocb_zone, aiocbe);
+ if (job->uaiocb.aio_nbytes > INT_MAX) {
+ uma_zfree(aiocb_zone, job);
return (EINVAL);
}
- if (aiocbe->uaiocb.aio_sigevent.sigev_notify != SIGEV_KEVENT &&
- aiocbe->uaiocb.aio_sigevent.sigev_notify != SIGEV_SIGNAL &&
- aiocbe->uaiocb.aio_sigevent.sigev_notify != SIGEV_THREAD_ID &&
- aiocbe->uaiocb.aio_sigevent.sigev_notify != SIGEV_NONE) {
- ops->store_error(job, EINVAL);
- uma_zfree(aiocb_zone, aiocbe);
+ if (job->uaiocb.aio_sigevent.sigev_notify != SIGEV_KEVENT &&
+ job->uaiocb.aio_sigevent.sigev_notify != SIGEV_SIGNAL &&
+ job->uaiocb.aio_sigevent.sigev_notify != SIGEV_THREAD_ID &&
+ job->uaiocb.aio_sigevent.sigev_notify != SIGEV_NONE) {
+ ops->store_error(ujob, EINVAL);
+ uma_zfree(aiocb_zone, job);
return (EINVAL);
}
- if ((aiocbe->uaiocb.aio_sigevent.sigev_notify == SIGEV_SIGNAL ||
- aiocbe->uaiocb.aio_sigevent.sigev_notify == SIGEV_THREAD_ID) &&
- !_SIG_VALID(aiocbe->uaiocb.aio_sigevent.sigev_signo)) {
- uma_zfree(aiocb_zone, aiocbe);
+ if ((job->uaiocb.aio_sigevent.sigev_notify == SIGEV_SIGNAL ||
+ job->uaiocb.aio_sigevent.sigev_notify == SIGEV_THREAD_ID) &&
+ !_SIG_VALID(job->uaiocb.aio_sigevent.sigev_signo)) {
+ uma_zfree(aiocb_zone, job);
return (EINVAL);
}
- ksiginfo_init(&aiocbe->ksi);
+ ksiginfo_init(&job->ksi);
/* Save userspace address of the job info. */
- aiocbe->uuaiocb = job;
+ job->ujob = ujob;
/* Get the opcode. */
if (type != LIO_NOP)
- aiocbe->uaiocb.aio_lio_opcode = type;
- opcode = aiocbe->uaiocb.aio_lio_opcode;
+ job->uaiocb.aio_lio_opcode = type;
+ opcode = job->uaiocb.aio_lio_opcode;
/*
* Validate the opcode and fetch the file object for the specified
@@ -1597,7 +1597,7 @@ aio_aqueue(struct thread *td, struct aiocb *job, struct aioliojob *lj,
* retrieve a file descriptor without knowing what the capabiltity
* should be.
*/
- fd = aiocbe->uaiocb.aio_fildes;
+ fd = job->uaiocb.aio_fildes;
switch (opcode) {
case LIO_WRITE:
error = fget_write(td, fd,
@@ -1620,8 +1620,8 @@ aio_aqueue(struct thread *td, struct aiocb *job, struct aioliojob *lj,
error = EINVAL;
}
if (error) {
- uma_zfree(aiocb_zone, aiocbe);
- ops->store_error(job, error);
+ uma_zfree(aiocb_zone, job);
+ ops->store_error(ujob, error);
return (error);
}
@@ -1630,60 +1630,60 @@ aio_aqueue(struct thread *td, struct aiocb *job, struct aioliojob *lj,
goto aqueue_fail;
}
- if (opcode != LIO_SYNC && aiocbe->uaiocb.aio_offset == -1LL) {
+ if (opcode != LIO_SYNC && job->uaiocb.aio_offset == -1LL) {
error = EINVAL;
goto aqueue_fail;
}
- aiocbe->fd_file = fp;
+ job->fd_file = fp;
mtx_lock(&aio_job_mtx);
jid = jobrefid++;
- aiocbe->seqno = jobseqno++;
+ job->seqno = jobseqno++;
mtx_unlock(&aio_job_mtx);
- error = ops->store_kernelinfo(job, jid);
+ error = ops->store_kernelinfo(ujob, jid);
if (error) {
error = EINVAL;
goto aqueue_fail;
}
- aiocbe->uaiocb._aiocb_private.kernelinfo = (void *)(intptr_t)jid;
+ job->uaiocb._aiocb_private.kernelinfo = (void *)(intptr_t)jid;
if (opcode == LIO_NOP) {
fdrop(fp, td);
- uma_zfree(aiocb_zone, aiocbe);
+ uma_zfree(aiocb_zone, job);
return (0);
}
- if (aiocbe->uaiocb.aio_sigevent.sigev_notify != SIGEV_KEVENT)
+ if (job->uaiocb.aio_sigevent.sigev_notify != SIGEV_KEVENT)
goto no_kqueue;
- evflags = aiocbe->uaiocb.aio_sigevent.sigev_notify_kevent_flags;
+ evflags = job->uaiocb.aio_sigevent.sigev_notify_kevent_flags;
if ((evflags & ~(EV_CLEAR | EV_DISPATCH | EV_ONESHOT)) != 0) {
error = EINVAL;
goto aqueue_fail;
}
- kqfd = aiocbe->uaiocb.aio_sigevent.sigev_notify_kqueue;
- kev.ident = (uintptr_t)aiocbe->uuaiocb;
+ kqfd = job->uaiocb.aio_sigevent.sigev_notify_kqueue;
+ kev.ident = (uintptr_t)job->ujob;
kev.filter = EVFILT_AIO;
kev.flags = EV_ADD | EV_ENABLE | EV_FLAG1 | evflags;
- kev.data = (intptr_t)aiocbe;
- kev.udata = aiocbe->uaiocb.aio_sigevent.sigev_value.sival_ptr;
+ kev.data = (intptr_t)job;
+ kev.udata = job->uaiocb.aio_sigevent.sigev_value.sival_ptr;
error = kqfd_register(kqfd, &kev, td, 1);
aqueue_fail:
if (error) {
if (fp)
fdrop(fp, td);
- uma_zfree(aiocb_zone, aiocbe);
- ops->store_error(job, error);
+ uma_zfree(aiocb_zone, job);
+ ops->store_error(ujob, error);
goto done;
}
no_kqueue:
- ops->store_error(job, EINPROGRESS);
- aiocbe->uaiocb._aiocb_private.error = EINPROGRESS;
- aiocbe->userproc = p;
- aiocbe->cred = crhold(td->td_ucred);
- aiocbe->jobflags = 0;
- aiocbe->lio = lj;
+ ops->store_error(ujob, EINPROGRESS);
+ job->uaiocb._aiocb_private.error = EINPROGRESS;
+ job->userproc = p;
+ job->cred = crhold(td->td_ucred);
+ job->jobflags = 0;
+ job->lio = lj;
if (opcode == LIO_SYNC)
goto queueit;
@@ -1695,7 +1695,7 @@ no_kqueue:
* socket is ready to be read or written (based on the requested
* operation).
*
- * If it is not ready for io, then queue the aiocbe on the
+ * If it is not ready for io, then queue the job on the
* socket, and set the flags so we get a call when sbnotify()
* happens.
*
@@ -1710,13 +1710,13 @@ no_kqueue:
sb->sb_flags |= SB_AIO;
mtx_lock(&aio_job_mtx);
- TAILQ_INSERT_TAIL(&so->so_aiojobq, aiocbe, list);
+ TAILQ_INSERT_TAIL(&so->so_aiojobq, job, list);
mtx_unlock(&aio_job_mtx);
AIO_LOCK(ki);
- TAILQ_INSERT_TAIL(&ki->kaio_all, aiocbe, allist);
- TAILQ_INSERT_TAIL(&ki->kaio_jobqueue, aiocbe, plist);
- aiocbe->jobstate = JOBST_JOBQSOCK;
+ TAILQ_INSERT_TAIL(&ki->kaio_all, job, allist);
+ TAILQ_INSERT_TAIL(&ki->kaio_jobqueue, job, plist);
+ job->jobstate = JOBST_JOBQSOCK;
ki->kaio_count++;
if (lj)
lj->lioj_count++;
@@ -1729,12 +1729,12 @@ no_kqueue:
SOCKBUF_UNLOCK(sb);
}
- if ((error = aio_qphysio(p, aiocbe)) == 0)
+ if ((error = aio_qphysio(p, job)) == 0)
goto done;
#if 0
if (error > 0) {
- aiocbe->uaiocb._aiocb_private.error = error;
- ops->store_error(job, error);
+ job->uaiocb._aiocb_private.error = error;
+ ops->store_error(ujob, error);
goto done;
}
#endif
@@ -1745,35 +1745,35 @@ queueit:
ki->kaio_count++;
if (lj)
lj->lioj_count++;
- TAILQ_INSERT_TAIL(&ki->kaio_jobqueue, aiocbe, plist);
- TAILQ_INSERT_TAIL(&ki->kaio_all, aiocbe, allist);
+ TAILQ_INSERT_TAIL(&ki->kaio_jobqueue, job, plist);
+ TAILQ_INSERT_TAIL(&ki->kaio_all, job, allist);
if (opcode == LIO_SYNC) {
- TAILQ_FOREACH(cb, &ki->kaio_jobqueue, plist) {
- if (cb->fd_file == aiocbe->fd_file &&
- cb->uaiocb.aio_lio_opcode != LIO_SYNC &&
- cb->seqno < aiocbe->seqno) {
- cb->jobflags |= AIOCBLIST_CHECKSYNC;
- aiocbe->pending++;
+ TAILQ_FOREACH(job2, &ki->kaio_jobqueue, plist) {
+ if (job2->fd_file == job->fd_file &&
+ job2->uaiocb.aio_lio_opcode != LIO_SYNC &&
+ job2->seqno < job->seqno) {
+ job2->jobflags |= KAIOCB_CHECKSYNC;
+ job->pending++;
}
}
- TAILQ_FOREACH(cb, &ki->kaio_bufqueue, plist) {
- if (cb->fd_file == aiocbe->fd_file &&
- cb->uaiocb.aio_lio_opcode != LIO_SYNC &&
- cb->seqno < aiocbe->seqno) {
- cb->jobflags |= AIOCBLIST_CHECKSYNC;
- aiocbe->pending++;
+ TAILQ_FOREACH(job2, &ki->kaio_bufqueue, plist) {
+ if (job2->fd_file == job->fd_file &&
+ job2->uaiocb.aio_lio_opcode != LIO_SYNC &&
+ job2->seqno < job->seqno) {
+ job2->jobflags |= KAIOCB_CHECKSYNC;
+ job->pending++;
}
}
- if (aiocbe->pending != 0) {
- TAILQ_INSERT_TAIL(&ki->kaio_syncqueue, aiocbe, list);
- aiocbe->jobstate = JOBST_JOBQSYNC;
+ if (job->pending != 0) {
+ TAILQ_INSERT_TAIL(&ki->kaio_syncqueue, job, list);
+ job->jobstate = JOBST_JOBQSYNC;
AIO_UNLOCK(ki);
goto done;
}
}
mtx_lock(&aio_job_mtx);
- TAILQ_INSERT_TAIL(&aio_jobs, aiocbe, list);
- aiocbe->jobstate = JOBST_JOBQGLOBAL;
+ TAILQ_INSERT_TAIL(&aio_jobs, job, list);
+ job->jobstate = JOBST_JOBQGLOBAL;
aio_kick_nowait(p);
mtx_unlock(&aio_job_mtx);
AIO_UNLOCK(ki);
@@ -1848,10 +1848,10 @@ aio_kick_helper(void *context, int pending)
* released.
*/
static int
-kern_aio_return(struct thread *td, struct aiocb *uaiocb, struct aiocb_ops *ops)
+kern_aio_return(struct thread *td, struct aiocb *ujob, struct aiocb_ops *ops)
{
struct proc *p = td->td_proc;
- struct aiocblist *cb;
+ struct kaiocb *job;
struct kaioinfo *ki;
int status, error;
@@ -1859,26 +1859,26 @@ kern_aio_return(struct thread *td, struct aiocb *uaiocb, struct aiocb_ops *ops)
if (ki == NULL)
return (EINVAL);
AIO_LOCK(ki);
- TAILQ_FOREACH(cb, &ki->kaio_done, plist) {
- if (cb->uuaiocb == uaiocb)
+ TAILQ_FOREACH(job, &ki->kaio_done, plist) {
+ if (job->ujob == ujob)
break;
}
- if (cb != NULL) {
- MPASS(cb->jobstate == JOBST_JOBFINISHED);
- status = cb->uaiocb._aiocb_private.status;
- error = cb->uaiocb._aiocb_private.error;
+ if (job != NULL) {
+ MPASS(job->jobstate == JOBST_JOBFINISHED);
+ status = job->uaiocb._aiocb_private.status;
+ error = job->uaiocb._aiocb_private.error;
td->td_retval[0] = status;
- if (cb->uaiocb.aio_lio_opcode == LIO_WRITE) {
- td->td_ru.ru_oublock += cb->outputcharge;
- cb->outputcharge = 0;
- } else if (cb->uaiocb.aio_lio_opcode == LIO_READ) {
- td->td_ru.ru_inblock += cb->inputcharge;
- cb->inputcharge = 0;
+ if (job->uaiocb.aio_lio_opcode == LIO_WRITE) {
+ td->td_ru.ru_oublock += job->outputcharge;
+ job->outputcharge = 0;
+ } else if (job->uaiocb.aio_lio_opcode == LIO_READ) {
+ td->td_ru.ru_inblock += job->inputcharge;
+ job->inputcharge = 0;
}
- aio_free_entry(cb);
+ aio_free_entry(job);
AIO_UNLOCK(ki);
- ops->store_error(uaiocb, error);
- ops->store_status(uaiocb, status);
+ ops->store_error(ujob, error);
+ ops->store_status(ujob, status);
} else {
error = EINVAL;
AIO_UNLOCK(ki);
@@ -1903,7 +1903,7 @@ kern_aio_suspend(struct thread *td, int njoblist, struct aiocb **ujoblist,
struct proc *p = td->td_proc;
struct timeval atv;
struct kaioinfo *ki;
- struct aiocblist *cb, *cbfirst;
+ struct kaiocb *firstjob, *job;
int error, i, timo;
timo = 0;
@@ -1926,20 +1926,20 @@ kern_aio_suspend(struct thread *td, int njoblist, struct aiocb **ujoblist,
AIO_LOCK(ki);
for (;;) {
- cbfirst = NULL;
+ firstjob = NULL;
error = 0;
- TAILQ_FOREACH(cb, &ki->kaio_all, allist) {
+ TAILQ_FOREACH(job, &ki->kaio_all, allist) {
for (i = 0; i < njoblist; i++) {
- if (cb->uuaiocb == ujoblist[i]) {
- if (cbfirst == NULL)
- cbfirst = cb;
- if (cb->jobstate == JOBST_JOBFINISHED)
+ if (job->ujob == ujoblist[i]) {
+ if (firstjob == NULL)
+ firstjob = job;
+ if (job->jobstate == JOBST_JOBFINISHED)
goto RETURN;
}
}
}
/* All tasks were finished. */
- if (cbfirst == NULL)
+ if (firstjob == NULL)
break;
ki->kaio_flags |= KAIO_WAKEUP;
@@ -1990,7 +1990,7 @@ sys_aio_cancel(struct thread *td, struct aio_cancel_args *uap)
{
struct proc *p = td->td_proc;
struct kaioinfo *ki;
- struct aiocblist *cbe, *cbn;
+ struct kaiocb *job, *jobn;
struct file *fp;
struct socket *so;
cap_rights_t rights;
@@ -2019,32 +2019,32 @@ sys_aio_cancel(struct thread *td, struct aio_cancel_args *uap)
}
AIO_LOCK(ki);
- TAILQ_FOREACH_SAFE(cbe, &ki->kaio_jobqueue, plist, cbn) {
- if ((uap->fd == cbe->uaiocb.aio_fildes) &&
+ TAILQ_FOREACH_SAFE(job, &ki->kaio_jobqueue, plist, jobn) {
+ if ((uap->fd == job->uaiocb.aio_fildes) &&
((uap->aiocbp == NULL) ||
- (uap->aiocbp == cbe->uuaiocb))) {
+ (uap->aiocbp == job->ujob))) {
remove = 0;
mtx_lock(&aio_job_mtx);
- if (cbe->jobstate == JOBST_JOBQGLOBAL) {
- TAILQ_REMOVE(&aio_jobs, cbe, list);
+ if (job->jobstate == JOBST_JOBQGLOBAL) {
+ TAILQ_REMOVE(&aio_jobs, job, list);
remove = 1;
- } else if (cbe->jobstate == JOBST_JOBQSOCK) {
+ } else if (job->jobstate == JOBST_JOBQSOCK) {
MPASS(fp->f_type == DTYPE_SOCKET);
so = fp->f_data;
- TAILQ_REMOVE(&so->so_aiojobq, cbe, list);
+ TAILQ_REMOVE(&so->so_aiojobq, job, list);
remove = 1;
- } else if (cbe->jobstate == JOBST_JOBQSYNC) {
- TAILQ_REMOVE(&ki->kaio_syncqueue, cbe, list);
+ } else if (job->jobstate == JOBST_JOBQSYNC) {
+ TAILQ_REMOVE(&ki->kaio_syncqueue, job, list);
remove = 1;
}
mtx_unlock(&aio_job_mtx);
if (remove) {
- TAILQ_REMOVE(&ki->kaio_jobqueue, cbe, plist);
- cbe->uaiocb._aiocb_private.status = -1;
- cbe->uaiocb._aiocb_private.error = ECANCELED;
- aio_bio_done_notify(p, cbe, DONE_QUEUE);
+ TAILQ_REMOVE(&ki->kaio_jobqueue, job, plist);
+ job->uaiocb._aiocb_private.status = -1;
+ job->uaiocb._aiocb_private.error = ECANCELED;
+ aio_bio_done_notify(p, job, DONE_QUEUE);
cancelled++;
} else {
notcancelled++;
@@ -2086,10 +2086,10 @@ done:
* a userland subroutine.
*/
static int
-kern_aio_error(struct thread *td, struct aiocb *aiocbp, struct aiocb_ops *ops)
+kern_aio_error(struct thread *td, struct aiocb *ujob, struct aiocb_ops *ops)
{
struct proc *p = td->td_proc;
- struct aiocblist *cb;
+ struct kaiocb *job;
struct kaioinfo *ki;
int status;
@@ -2100,11 +2100,11 @@ kern_aio_error(struct thread *td, struct aiocb *aiocbp, struct aiocb_ops *ops)
}
AIO_LOCK(ki);
- TAILQ_FOREACH(cb, &ki->kaio_all, allist) {
- if (cb->uuaiocb == aiocbp) {
- if (cb->jobstate == JOBST_JOBFINISHED)
+ TAILQ_FOREACH(job, &ki->kaio_all, allist) {
+ if (job->ujob == ujob) {
+ if (job->jobstate == JOBST_JOBFINISHED)
td->td_retval[0] =
- cb->uaiocb._aiocb_private.error;
+ job->uaiocb._aiocb_private.error;
else
td->td_retval[0] = EINPROGRESS;
AIO_UNLOCK(ki);
@@ -2116,9 +2116,9 @@ kern_aio_error(struct thread *td, struct aiocb *aiocbp, struct aiocb_ops *ops)
/*
* Hack for failure of aio_aqueue.
*/
- status = ops->fetch_status(aiocbp);
+ status = ops->fetch_status(ujob);
if (status == -1) {
- td->td_retval[0] = ops->fetch_error(aiocbp);
+ td->td_retval[0] = ops->fetch_error(ujob);
return (0);
}
@@ -2178,7 +2178,7 @@ kern_lio_listio(struct thread *td, int mode, struct aiocb * const *uacb_list,
struct aiocb_ops *ops)
{
struct proc *p = td->td_proc;
- struct aiocb *iocb;
+ struct aiocb *job;
struct kaioinfo *ki;
struct aioliojob *lj;
struct kevent kev;
@@ -2254,9 +2254,9 @@ kern_lio_listio(struct thread *td, int mode, struct aiocb * const *uacb_list,
*/
nerror = 0;
for (i = 0; i < nent; i++) {
- iocb = acb_list[i];
- if (iocb != NULL) {
- error = aio_aqueue(td, iocb, lj, LIO_NOP, ops);
+ job = acb_list[i];
+ if (job != NULL) {
+ error = aio_aqueue(td, job, lj, LIO_NOP, ops);
if (error != 0)
nerror++;
}
@@ -2379,37 +2379,37 @@ sys_lio_listio(struct thread *td, struct lio_listio_args *uap)
static void
aio_physwakeup(struct bio *bp)
{
- struct aiocblist *aiocbe = (struct aiocblist *)bp->bio_caller1;
+ struct kaiocb *job = (struct kaiocb *)bp->bio_caller1;
struct proc *userp;
struct kaioinfo *ki;
int nblks;
/* Release mapping into kernel space. */
- if (aiocbe->pbuf) {
- pmap_qremove((vm_offset_t)aiocbe->pbuf->b_data, aiocbe->npages);
- relpbuf(aiocbe->pbuf, NULL);
- aiocbe->pbuf = NULL;
+ if (job->pbuf) {
+ pmap_qremove((vm_offset_t)job->pbuf->b_data, job->npages);
+ relpbuf(job->pbuf, NULL);
+ job->pbuf = NULL;
atomic_subtract_int(&num_buf_aio, 1);
}
- vm_page_unhold_pages(aiocbe->pages, aiocbe->npages);
+ vm_page_unhold_pages(job->pages, job->npages);
- bp = aiocbe->bp;
- aiocbe->bp = NULL;
- userp = aiocbe->userproc;
+ bp = job->bp;
+ job->bp = NULL;
+ userp = job->userproc;
ki = userp->p_aioinfo;
AIO_LOCK(ki);
- aiocbe->uaiocb._aiocb_private.status -= bp->bio_resid;
- aiocbe->uaiocb._aiocb_private.error = 0;
+ job->uaiocb._aiocb_private.status -= bp->bio_resid;
+ job->uaiocb._aiocb_private.error = 0;
if (bp->bio_flags & BIO_ERROR)
- aiocbe->uaiocb._aiocb_private.error = bp->bio_error;
- nblks = btodb(aiocbe->uaiocb.aio_nbytes);
- if (aiocbe->uaiocb.aio_lio_opcode == LIO_WRITE)
- aiocbe->outputcharge += nblks;
+ job->uaiocb._aiocb_private.error = bp->bio_error;
+ nblks = btodb(job->uaiocb.aio_nbytes);
+ if (job->uaiocb.aio_lio_opcode == LIO_WRITE)
+ job->outputcharge += nblks;
else
- aiocbe->inputcharge += nblks;
- TAILQ_REMOVE(&userp->p_aioinfo->kaio_bufqueue, aiocbe, plist);
+ job->inputcharge += nblks;
+ TAILQ_REMOVE(&userp->p_aioinfo->kaio_bufqueue, job, plist);
ki->kaio_buffer_count--;
- aio_bio_done_notify(userp, aiocbe, DONE_BUF);
+ aio_bio_done_notify(userp, job, DONE_BUF);
AIO_UNLOCK(ki);
g_destroy_bio(bp);
@@ -2417,17 +2417,17 @@ aio_physwakeup(struct bio *bp)
/* syscall - wait for the next completion of an aio request */
static int
-kern_aio_waitcomplete(struct thread *td, struct aiocb **aiocbp,
+kern_aio_waitcomplete(struct thread *td, struct aiocb **ujobp,
struct timespec *ts, struct aiocb_ops *ops)
{
struct proc *p = td->td_proc;
struct timeval atv;
struct kaioinfo *ki;
- struct aiocblist *cb;
- struct aiocb *uuaiocb;
+ struct kaiocb *job;
+ struct aiocb *ujob;
int error, status, timo;
- ops->store_aiocb(aiocbp, NULL);
+ ops->store_aiocb(ujobp, NULL);
if (ts == NULL) {
timo = 0;
@@ -2448,9 +2448,9 @@ kern_aio_waitcomplete(struct thread *td, struct aiocb **aiocbp,
ki = p->p_aioinfo;
error = 0;
- cb = NULL;
+ job = NULL;
AIO_LOCK(ki);
- while ((cb = TAILQ_FIRST(&ki->kaio_done)) == NULL) {
+ while ((job = TAILQ_FIRST(&ki->kaio_done)) == NULL) {
if (timo == -1) {
error = EWOULDBLOCK;
break;
@@ -2464,24 +2464,24 @@ kern_aio_waitcomplete(struct thread *td, struct aiocb **aiocbp,
break;
}
- if (cb != NULL) {
- MPASS(cb->jobstate == JOBST_JOBFINISHED);
- uuaiocb = cb->uuaiocb;
- status = cb->uaiocb._aiocb_private.status;
- error = cb->uaiocb._aiocb_private.error;
+ if (job != NULL) {
+ MPASS(job->jobstate == JOBST_JOBFINISHED);
+ ujob = job->ujob;
+ status = job->uaiocb._aiocb_private.status;
+ error = job->uaiocb._aiocb_private.error;
td->td_retval[0] = status;
- if (cb->uaiocb.aio_lio_opcode == LIO_WRITE) {
- td->td_ru.ru_oublock += cb->outputcharge;
- cb->outputcharge = 0;
- } else if (cb->uaiocb.aio_lio_opcode == LIO_READ) {
- td->td_ru.ru_inblock += cb->inputcharge;
- cb->inputcharge = 0;
+ if (job->uaiocb.aio_lio_opcode == LIO_WRITE) {
+ td->td_ru.ru_oublock += job->outputcharge;
+ job->outputcharge = 0;
+ } else if (job->uaiocb.aio_lio_opcode == LIO_READ) {
+ td->td_ru.ru_inblock += job->inputcharge;
+ job->inputcharge = 0;
}
- aio_free_entry(cb);
+ aio_free_entry(job);
AIO_UNLOCK(ki);
- ops->store_aiocb(aiocbp, uuaiocb);
- ops->store_error(uuaiocb, error);
- ops->store_status(uuaiocb, status);
+ ops->store_aiocb(ujobp, ujob);
+ ops->store_error(ujob, error);
+ ops->store_status(ujob, status);
} else
AIO_UNLOCK(ki);
@@ -2507,7 +2507,7 @@ sys_aio_waitcomplete(struct thread *td, struct aio_waitcomplete_args *uap)
}
static int
-kern_aio_fsync(struct thread *td, int op, struct aiocb *aiocbp,
+kern_aio_fsync(struct thread *td, int op, struct aiocb *ujob,
struct aiocb_ops *ops)
{
struct proc *p = td->td_proc;
@@ -2518,7 +2518,7 @@ kern_aio_fsync(struct thread *td, int op, struct aiocb *aiocbp,
ki = p->p_aioinfo;
if (ki == NULL)
aio_init_aioinfo(p);
- return (aio_aqueue(td, aiocbp, NULL, LIO_SYNC, ops));
+ return (aio_aqueue(td, ujob, NULL, LIO_SYNC, ops));
}
int
@@ -2532,19 +2532,19 @@ sys_aio_fsync(struct thread *td, struct aio_fsync_args *uap)
static int
filt_aioattach(struct knote *kn)
{
- struct aiocblist *aiocbe = (struct aiocblist *)kn->kn_sdata;
+ struct kaiocb *job = (struct kaiocb *)kn->kn_sdata;
/*
- * The aiocbe pointer must be validated before using it, so
+ * The job pointer must be validated before using it, so
* registration is restricted to the kernel; the user cannot
* set EV_FLAG1.
*/
if ((kn->kn_flags & EV_FLAG1) == 0)
return (EPERM);
- kn->kn_ptr.p_aio = aiocbe;
+ kn->kn_ptr.p_aio = job;
kn->kn_flags &= ~EV_FLAG1;
- knlist_add(&aiocbe->klist, kn, 0);
+ knlist_add(&job->klist, kn, 0);
return (0);
}
@@ -2567,10 +2567,10 @@ filt_aiodetach(struct knote *kn)
static int
filt_aio(struct knote *kn, long hint)
{
- struct aiocblist *aiocbe = kn->kn_ptr.p_aio;
+ struct kaiocb *job = kn->kn_ptr.p_aio;
- kn->kn_data = aiocbe->uaiocb._aiocb_private.error;
- if (aiocbe->jobstate != JOBST_JOBFINISHED)
+ kn->kn_data = job->uaiocb._aiocb_private.error;
+ if (job->jobstate != JOBST_JOBFINISHED)
return (0);
kn->kn_flags |= EV_EOF;
return (1);
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index eb392cb..e272f9d 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -2245,7 +2245,7 @@ brelse(struct buf *bp)
int qindex;
/*
- * Many function erroneously call brelse with a NULL bp under rare
+ * Many functions erroneously call brelse with a NULL bp under rare
* error conditions. Simply return when called with a NULL bp.
*/
if (bp == NULL)
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
index 3ca995f..505da75 100644
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -880,10 +880,10 @@ vfs_domount_update(
struct vfsoptlist **optlist /* Options local to the filesystem. */
)
{
- struct oexport_args oexport;
struct export_args export;
+ void *bufp;
struct mount *mp;
- int error, export_error;
+ int error, export_error, len;
uint64_t flag;
ASSERT_VOP_ELOCKED(vp, __func__);
@@ -951,23 +951,21 @@ vfs_domount_update(
error = VFS_MOUNT(mp);
export_error = 0;
- if (error == 0) {
- /* Process the export option. */
- if (vfs_copyopt(mp->mnt_optnew, "export", &export,
- sizeof(export)) == 0) {
- export_error = vfs_export(mp, &export);
- } else if (vfs_copyopt(mp->mnt_optnew, "export", &oexport,
- sizeof(oexport)) == 0) {
- export.ex_flags = oexport.ex_flags;
- export.ex_root = oexport.ex_root;
- export.ex_anon = oexport.ex_anon;
- export.ex_addr = oexport.ex_addr;
- export.ex_addrlen = oexport.ex_addrlen;
- export.ex_mask = oexport.ex_mask;
- export.ex_masklen = oexport.ex_masklen;
- export.ex_indexfile = oexport.ex_indexfile;
- export.ex_numsecflavors = 0;
+ /* Process the export option. */
+ if (error == 0 && vfs_getopt(mp->mnt_optnew, "export", &bufp,
+ &len) == 0) {
+ /* Assume that there is only 1 ABI for each length. */
+ switch (len) {
+ case (sizeof(struct oexport_args)):
+ bzero(&export, sizeof(export));
+ /* FALLTHROUGH */
+ case (sizeof(export)):
+ bcopy(bufp, &export, len);
export_error = vfs_export(mp, &export);
+ break;
+ default:
+ export_error = EINVAL;
+ break;
}
}
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index c246b9e..0762ca7a 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -987,7 +987,8 @@ kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
}
/*
- * Allocate the file descriptor, but don't install a descriptor yet.
+ * Allocate a file structure. The descriptor to reference it
+ * is allocated and set by finstall() below.
*/
error = falloc_noinstall(td, &fp);
if (error != 0)
diff --git a/sys/mips/mips/uma_machdep.c b/sys/mips/mips/uma_machdep.c
index b4006e1..7014703 100644
--- a/sys/mips/mips/uma_machdep.c
+++ b/sys/mips/mips/uma_machdep.c
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/systm.h>
+#include <sys/taskqueue.h>
#include <vm/vm.h>
#include <vm/vm_page.h>
#include <vm/vm_pageout.h>
diff --git a/sys/mips/mips/vm_machdep.c b/sys/mips/mips/vm_machdep.c
index f952ecc..03fc60e 100644
--- a/sys/mips/mips/vm_machdep.c
+++ b/sys/mips/mips/vm_machdep.c
@@ -56,6 +56,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/sysctl.h>
#include <sys/unistd.h>
+#include <sys/taskqueue.h>
#include <machine/cache.h>
#include <machine/clock.h>
diff --git a/sys/powerpc/fpu/fpu_emu.c b/sys/powerpc/fpu/fpu_emu.c
index 9056dca..011b999 100644
--- a/sys/powerpc/fpu/fpu_emu.c
+++ b/sys/powerpc/fpu/fpu_emu.c
@@ -275,7 +275,7 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn)
vm_offset_t addr;
int ra, rb, rc, rt, type, mask, fsr, cx, bf, setcr;
unsigned int cond;
- struct fpreg *fs;
+ struct fpu *fs;
/* Setup work. */
fp = NULL;
@@ -335,7 +335,7 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn)
if (ra != 0)
addr += tf->fixreg[ra];
rt = instr.i_x.i_rt;
- a = (int *)&fs->fpreg[rt].fpr;
+ a = (int *)&fs->fpr[rt].fpr;
DPRINTF(FPE_INSN,
("fpu_execute: Store INT %x at %p\n",
a[1], (void *)addr));
@@ -402,7 +402,7 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn)
DPRINTF(FPE_INSN,
("fpu_execute: Store DBL at %p\n",
(void *)addr));
- if (copyout(&fs->fpreg[rt].fpr, (void *)addr,
+ if (copyout(&fs->fpr[rt].fpr, (void *)addr,
size))
return (FAULT);
}
@@ -411,13 +411,13 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn)
FPU_EMU_EVCNT_INCR(fpload);
DPRINTF(FPE_INSN, ("fpu_execute: Load from %p\n",
(void *)addr));
- if (copyin((const void *)addr, &fs->fpreg[rt].fpr,
+ if (copyin((const void *)addr, &fs->fpr[rt].fpr,
size))
return (FAULT);
if (type != FTYPE_DBL) {
fpu_explode(fe, fp = &fe->fe_f1, type, rt);
fpu_implode(fe, fp, FTYPE_DBL,
- (u_int *)&fs->fpreg[rt].fpr);
+ (u_int *)&fs->fpr[rt].fpr);
}
}
if (update)
@@ -470,7 +470,7 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn)
DPRINTF(FPE_INSN, ("fpu_execute: FRSP\n"));
fpu_explode(fe, fp = &fe->fe_f1, FTYPE_DBL, rb);
fpu_implode(fe, fp, FTYPE_SNG,
- (u_int *)&fs->fpreg[rt].fpr);
+ (u_int *)&fs->fpr[rt].fpr);
fpu_explode(fe, fp = &fe->fe_f1, FTYPE_SNG, rt);
type = FTYPE_DBL;
break;
@@ -503,9 +503,9 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn)
case OPC63_FNEG:
FPU_EMU_EVCNT_INCR(fnegabs);
DPRINTF(FPE_INSN, ("fpu_execute: FNEGABS\n"));
- memcpy(&fs->fpreg[rt].fpr, &fs->fpreg[rb].fpr,
+ memcpy(&fs->fpr[rt].fpr, &fs->fpr[rb].fpr,
sizeof(double));
- a = (int *)&fs->fpreg[rt].fpr;
+ a = (int *)&fs->fpr[rt].fpr;
*a ^= (1U << 31);
break;
case OPC63_MCRFS:
@@ -533,7 +533,7 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn)
case OPC63_FMR:
FPU_EMU_EVCNT_INCR(fmr);
DPRINTF(FPE_INSN, ("fpu_execute: FMR\n"));
- memcpy(&fs->fpreg[rt].fpr, &fs->fpreg[rb].fpr,
+ memcpy(&fs->fpr[rt].fpr, &fs->fpr[rb].fpr,
sizeof(double));
break;
case OPC63_MTFSFI:
@@ -550,23 +550,23 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn)
case OPC63_FNABS:
FPU_EMU_EVCNT_INCR(fnabs);
DPRINTF(FPE_INSN, ("fpu_execute: FABS\n"));
- memcpy(&fs->fpreg[rt].fpr, &fs->fpreg[rb].fpr,
+ memcpy(&fs->fpr[rt].fpr, &fs->fpr[rb].fpr,
sizeof(double));
- a = (int *)&fs->fpreg[rt].fpr;
+ a = (int *)&fs->fpr[rt].fpr;
*a |= (1U << 31);
break;
case OPC63_FABS:
FPU_EMU_EVCNT_INCR(fabs);
DPRINTF(FPE_INSN, ("fpu_execute: FABS\n"));
- memcpy(&fs->fpreg[rt].fpr, &fs->fpreg[rb].fpr,
+ memcpy(&fs->fpr[rt].fpr, &fs->fpr[rb].fpr,
sizeof(double));
- a = (int *)&fs->fpreg[rt].fpr;
+ a = (int *)&fs->fpr[rt].fpr;
*a &= ~(1U << 31);
break;
case OPC63_MFFS:
FPU_EMU_EVCNT_INCR(mffs);
DPRINTF(FPE_INSN, ("fpu_execute: MFFS\n"));
- memcpy(&fs->fpreg[rt].fpr, &fs->fpscr,
+ memcpy(&fs->fpr[rt].fpr, &fs->fpscr,
sizeof(fs->fpscr));
break;
case OPC63_MTFSF:
@@ -581,7 +581,7 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn)
if (rt & (1<<ra))
mask |= (0xf<<(4*ra));
}
- a = (int *)&fs->fpreg[rt].fpr;
+ a = (int *)&fs->fpr[rt].fpr;
fe->fe_cx = mask & a[1];
fe->fe_fpscr = (fe->fe_fpscr&~mask) |
(fe->fe_cx);
@@ -648,12 +648,12 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn)
case OPC63M_FSEL:
FPU_EMU_EVCNT_INCR(fsel);
DPRINTF(FPE_INSN, ("fpu_execute: FSEL\n"));
- a = (int *)&fe->fe_fpstate->fpreg[ra].fpr;
+ a = (int *)&fe->fe_fpstate->fpr[ra].fpr;
if ((*a & 0x80000000) && (*a & 0x7fffffff))
/* fra < 0 */
rc = rb;
DPRINTF(FPE_INSN, ("f%d => f%d\n", rc, rt));
- memcpy(&fs->fpreg[rt].fpr, &fs->fpreg[rc].fpr,
+ memcpy(&fs->fpr[rt].fpr, &fs->fpr[rc].fpr,
sizeof(double));
break;
case OPC59_FRES:
@@ -662,7 +662,7 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn)
fpu_explode(fe, &fe->fe_f1, type, rb);
fp = fpu_sqrt(fe);
/* now we've gotta overwrite the dest reg */
- *((int *)&fe->fe_fpstate->fpreg[rt].fpr) = 1;
+ *((int *)&fe->fe_fpstate->fpr[rt].fpr) = 1;
fpu_explode(fe, &fe->fe_f1, FTYPE_INT, rt);
fpu_div(fe);
break;
@@ -681,7 +681,7 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn)
fp = fpu_sqrt(fe);
fe->fe_f2 = *fp;
/* now we've gotta overwrite the dest reg */
- *((int *)&fe->fe_fpstate->fpreg[rt].fpr) = 1;
+ *((int *)&fe->fe_fpstate->fpr[rt].fpr) = 1;
fpu_explode(fe, &fe->fe_f1, FTYPE_INT, rt);
fpu_div(fe);
break;
@@ -737,7 +737,7 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn)
/* If the instruction was single precision, round */
if (!(instr.i_any.i_opcd & 0x4)) {
fpu_implode(fe, fp, FTYPE_SNG,
- (u_int *)&fs->fpreg[rt].fpr);
+ (u_int *)&fs->fpr[rt].fpr);
fpu_explode(fe, fp = &fe->fe_f1, FTYPE_SNG, rt);
}
}
@@ -752,7 +752,7 @@ fpu_execute(struct trapframe *tf, struct fpemu *fe, union instr *insn)
* Otherwise set new current exceptions and accrue.
*/
if (fp)
- fpu_implode(fe, fp, type, (u_int *)&fs->fpreg[rt].fpr);
+ fpu_implode(fe, fp, type, (u_int *)&fs->fpr[rt].fpr);
cx = fe->fe_cx;
fsr = fe->fe_fpscr;
if (cx != 0) {
diff --git a/sys/powerpc/fpu/fpu_explode.c b/sys/powerpc/fpu/fpu_explode.c
index 1ebd96e..84073a4 100644
--- a/sys/powerpc/fpu/fpu_explode.c
+++ b/sys/powerpc/fpu/fpu_explode.c
@@ -53,7 +53,7 @@ __FBSDID("$FreeBSD$");
#include <machine/fpu.h>
#include <machine/ieee.h>
-#include <machine/reg.h>
+#include <machine/pcb.h>
#include <powerpc/fpu/fpu_arith.h>
#include <powerpc/fpu/fpu_emu.h>
@@ -211,9 +211,9 @@ fpu_explode(struct fpemu *fe, struct fpn *fp, int type, int reg)
u_int s, *space;
u_int64_t l, *xspace;
- xspace = (u_int64_t *)&fe->fe_fpstate->fpreg[reg].fpr;
+ xspace = (u_int64_t *)&fe->fe_fpstate->fpr[reg].fpr;
l = xspace[0];
- space = (u_int *)&fe->fe_fpstate->fpreg[reg].fpr;
+ space = (u_int *)&fe->fe_fpstate->fpr[reg].fpr;
s = space[0];
fp->fp_sign = s >> 31;
fp->fp_sticky = 0;
diff --git a/sys/powerpc/powerpc/uma_machdep.c b/sys/powerpc/powerpc/uma_machdep.c
index d5a458f..2e02396 100644
--- a/sys/powerpc/powerpc/uma_machdep.c
+++ b/sys/powerpc/powerpc/uma_machdep.c
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/systm.h>
#include <sys/sysctl.h>
+#include <sys/taskqueue.h>
#include <vm/vm.h>
#include <vm/vm_page.h>
#include <vm/vm_kern.h>
diff --git a/sys/riscv/include/asm.h b/sys/riscv/include/asm.h
index fb0c844..adcc23a 100644
--- a/sys/riscv/include/asm.h
+++ b/sys/riscv/include/asm.h
@@ -59,9 +59,7 @@
.set alias,sym
#define SET_FAULT_HANDLER(handler, tmp) \
- la tmp, pcpup; \
- ld tmp, 0(tmp); \
- ld tmp, PC_CURTHREAD(tmp); \
+ ld tmp, PC_CURTHREAD(gp); \
ld tmp, TD_PCB(tmp); /* Load the pcb */ \
sd handler, PCB_ONFAULT(tmp) /* Set the handler */
diff --git a/sys/riscv/include/pcpu.h b/sys/riscv/include/pcpu.h
index c60a954..7dfe23d 100644
--- a/sys/riscv/include/pcpu.h
+++ b/sys/riscv/include/pcpu.h
@@ -47,8 +47,11 @@ extern struct pcpu *pcpup;
static inline struct pcpu *
get_pcpu(void)
{
+ struct pcpu *pcpu;
- return (pcpup);
+ __asm __volatile("mv %0, gp" : "=&r"(pcpu));
+
+ return (pcpu);
}
static inline struct thread *
@@ -56,7 +59,7 @@ get_curthread(void)
{
struct thread *td;
- td = (struct thread *)*(uint64_t *)pcpup;
+ __asm __volatile("ld %0, 0(gp)" : "=&r"(td));
return (td);
}
diff --git a/sys/riscv/riscv/exception.S b/sys/riscv/riscv/exception.S
index 07fcfc5..814fcf6 100644
--- a/sys/riscv/riscv/exception.S
+++ b/sys/riscv/riscv/exception.S
@@ -41,12 +41,16 @@ __FBSDID("$FreeBSD$");
#include <machine/riscvreg.h>
.macro save_registers el
- addi sp, sp, -280
+ addi sp, sp, -(TF_SIZE)
sd ra, (TF_RA)(sp)
- sd gp, (TF_GP)(sp)
sd tp, (TF_TP)(sp)
+.if \el == 0 /* We came from userspace. Load our pcpu */
+ sd gp, (TF_GP)(sp)
+ ld gp, (TF_SIZE)(sp)
+.endif
+
sd t0, (TF_T + 0 * 8)(sp)
sd t1, (TF_T + 1 * 8)(sp)
sd t2, (TF_T + 2 * 8)(sp)
@@ -127,13 +131,16 @@ __FBSDID("$FreeBSD$");
csrw sepc, t0
.if \el == 0
- /* Load user sp */
+ /* We go to userspace. Load user sp */
ld t0, (TF_SP)(sp)
csrw sscratch, t0
+
+ /* And store our pcpu */
+ sd gp, (TF_SIZE)(sp)
+ ld gp, (TF_GP)(sp)
.endif
ld ra, (TF_RA)(sp)
- ld gp, (TF_GP)(sp)
ld tp, (TF_TP)(sp)
ld t0, (TF_T + 0 * 8)(sp)
@@ -166,7 +173,7 @@ __FBSDID("$FreeBSD$");
ld a6, (TF_A + 6 * 8)(sp)
ld a7, (TF_A + 7 * 8)(sp)
- addi sp, sp, 280
+ addi sp, sp, (TF_SIZE)
.endm
.macro do_ast
@@ -175,9 +182,7 @@ __FBSDID("$FreeBSD$");
1:
csrci sstatus, SSTATUS_IE
- la a1, pcpup
- ld a1, 0(a1)
- ld a1, PC_CURTHREAD(a1)
+ ld a1, PC_CURTHREAD(gp)
lw a2, TD_FLAGS(a1)
li a3, (TDF_ASTPENDING|TDF_NEEDRESCHED)
diff --git a/sys/riscv/riscv/genassym.c b/sys/riscv/riscv/genassym.c
index f5c971d..bf6c8fb 100644
--- a/sys/riscv/riscv/genassym.c
+++ b/sys/riscv/riscv/genassym.c
@@ -85,6 +85,7 @@ ASSYM(TD_FRAME, offsetof(struct thread, td_frame));
ASSYM(TD_MD, offsetof(struct thread, td_md));
ASSYM(TD_LOCK, offsetof(struct thread, td_lock));
+ASSYM(TF_SIZE, sizeof(struct trapframe));
ASSYM(TF_RA, offsetof(struct trapframe, tf_ra));
ASSYM(TF_SP, offsetof(struct trapframe, tf_sp));
ASSYM(TF_GP, offsetof(struct trapframe, tf_gp));
diff --git a/sys/riscv/riscv/machdep.c b/sys/riscv/riscv/machdep.c
index 5f9bd1f..79688e6 100644
--- a/sys/riscv/riscv/machdep.c
+++ b/sys/riscv/riscv/machdep.c
@@ -256,7 +256,9 @@ ptrace_clear_single_step(struct thread *td)
void
exec_setregs(struct thread *td, struct image_params *imgp, u_long stack)
{
- struct trapframe *tf = td->td_frame;
+ struct trapframe *tf;
+
+ tf = td->td_frame;
memset(tf, 0, sizeof(struct trapframe));
@@ -563,6 +565,7 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
static void
init_proc0(vm_offset_t kstack)
{
+
pcpup = &__pcpu[0];
proc_linkup0(&proc0, &thread0);
@@ -760,11 +763,7 @@ initriscv(struct riscv_bootparams *rvbp)
pcpu_init(pcpup, 0, sizeof(struct pcpu));
/* Set the pcpu pointer */
-#if 0
- /* SMP TODO: try re-use gp for pcpu pointer */
- __asm __volatile(
- "mv gp, %0" :: "r"(pcpup));
-#endif
+ __asm __volatile("mv gp, %0" :: "r"(pcpup));
PCPU_SET(curthread, &thread0);
diff --git a/sys/riscv/riscv/swtch.S b/sys/riscv/riscv/swtch.S
index 945fce3..c6336a9 100644
--- a/sys/riscv/riscv/swtch.S
+++ b/sys/riscv/riscv/swtch.S
@@ -46,14 +46,11 @@ __FBSDID("$FreeBSD$");
* void cpu_throw(struct thread *old, struct thread *new)
*/
ENTRY(cpu_throw)
- /* Load pcpu */
- la x14, pcpup
- ld x14, 0(x14)
/* Store the new curthread */
- sd a1, PC_CURTHREAD(x14)
+ sd a1, PC_CURTHREAD(gp)
/* And the new pcb */
ld x13, TD_PCB(a1)
- sd x13, PC_CURPCB(x14)
+ sd x13, PC_CURPCB(gp)
sfence.vm
@@ -74,8 +71,6 @@ ENTRY(cpu_throw)
/* Load registers */
ld ra, (PCB_RA)(x13)
ld sp, (PCB_SP)(x13)
- ld gp, (PCB_GP)(x13)
- ld tp, (PCB_TP)(x13)
/* s[0-11] */
ld s0, (PCB_S + 0 * 8)(x13)
@@ -105,14 +100,11 @@ END(cpu_throw)
* x3 to x7, x16 and x17 are caller saved
*/
ENTRY(cpu_switch)
- /* Load pcpu */
- la x14, pcpup
- ld x14, 0(x14)
/* Store the new curthread */
- sd a1, PC_CURTHREAD(x14)
+ sd a1, PC_CURTHREAD(gp)
/* And the new pcb */
ld x13, TD_PCB(a1)
- sd x13, PC_CURPCB(x14)
+ sd x13, PC_CURPCB(gp)
/* Save the old context. */
ld x13, TD_PCB(a0)
@@ -120,8 +112,6 @@ ENTRY(cpu_switch)
/* Store the callee-saved registers */
sd ra, (PCB_RA)(x13)
sd sp, (PCB_SP)(x13)
- sd gp, (PCB_GP)(x13)
- sd tp, (PCB_TP)(x13)
/* We use these in fork_trampoline */
sd t0, (PCB_T + 0 * 8)(x13)
@@ -176,8 +166,6 @@ ENTRY(cpu_switch)
/* Restore the registers */
ld ra, (PCB_RA)(x13)
ld sp, (PCB_SP)(x13)
- ld gp, (PCB_GP)(x13)
- ld tp, (PCB_TP)(x13)
/* We use these in fork_trampoline */
ld t0, (PCB_T + 0 * 8)(x13)
@@ -254,12 +242,23 @@ ENTRY(fork_trampoline)
ld a6, (TF_A + 6 * 8)(sp)
ld a7, (TF_A + 7 * 8)(sp)
+ /* Load user ra and sp */
+ ld tp, (TF_TP)(sp)
+ ld ra, (TF_RA)(sp)
+
+ /*
+ * Store our pcpup on stack, we will load it back
+ * on kernel mode trap.
+ */
+ sd gp, (TF_SIZE)(sp)
+ ld gp, (TF_GP)(sp)
+
/* Save kernel stack so we can use it doing a user trap */
+ addi sp, sp, TF_SIZE
csrw sscratch, sp
- /* Load user ra and sp */
- ld ra, (TF_RA)(sp)
- ld sp, (TF_SP)(sp)
+ /* Load user stack */
+ ld sp, (TF_SP - TF_SIZE)(sp)
eret
END(fork_trampoline)
diff --git a/sys/riscv/riscv/uma_machdep.c b/sys/riscv/riscv/uma_machdep.c
index ba48071..b3f2d82 100644
--- a/sys/riscv/riscv/uma_machdep.c
+++ b/sys/riscv/riscv/uma_machdep.c
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/systm.h>
+#include <sys/taskqueue.h>
#include <vm/vm.h>
#include <vm/vm_page.h>
#include <vm/vm_pageout.h>
diff --git a/sys/riscv/riscv/vm_machdep.c b/sys/riscv/riscv/vm_machdep.c
index 62e466f..fef626b 100644
--- a/sys/riscv/riscv/vm_machdep.c
+++ b/sys/riscv/riscv/vm_machdep.c
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sf_buf.h>
#include <sys/signal.h>
#include <sys/unistd.h>
+#include <sys/taskqueue.h>
#include <vm/vm.h>
#include <vm/vm_page.h>
@@ -217,7 +218,7 @@ cpu_thread_alloc(struct thread *td)
td->td_pcb = (struct pcb *)(td->td_kstack +
td->td_kstack_pages * PAGE_SIZE) - 1;
td->td_frame = (struct trapframe *)STACKALIGN(
- td->td_pcb - 1);
+ (caddr_t)td->td_pcb - 8 - sizeof(struct trapframe));
}
void
diff --git a/sys/sparc64/sparc64/vm_machdep.c b/sys/sparc64/sparc64/vm_machdep.c
index df8be0b..9780406 100644
--- a/sys/sparc64/sparc64/vm_machdep.c
+++ b/sys/sparc64/sparc64/vm_machdep.c
@@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sysctl.h>
#include <sys/unistd.h>
#include <sys/vmmeter.h>
+#include <sys/taskqueue.h>
#include <dev/ofw/openfirm.h>
diff --git a/sys/sys/ata.h b/sys/sys/ata.h
index 272b46a..5df610e 100644
--- a/sys/sys/ata.h
+++ b/sys/sys/ata.h
@@ -368,6 +368,9 @@ struct ata_params {
#define ATA_WRITE_LOG_EXT 0x3f
#define ATA_READ_VERIFY 0x40
#define ATA_READ_VERIFY48 0x42
+#define ATA_WRITE_UNCORRECTABLE48 0x45 /* write uncorrectable 48bit LBA */
+#define ATA_WU_PSEUDO 0x55 /* pseudo-uncorrectable error */
+#define ATA_WU_FLAGGED 0xaa /* flagged-uncorrectable error */
#define ATA_READ_LOG_DMA_EXT 0x47 /* read log DMA ext - PIO Data-In */
#define ATA_READ_FPDMA_QUEUED 0x60 /* read DMA NCQ */
#define ATA_WRITE_FPDMA_QUEUED 0x61 /* write DMA NCQ */
diff --git a/sys/sys/event.h b/sys/sys/event.h
index 35aad99..7897c81 100644
--- a/sys/sys/event.h
+++ b/sys/sys/event.h
@@ -222,7 +222,7 @@ struct knote {
union {
struct file *p_fp; /* file data pointer */
struct proc *p_proc; /* proc pointer */
- struct aiocblist *p_aio; /* AIO job pointer */
+ struct kaiocb *p_aio; /* AIO job pointer */
struct aioliojob *p_lio; /* LIO job pointer */
sbintime_t *p_nexttime; /* next timer event fires at */
void *p_v; /* generic other pointer */
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index f2f4a9d..039fd39 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -907,6 +907,16 @@ struct proc *pfind_locked(pid_t pid);
struct pgrp *pgfind(pid_t); /* Find process group by id. */
struct proc *zpfind(pid_t); /* Find zombie process by id. */
+struct fork_req {
+ int fr_flags;
+ int fr_pages;
+ int *fr_pidp;
+ struct proc **fr_procp;
+ int *fr_pd_fd;
+ int fr_pd_flags;
+ struct filecaps *fr_pd_fcaps;
+};
+
/*
* pget() flags.
*/
@@ -930,8 +940,7 @@ int enterpgrp(struct proc *p, pid_t pgid, struct pgrp *pgrp,
int enterthispgrp(struct proc *p, struct pgrp *pgrp);
void faultin(struct proc *p);
void fixjobc(struct proc *p, struct pgrp *pgrp, int entering);
-int fork1(struct thread *, int, int, struct proc **, int *, int,
- struct filecaps *);
+int fork1(struct thread *, struct fork_req *);
void fork_exit(void (*)(void *, struct trapframe *), void *,
struct trapframe *);
void fork_return(struct thread *, struct trapframe *);
diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h
index 55a7950..f101849 100644
--- a/sys/sys/socketvar.h
+++ b/sys/sys/socketvar.h
@@ -104,7 +104,7 @@ struct socket {
struct sigio *so_sigio; /* [sg] information for async I/O or
out of band data (SIGURG) */
u_long so_oobmark; /* (c) chars to oob mark */
- TAILQ_HEAD(, aiocblist) so_aiojobq; /* AIO ops waiting on socket */
+ TAILQ_HEAD(, kaiocb) so_aiojobq; /* AIO ops waiting on socket */
struct sockbuf so_rcv, so_snd;
diff --git a/sys/vm/memguard.c b/sys/vm/memguard.c
index d4efc2b..fb70a41 100644
--- a/sys/vm/memguard.c
+++ b/sys/vm/memguard.c
@@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/malloc.h>
#include <sys/sysctl.h>
+#include <sys/taskqueue.h>
#include <sys/vmem.h>
#include <vm/vm.h>
diff --git a/sys/vm/sg_pager.c b/sys/vm/sg_pager.c
index 84bfa49..2cccb7ea 100644
--- a/sys/vm/sg_pager.c
+++ b/sys/vm/sg_pager.c
@@ -189,6 +189,9 @@ sg_pager_getpages(vm_object_t object, vm_page_t *m, int count, int *rbehind,
VM_OBJECT_WLOCK(object);
TAILQ_INSERT_TAIL(&object->un_pager.sgp.sgp_pglist, page, plinks.q);
vm_page_replace_checked(page, object, offset, m[0]);
+ vm_page_lock(m[0]);
+ vm_page_free(m[0]);
+ vm_page_unlock(m[0]);
m[0] = page;
page->valid = VM_PAGE_BITS_ALL;
diff --git a/sys/vm/uma.h b/sys/vm/uma.h
index d218e60..21c6121 100644
--- a/sys/vm/uma.h
+++ b/sys/vm/uma.h
@@ -530,7 +530,7 @@ void uma_zone_set_warning(uma_zone_t zone, const char *warning);
* Returns:
* Nothing
*/
-typedef void (*uma_maxaction_t)(uma_zone_t);
+typedef void (*uma_maxaction_t)(uma_zone_t, int);
void uma_zone_set_maxaction(uma_zone_t zone, uma_maxaction_t);
/*
diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c
index 4600589..0d45046 100644
--- a/sys/vm/uma_core.c
+++ b/sys/vm/uma_core.c
@@ -78,6 +78,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sbuf.h>
#include <sys/sched.h>
#include <sys/smp.h>
+#include <sys/taskqueue.h>
#include <sys/vmmeter.h>
#include <vm/vm.h>
@@ -275,6 +276,11 @@ void uma_print_stats(void);
static int sysctl_vm_zone_count(SYSCTL_HANDLER_ARGS);
static int sysctl_vm_zone_stats(SYSCTL_HANDLER_ARGS);
+#ifdef INVARIANTS
+static void uma_dbg_free(uma_zone_t zone, uma_slab_t slab, void *item);
+static void uma_dbg_alloc(uma_zone_t zone, uma_slab_t slab, void *item);
+#endif
+
SYSINIT(uma_startup3, SI_SUB_VM_CONF, SI_ORDER_SECOND, uma_startup3, NULL);
SYSCTL_PROC(_vm, OID_AUTO, zone_count, CTLFLAG_RD|CTLTYPE_INT,
@@ -434,8 +440,9 @@ zone_log_warning(uma_zone_t zone)
static inline void
zone_maxaction(uma_zone_t zone)
{
- if (zone->uz_maxaction)
- (*zone->uz_maxaction)(zone);
+
+ if (zone->uz_maxaction.ta_func != NULL)
+ taskqueue_enqueue(taskqueue_thread, &zone->uz_maxaction);
}
static void
@@ -1585,7 +1592,6 @@ zone_ctor(void *mem, int size, void *udata, int flags)
zone->uz_flags = 0;
zone->uz_warning = NULL;
timevalclear(&zone->uz_ratecheck);
- zone->uz_maxaction = NULL;
keg = arg->keg;
ZONE_LOCK_INIT(zone, (arg->flags & UMA_ZONE_MTXCLASS));
@@ -3022,7 +3028,7 @@ uma_zone_set_maxaction(uma_zone_t zone, uma_maxaction_t maxaction)
{
ZONE_LOCK(zone);
- zone->uz_maxaction = maxaction;
+ TASK_INIT(&zone->uz_maxaction, 0, (task_fn_t *)maxaction, zone);
ZONE_UNLOCK(zone);
}
@@ -3607,6 +3613,102 @@ sysctl_handle_uma_zone_cur(SYSCTL_HANDLER_ARGS)
return (sysctl_handle_int(oidp, &cur, 0, req));
}
+#ifdef INVARIANTS
+static uma_slab_t
+uma_dbg_getslab(uma_zone_t zone, void *item)
+{
+ uma_slab_t slab;
+ uma_keg_t keg;
+ uint8_t *mem;
+
+ mem = (uint8_t *)((uintptr_t)item & (~UMA_SLAB_MASK));
+ if (zone->uz_flags & UMA_ZONE_VTOSLAB) {
+ slab = vtoslab((vm_offset_t)mem);
+ } else {
+ /*
+ * It is safe to return the slab here even though the
+ * zone is unlocked because the item's allocation state
+ * essentially holds a reference.
+ */
+ ZONE_LOCK(zone);
+ keg = LIST_FIRST(&zone->uz_kegs)->kl_keg;
+ if (keg->uk_flags & UMA_ZONE_HASH)
+ slab = hash_sfind(&keg->uk_hash, mem);
+ else
+ slab = (uma_slab_t)(mem + keg->uk_pgoff);
+ ZONE_UNLOCK(zone);
+ }
+
+ return (slab);
+}
+
+/*
+ * Set up the slab's freei data such that uma_dbg_free can function.
+ *
+ */
+static void
+uma_dbg_alloc(uma_zone_t zone, uma_slab_t slab, void *item)
+{
+ uma_keg_t keg;
+ int freei;
+
+ if (zone_first_keg(zone) == NULL)
+ return;
+ if (slab == NULL) {
+ slab = uma_dbg_getslab(zone, item);
+ if (slab == NULL)
+ panic("uma: item %p did not belong to zone %s\n",
+ item, zone->uz_name);
+ }
+ keg = slab->us_keg;
+ freei = ((uintptr_t)item - (uintptr_t)slab->us_data) / keg->uk_rsize;
+
+ if (BIT_ISSET(SLAB_SETSIZE, freei, &slab->us_debugfree))
+ panic("Duplicate alloc of %p from zone %p(%s) slab %p(%d)\n",
+ item, zone, zone->uz_name, slab, freei);
+ BIT_SET_ATOMIC(SLAB_SETSIZE, freei, &slab->us_debugfree);
+
+ return;
+}
+
+/*
+ * Verifies freed addresses. Checks for alignment, valid slab membership
+ * and duplicate frees.
+ *
+ */
+static void
+uma_dbg_free(uma_zone_t zone, uma_slab_t slab, void *item)
+{
+ uma_keg_t keg;
+ int freei;
+
+ if (zone_first_keg(zone) == NULL)
+ return;
+ if (slab == NULL) {
+ slab = uma_dbg_getslab(zone, item);
+ if (slab == NULL)
+ panic("uma: Freed item %p did not belong to zone %s\n",
+ item, zone->uz_name);
+ }
+ keg = slab->us_keg;
+ freei = ((uintptr_t)item - (uintptr_t)slab->us_data) / keg->uk_rsize;
+
+ if (freei >= keg->uk_ipers)
+ panic("Invalid free of %p from zone %p(%s) slab %p(%d)\n",
+ item, zone, zone->uz_name, slab, freei);
+
+ if (((freei * keg->uk_rsize) + slab->us_data) != item)
+ panic("Unaligned free of %p from zone %p(%s) slab %p(%d)\n",
+ item, zone, zone->uz_name, slab, freei);
+
+ if (!BIT_ISSET(SLAB_SETSIZE, freei, &slab->us_debugfree))
+ panic("Duplicate free of %p from zone %p(%s) slab %p(%d)\n",
+ item, zone, zone->uz_name, slab, freei);
+
+ BIT_CLR_ATOMIC(SLAB_SETSIZE, freei, &slab->us_debugfree);
+}
+#endif /* INVARIANTS */
+
#ifdef DDB
DB_SHOW_COMMAND(uma, db_show_uma)
{
@@ -3664,4 +3766,4 @@ DB_SHOW_COMMAND(umacache, db_show_umacache)
return;
}
}
-#endif
+#endif /* DDB */
diff --git a/sys/vm/uma_dbg.c b/sys/vm/uma_dbg.c
index 3fbd29b..7bf06d3 100644
--- a/sys/vm/uma_dbg.c
+++ b/sys/vm/uma_dbg.c
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/malloc.h>
+#include <sys/taskqueue.h>
#include <vm/vm.h>
#include <vm/vm_object.h>
@@ -196,100 +197,3 @@ mtrash_fini(void *mem, int size)
{
(void)mtrash_ctor(mem, size, NULL, 0);
}
-
-#ifdef INVARIANTS
-static uma_slab_t
-uma_dbg_getslab(uma_zone_t zone, void *item)
-{
- uma_slab_t slab;
- uma_keg_t keg;
- uint8_t *mem;
-
- mem = (uint8_t *)((uintptr_t)item & (~UMA_SLAB_MASK));
- if (zone->uz_flags & UMA_ZONE_VTOSLAB) {
- slab = vtoslab((vm_offset_t)mem);
- } else {
- /*
- * It is safe to return the slab here even though the
- * zone is unlocked because the item's allocation state
- * essentially holds a reference.
- */
- ZONE_LOCK(zone);
- keg = LIST_FIRST(&zone->uz_kegs)->kl_keg;
- if (keg->uk_flags & UMA_ZONE_HASH)
- slab = hash_sfind(&keg->uk_hash, mem);
- else
- slab = (uma_slab_t)(mem + keg->uk_pgoff);
- ZONE_UNLOCK(zone);
- }
-
- return (slab);
-}
-
-/*
- * Set up the slab's freei data such that uma_dbg_free can function.
- *
- */
-void
-uma_dbg_alloc(uma_zone_t zone, uma_slab_t slab, void *item)
-{
- uma_keg_t keg;
- int freei;
-
- if (zone_first_keg(zone) == NULL)
- return;
- if (slab == NULL) {
- slab = uma_dbg_getslab(zone, item);
- if (slab == NULL)
- panic("uma: item %p did not belong to zone %s\n",
- item, zone->uz_name);
- }
- keg = slab->us_keg;
- freei = ((uintptr_t)item - (uintptr_t)slab->us_data) / keg->uk_rsize;
-
- if (BIT_ISSET(SLAB_SETSIZE, freei, &slab->us_debugfree))
- panic("Duplicate alloc of %p from zone %p(%s) slab %p(%d)\n",
- item, zone, zone->uz_name, slab, freei);
- BIT_SET_ATOMIC(SLAB_SETSIZE, freei, &slab->us_debugfree);
-
- return;
-}
-
-/*
- * Verifies freed addresses. Checks for alignment, valid slab membership
- * and duplicate frees.
- *
- */
-void
-uma_dbg_free(uma_zone_t zone, uma_slab_t slab, void *item)
-{
- uma_keg_t keg;
- int freei;
-
- if (zone_first_keg(zone) == NULL)
- return;
- if (slab == NULL) {
- slab = uma_dbg_getslab(zone, item);
- if (slab == NULL)
- panic("uma: Freed item %p did not belong to zone %s\n",
- item, zone->uz_name);
- }
- keg = slab->us_keg;
- freei = ((uintptr_t)item - (uintptr_t)slab->us_data) / keg->uk_rsize;
-
- if (freei >= keg->uk_ipers)
- panic("Invalid free of %p from zone %p(%s) slab %p(%d)\n",
- item, zone, zone->uz_name, slab, freei);
-
- if (((freei * keg->uk_rsize) + slab->us_data) != item)
- panic("Unaligned free of %p from zone %p(%s) slab %p(%d)\n",
- item, zone, zone->uz_name, slab, freei);
-
- if (!BIT_ISSET(SLAB_SETSIZE, freei, &slab->us_debugfree))
- panic("Duplicate free of %p from zone %p(%s) slab %p(%d)\n",
- item, zone, zone->uz_name, slab, freei);
-
- BIT_CLR_ATOMIC(SLAB_SETSIZE, freei, &slab->us_debugfree);
-}
-
-#endif /* INVARIANTS */
diff --git a/sys/vm/uma_dbg.h b/sys/vm/uma_dbg.h
index 341cecb..e3c9df0 100644
--- a/sys/vm/uma_dbg.h
+++ b/sys/vm/uma_dbg.h
@@ -49,7 +49,4 @@ void mtrash_dtor(void *mem, int size, void *arg);
int mtrash_init(void *mem, int size, int flags);
void mtrash_fini(void *mem, int size);
-void uma_dbg_free(uma_zone_t zone, uma_slab_t slab, void *item);
-void uma_dbg_alloc(uma_zone_t zone, uma_slab_t slab, void *item);
-
#endif /* VM_UMA_DBG_H */
diff --git a/sys/vm/uma_int.h b/sys/vm/uma_int.h
index 5d7ecd3..1b0d5d5 100644
--- a/sys/vm/uma_int.h
+++ b/sys/vm/uma_int.h
@@ -307,7 +307,7 @@ struct uma_zone {
const char *uz_warning; /* Warning to print on failure */
struct timeval uz_ratecheck; /* Warnings rate-limiting */
- uma_maxaction_t uz_maxaction; /* Function to run when at limit */
+ struct task uz_maxaction; /* Task to run when at limit */
/*
* This HAS to be the last item because we adjust the zone size
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index d27eb2d..b510696 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -102,6 +102,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sysctl.h>
#include <sys/vmmeter.h>
#include <sys/vnode.h>
+#include <sys/taskqueue.h>
#include <vm/vm.h>
#include <vm/pmap.h>
diff --git a/tests/sys/acl/Makefile b/tests/sys/acl/Makefile
index b85cf00..7db6682 100644
--- a/tests/sys/acl/Makefile
+++ b/tests/sys/acl/Makefile
@@ -25,8 +25,14 @@ TAP_TESTS_SH+= 04
TEST_METADATA.$t+= required_user="root"
.endfor
+_ACL_PROGS= getfacl setfacl
+
.for t in 01 03 04
-TEST_METADATA.$t+= required_programs="/sbin/zpool"
+TEST_METADATA.$t+= required_programs="zpool ${_ACL_PROGS}"
+.endfor
+
+.for t in 00 02
+TEST_METADATA.$t+= required_programs="${_ACL_PROGS}"
.endfor
.include <bsd.test.mk>
diff --git a/tools/regression/sysvsem/semtest.c b/tools/regression/sysvsem/semtest.c
index 8a997d0..39c4164 100644
--- a/tools/regression/sysvsem/semtest.c
+++ b/tools/regression/sysvsem/semtest.c
@@ -152,6 +152,15 @@ main(int argc, char *argv[])
print_semid_ds(&s_ds, 0600);
+ errno = 0;
+ if (semget(semkey, 1, IPC_CREAT | IPC_EXCL | 0600) != -1 ||
+ errno != EEXIST)
+ err(1, "semget IPC_EXCL 1 did not fail with [EEXIST]");
+ errno = 0;
+ if (semget(semkey, 2, IPC_CREAT | IPC_EXCL | 0600) != -1 ||
+ errno != EEXIST)
+ err(1, "semget IPC_EXCL 2 did not fail with [EEXIST]");
+
for (child_count = 0; child_count < 5; child_count++) {
switch ((child_pid = fork())) {
case -1:
diff --git a/tools/tools/ath/athaggrstats/main.c b/tools/tools/ath/athaggrstats/main.c
index 95e7917..6a0de98 100644
--- a/tools/tools/ath/athaggrstats/main.c
+++ b/tools/tools/ath/athaggrstats/main.c
@@ -89,7 +89,7 @@ main(int argc, char *argv[])
ifname = getenv("ATH");
if (ifname == NULL)
- ifname = "ath0";
+ ifname = ATH_DEFAULT;
wf = athaggrstats_new(ifname, getfmt("default"));
while ((c = getopt(argc, argv, "bi:lo:z")) != -1) {
switch (c) {
diff --git a/tools/tools/ath/athdebug/athdebug.c b/tools/tools/ath/athdebug/athdebug.c
index bcdbcc8..b28f043 100644
--- a/tools/tools/ath/athdebug/athdebug.c
+++ b/tools/tools/ath/athdebug/athdebug.c
@@ -31,7 +31,7 @@
/*
* athdebug [-i interface] flags
- * (default interface is ath0).
+ * (default interface is wlan0).
*/
#include <sys/param.h>
@@ -156,7 +156,7 @@ main(int argc, char *argv[])
ifname = getenv("ATH");
if (ifname == NULL)
- ifname = "ath0";
+ ifname = ATH_DEFAULT;
progname = argv[0];
if (argc > 1) {
if (strcmp(argv[1], "-i") == 0) {
diff --git a/tools/tools/ath/athradar/athradar.c b/tools/tools/ath/athradar/athradar.c
index f40e1bd..69f4416 100644
--- a/tools/tools/ath/athradar/athradar.c
+++ b/tools/tools/ath/athradar/athradar.c
@@ -30,10 +30,6 @@
#include "ah.h"
#include "ah_internal.h"
-#ifndef ATH_DEFAULT
-#define ATH_DEFAULT "ath0"
-#endif
-
#include <getopt.h>
#include <errno.h>
#include <err.h>
diff --git a/tools/tools/ath/athratestats/main.c b/tools/tools/ath/athratestats/main.c
index 3881e85..b3f85f7 100644
--- a/tools/tools/ath/athratestats/main.c
+++ b/tools/tools/ath/athratestats/main.c
@@ -310,7 +310,7 @@ main(int argc, char *argv[])
ifname = getenv("ATH");
if (ifname == NULL)
- ifname = "ath0";
+ ifname = ATH_DEFAULT;
while ((c = getopt(argc, argv, "ahi:m:s:")) != -1) {
switch (c) {
diff --git a/tools/tools/ath/athregs/dumpregs.c b/tools/tools/ath/athregs/dumpregs.c
index 4a50726..472df05 100644
--- a/tools/tools/ath/athregs/dumpregs.c
+++ b/tools/tools/ath/athregs/dumpregs.c
@@ -155,7 +155,7 @@ main(int argc, char *argv[])
atd.ad_out_data = (caddr_t) &state.revs;
atd.ad_out_size = sizeof(state.revs);
if (ioctl(s, SIOCGATHDIAG, &atd) < 0)
- err(1, atd.ad_name);
+ err(1, "%s", atd.ad_name);
if (ath_hal_setupregs(&atd, what) == 0)
errx(-1, "no registers are known for this part "
@@ -173,7 +173,7 @@ main(int argc, char *argv[])
}
atd.ad_id = HAL_DIAG_REGS | ATH_DIAG_IN | ATH_DIAG_DYN;
if (ioctl(s, SIOCGATHDIAG, &atd) < 0)
- err(1, atd.ad_name);
+ err(1, "%s", atd.ad_name);
/*
* Expand register data into global space that can be
diff --git a/tools/tools/ath/athspectral/athspectral.c b/tools/tools/ath/athspectral/athspectral.c
index 1ec9085..91045d0 100644
--- a/tools/tools/ath/athspectral/athspectral.c
+++ b/tools/tools/ath/athspectral/athspectral.c
@@ -30,10 +30,6 @@
#include "ah.h"
#include "ah_internal.h"
-#ifndef ATH_DEFAULT
-#define ATH_DEFAULT "ath0"
-#endif
-
#include <getopt.h>
#include <errno.h>
#include <err.h>
diff --git a/tools/tools/ath/athstats/main.c b/tools/tools/ath/athstats/main.c
index bf0323d..29e8636 100644
--- a/tools/tools/ath/athstats/main.c
+++ b/tools/tools/ath/athstats/main.c
@@ -94,7 +94,7 @@ main(int argc, char *argv[])
ifname = getenv("ATH");
if (ifname == NULL)
- ifname = "ath0";
+ ifname = ATH_DEFAULT;
wf = athstats_new(ifname, getfmt("default"));
while ((c = getopt(argc, argv, "bi:lo:z")) != -1) {
switch (c) {
diff --git a/tools/tools/nanobsd/defaults.sh b/tools/tools/nanobsd/defaults.sh
index a0e6be5..9a5c5cb 100755
--- a/tools/tools/nanobsd/defaults.sh
+++ b/tools/tools/nanobsd/defaults.sh
@@ -356,7 +356,7 @@ clean_world ( ) (
rm -r ${NANO_OBJ}/
fi
mkdir -p "${NANO_OBJ}" "${NANO_WORLDDIR}"
- printenv > ${NANO_OBJ}/_.env
+ printenv > ${NANO_LOG}/_.env
else
pprint 2 "Clean and create world directory (${NANO_WORLDDIR})"
if ! rm -rf "${NANO_WORLDDIR}/" > /dev/null 2>&1 ; then
@@ -385,7 +385,7 @@ make_conf_install ( ) (
install_world ( ) (
pprint 2 "installworld"
- pprint 3 "log: ${NANO_OBJ}/_.iw"
+ pprint 3 "log: ${NANO_LOG}/_.iw"
(
nano_make_install_env
@@ -393,13 +393,13 @@ install_world ( ) (
cd "${NANO_SRC}"
${NANO_MAKE} installworld DESTDIR="${NANO_WORLDDIR}"
chflags -R noschg "${NANO_WORLDDIR}"
- ) > ${NANO_OBJ}/_.iw 2>&1
+ ) > ${NANO_LOG}/_.iw 2>&1
)
install_etc ( ) (
pprint 2 "install /etc"
- pprint 3 "log: ${NANO_OBJ}/_.etc"
+ pprint 3 "log: ${NANO_LOG}/_.etc"
(
nano_make_install_env
@@ -409,14 +409,14 @@ install_etc ( ) (
# make.conf doesn't get created by default, but some ports need it
# so they can spam it.
cp /dev/null "${NANO_WORLDDIR}"/etc/make.conf
- ) > ${NANO_OBJ}/_.etc 2>&1
+ ) > ${NANO_LOG}/_.etc 2>&1
)
install_kernel ( ) (
local extra
pprint 2 "install kernel ($NANO_KERNEL)"
- pprint 3 "log: ${NANO_OBJ}/_.ik"
+ pprint 3 "log: ${NANO_LOG}/_.ik"
(
@@ -432,12 +432,12 @@ install_kernel ( ) (
cd "${NANO_SRC}"
${NANO_MAKE} installkernel DESTDIR="${NANO_WORLDDIR}"
- ) > ${NANO_OBJ}/_.ik 2>&1
+ ) > ${NANO_LOG}/_.ik 2>&1
)
native_xtools ( ) (
print 2 "Installing the optimized native build tools for cross env"
- pprint 3 "log: ${NANO_OBJ}/_.native_xtools"
+ pprint 3 "log: ${NANO_LOG}/_.native_xtools"
(
@@ -446,7 +446,7 @@ native_xtools ( ) (
cd "${NANO_SRC}"
${NANO_MAKE} native-xtools DESTDIR="${NANO_WORLDDIR}"
- ) > ${NANO_OBJ}/_.native_xtools 2>&1
+ ) > ${NANO_LOG}/_.native_xtools 2>&1
)
#
@@ -460,9 +460,9 @@ run_customize ( ) (
for c in $NANO_CUSTOMIZE
do
pprint 2 "customize \"$c\""
- pprint 3 "log: ${NANO_OBJ}/_.cust.$c"
+ pprint 3 "log: ${NANO_LOG}/_.cust.$c"
pprint 4 "`type $c`"
- ( set -x ; $c ) > ${NANO_OBJ}/_.cust.$c 2>&1
+ ( set -x ; $c ) > ${NANO_LOG}/_.cust.$c 2>&1
done
)
@@ -476,9 +476,9 @@ run_late_customize ( ) (
for c in $NANO_LATE_CUSTOMIZE
do
pprint 2 "late customize \"$c\""
- pprint 3 "log: ${NANO_OBJ}/_.late_cust.$c"
+ pprint 3 "log: ${NANO_LOG}/_.late_cust.$c"
pprint 4 "`type $c`"
- ( set -x ; $c ) > ${NANO_OBJ}/_.late_cust.$c 2>&1
+ ( set -x ; $c ) > ${NANO_LOG}/_.late_cust.$c 2>&1
done
)
@@ -510,7 +510,7 @@ fixup_before_diskimage ( ) (
setup_nanobsd ( ) (
pprint 2 "configure nanobsd setup"
- pprint 3 "log: ${NANO_OBJ}/_.dl"
+ pprint 3 "log: ${NANO_LOG}/_.dl"
(
cd "${NANO_WORLDDIR}"
@@ -547,7 +547,7 @@ setup_nanobsd ( ) (
# Put /tmp on the /var ramdisk (could be symlink already)
tgt_dir2symlink tmp var/tmp
- ) > ${NANO_OBJ}/_.dl 2>&1
+ ) > ${NANO_LOG}/_.dl 2>&1
)
setup_nanobsd_etc ( ) (
@@ -630,7 +630,7 @@ populate_data_slice ( ) (
create_diskimage ( ) (
pprint 2 "build diskimage"
- pprint 3 "log: ${NANO_OBJ}/_.di"
+ pprint 3 "log: ${NANO_LOG}/_.di"
(
echo $NANO_MEDIASIZE $NANO_IMAGES \
@@ -699,7 +699,7 @@ create_diskimage ( ) (
# for booting the image from a USB device to work.
print "a 1"
}
- ' > ${NANO_OBJ}/_.fdisk
+ ' > ${NANO_LOG}/_.fdisk
IMG=${NANO_DISKIMGDIR}/${NANO_IMGNAME}
MNT=${NANO_OBJ}/_.mnt
@@ -718,7 +718,7 @@ create_diskimage ( ) (
trap "echo 'Running exit trap code' ; df -i ${MNT} ; nano_umount ${MNT} || true ; mdconfig -d -u $MD" 1 2 15 EXIT
- fdisk -i -f ${NANO_OBJ}/_.fdisk ${MD}
+ fdisk -i -f ${NANO_LOG}/_.fdisk ${MD}
fdisk ${MD}
# XXX: params
# XXX: pick up cached boot* files, they may not be in image anymore.
@@ -736,8 +736,8 @@ create_diskimage ( ) (
populate_slice /dev/${MD}${NANO_ROOT} ${NANO_WORLDDIR} ${MNT} "${NANO_ROOT}"
mount /dev/${MD}${NANO_ROOT} ${MNT}
echo "Generating mtree..."
- ( cd "${MNT}" && mtree -c ) > ${NANO_OBJ}/_.mtree
- ( cd "${MNT}" && du -k ) > ${NANO_OBJ}/_.du
+ ( cd "${MNT}" && mtree -c ) > ${NANO_LOG}/_.mtree
+ ( cd "${MNT}" && du -k ) > ${NANO_LOG}/_.du
nano_umount "${MNT}"
if [ $NANO_IMAGES -gt 1 -a $NANO_INIT_IMG2 -gt 0 ] ; then
@@ -792,7 +792,7 @@ create_diskimage ( ) (
trap - 1 2 15
trap nano_cleanup EXIT
- ) > ${NANO_OBJ}/_.di 2>&1
+ ) > ${NANO_LOG}/_.di 2>&1
)
last_orders ( ) (
@@ -1026,7 +1026,8 @@ set_defaults_and_export ( ) {
: ${NANO_OBJ:=/usr/obj/nanobsd.${NANO_NAME}}
: ${MAKEOBJDIRPREFIX:=${NANO_OBJ}}
: ${NANO_DISKIMGDIR:=${NANO_OBJ}}
- NANO_WORLDDIR=${NANO_OBJ}/_.w
+ : ${NANO_WORLDDIR:=${NANO_OBJ}/_.w}
+ : ${NANO_LOG:=${NANO_OBJ}}
NANO_MAKE_CONF_BUILD=${MAKEOBJDIRPREFIX}/make.conf.build
NANO_MAKE_CONF_INSTALL=${NANO_OBJ}/make.conf.install
@@ -1070,6 +1071,7 @@ set_defaults_and_export ( ) {
export_var NANO_MODULES
export_var NANO_NOPRIV_BUILD
export_var NANO_METALOG
+ export_var NANO_LOG
export_var SRCCONF
export_var SRC_ENV_CONF
}
diff --git a/tools/tools/nanobsd/embedded/common b/tools/tools/nanobsd/embedded/common
index bbac162..50e507f 100644
--- a/tools/tools/nanobsd/embedded/common
+++ b/tools/tools/nanobsd/embedded/common
@@ -76,7 +76,7 @@ fi
NANO_SLICE_FAT_SIZE=32m
NANO_SLICE_CFG_SIZE=32m
-NANO_BOOT2CFG="-D -h -S115200 comconsole_port=0x3e8"
+NANO_BOOT2CFG="-P -S115200"
NANO_RAM_ETCSIZE=8192
NANO_RAM_TMPVARSIZE=8192
@@ -88,23 +88,32 @@ NANO_CFG_BASE=$(pwd)
NANO_CFG_BASE=$(realpath ${NANO_CFG_BASE}/..)
NANO_SRC=$(realpath ${NANO_CFG_BASE}/../../..)
#### XXX share obj
-NANO_OBJ=${NANO_SRC}/../$NANO_NAME/obj
-# Where cust_pkg() finds packages to install
-#XXX: Is this the right place?
-#NANO_PORTS=$(realpath ${NANO_SRC}/../ports)
-NANO_PORTS=/usr/ports
-NANO_PACKAGE_DIR=${NANO_SRC}/${NANO_TOOLS}/Pkg
+if [ -z ${NANO_CPUTYPE} ]; then
+ NANO_OBJ=${NANO_SRC}/../embedded/obj
+else
+ # Alas, I can't set OBJTREE to ${MACHINE}.${MACHINE_ARCH}.${CPUTYPE}
+ # so this will have to do until I can.
+ NANO_OBJ=${NANO_SRC}/../embedded/obj.${NANO_CPUTYPE}
+fi
+NANO_LOG=${NANO_OBJ}/../${NANO_NAME}
+NANO_DISKIMGDIR=${NANO_OBJ}/../images
+NANO_WORLDDIR=${NANO_LOG}/_.w
NANO_INIT_IMG2=0
NANO_NOPRIV_BUILD=t
unset MAKEOBJDIRPREFIX
-# this to go into nanobsd.sh
-NANO_PORTS=${NANO_PORTS:-/usr/ports}
-
mkdir -p ${NANO_OBJ}
NANO_OBJ=$(realpath ${NANO_OBJ})
+mkdir -p ${NANO_LOG}
+NANO_LOG=$(realpath ${NANO_LOG})
+mkdir -p ${NANO_IMAGES}
+NANO_IMAGES=$(realpath ${NANO_IMAGES})
+mkdir -p ${NANO_WORLDDIR}
+NANO_WORLDDIR=$(realpath ${NANO_WORLDDIR})
+mkdir -p ${NANO_DISKIMGDIR}
+NANO_DISKIMGDIR=$(realpath ${NANO_DISKIMGDIR})
-NANO_FAT_DIR=${NANO_OBJ}/_.fat
+NANO_FAT_DIR=${NANO_LOG}/_.fat
customize_cmd cust_allow_ssh_root
@@ -180,109 +189,18 @@ WITHOUT_RCS=true
NANO_PACKAGE_ONLY=1
-# install a package from a pre-built binary
-do_add_pkg ( ) (
- # Need to create ${NANO_OBJ}/ports in this add_pkg_${port} function
- set -x
- mkdir -p ${NANO_OBJ}/ports/distfiles
- mkdir -p ${NANO_OBJ}/ports/packages
- mkdir -p ${NANO_WORLDDIR}/usr/ports/packages
- mkdir -p ${NANO_WORLDDIR}/usr/ports/distfiles
- mount -t nullfs -o noatime ${NANO_OBJ}/ports/packages \
- ${NANO_WORLDDIR}/usr/ports/packages
- mount -t nullfs -o noatime ${NANO_OBJ}/ports/distfiles \
- ${NANO_WORLDDIR}/usr/ports/distfiles
- CR env ASSUME_ALWAYS_YES=YES SIGNATURE_TYPE=none /usr/sbin/pkg add /usr/ports/packages/All/$1.txz
- umount ${NANO_WORLDDIR}/usr/ports/distfiles
- umount ${NANO_WORLDDIR}/usr/ports/packages
- rmdir ${NANO_WORLDDIR}/usr/ports/packages
- rmdir ${NANO_WORLDDIR}/usr/ports/distfiles
- rmdir ${NANO_WORLDDIR}/usr/ports
- set +x
-)
+# Creates images for all the formats that use MBR / GPT
+# split later if the #ifdef soup gets too bad.
+create_diskimage_gpt ( ) (
+ pprint 2 "build diskimage gpt ${NANO_NAME}"
-# Build a port (with the side effect of creating a package)
-do_add_port ( ) (
- local port_path
- port_path=$1
- shift
- set -x
- # Need to create ${NANO_OBJ}/ports in this add_port_${port} function
- mkdir -p ${NANO_OBJ}/ports/distfiles
- mkdir -p ${NANO_OBJ}/ports/packages
- mkdir -p ${NANO_PORTS}/packages
- mkdir -p ${NANO_PORTS}/distfiles
- mkdir -p ${NANO_WORLDDIR}/usr/src
- mkdir -p ${NANO_WORLDDIR}/usr/ports
- mount -t nullfs -o noatime ${NANO_SRC} ${NANO_WORLDDIR}/usr/src
- mount -t nullfs -o noatime ${NANO_PORTS} ${NANO_WORLDDIR}/usr/ports
- mount -t nullfs -o noatime ${NANO_OBJ}/ports/packages \
- ${NANO_WORLDDIR}/usr/ports/packages
- mount -t nullfs -o noatime ${NANO_OBJ}/ports/distfiles \
- ${NANO_WORLDDIR}/usr/ports/distfiles
- mkdir -p ${NANO_WORLDDIR}/dev
- mount -t devfs devfs ${NANO_WORLDDIR}/dev
- mkdir -p ${NANO_WORLDDIR}/usr/workdir
- cp /etc/resolv.conf ${NANO_WORLDDIR}/etc/resolv.conf
- # OK, a little inefficient, but likely not enough to worry about.
- CR ldconfig /lib /usr/lib /usr/local/lib
- CR ldconfig -R
- CR ldconfig -r
-# Improvement: Don't know why package-recursive don't works here
- CR "env UNAME_p=${NANO_ARCH} TARGET=${NANO_ARCH} \
- TARGET_ARCH=${NANO_ARCH} PORTSDIR=${NANO_PORTS} make \
- __MAKE_CONF=${NANO_MAKE_CONF_BUILD} \
- WRKDIRPREFIX=/usr/workdir -C /usr/ports/$port_path \
- package-recursive BATCH=yes $* clean FORCE_PKG_REGISTER=t"
- rm ${NANO_WORLDDIR}/etc/resolv.conf
- rm -rf ${NANO_WORLDDIR}/usr/obj
- rm -rf ${NANO_WORLDDIR}/usr/workdir
- umount ${NANO_WORLDDIR}/dev
- umount ${NANO_WORLDDIR}/usr/ports/packages
- umount ${NANO_WORLDDIR}/usr/ports/distfiles
- umount ${NANO_WORLDDIR}/usr/ports
- umount ${NANO_WORLDDIR}/usr/src
- set +x
+ create_diskimage_mbr $*
)
-# Need to check if this function works with cross-compiling architecture!!!!
-# Recursive complex fonction: Generate one function for each ports
-# writes shell functions called later, so don't do in subshell.
-add_port ( ) {
- local port_path=$1
- local port=`echo $1 | sed -e 's/\//_/'`
- shift
- # Check if package allready exist
- # Need to:
- # 1. check ARCH of this package!
- # 2. Add a trap
- cd ${NANO_PORTS}/${port_path}
- PKG_NAME=`env PORTSDIR=${NANO_PORTS} make __MAKE_CONF=${NANO_MAKE_CONF_BUILD} package-name`
- if [ -f ${NANO_OBJ}/ports/packages/All/${PKG_NAME}.txz ]; then
- # Pkg file found: Generate add_pkg_NAME function
- eval "
- add_pkg_${port} ( ) {
- do_add_pkg ${PKG_NAME}
- }
- customize_cmd add_pkg_${port}
- "
- else
- # No pkg file: Generate add_port_NAME function
- eval "
- add_port_${port} ( ) {
- do_add_port ${port_path} $*
- }
- customize_cmd add_port_${port}
- "
- NANO_PACKAGE_ONLY=0
- fi
-}
-
-# Creates images for all the formats that use MBR
create_diskimage_mbr ( ) (
pprint 2 "build diskimage ${NANO_NAME}"
- pprint 3 "log: ${NANO_OBJ}/_.di"
+ pprint 3 "log: ${NANO_LOG}/_.di"
(
local extra i sz fmt fmtarg bootmbr bootbsd skiparg
@@ -295,44 +213,54 @@ create_diskimage_mbr ( ) (
skiparg=${NANO_MBR_FIRST_SKIP:+-S ${NANO_MBR_FIRST_SKIP}}
for i in s1 s2 s3 s4 p1 p2 p3 p4 p5 empty; do
- rm -fr ${NANO_OBJ}/_.${i}*
+ rm -fr ${NANO_LOG}/_.${i}*
done
# Populate the FAT partition, if needed
if [ -n "${NANO_SLICE_FAT}" ]; then
echo Creating MSDOS partition for kernel
newfs_msdos -C ${NANO_SLICE_FAT_SIZE} -F 16 -L ${NANO_NAME} \
- ${NANO_OBJ}/_.${NANO_SLICE_FAT}
+ ${NANO_LOG}/_.${NANO_SLICE_FAT}
if [ -d ${NANO_FAT_DIR} ]; then
# Need to copy files from ${NANO_FATDIR} with mtools, or use
# makefs -t msdos once that's supported
- mcopy -i ${NANO_OBJ}/_.${NANO_SLICE_FAT} ${NANO_FAT_DIR}/* ::
+ mcopy -i ${NANO_LOG}/_.${NANO_SLICE_FAT} ${NANO_FAT_DIR}/* ::
fi
fi
# Populate the Powerpc boot image, if needed
if [ "${NANO_LAYOUT}" = powerpc64-ibm ]; then
- dd if=${NANO_WORLDDIR}/boot/boot1.elf of=${NANO_OBJ}/_.s1 bs=800k count=1 conv=sync
+ dd if=${NANO_WORLDDIR}/boot/boot1.elf of=${NANO_LOG}/_.s1 bs=800k count=1 conv=sync
fi
# Populate the / partition, and place it into a slice with a
# bsd label
[ -z ${NANO_NOPRIV_BUILD} ] || extra="-F ${NANO_METALOG}"
sz=${NANO_SLICE_ROOT_SIZE:+-s ${NANO_SLICE_ROOT_SIZE}}
- eval "${NANO_MAKEFS_UFS}" ${extra} $sz "${NANO_OBJ}/_.${NANO_SLICE_ROOT}" \
+ eval "${NANO_MAKEFS_UFS}" ${extra} $sz "${NANO_LOG}/_.${NANO_ROOT}" \
"${NANO_WORLDDIR}"
-# mkimg -s bsd ${bootbsd} -p freebsd-ufs:=${NANO_OBJ}/_.${NANO_SLICE_ROOT} \
-# -o ${NANO_OBJ}/_.${NANO_SLICE_ROOT}
+ case ${NANO_DISK_SCHEME} in
+ mbr)
+ mkimg -s bsd ${bootbsd} -p freebsd-ufs:=${NANO_LOG}/_.${NANO_ROOT} \
+ -o ${NANO_LOG}/_.${NANO_SLICE_ROOT}
+ eval $NANO_SLICE_CFG=freebsd
+ eval $NANO_SLICE_ROOT=freebsd
+ ;;
+ gpt)
+ eval $NANO_SLICE_CFG=freebsd-ufs
+ eval $NANO_SLICE_ROOT=freebsd-ufs
+ ;;
+ esac
# Populate the /cfg partition, empty if none given
if [ -z "${NANO_CFGDIR}" ]; then
echo "Faking cfg dir, it's empty"
- NANO_CFGDIR=${NANO_OBJ}/_.empty
+ NANO_CFGDIR=${NANO_LOG}/_.empty
mkdir -p ${NANO_CFGDIR}
fi
# XXX -F cfg-mtree
eval "${NANO_MAKEFS_UFS}" -s ${NANO_SLICE_CFG_SIZE} \
- "${NANO_OBJ}/_.${NANO_SLICE_CFG}" "${NANO_CFGDIR}"
+ "${NANO_LOG}/_.${NANO_SLICE_CFG}" "${NANO_CFGDIR}"
# data slice not supported since we need the part for FAT for
# booting
@@ -341,43 +269,33 @@ create_diskimage_mbr ( ) (
if [ -n "$NANO_SLICE_FAT" ]; then
eval $NANO_SLICE_FAT=fat16b
fi
- case ${NANO_SLICE_CFG} in
- s*)
- echo slice
- eval $NANO_SLICE_CFG=freebsd
- eval $NANO_SLICE_ROOT=freebsd
- ;;
- p*)
- echo part
- eval $NANO_SLICE_CFG=freebsd-ufs
- eval $NANO_SLICE_ROOT=freebsd-ufs
- ;;
- esac
+
+ out=${NANO_DISKIMGDIR}/_.disk.image.${NANO_NAME}${fmt}
# below depends on https://reviews.freebsd.org/D4403 not yet in the tree
# but there's problems: it marks all partitions as active, so you have to
# boot off parittion 3 or 2 by hand if you're playing around with this WIP
case ${NANO_LAYOUT} in
std-embedded)
- mkimg -a 3 ${skiparg} ${fmtarg} ${bootmbr} -s mbr -p ${s1}:=${NANO_OBJ}/_.s1 \
- -p ${s2}:=${NANO_OBJ}/_.s2 \
- -p ${s3}:=${NANO_OBJ}/_.s3 \
- -o ${NANO_OBJ}/_.disk.image.${NANO_NAME}${fmt}
+ mkimg -a 3 ${skiparg} ${fmtarg} ${bootmbr} -s mbr -p ${s1}:=${NANO_LOG}/_.s1 \
+ -p ${s2}:=${NANO_LOG}/_.s2 \
+ -p ${s3}:=${NANO_LOG}/_.s3 \
+ -o ${out}
;;
std-x86)
# s1 is cfg, s2 is /, not sure how to make that
# boot (marked as active) with mkimg yet
- mkimg -a 2 ${fmtarg} ${bootmbr} -s mbr -p ${s1}:=${NANO_OBJ}/_.s1 \
- -p ${s2}:=${NANO_OBJ}/_.s2 \
- -o ${NANO_OBJ}/_.disk.image.${NANO_NAME}${fmt}
+ mkimg -a 2 ${fmtarg} ${bootmbr} -s mbr -p ${s1}:=${NANO_LOG}/_.s1 \
+ -p ${s2}:=${NANO_LOG}/_.s2 \
+ -o ${out}
;;
std-uefi)
# s1 is boot, s2 is cfg, s3 is /, not sure how to make that
# boot (marked as active) with mkimg yet
mkimg -a 2 ${fmtarg} ${bootmbr} -s mbr \
-p efi:=${NANO_WORLDDIR}/boot/boot1.efifat \
- -p ${s2}:=${NANO_OBJ}/_.s2 \
- -p ${s3}:=${NANO_OBJ}/_.s3 \
- -o ${NANO_OBJ}/_.disk.image.${NANO_NAME}${fmt}
+ -p ${s2}:=${NANO_LOG}/_.s2 \
+ -p ${s3}:=${NANO_LOG}/_.s3 \
+ -o ${out}
;;
std-uefi-bios)
# p1 is boot for uefi, p2 is boot for gpt, p3 is cfg, p4 is /
@@ -385,9 +303,9 @@ create_diskimage_mbr ( ) (
mkimg -a 2 ${fmtarg} ${bootmbr} -s gpt \
-p efi:=${NANO_WORLDDIR}/boot/boot1.efifat \
-p freebsd-boot:=${NAANO_WORLDDIR}/boot/gptboot \
- -p ${p3}:=${NANO_OBJ}/_.p3 \
- -p ${p4}:=${NANO_OBJ}/_.p4 \
- -o ${NANO_OBJ}/_.disk.image.${NANO_NAME}${fmt}
+ -p ${p3}:=${NANO_LOG}/_.p3 \
+ -p ${p4}:=${NANO_LOG}/_.p4 \
+ -o ${out}
;;
powerpc64-ibm)
# A lie to make the boot loader work, it boots the first BSD partition
@@ -396,13 +314,14 @@ create_diskimage_mbr ( ) (
# boot image is on a special partition, ala std-embedded, but that
# partition isn't FAT with special files, but a copy of the boot
# loader itself.
- mkimg -a 1 ${fmtarg} -s mbr -p prepboot:=${NANO_OBJ}/_.s1 \
- -p ${s2}:=${NANO_OBJ}/_.s2 \
- -p ${s3}:=${NANO_OBJ}/_.s3a \
- -o ${NANO_OBJ}/_.disk.image.${NANO_NAME}${fmt}
+ mkimg -a 1 ${fmtarg} -s mbr -p prepboot:=${NANO_LOG}/_.s1 \
+ -p ${s2}:=${NANO_LOG}/_.s2 \
+ -p ${s3}:=${NANO_LOG}/_.s3a \
+ -o ${out}
;;
esac
- ) > ${NANO_OBJ}/_.di 2>&1
+ xz -9 --keep ${out}
+ ) > ${NANO_LOG}/_.di 2>&1
)
die( ) {
@@ -662,11 +581,21 @@ eval std_${NANO_ARCH}
# off the top. We also resize the 'a' partion on first boot
# to the size of the partition for the ping/pong upgrade.
# This feature needs support in the rc.d bootup script.
+#
+# Ideally, we'd not put BSD labels on the MBR disks.
+# However, we can't boot off raw MBR disks. First,
+# boot2 defaults to 'a' partition, and freaks out
+# unless you tell it to use 'c'. But even if we
+# hack that, then /boot/loader wants to load off
+# of 'c' partition. If you fix that, then we'll
+# try to mount root, but sanity checks prevent
+# slices from working.
+#
: ${NANO_ENDIAN:=little} # make -V something to figure it out?
: ${NANO_LAYOUT:=std-embedded}
: ${NANO_MAKEFS_UFS:=makefs -t ffs -B ${NANO_ENDIAN}}
-: ${NANO_DISK_SCHEME:=mbr} # No others really supported ATM
+: ${NANO_DISK_SCHEME:=mbr} # No others really supported ATM (well, gpt)
case ${NANO_LAYOUT} in
std-embedded)
NANO_SLICE_FAT=s1
@@ -696,11 +625,15 @@ std-uefi)
NANO_SLICE_ALTROOT=s4
;;
std-uefi-bios)
+ NANO_DISK_SCHEME=gpt
NANO_SLICE_UEFI=p1
NANO_SLICE_BOOT=p2
NANO_SLICE_CFG=p3
NANO_SLICE_ROOT=p4
NANO_SLICE_ALTROOT=p5
+ # override root name
+ NANO_ROOT=${NANO_SLICE_ROOT}
+ NANO_ALTROOT=${NANO_SLICE_ALTROOT}
;;
*)
echo Unknown Layout ${NANO_LAYOUT}
@@ -708,10 +641,6 @@ std-uefi-bios)
;;
esac
-# For this config, no BSD labels so NANO_ROOT and NANO_ALTROOT need to be
-# adjusted
-NANO_ROOT=${NANO_SLICE_ROOT}
-NANO_ALTROOT=${NANO_SLICE_ALTROOT}
NANO_SLICE_DATA= # Not included
diff --git a/tools/tools/nanobsd/embedded/i386.cfg b/tools/tools/nanobsd/embedded/i386.cfg
new file mode 100644
index 0000000..7fd9a528
--- /dev/null
+++ b/tools/tools/nanobsd/embedded/i386.cfg
@@ -0,0 +1,34 @@
+# $FreeBSD$
+
+#-
+# Copyright (c) 2015 Warner Losh. All Rights Reserved.
+# Copyright (c) 2010-2011 iXsystems, 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 iXsystems, Inc. OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+NANO_ARCH=i386
+NANO_KERNEL=GENERIC
+NANO_DRIVE=ada0
+NANO_NAME=i386
+
+. common # Pull in common definitions, keep last
diff --git a/usr.sbin/bsdconfig/share/common.subr b/usr.sbin/bsdconfig/share/common.subr
index 5996446..2b911fc 100644
--- a/usr.sbin/bsdconfig/share/common.subr
+++ b/usr.sbin/bsdconfig/share/common.subr
@@ -1,7 +1,7 @@
if [ ! "$_COMMON_SUBR" ]; then _COMMON_SUBR=1
#
# Copyright (c) 2012 Ron McDowell
-# Copyright (c) 2012-2015 Devin Teske
+# Copyright (c) 2012-2016 Devin Teske
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -1015,10 +1015,9 @@ f_count_ifs()
#
# Trap signals so we can recover gracefully
#
-trap 'f_interrupt' SIGINT
-trap 'f_die' SIGTERM SIGPIPE SIGXCPU SIGXFSZ \
- SIGFPE SIGTRAP SIGABRT SIGSEGV
-trap '' SIGALRM SIGPROF SIGUSR1 SIGUSR2 SIGHUP SIGVTALRM
+trap 'f_interrupt' INT
+trap 'f_die' TERM PIPE XCPU XFSZ FPE TRAP ABRT SEGV
+trap '' ALRM PROF USR1 USR2 HUP VTALRM
#
# Clone terminal stdout/stderr so we can redirect to it from within sub-shells
diff --git a/usr.sbin/bsdconfig/share/strings.subr b/usr.sbin/bsdconfig/share/strings.subr
index f1dbbd7..f33f4df 100644
--- a/usr.sbin/bsdconfig/share/strings.subr
+++ b/usr.sbin/bsdconfig/share/strings.subr
@@ -65,54 +65,60 @@ f_isinteger()
# f_substr [-v $var_to_set] $string $start [$length]
#
# Similar to awk(1)'s substr(), return length substring of string that begins
-# at start position counted from 1.
+# at start position counted from 1.
#
-f_substr()
-{
- local OPTIND=1 OPTARG __flag __var_to_set=
- while getopts v: __flag; do
- case "$__flag" in
- v) __var_to_set="$OPTARG" ;;
+case "$BASH_VERSION" in
+*?*)
+ f_substr()
+ {
+ local __var_to_set=
+ case "$1" in
+ -v) __var_to_set="$2"; shift 2 ;;
+ -v?*) __var_to_set="${2#-v}"; shift 1 ;;
esac
- done
- shift $(( $OPTIND - 1 ))
-
- local __tmp="$1" __start="${2:-1}" __size="$3"
- local __tbuf __tbuf_len __trim __trimq
-
- if [ ! "$__tmp" ]; then
- [ "$__var_to_set" ] && setvar "$__var_to_set" ""
- return ${SUCCESS:-0}
- fi
- [ "$__start" -ge 1 ] 2> /dev/null || __start=1
- if ! [ "${__size:-1}" -ge 1 ] 2> /dev/null; then
- [ "$__var_to_set" ] && setvar "$__var_to_set" ""
- return ${FAILURE:-1}
- fi
-
- __trim=$(( $__start - 1 ))
- while [ $__trim -gt 0 ]; do
- __tbuf="?"
- __tbuf_len=1
- while [ $__tbuf_len -lt $(( $__trim / $__tbuf_len )) ]; do
- __tbuf="$__tbuf?"
- __tbuf_len=$(( $__tbuf_len + 1 ))
- done
- __trimq=$(( $__trim / $__tbuf_len ))
- __trim=$(( $__trim - $__tbuf_len * $__trimq ))
- while [ $__trimq -gt 0 ]; do
- __tmp="${__tmp#$__tbuf}"
- __trimq=$(( $__trimq - 1 ))
+ local __tmp="$1" __start="${2:-1}" __len="$3"
+ [ "$__start" -gt 0 ] 2> /dev/null &&
+ __start=$(( $__start - 1 ))
+ if [ ! "$__var_to_set" ]; then
+ eval echo \"\${__tmp:\$__start${__len:+:\$__len}}\"
+ return $?
+ fi
+ if [ "$__len" ]; then
+ eval $__var_to_set=\"\${__tmp:\$__start:\$__len}\"
+ else
+ eval $__var_to_set=\"\${__tmp:\$__start}\"
+ fi
+ }
+ ;;
+*)
+ # NB: On FreeBSD, sh(1) runs this faster than bash(1) runs the above
+ f_substr()
+ {
+ local OPTIND=1 OPTARG __flag __var_to_set=
+ while getopts v: __flag; do
+ case "$__flag" in
+ v) __var_to_set="$OPTARG" ;;
+ esac
done
- done
+ shift $(( $OPTIND - 1 ))
+
+ local __tmp="$1" __start="${2:-1}" __size="$3"
+ local __tbuf __tbuf_len __trim __trimq
+
+ if [ ! "$__tmp" ]; then
+ [ "$__var_to_set" ] && setvar "$__var_to_set" ""
+ return ${SUCCESS:-0}
+ fi
+ [ "$__start" -ge 1 ] 2> /dev/null || __start=1
+ if ! [ "${__size:-1}" -ge 1 ] 2> /dev/null; then
+ [ "$__var_to_set" ] && setvar "$__var_to_set" ""
+ return ${FAILURE:-1}
+ fi
- local __tmp_size=${#__tmp}
- local __mask __mask_len
- __trim=$(( $__tmp_size - ${__size:-$__tmp_size} ))
- while [ $__trim -gt 0 ]; do
- __tbuf="?"
- __tbuf_len=1
- if [ $__trim -le $__size ]; then
+ __trim=$(( $__start - 1 ))
+ while [ $__trim -gt 0 ]; do
+ __tbuf="?"
+ __tbuf_len=1
while [ $__tbuf_len -lt $(( $__trim / $__tbuf_len )) ]
do
__tbuf="$__tbuf?"
@@ -121,33 +127,66 @@ f_substr()
__trimq=$(( $__trim / $__tbuf_len ))
__trim=$(( $__trim - $__tbuf_len * $__trimq ))
while [ $__trimq -gt 0 ]; do
- __tmp="${__tmp%$__tbuf}"
+ __tmp="${__tmp#$__tbuf}"
__trimq=$(( $__trimq - 1 ))
done
- else
- __mask="$__tmp"
- while [ $__tbuf_len -lt $(( $__size / $__tbuf_len )) ]
- do
- __tbuf="$__tbuf?"
- __tbuf_len=$(( $__tbuf_len + 1 ))
- done
- __trimq=$(( $__size / $__tbuf_len ))
- if [ $(( $__trimq * $__tbuf_len )) -ne $__size ]; then
- __tbuf="$__tbuf?"
- __tbuf_len=$(( $__tbuf_len + 1 ))
+ done
+
+ local __tmp_size=${#__tmp}
+ local __mask __mask_len
+ __trim=$(( $__tmp_size - ${__size:-$__tmp_size} ))
+ while [ $__trim -gt 0 ]; do
+ __tbuf="?"
+ __tbuf_len=1
+ if [ $__trim -le $__size ]; then
+ while [ $__tbuf_len -lt $((
+ $__trim / $__tbuf_len
+ )) ]; do
+ __tbuf="$__tbuf?"
+ __tbuf_len=$(( $__tbuf_len + 1 ))
+ done
+ __trimq=$(( $__trim / $__tbuf_len ))
+ __trim=$(( $__trim - $__tbuf_len * $__trimq ))
+ while [ $__trimq -gt 0 ]; do
+ __tmp="${__tmp%$__tbuf}"
+ __trimq=$(( $__trimq - 1 ))
+ done
+ else
+ __mask="$__tmp"
+ while [ $__tbuf_len -lt $((
+ $__size / $__tbuf_len
+ )) ]; do
+ __tbuf="$__tbuf?"
+ __tbuf_len=$(( $__tbuf_len + 1 ))
+ done
+ __trimq=$(( $__size / $__tbuf_len ))
+ if [ $__size -ne $((
+ $__trimq * $__tbuf_len
+ )) ]; then
+ __tbuf="$__tbuf?"
+ __tbuf_len=$(( $__tbuf_len + 1 ))
+ fi
+ __mask_len=$((
+ $__tmp_size - $__tbuf_len * $__trimq
+ ))
+ __trim=$((
+ $__tmp_size - $__mask_len - $__size
+ ))
+ while [ $__trimq -gt 0 ]; do
+ __mask="${__mask#$__tbuf}"
+ __trimq=$(( $__trimq - 1 ))
+ done
+ __tmp="${__tmp%"$__mask"}"
fi
- __mask_len=$(( $__tmp_size - $__tbuf_len * $__trimq ))
- __trim=$(( $__tmp_size - $__mask_len - $__size ))
- while [ $__trimq -gt 0 ]; do
- __mask="${__mask#$__tbuf}"
- __trimq=$(( $__trimq - 1 ))
- done
- __tmp="${__tmp%"$__mask"}"
- fi
- done
+ done
- setvar "$__var_to_set" "$__tmp"
-}
+ if [ "$__var_to_set" ]; then
+ setvar "$__var_to_set" "$__tmp"
+ else
+ echo "$__tmp"
+ fi
+ }
+esac
# f_sprintf $var_to_set $format [$arguments ...]
#
diff --git a/usr.sbin/ctld/Makefile b/usr.sbin/ctld/Makefile
index 6169d30..664dc22 100644
--- a/usr.sbin/ctld/Makefile
+++ b/usr.sbin/ctld/Makefile
@@ -1,8 +1,11 @@
# $FreeBSD$
+CFLAGS+=-I${.CURDIR}/../../contrib/libucl/include
+.PATH: ${.CURDIR}/../../contrib/libucl/include
+
PROG= ctld
SRCS= chap.c ctld.c discovery.c isns.c kernel.c keys.c log.c
-SRCS+= login.c parse.y pdu.c token.l y.tab.h
+SRCS+= login.c parse.y pdu.c token.l y.tab.h uclparse.c
CFLAGS+= -I${.CURDIR}
CFLAGS+= -I${.CURDIR}/../../sys
CFLAGS+= -I${.CURDIR}/../../sys/cam/ctl
@@ -10,7 +13,7 @@ CFLAGS+= -I${.CURDIR}/../../sys/dev/iscsi
#CFLAGS+= -DICL_KERNEL_PROXY
MAN= ctld.8 ctl.conf.5
-LIBADD= bsdxml l md sbuf util
+LIBADD= bsdxml l md sbuf util ucl m
YFLAGS+= -v
CLEANFILES= y.tab.c y.tab.h y.output
diff --git a/usr.sbin/ctld/ctld.c b/usr.sbin/ctld/ctld.c
index 92fa553..6c8b4a8 100644
--- a/usr.sbin/ctld/ctld.c
+++ b/usr.sbin/ctld/ctld.c
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
+#include <sys/stat.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@@ -2491,6 +2492,104 @@ register_signals(void)
log_err(1, "sigaction");
}
+static void
+check_perms(const char *path)
+{
+ struct stat sb;
+ int error;
+
+ error = stat(path, &sb);
+ if (error != 0) {
+ log_warn("stat");
+ return;
+ }
+ if (sb.st_mode & S_IWOTH) {
+ log_warnx("%s is world-writable", path);
+ } else if (sb.st_mode & S_IROTH) {
+ log_warnx("%s is world-readable", path);
+ } else if (sb.st_mode & S_IXOTH) {
+ /*
+ * Ok, this one doesn't matter, but still do it,
+ * just for consistency.
+ */
+ log_warnx("%s is world-executable", path);
+ }
+
+ /*
+ * XXX: Should we also check for owner != 0?
+ */
+}
+
+static struct conf *
+conf_new_from_file(const char *path, struct conf *oldconf, bool ucl)
+{
+ struct conf *conf;
+ struct auth_group *ag;
+ struct portal_group *pg;
+ struct pport *pp;
+ int error;
+
+ log_debugx("obtaining configuration from %s", path);
+
+ conf = conf_new();
+
+ TAILQ_FOREACH(pp, &oldconf->conf_pports, pp_next)
+ pport_copy(pp, conf);
+
+ ag = auth_group_new(conf, "default");
+ assert(ag != NULL);
+
+ ag = auth_group_new(conf, "no-authentication");
+ assert(ag != NULL);
+ ag->ag_type = AG_TYPE_NO_AUTHENTICATION;
+
+ ag = auth_group_new(conf, "no-access");
+ assert(ag != NULL);
+ ag->ag_type = AG_TYPE_DENY;
+
+ pg = portal_group_new(conf, "default");
+ assert(pg != NULL);
+
+ if (ucl)
+ error = uclparse_conf(conf, path);
+ else
+ error = parse_conf(conf, path);
+
+ if (error != 0) {
+ conf_delete(conf);
+ return (NULL);
+ }
+
+ check_perms(path);
+
+ if (conf->conf_default_ag_defined == false) {
+ log_debugx("auth-group \"default\" not defined; "
+ "going with defaults");
+ ag = auth_group_find(conf, "default");
+ assert(ag != NULL);
+ ag->ag_type = AG_TYPE_DENY;
+ }
+
+ if (conf->conf_default_pg_defined == false) {
+ log_debugx("portal-group \"default\" not defined; "
+ "going with defaults");
+ pg = portal_group_find(conf, "default");
+ assert(pg != NULL);
+ portal_group_add_listen(pg, "0.0.0.0:3260", false);
+ portal_group_add_listen(pg, "[::]:3260", false);
+ }
+
+ conf->conf_kernel_port_on = true;
+
+ error = conf_verify(conf);
+ if (error != 0) {
+ conf_delete(conf);
+ return (NULL);
+ }
+
+ return (conf);
+}
+
int
main(int argc, char **argv)
{
@@ -2499,13 +2598,17 @@ main(int argc, char **argv)
const char *config_path = DEFAULT_CONFIG_PATH;
int debug = 0, ch, error;
bool dont_daemonize = false;
+ bool use_ucl = false;
- while ((ch = getopt(argc, argv, "df:R")) != -1) {
+ while ((ch = getopt(argc, argv, "duf:R")) != -1) {
switch (ch) {
case 'd':
dont_daemonize = true;
debug++;
break;
+ case 'u':
+ use_ucl = true;
+ break;
case 'f':
config_path = optarg;
break;
@@ -2529,7 +2632,8 @@ main(int argc, char **argv)
kernel_init();
oldconf = conf_new_from_kernel();
- newconf = conf_new_from_file(config_path, oldconf);
+ newconf = conf_new_from_file(config_path, oldconf, use_ucl);
+
if (newconf == NULL)
log_errx(1, "configuration error; exiting");
if (debug > 0) {
@@ -2564,7 +2668,9 @@ main(int argc, char **argv)
if (sighup_received) {
sighup_received = false;
log_debugx("received SIGHUP, reloading configuration");
- tmpconf = conf_new_from_file(config_path, newconf);
+ tmpconf = conf_new_from_file(config_path, newconf,
+ use_ucl);
+
if (tmpconf == NULL) {
log_warnx("configuration error, "
"continuing with old configuration");
diff --git a/usr.sbin/ctld/ctld.h b/usr.sbin/ctld/ctld.h
index 808b722..e9152329 100644
--- a/usr.sbin/ctld/ctld.h
+++ b/usr.sbin/ctld/ctld.h
@@ -297,8 +297,10 @@ int rchap_receive(struct rchap *rchap,
char *rchap_get_response(struct rchap *rchap);
void rchap_delete(struct rchap *rchap);
+int parse_conf(struct conf *conf, const char *path);
+int uclparse_conf(struct conf *conf, const char *path);
+
struct conf *conf_new(void);
-struct conf *conf_new_from_file(const char *path, struct conf *old);
struct conf *conf_new_from_kernel(void);
void conf_delete(struct conf *conf);
int conf_verify(struct conf *conf);
diff --git a/usr.sbin/ctld/parse.y b/usr.sbin/ctld/parse.y
index afbf315..820b4c7 100644
--- a/usr.sbin/ctld/parse.y
+++ b/usr.sbin/ctld/parse.y
@@ -1044,70 +1044,18 @@ yyerror(const char *str)
lineno, yytext, str);
}
-static void
-check_perms(const char *path)
+int
+parse_conf(struct conf *newconf, const char *path)
{
- struct stat sb;
int error;
- error = stat(path, &sb);
- if (error != 0) {
- log_warn("stat");
- return;
- }
- if (sb.st_mode & S_IWOTH) {
- log_warnx("%s is world-writable", path);
- } else if (sb.st_mode & S_IROTH) {
- log_warnx("%s is world-readable", path);
- } else if (sb.st_mode & S_IXOTH) {
- /*
- * Ok, this one doesn't matter, but still do it,
- * just for consistency.
- */
- log_warnx("%s is world-executable", path);
- }
-
- /*
- * XXX: Should we also check for owner != 0?
- */
-}
-
-struct conf *
-conf_new_from_file(const char *path, struct conf *oldconf)
-{
- struct auth_group *ag;
- struct portal_group *pg;
- struct pport *pp;
- int error;
-
- log_debugx("obtaining configuration from %s", path);
-
- conf = conf_new();
-
- TAILQ_FOREACH(pp, &oldconf->conf_pports, pp_next)
- pport_copy(pp, conf);
-
- ag = auth_group_new(conf, "default");
- assert(ag != NULL);
-
- ag = auth_group_new(conf, "no-authentication");
- assert(ag != NULL);
- ag->ag_type = AG_TYPE_NO_AUTHENTICATION;
-
- ag = auth_group_new(conf, "no-access");
- assert(ag != NULL);
- ag->ag_type = AG_TYPE_DENY;
-
- pg = portal_group_new(conf, "default");
- assert(pg != NULL);
-
+ conf = newconf;
yyin = fopen(path, "r");
if (yyin == NULL) {
log_warn("unable to open configuration file %s", path);
- conf_delete(conf);
- return (NULL);
+ return (1);
}
- check_perms(path);
+
lineno = 1;
yyrestart(yyin);
error = yyparse();
@@ -1116,35 +1064,6 @@ conf_new_from_file(const char *path, struct conf *oldconf)
target = NULL;
lun = NULL;
fclose(yyin);
- if (error != 0) {
- conf_delete(conf);
- return (NULL);
- }
-
- if (conf->conf_default_ag_defined == false) {
- log_debugx("auth-group \"default\" not defined; "
- "going with defaults");
- ag = auth_group_find(conf, "default");
- assert(ag != NULL);
- ag->ag_type = AG_TYPE_DENY;
- }
-
- if (conf->conf_default_pg_defined == false) {
- log_debugx("portal-group \"default\" not defined; "
- "going with defaults");
- pg = portal_group_find(conf, "default");
- assert(pg != NULL);
- portal_group_add_listen(pg, "0.0.0.0:3260", false);
- portal_group_add_listen(pg, "[::]:3260", false);
- }
-
- conf->conf_kernel_port_on = true;
-
- error = conf_verify(conf);
- if (error != 0) {
- conf_delete(conf);
- return (NULL);
- }
- return (conf);
+ return (error);
}
diff --git a/usr.sbin/ctld/uclparse.c b/usr.sbin/ctld/uclparse.c
new file mode 100644
index 0000000..fb2cce0
--- /dev/null
+++ b/usr.sbin/ctld/uclparse.c
@@ -0,0 +1,900 @@
+/*-
+ * Copyright (c) 2015 iXsystems Inc.
+ * All rights reserved.
+ *
+ * This software was developed by Jakub Klama <jceel@FreeBSD.org>
+ * under sponsorship from iXsystems Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 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$
+ */
+
+#include <sys/queue.h>
+#include <sys/types.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ucl.h>
+
+#include "ctld.h"
+
+static struct conf *conf = NULL;
+
+static int uclparse_toplevel(const ucl_object_t *);
+static int uclparse_chap(struct auth_group *, const ucl_object_t *);
+static int uclparse_chap_mutual(struct auth_group *, const ucl_object_t *);
+static int uclparse_lun(const char *, const ucl_object_t *);
+static int uclparse_auth_group(const char *, const ucl_object_t *);
+static int uclparse_portal_group(const char *, const ucl_object_t *);
+static int uclparse_target(const char *, const ucl_object_t *);
+static int uclparse_target_portal_group(struct target *, const ucl_object_t *);
+static int uclparse_target_lun(struct target *, const ucl_object_t *);
+
+static int
+uclparse_chap(struct auth_group *auth_group, const ucl_object_t *obj)
+{
+ const struct auth *ca;
+ const ucl_object_t *user, *secret;
+
+ user = ucl_object_find_key(obj, "user");
+ if (!user || user->type != UCL_STRING) {
+ log_warnx("chap section in auth-group \"%s\" is missing "
+ "\"user\" string key", auth_group->ag_name);
+ return (1);
+ }
+
+ secret = ucl_object_find_key(obj, "secret");
+ if (!secret || secret->type != UCL_STRING) {
+ log_warnx("chap section in auth-group \"%s\" is missing "
+ "\"secret\" string key", auth_group->ag_name);
+ }
+
+ ca = auth_new_chap(auth_group,
+ ucl_object_tostring(user),
+ ucl_object_tostring(secret));
+
+ if (ca == NULL)
+ return (1);
+
+ return (0);
+}
+
+static int
+uclparse_chap_mutual(struct auth_group *auth_group, const ucl_object_t *obj)
+{
+ const struct auth *ca;
+ const ucl_object_t *user, *secret, *mutual_user;
+ const ucl_object_t *mutual_secret;
+
+ user = ucl_object_find_key(obj, "user");
+ if (!user || user->type != UCL_STRING) {
+ log_warnx("chap-mutual section in auth-group \"%s\" is missing "
+ "\"user\" string key", auth_group->ag_name);
+ return (1);
+ }
+
+ secret = ucl_object_find_key(obj, "secret");
+ if (!secret || secret->type != UCL_STRING) {
+ log_warnx("chap-mutual section in auth-group \"%s\" is missing "
+ "\"secret\" string key", auth_group->ag_name);
+ return (1);
+ }
+
+ mutual_user = ucl_object_find_key(obj, "mutual-user");
+ if (!user || user->type != UCL_STRING) {
+ log_warnx("chap-mutual section in auth-group \"%s\" is missing "
+ "\"mutual-user\" string key", auth_group->ag_name);
+ return (1);
+ }
+
+ mutual_secret = ucl_object_find_key(obj, "mutual-secret");
+ if (!secret || secret->type != UCL_STRING) {
+ log_warnx("chap-mutual section in auth-group \"%s\" is missing "
+ "\"mutual-secret\" string key", auth_group->ag_name);
+ return (1);
+ }
+
+ ca = auth_new_chap_mutual(auth_group,
+ ucl_object_tostring(user),
+ ucl_object_tostring(secret),
+ ucl_object_tostring(mutual_user),
+ ucl_object_tostring(mutual_secret));
+
+ if (ca == NULL)
+ return (1);
+
+ return (0);
+}
+
+static int
+uclparse_target_portal_group(struct target *target, const ucl_object_t *obj)
+{
+ struct portal_group *tpg;
+ struct auth_group *tag = NULL;
+ struct port *tp;
+ const ucl_object_t *portal_group, *auth_group;
+
+ portal_group = ucl_object_find_key(obj, "name");
+ if (!portal_group || portal_group->type != UCL_STRING) {
+ log_warnx("portal-group section in target \"%s\" is missing "
+ "\"name\" string key", target->t_name);
+ return (1);
+ }
+
+ auth_group = ucl_object_find_key(obj, "auth-group-name");
+ if (auth_group && auth_group->type != UCL_STRING) {
+ log_warnx("portal-group section in target \"%s\" is missing "
+ "\"auth-group-name\" string key", target->t_name);
+ return (1);
+ }
+
+
+ tpg = portal_group_find(conf, ucl_object_tostring(portal_group));
+ if (tpg == NULL) {
+ log_warnx("unknown portal-group \"%s\" for target "
+ "\"%s\"", ucl_object_tostring(portal_group), target->t_name);
+ return (1);
+ }
+
+ if (auth_group) {
+ tag = auth_group_find(conf, ucl_object_tostring(auth_group));
+ if (tag == NULL) {
+ log_warnx("unknown auth-group \"%s\" for target "
+ "\"%s\"", ucl_object_tostring(auth_group),
+ target->t_name);
+ return (1);
+ }
+ }
+
+ tp = port_new(conf, target, tpg);
+ if (tp == NULL) {
+ log_warnx("can't link portal-group \"%s\" to target "
+ "\"%s\"", ucl_object_tostring(portal_group), target->t_name);
+ return (1);
+ }
+ tp->p_auth_group = tag;
+
+ return (0);
+}
+
+static int
+uclparse_target_lun(struct target *target, const ucl_object_t *obj)
+{
+ struct lun *lun;
+
+ if (obj->type == UCL_INT) {
+ char *name;
+
+ asprintf(&name, "%s,lun,%ju", target->t_name,
+ ucl_object_toint(obj));
+ lun = lun_new(conf, name);
+ if (lun == NULL)
+ return (1);
+
+ lun_set_scsiname(lun, name);
+ target->t_luns[ucl_object_toint(obj)] = lun;
+ return (0);
+ }
+
+ if (obj->type == UCL_OBJECT) {
+ const ucl_object_t *num = ucl_object_find_key(obj, "number");
+ const ucl_object_t *name = ucl_object_find_key(obj, "name");
+
+ if (num == NULL || num->type != UCL_INT) {
+ log_warnx("lun section in target \"%s\" is missing "
+ "\"number\" integer property", target->t_name);
+ return (1);
+ }
+
+ if (name == NULL || name->type != UCL_STRING) {
+ log_warnx("lun section in target \"%s\" is missing "
+ "\"name\" string property", target->t_name);
+ return (1);
+ }
+
+ lun = lun_find(conf, ucl_object_tostring(name));
+ if (lun == NULL)
+ return (1);
+
+ target->t_luns[ucl_object_toint(num)] = lun;
+ }
+
+ return (0);
+}
+
+static int
+uclparse_toplevel(const ucl_object_t *top)
+{
+ ucl_object_iter_t it = NULL, iter = NULL;
+ const ucl_object_t *obj = NULL, *child = NULL;
+ int err = 0;
+
+ /* Pass 1 - everything except targets */
+ while ((obj = ucl_iterate_object(top, &it, true))) {
+ const char *key = ucl_object_key(obj);
+
+ if (!strcmp(key, "debug")) {
+ if (obj->type == UCL_INT)
+ conf->conf_debug = ucl_object_toint(obj);
+ else {
+ log_warnx("\"debug\" property value is not integer");
+ return (1);
+ }
+ }
+
+ if (!strcmp(key, "timeout")) {
+ if (obj->type == UCL_INT)
+ conf->conf_timeout = ucl_object_toint(obj);
+ else {
+ log_warnx("\"timeout\" property value is not integer");
+ return (1);
+ }
+ }
+
+ if (!strcmp(key, "maxproc")) {
+ if (obj->type == UCL_INT)
+ conf->conf_maxproc = ucl_object_toint(obj);
+ else {
+ log_warnx("\"maxproc\" property value is not integer");
+ return (1);
+ }
+ }
+
+ if (!strcmp(key, "pidfile")) {
+ if (obj->type == UCL_STRING)
+ conf->conf_pidfile_path = strdup(
+ ucl_object_tostring(obj));
+ else {
+ log_warnx("\"pidfile\" property value is not string");
+ return (1);
+ }
+ }
+
+ if (!strcmp(key, "isns-server")) {
+ if (obj->type == UCL_ARRAY) {
+ iter = NULL;
+ while ((child = ucl_iterate_object(obj, &iter,
+ true))) {
+ if (child->type != UCL_STRING)
+ return (1);
+
+ err = isns_new(conf,
+ ucl_object_tostring(child));
+ if (err != 0) {
+ return (1);
+ }
+ }
+ } else {
+ log_warnx("\"isns-server\" property value is "
+ "not an array");
+ return (1);
+ }
+ }
+
+ if (!strcmp(key, "isns-period")) {
+ if (obj->type == UCL_INT)
+ conf->conf_timeout = ucl_object_toint(obj);
+ else {
+ log_warnx("\"isns-period\" property value is not integer");
+ return (1);
+ }
+ }
+
+ if (!strcmp(key, "isns-timeout")) {
+ if (obj->type == UCL_INT)
+ conf->conf_timeout = ucl_object_toint(obj);
+ else {
+ log_warnx("\"isns-timeout\" property value is not integer");
+ return (1);
+ }
+ }
+
+ if (!strcmp(key, "auth-group")) {
+ if (obj->type == UCL_OBJECT) {
+ iter = NULL;
+ while ((child = ucl_iterate_object(obj, &iter, true))) {
+ uclparse_auth_group(ucl_object_key(child), child);
+ }
+ } else {
+ log_warnx("\"auth-group\" section is not an object");
+ return (1);
+ }
+ }
+
+ if (!strcmp(key, "portal-group")) {
+ if (obj->type == UCL_OBJECT) {
+ iter = NULL;
+ while ((child = ucl_iterate_object(obj, &iter, true))) {
+ uclparse_portal_group(ucl_object_key(child), child);
+ }
+ } else {
+ log_warnx("\"portal-group\" section is not an object");
+ return (1);
+ }
+ }
+
+ if (!strcmp(key, "lun")) {
+ if (obj->type == UCL_OBJECT) {
+ iter = NULL;
+ while ((child = ucl_iterate_object(obj, &iter, true))) {
+ uclparse_lun(ucl_object_key(child), child);
+ }
+ } else {
+ log_warnx("\"lun\" section is not an object");
+ return (1);
+ }
+ }
+ }
+
+ /* Pass 2 - targets */
+ it = NULL;
+ while ((obj = ucl_iterate_object(top, &it, true))) {
+ const char *key = ucl_object_key(obj);
+
+ if (!strcmp(key, "target")) {
+ if (obj->type == UCL_OBJECT) {
+ iter = NULL;
+ while ((child = ucl_iterate_object(obj, &iter,
+ true))) {
+ uclparse_target(ucl_object_key(child),
+ child);
+ }
+ } else {
+ log_warnx("\"target\" section is not an object");
+ return (1);
+ }
+ }
+ }
+
+ return (0);
+}
+
+static int
+uclparse_auth_group(const char *name, const ucl_object_t *top)
+{
+ struct auth_group *auth_group;
+ const struct auth_name *an;
+ const struct auth_portal *ap;
+ ucl_object_iter_t it = NULL, it2 = NULL;
+ const ucl_object_t *obj = NULL, *tmp = NULL;
+ const char *key;
+ int err;
+
+ if (!strcmp(name, "default") &&
+ conf->conf_default_ag_defined == false) {
+ auth_group = auth_group_find(conf, name);
+ conf->conf_default_ag_defined = true;
+ } else {
+ auth_group = auth_group_new(conf, name);
+ }
+
+ if (auth_group == NULL)
+ return (1);
+
+ while ((obj = ucl_iterate_object(top, &it, true))) {
+ key = ucl_object_key(obj);
+
+ if (!strcmp(key, "auth-type")) {
+ const char *value = ucl_object_tostring(obj);
+
+ err = auth_group_set_type(auth_group, value);
+ if (err)
+ return (1);
+ }
+
+ if (!strcmp(key, "chap")) {
+ if (obj->type != UCL_ARRAY) {
+ log_warnx("\"chap\" property of "
+ "auth-group \"%s\" is not an array",
+ name);
+ return (1);
+ }
+
+ it2 = NULL;
+ while ((tmp = ucl_iterate_object(obj, &it2, true))) {
+ if (uclparse_chap(auth_group, tmp) != 0)
+ return (1);
+ }
+ }
+
+ if (!strcmp(key, "chap-mutual")) {
+ if (obj->type != UCL_ARRAY) {
+ log_warnx("\"chap-mutual\" property of "
+ "auth-group \"%s\" is not an array",
+ name);
+ return (1);
+ }
+
+ it2 = NULL;
+ while ((tmp = ucl_iterate_object(obj, &it2, true))) {
+ if (uclparse_chap_mutual(auth_group, tmp) != 0)
+ return (1);
+ }
+ }
+
+ if (!strcmp(key, "initiator-name")) {
+ if (obj->type != UCL_ARRAY) {
+ log_warnx("\"initiator-name\" property of "
+ "auth-group \"%s\" is not an array",
+ name);
+ return (1);
+ }
+
+ it2 = NULL;
+ while ((tmp = ucl_iterate_object(obj, &it2, true))) {
+ const char *value = ucl_object_tostring(tmp);
+
+ an = auth_name_new(auth_group, value);
+ if (an == NULL)
+ return (1);
+ }
+ }
+
+ if (!strcmp(key, "initiator-portal")) {
+ if (obj->type != UCL_ARRAY) {
+ log_warnx("\"initiator-portal\" property of "
+ "auth-group \"%s\" is not an array",
+ name);
+ return (1);
+ }
+
+ it2 = NULL;
+ while ((tmp = ucl_iterate_object(obj, &it2, true))) {
+ const char *value = ucl_object_tostring(tmp);
+
+ ap = auth_portal_new(auth_group, value);
+ if (ap == NULL)
+ return (1);
+ }
+ }
+ }
+
+ return (0);
+}
+
+static int
+uclparse_portal_group(const char *name, const ucl_object_t *top)
+{
+ struct portal_group *portal_group;
+ ucl_object_iter_t it = NULL, it2 = NULL;
+ const ucl_object_t *obj = NULL, *tmp = NULL;
+ const char *key;
+
+ if (strcmp(name, "default") == 0 &&
+ conf->conf_default_pg_defined == false) {
+ portal_group = portal_group_find(conf, name);
+ conf->conf_default_pg_defined = true;
+ } else {
+ portal_group = portal_group_new(conf, name);
+ }
+
+ if (portal_group == NULL)
+ return (1);
+
+ while ((obj = ucl_iterate_object(top, &it, true))) {
+ key = ucl_object_key(obj);
+
+ if (!strcmp(key, "discovery-auth-group")) {
+ portal_group->pg_discovery_auth_group =
+ auth_group_find(conf, ucl_object_tostring(obj));
+ if (portal_group->pg_discovery_auth_group == NULL) {
+ log_warnx("unknown discovery-auth-group \"%s\" "
+ "for portal-group \"%s\"",
+ ucl_object_tostring(obj),
+ portal_group->pg_name);
+ return (1);
+ }
+ }
+
+ if (!strcmp(key, "discovery-filter")) {
+ if (obj->type != UCL_STRING) {
+ log_warnx("\"discovery-filter\" property of "
+ "portal-group \"%s\" is not a string",
+ portal_group->pg_name);
+ return (1);
+ }
+
+ if (portal_group_set_filter(portal_group,
+ ucl_object_tostring(obj)) != 0)
+ return (1);
+ }
+
+ if (!strcmp(key, "listen")) {
+ if (obj->type == UCL_STRING) {
+ if (portal_group_add_listen(portal_group,
+ ucl_object_tostring(obj), false) != 0)
+ return (1);
+ } else if (obj->type == UCL_ARRAY) {
+ while ((tmp = ucl_iterate_object(obj, &it2,
+ true))) {
+ if (portal_group_add_listen(
+ portal_group,
+ ucl_object_tostring(tmp),
+ false) != 0)
+ return (1);
+ }
+ } else {
+ log_warnx("\"listen\" property of "
+ "portal-group \"%s\" is not a string",
+ portal_group->pg_name);
+ return (1);
+ }
+ }
+
+ if (!strcmp(key, "listen-iser")) {
+ if (obj->type == UCL_STRING) {
+ if (portal_group_add_listen(portal_group,
+ ucl_object_tostring(obj), true) != 0)
+ return (1);
+ } else if (obj->type == UCL_ARRAY) {
+ while ((tmp = ucl_iterate_object(obj, &it2,
+ true))) {
+ if (portal_group_add_listen(
+ portal_group,
+ ucl_object_tostring(tmp),
+ true) != 0)
+ return (1);
+ }
+ } else {
+ log_warnx("\"listen\" property of "
+ "portal-group \"%s\" is not a string",
+ portal_group->pg_name);
+ return (1);
+ }
+ }
+
+ if (!strcmp(key, "redirect")) {
+ if (obj->type != UCL_STRING) {
+ log_warnx("\"listen\" property of "
+ "portal-group \"%s\" is not a string",
+ portal_group->pg_name);
+ return (1);
+ }
+
+ if (portal_group_set_redirection(portal_group,
+ ucl_object_tostring(obj)) != 0)
+ return (1);
+ }
+
+ if (!strcmp(key, "options")) {
+ if (obj->type != UCL_OBJECT) {
+ log_warnx("\"options\" property of portal group "
+ "\"%s\" is not an object", portal_group->pg_name);
+ return (1);
+ }
+
+ while ((tmp = ucl_iterate_object(obj, &it2,
+ true))) {
+ option_new(&portal_group->pg_options,
+ ucl_object_key(tmp),
+ ucl_object_tostring_forced(tmp));
+ }
+ }
+ }
+
+ return (0);
+}
+
+static int
+uclparse_target(const char *name, const ucl_object_t *top)
+{
+ struct target *target;
+ ucl_object_iter_t it = NULL, it2 = NULL;
+ const ucl_object_t *obj = NULL, *tmp = NULL;
+ const char *key;
+
+ target = target_new(conf, name);
+
+ while ((obj = ucl_iterate_object(top, &it, true))) {
+ key = ucl_object_key(obj);
+
+ if (!strcmp(key, "alias")) {
+ if (obj->type != UCL_STRING) {
+ log_warnx("\"alias\" property of target "
+ "\"%s\" is not a string", target->t_name);
+ return (1);
+ }
+
+ target->t_alias = strdup(ucl_object_tostring(obj));
+ }
+
+ if (!strcmp(key, "auth-group")) {
+ if (target->t_auth_group != NULL) {
+ if (target->t_auth_group->ag_name != NULL)
+ log_warnx("auth-group for target \"%s\" "
+ "specified more than once",
+ target->t_name);
+ else
+ log_warnx("cannot use both auth-group "
+ "and explicit authorisations for "
+ "target \"%s\"", target->t_name);
+ return (1);
+ }
+ target->t_auth_group = auth_group_find(conf,
+ ucl_object_tostring(obj));
+ if (target->t_auth_group == NULL) {
+ log_warnx("unknown auth-group \"%s\" for target "
+ "\"%s\"", ucl_object_tostring(obj),
+ target->t_name);
+ return (1);
+ }
+ }
+
+ if (!strcmp(key, "auth-type")) {
+ int error;
+
+ if (target->t_auth_group != NULL) {
+ if (target->t_auth_group->ag_name != NULL) {
+ log_warnx("cannot use both auth-group and "
+ "auth-type for target \"%s\"",
+ target->t_name);
+ return (1);
+ }
+ } else {
+ target->t_auth_group = auth_group_new(conf, NULL);
+ if (target->t_auth_group == NULL)
+ return (1);
+
+ target->t_auth_group->ag_target = target;
+ }
+ error = auth_group_set_type(target->t_auth_group,
+ ucl_object_tostring(obj));
+ if (error != 0)
+ return (1);
+ }
+
+ if (!strcmp(key, "chap")) {
+ if (uclparse_chap(target->t_auth_group, obj) != 0)
+ return (1);
+ }
+
+ if (!strcmp(key, "chap-mutual")) {
+ if (uclparse_chap_mutual(target->t_auth_group, obj) != 0)
+ return (1);
+ }
+
+ if (!strcmp(key, "initiator-name")) {
+ const struct auth_name *an;
+
+ if (target->t_auth_group != NULL) {
+ if (target->t_auth_group->ag_name != NULL) {
+ log_warnx("cannot use both auth-group and "
+ "initiator-name for target \"%s\"",
+ target->t_name);
+ return (1);
+ }
+ } else {
+ target->t_auth_group = auth_group_new(conf, NULL);
+ if (target->t_auth_group == NULL)
+ return (1);
+
+ target->t_auth_group->ag_target = target;
+ }
+ an = auth_name_new(target->t_auth_group,
+ ucl_object_tostring(obj));
+ if (an == NULL)
+ return (1);
+ }
+
+ if (!strcmp(key, "initiator-portal")) {
+ const struct auth_portal *ap;
+
+ if (target->t_auth_group != NULL) {
+ if (target->t_auth_group->ag_name != NULL) {
+ log_warnx("cannot use both auth-group and "
+ "initiator-portal for target \"%s\"",
+ target->t_name);
+ return (1);
+ }
+ } else {
+ target->t_auth_group = auth_group_new(conf, NULL);
+ if (target->t_auth_group == NULL)
+ return (1);
+
+ target->t_auth_group->ag_target = target;
+ }
+ ap = auth_portal_new(target->t_auth_group,
+ ucl_object_tostring(obj));
+ if (ap == NULL)
+ return (1);
+ }
+
+ if (!strcmp(key, "portal-group")) {
+ if (obj->type == UCL_OBJECT) {
+ if (uclparse_target_portal_group(target, obj) != 0)
+ return (1);
+ }
+
+ if (obj->type == UCL_ARRAY) {
+ while ((tmp = ucl_iterate_object(obj, &it2,
+ true))) {
+ if (uclparse_target_portal_group(target,
+ tmp) != 0)
+ return (1);
+ }
+ }
+ }
+
+ if (!strcmp(key, "port")) {
+ struct pport *pp;
+ struct port *tp;
+ const char *value = ucl_object_tostring(obj);
+
+ pp = pport_find(conf, value);
+ if (pp == NULL) {
+ log_warnx("unknown port \"%s\" for target \"%s\"",
+ value, target->t_name);
+ return (1);
+ }
+ if (!TAILQ_EMPTY(&pp->pp_ports)) {
+ log_warnx("can't link port \"%s\" to target \"%s\", "
+ "port already linked to some target",
+ value, target->t_name);
+ return (1);
+ }
+ tp = port_new_pp(conf, target, pp);
+ if (tp == NULL) {
+ log_warnx("can't link port \"%s\" to target \"%s\"",
+ value, target->t_name);
+ return (1);
+ }
+ }
+
+ if (!strcmp(key, "redirect")) {
+ if (obj->type != UCL_STRING) {
+ log_warnx("\"redirect\" property of target "
+ "\"%s\" is not a string", target->t_name);
+ return (1);
+ }
+
+ if (target_set_redirection(target,
+ ucl_object_tostring(obj)) != 0)
+ return (1);
+ }
+
+ if (!strcmp(key, "lun")) {
+ while ((tmp = ucl_iterate_object(obj, &it2, true))) {
+ if (uclparse_target_lun(target, tmp) != 0)
+ return (1);
+ }
+ }
+ }
+
+ return (0);
+}
+
+static int
+uclparse_lun(const char *name, const ucl_object_t *top)
+{
+ struct lun *lun;
+ ucl_object_iter_t it = NULL, child_it = NULL;
+ const ucl_object_t *obj = NULL, *child = NULL;
+ const char *key;
+
+ lun = lun_new(conf, name);
+
+ while ((obj = ucl_iterate_object(top, &it, true))) {
+ key = ucl_object_key(obj);
+
+ if (!strcmp(key, "backend")) {
+ if (obj->type != UCL_STRING) {
+ log_warnx("\"backend\" property of lun "
+ "\"%s\" is not a string",
+ lun->l_name);
+ return (1);
+ }
+
+ lun_set_backend(lun, ucl_object_tostring(obj));
+ }
+
+ if (!strcmp(key, "blocksize")) {
+ if (obj->type != UCL_INT) {
+ log_warnx("\"blocksize\" property of lun "
+ "\"%s\" is not an integer", lun->l_name);
+ return (1);
+ }
+
+ lun_set_blocksize(lun, ucl_object_toint(obj));
+ }
+
+ if (!strcmp(key, "device-id")) {
+ if (obj->type != UCL_STRING) {
+ log_warnx("\"device-id\" property of lun "
+ "\"%s\" is not an integer", lun->l_name);
+ return (1);
+ }
+
+ lun_set_device_id(lun, ucl_object_tostring(obj));
+ }
+
+ if (!strcmp(key, "options")) {
+ if (obj->type != UCL_OBJECT) {
+ log_warnx("\"options\" property of lun "
+ "\"%s\" is not an object", lun->l_name);
+ return (1);
+ }
+
+ while ((child = ucl_iterate_object(obj, &child_it,
+ true))) {
+ option_new(&lun->l_options,
+ ucl_object_key(child),
+ ucl_object_tostring_forced(child));
+ }
+ }
+
+ if (!strcmp(key, "path")) {
+ if (obj->type != UCL_STRING) {
+ log_warnx("\"path\" property of lun "
+ "\"%s\" is not a string", lun->l_name);
+ return (1);
+ }
+
+ lun_set_path(lun, ucl_object_tostring(obj));
+ }
+
+ if (!strcmp(key, "serial")) {
+ if (obj->type != UCL_STRING) {
+ log_warnx("\"serial\" property of lun "
+ "\"%s\" is not a string", lun->l_name);
+ return (1);
+ }
+
+ lun_set_serial(lun, ucl_object_tostring(obj));
+ }
+
+ if (!strcmp(key, "size")) {
+ if (obj->type != UCL_INT) {
+ log_warnx("\"size\" property of lun "
+ "\"%s\" is not an integer", lun->l_name);
+ return (1);
+ }
+
+ lun_set_size(lun, ucl_object_toint(obj));
+ }
+ }
+
+ return (0);
+}
+
+int
+uclparse_conf(struct conf *newconf, const char *path)
+{
+ struct ucl_parser *parser;
+ int error;
+
+ conf = newconf;
+ parser = ucl_parser_new(0);
+ ucl_parser_add_file(parser, path);
+
+ if (ucl_parser_get_error(parser)) {
+ log_warn("unable to parse configuration file %s: %s", path,
+ ucl_parser_get_error(parser));
+ return (1);
+ }
+
+ error = uclparse_toplevel(ucl_parser_get_object(parser));
+
+ return (error);
+}
diff --git a/usr.sbin/freebsd-update/freebsd-update.sh b/usr.sbin/freebsd-update/freebsd-update.sh
index cce2af5..feb8db6 100644
--- a/usr.sbin/freebsd-update/freebsd-update.sh
+++ b/usr.sbin/freebsd-update/freebsd-update.sh
@@ -45,7 +45,7 @@ Options:
(default: /etc/freebsd-update.conf)
-F -- Force a fetch operation to proceed
-k KEY -- Trust an RSA key with SHA256 hash of KEY
- -r release -- Target for upgrade (e.g., 6.2-RELEASE)
+ -r release -- Target for upgrade (e.g., 11.1-RELEASE)
-s server -- Server from which to fetch updates
(default: update.FreeBSD.org)
-t address -- Mail output of cron command, if any, to address
OpenPOWER on IntegriCloud