From 633e1868c3d57650c964455860f7fc1fc0726aa4 Mon Sep 17 00:00:00 2001 From: dteske Date: Tue, 2 Feb 2016 22:34:48 +0000 Subject: [PATCH 001/129] Bump version to 7.1 for +=/-= fix MFC after: 3 days X-MFC-to: stable/10 X-MFC-with: r295169, r295170 --- usr.sbin/sysrc/sysrc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr.sbin/sysrc/sysrc b/usr.sbin/sysrc/sysrc index aa57f1beb7f2..065b7ae49ee2 100644 --- a/usr.sbin/sysrc/sysrc +++ b/usr.sbin/sysrc/sysrc @@ -1,6 +1,6 @@ #!/bin/sh #- -# Copyright (c) 2010-2015 Devin Teske +# Copyright (c) 2010-2016 Devin Teske # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -40,7 +40,7 @@ BSDCFG_SHARE="/usr/share/bsdconfig" # # Version information # -SYSRC_VERSION="7.0 Sep-13,2015" +SYSRC_VERSION="7.1 Feb-2,2016" # # Options From 8d851d4e740abae7b12ae8a5ff7e3dc1daa32a29 Mon Sep 17 00:00:00 2001 From: jhb Date: Tue, 2 Feb 2016 22:55:03 +0000 Subject: [PATCH 002/129] - Note that devctl(8) will appear in 10.3 first. - Add missing devctl_set_driver entry to namelist in devlist(3). - Fix sorting of function prototypes in devlist(3). MFC after: 3 days --- lib/libdevctl/devctl.3 | 9 +++++---- usr.sbin/devctl/devctl.8 | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/libdevctl/devctl.3 b/lib/libdevctl/devctl.3 index be869f9d9868..b2734cf4aa30 100644 --- a/lib/libdevctl/devctl.3 +++ b/lib/libdevctl/devctl.3 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd December 26, 2014 +.Dd February 2, 2016 .Dt DEVCTL 3 .Os .Sh NAME @@ -35,6 +35,7 @@ .Nm devctl_disable , .Nm devctl_enable , .Nm devctl_resume , +.Nm devctl_set_driver , .Nm devctl_suspend .Nd device control library .Sh LIBRARY @@ -52,9 +53,9 @@ .Ft int .Fn devctl_resume "const char *device" .Ft int -.Fn devctl_suspend "const char *device" -.Ft int .Fn devctl_set_driver "const char *device" "const char *driver" "bool force" +.Ft int +.Fn devctl_suspend "const char *device" .Sh DESCRIPTION The .Nm @@ -287,7 +288,7 @@ The new device driver failed to attach. The .Nm library first appeared in -.Fx 11.0 . +.Fx 10.3 . .Sh BUGS If a device is suspended individually via .Fn devctl_suspend diff --git a/usr.sbin/devctl/devctl.8 b/usr.sbin/devctl/devctl.8 index fef42be13073..2257cb63cc3d 100644 --- a/usr.sbin/devctl/devctl.8 +++ b/usr.sbin/devctl/devctl.8 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd February 5, 2015 +.Dd February 2, 2016 .Dt DEVCTL 8 .Os .Sh NAME @@ -134,4 +134,4 @@ the device will not be changed. The .Nm utility first appeared in -.Fx 11.0 . +.Fx 10.3 . From 27e083b53bbc58462060f9d7e7a041bf72ccd3a7 Mon Sep 17 00:00:00 2001 From: bdrewery Date: Tue, 2 Feb 2016 23:33:58 +0000 Subject: [PATCH 003/129] Move logic to destroy a struct catentry to its own function. This will be used later for memory leak handling. Obtained from: OneFS Sponsored by: EMC / Isilon Storage Division --- lib/libc/nls/msgcat.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/lib/libc/nls/msgcat.c b/lib/libc/nls/msgcat.c index 0cba460403b3..3df76b60b4bd 100644 --- a/lib/libc/nls/msgcat.c +++ b/lib/libc/nls/msgcat.c @@ -325,6 +325,21 @@ catgets(nl_catd catd, int set_id, int msg_id, const char *s) return ((char *)s); } +static void +catfree(struct catentry *np) +{ + + if (np->catd != NULL && np->catd != NLERR) { + munmap(np->catd->__data, (size_t)np->catd->__size); + free(np->catd); + } + SLIST_REMOVE(&cache, np, catentry, list); + free(np->name); + free(np->path); + free(np->lang); + free(np); +} + int catclose(nl_catd catd) { @@ -341,15 +356,8 @@ catclose(nl_catd catd) SLIST_FOREACH(np, &cache, list) { if (catd == np->catd) { np->refcount--; - if (np->refcount == 0) { - munmap(catd->__data, (size_t)catd->__size); - free(catd); - SLIST_REMOVE(&cache, np, catentry, list); - free(np->name); - free(np->path); - free(np->lang); - free(np); - } + if (np->refcount == 0) + catfree(np); break; } } From 98d4913b4094d9b5522bdf1acdce47999e74ac7d Mon Sep 17 00:00:00 2001 From: dteske Date: Tue, 2 Feb 2016 23:51:39 +0000 Subject: [PATCH 004/129] Fix a typo in a comment --- usr.sbin/sysrc/sysrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.sbin/sysrc/sysrc b/usr.sbin/sysrc/sysrc index 065b7ae49ee2..1da537fd5992 100644 --- a/usr.sbin/sysrc/sysrc +++ b/usr.sbin/sysrc/sysrc @@ -595,7 +595,7 @@ fi if [ "$SHOW_ALL" ]; then # # Get a list of variables that are currently set in the rc.conf(5) - # files (included `/etc/defaults/rc.conf') by performing a call to + # files (including `/etc/defaults/rc.conf') by performing a call to # source_rc_confs() in a clean environment. # ( # Operate in a sub-shell to protect the parent environment From e5ae512d17e6046ae62a9952cb51217771139be4 Mon Sep 17 00:00:00 2001 From: dteske Date: Tue, 2 Feb 2016 23:54:07 +0000 Subject: [PATCH 005/129] Revert r295169 and switch `\ ' to `" "' MFC after: 3 days X-MFC-to: stable/10 X-MFC-with: r295169, r295170, r295173, r295177 --- usr.sbin/sysrc/sysrc.8 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr.sbin/sysrc/sysrc.8 b/usr.sbin/sysrc/sysrc.8 index 3996b1f9482c..075fc3bd8a1e 100644 --- a/usr.sbin/sysrc/sysrc.8 +++ b/usr.sbin/sysrc/sysrc.8 @@ -255,7 +255,7 @@ When using the .Ql key+=value syntax to add items to existing values, the first character of the value is taken as the delimiter separating items -.Pq usually Qo (space) Qc or Qo , Qc . +.Pq usually Qo " " Qc or Qo , Qc . For example, in the following statement: .Bl -item -offset indent .It @@ -316,7 +316,7 @@ When using the .Ql key-=value syntax to remove items from existing values, the first character of the value is taken as the delimiter separating items -.Pq usually Qo \ Qc or Qo , Qc . +.Pq usually Qo " " Qc or Qo , Qc . For example, in the following statement: .Pp .Dl Nm cloned_interfaces-=" gif0" From 5f95bf68114f2eb19fc30a8fb38352f8e0135f2a Mon Sep 17 00:00:00 2001 From: dteske Date: Wed, 3 Feb 2016 00:51:38 +0000 Subject: [PATCH 006/129] Define f_sprintf() dynamically at inclusion time No need to check/re-check capabilities that won't change at runtime. --- usr.sbin/bsdconfig/share/strings.subr | 29 ++++++++++++++++----------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/usr.sbin/bsdconfig/share/strings.subr b/usr.sbin/bsdconfig/share/strings.subr index 1a4fe6ef081c..f1dbbd76a5e6 100644 --- a/usr.sbin/bsdconfig/share/strings.subr +++ b/usr.sbin/bsdconfig/share/strings.subr @@ -154,20 +154,25 @@ f_substr() # Similar to sprintf(3), write a string into $var_to_set using printf(1) syntax # (`$format [$arguments ...]'). # -f_sprintf() -{ - local __var_to_set="$1" - shift 1 # var_to_set - - case "$BASH_VERSION" in - 3.1*|4.*) - local __tmp +case "$BASH_VERSION" in +3.1*|4.*) + f_sprintf() + { + local __var_to_set="$1" __tmp + shift 1 # var_to_set printf -v __tmp "$@" eval "$__var_to_set"=\"\${__tmp%\$NL}\" - ;; - *) eval "$__var_to_set"=\$\( printf -- \"\$@\" \) - esac -} + } + ;; +*) + # NB: On FreeBSD, sh(1) runs this faster than bash(1) runs the above + f_sprintf() + { + local __var_to_set="$1" + shift 1 # var_to_set + eval "$__var_to_set"=\$\( printf -- \"\$@\" \) + } +esac # f_vsprintf $var_to_set $format $format_args # From d6406df83942d9fa08b4b2cf53ee2c5527172039 Mon Sep 17 00:00:00 2001 From: jhibbits Date: Wed, 3 Feb 2016 01:29:06 +0000 Subject: [PATCH 007/129] Make lbc(4) the same driver pass as simplebus. Device trees mark lbc as compatible with simplebus. Since simplebus is passed first, it attaches first. When lbc's pass (default pass) comes, the bus is already attached to simplebus, so is skipped. Sponsored by: Alex Perez/Inertial Computing --- sys/powerpc/mpc85xx/lbc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/powerpc/mpc85xx/lbc.c b/sys/powerpc/mpc85xx/lbc.c index f9a1718635a0..7dfaa06ed966 100644 --- a/sys/powerpc/mpc85xx/lbc.c +++ b/sys/powerpc/mpc85xx/lbc.c @@ -113,7 +113,8 @@ static driver_t lbc_driver = { devclass_t lbc_devclass; -DRIVER_MODULE(lbc, ofwbus, lbc_driver, lbc_devclass, 0, 0); +EARLY_DRIVER_MODULE(lbc, ofwbus, lbc_driver, lbc_devclass, + 0, 0, BUS_PASS_BUS); /* * Calculate address mask used by OR(n) registers. Use memory region size to From d8a6a1cf148b47a295850717ae031f12d55b5741 Mon Sep 17 00:00:00 2001 From: cem Date: Wed, 3 Feb 2016 01:40:07 +0000 Subject: [PATCH 008/129] Revert r295167 at bdrewery's request $ svn merge -c -295167 . JHB reports Navdeep reports that it breaks distribution and etcupdate. Approved by: bdrewery --- Makefile.inc1 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile.inc1 b/Makefile.inc1 index 001df800a4bf..222d7ec2b74f 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -1087,7 +1087,9 @@ distrib-dirs: .MAKE .PHONY ${_+_}cd ${.CURDIR}/etc; ${CROSSENV} PATH=${TMPPATH} ${MAKE} \ ${IMAKE_INSTALL} ${IMAKE_MTREE} METALOG=${METALOG} ${.TARGET} -distribution: distrib-dirs .MAKE .PHONY +distribution: .MAKE .PHONY + ${_+_}cd ${.CURDIR}/etc; ${CROSSENV} PATH=${TMPPATH} ${MAKE} \ + ${IMAKE_INSTALL} ${IMAKE_MTREE} METALOG=${METALOG} ${.TARGET} ${_+_}cd ${.CURDIR}; ${CROSSENV} PATH=${TMPPATH} \ ${MAKE} -f Makefile.inc1 ${IMAKE_INSTALL} \ METALOG=${METALOG} installconfig From 86be85e87ea583d6b89dc395f00ae6b6ba8ec606 Mon Sep 17 00:00:00 2001 From: jhibbits Date: Wed, 3 Feb 2016 01:50:27 +0000 Subject: [PATCH 009/129] Align signal stack pointer to 16 bytes. The stack must be aligned to 16 bytes at all times. Clang 3.8 is especially adamant about this, and causes strange behavior and segmentation faults if it is not the case. PR: kern/206810 --- sys/powerpc/powerpc/exec_machdep.c | 6 +++--- sys/powerpc/powerpc/sigcode32.S | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sys/powerpc/powerpc/exec_machdep.c b/sys/powerpc/powerpc/exec_machdep.c index d8238a1b58f1..4e56429ea0bb 100644 --- a/sys/powerpc/powerpc/exec_machdep.c +++ b/sys/powerpc/powerpc/exec_machdep.c @@ -219,10 +219,10 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) */ if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack && SIGISMEMBER(psp->ps_sigonstack, sig)) { - usfp = (void *)((uintptr_t)td->td_sigstk.ss_sp + - td->td_sigstk.ss_size - rndfsize); + usfp = (void *)(((uintptr_t)td->td_sigstk.ss_sp + + td->td_sigstk.ss_size - rndfsize) & ~0xFul); } else { - usfp = (void *)(tf->fixreg[1] - rndfsize); + usfp = (void *)((tf->fixreg[1] - rndfsize) & ~0xFul); } /* diff --git a/sys/powerpc/powerpc/sigcode32.S b/sys/powerpc/powerpc/sigcode32.S index 023618215d32..cd4c3cf72f9e 100644 --- a/sys/powerpc/powerpc/sigcode32.S +++ b/sys/powerpc/powerpc/sigcode32.S @@ -45,9 +45,9 @@ */ .globl CNAME(sigcode32),CNAME(szsigcode32) CNAME(sigcode32): - addi 1,1,-20 /* reserved space for callee */ + addi 1,1,-32 /* reserved space for callee */ blrl - addi 3,1,20+SF_UC /* restore sp, and get &frame->sf_uc */ + addi 3,1,32+SF_UC /* restore sp, and get &frame->sf_uc */ li 0,SYS_sigreturn sc /* sigreturn(scp) */ li 0,SYS_exit From 075f458553f88ba29dc4d130e77dd6321f595b21 Mon Sep 17 00:00:00 2001 From: dteske Date: Wed, 3 Feb 2016 02:46:00 +0000 Subject: [PATCH 010/129] Remove trailing whitespace --- usr.sbin/bsdconfig/share/strings.subr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr.sbin/bsdconfig/share/strings.subr b/usr.sbin/bsdconfig/share/strings.subr index f1dbbd76a5e6..bf0604aa8142 100644 --- a/usr.sbin/bsdconfig/share/strings.subr +++ b/usr.sbin/bsdconfig/share/strings.subr @@ -65,7 +65,7 @@ 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() { @@ -76,7 +76,7 @@ f_substr() esac done shift $(( $OPTIND - 1 )) - + local __tmp="$1" __start="${2:-1}" __size="$3" local __tbuf __tbuf_len __trim __trimq From 65c2ff7ea86f0742ea35f9bca64c13656af2f529 Mon Sep 17 00:00:00 2001 From: dteske Date: Wed, 3 Feb 2016 03:03:04 +0000 Subject: [PATCH 011/129] f_substr: Write to stdout when no `-v var_to_set' Fixes ``setvar: : bad variable name'' --- usr.sbin/bsdconfig/share/strings.subr | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/usr.sbin/bsdconfig/share/strings.subr b/usr.sbin/bsdconfig/share/strings.subr index bf0604aa8142..f9e33c75d835 100644 --- a/usr.sbin/bsdconfig/share/strings.subr +++ b/usr.sbin/bsdconfig/share/strings.subr @@ -146,7 +146,11 @@ f_substr() fi done - setvar "$__var_to_set" "$__tmp" + if [ "$__var_to_set" ]; then + setvar "$__var_to_set" "$__tmp" + else + echo "$__tmp" + fi } # f_sprintf $var_to_set $format [$arguments ...] From b2bf30d1a948ddce18a8a4178be88dde5ec18c69 Mon Sep 17 00:00:00 2001 From: dteske Date: Wed, 3 Feb 2016 03:55:08 +0000 Subject: [PATCH 012/129] Remove SIG prefix from trapped signals Makes traps functional if running under shells/dash --- usr.sbin/bsdconfig/share/common.subr | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/usr.sbin/bsdconfig/share/common.subr b/usr.sbin/bsdconfig/share/common.subr index 599644637922..2b911fcec668 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 From 0129d4cd2c7ad3bc5d278e7ac95f23ffbe04166f Mon Sep 17 00:00:00 2001 From: dteske Date: Wed, 3 Feb 2016 04:02:50 +0000 Subject: [PATCH 013/129] f_substr(): Optimized recipe if running under bash This makes runnig f_substr() faster than it was when running under bash, but both sh and dash are still faster when using the non-bash recipe which features dynamically unrolled loops. --- usr.sbin/bsdconfig/share/strings.subr | 177 +++++++++++++++----------- 1 file changed, 106 insertions(+), 71 deletions(-) diff --git a/usr.sbin/bsdconfig/share/strings.subr b/usr.sbin/bsdconfig/share/strings.subr index f9e33c75d835..f33f4df566ad 100644 --- a/usr.sbin/bsdconfig/share/strings.subr +++ b/usr.sbin/bsdconfig/share/strings.subr @@ -67,52 +67,58 @@ f_isinteger() # Similar to awk(1)'s substr(), return length substring of string that begins # 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 )) + 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 - __trimq=$(( $__trim / $__tbuf_len )) - __trim=$(( $__trim - $__tbuf_len * $__trimq )) - while [ $__trimq -gt 0 ]; do - __tmp="${__tmp#$__tbuf}" - __trimq=$(( $__trimq - 1 )) - done - done + shift $(( $OPTIND - 1 )) - 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 + 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?" @@ -121,37 +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 )) - 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 - if [ "$__var_to_set" ]; then - setvar "$__var_to_set" "$__tmp" - else - echo "$__tmp" - 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 + 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 + done + + if [ "$__var_to_set" ]; then + setvar "$__var_to_set" "$__tmp" + else + echo "$__tmp" + fi + } +esac # f_sprintf $var_to_set $format [$arguments ...] # From 4de365e69c81fbfd2f2d24281ad241f229e9ef02 Mon Sep 17 00:00:00 2001 From: mmel Date: Wed, 3 Feb 2016 08:12:21 +0000 Subject: [PATCH 014/129] ARM: acle-compat.h is arm specific header, don't include it for aarch64. This fixes aarch64 buildkernel. --- sys/arm/arm/devmap.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/arm/arm/devmap.c b/sys/arm/arm/devmap.c index 380e12941dc2..4dffa8cc7a2b 100644 --- a/sys/arm/arm/devmap.c +++ b/sys/arm/arm/devmap.c @@ -40,7 +40,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#ifdef __arm__ #include +#endif #include #include #include From d10f7c8df15f0065949470152e01d5f035d49f26 Mon Sep 17 00:00:00 2001 From: mmel Date: Wed, 3 Feb 2016 08:59:12 +0000 Subject: [PATCH 015/129] ARM: The arm/xscale/i80321 directory is now orphaned, but two drivers are shared with i8134x. In preparation for removal of i80321, copy these drivers to i8134x. --- sys/arm/xscale/i8134x/crb_machdep.c | 2 +- sys/arm/xscale/i8134x/files.i81342 | 4 +- sys/arm/xscale/i8134x/i80321_timer.c | 485 ++++++++++++++++++++++++ sys/arm/xscale/i8134x/i80321_wdog.c | 154 ++++++++ sys/arm/xscale/i8134x/i80321reg.h | 547 +++++++++++++++++++++++++++ sys/arm/xscale/i8134x/i80321var.h | 137 +++++++ 6 files changed, 1326 insertions(+), 3 deletions(-) create mode 100644 sys/arm/xscale/i8134x/i80321_timer.c create mode 100644 sys/arm/xscale/i8134x/i80321_wdog.c create mode 100644 sys/arm/xscale/i8134x/i80321reg.h create mode 100644 sys/arm/xscale/i8134x/i80321var.h diff --git a/sys/arm/xscale/i8134x/crb_machdep.c b/sys/arm/xscale/i8134x/crb_machdep.c index 2bd77a5f30a7..e306a75a5b12 100644 --- a/sys/arm/xscale/i8134x/crb_machdep.c +++ b/sys/arm/xscale/i8134x/crb_machdep.c @@ -92,7 +92,7 @@ __FBSDID("$FreeBSD$"); #include -#include /* For i80321_calibrate_delay() */ +#include /* For i80321_calibrate_delay() */ #include #include diff --git a/sys/arm/xscale/i8134x/files.i81342 b/sys/arm/xscale/i8134x/files.i81342 index ed93e6bf855a..63c715cb4be7 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/i8134x/i80321_timer.c b/sys/arm/xscale/i8134x/i80321_timer.c new file mode 100644 index 000000000000..ea15d920bf01 --- /dev/null +++ b/sys/arm/xscale/i8134x/i80321_timer.c @@ -0,0 +1,485 @@ +/* $NetBSD: i80321_timer.c,v 1.7 2003/07/27 04:52:28 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. + */ + +/* + * Timer/clock support for the Intel i80321 I/O processor. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CPU_XSCALE_81342 +#define ICU_INT_TIMER0 (8) /* XXX: Can't include i81342reg.h because + definitions overrides the ones from i80321reg.h + */ +#endif +#include "opt_timer.h" + +void (*i80321_hardclock_hook)(void) = NULL; +struct i80321_timer_softc { + device_t dev; +} timer_softc; + + +static unsigned i80321_timer_get_timecount(struct timecounter *tc); + + +static uint32_t counts_per_hz; + +#if defined(XSCALE_DISABLE_CCNT) || defined(CPU_XSCALE_81342) +static uint32_t offset; +static uint32_t last = -1; +#endif + +static int ticked = 0; + +#ifndef COUNTS_PER_SEC +#define COUNTS_PER_SEC 200000000 /* 200MHz */ +#endif + +#define COUNTS_PER_USEC (COUNTS_PER_SEC / 1000000) + +static struct timecounter i80321_timer_timecounter = { + i80321_timer_get_timecount, /* get_timecount */ + NULL, /* no poll_pps */ + ~0u, /* counter_mask */ +#if defined(XSCALE_DISABLE_CCNT) || defined(CPU_XSCALE_81342) + COUNTS_PER_SEC, +#else + COUNTS_PER_SEC * 3, /* frequency */ +#endif + "i80321 timer", /* name */ + 1000 /* quality */ +}; + +static int +i80321_timer_probe(device_t dev) +{ + + device_set_desc(dev, "i80321 timer"); + return (0); +} + +static int +i80321_timer_attach(device_t dev) +{ + timer_softc.dev = dev; + + return (0); +} + +static device_method_t i80321_timer_methods[] = { + DEVMETHOD(device_probe, i80321_timer_probe), + DEVMETHOD(device_attach, i80321_timer_attach), + {0, 0}, +}; + +static driver_t i80321_timer_driver = { + "itimer", + i80321_timer_methods, + sizeof(struct i80321_timer_softc), +}; +static devclass_t i80321_timer_devclass; + +DRIVER_MODULE(itimer, iq, i80321_timer_driver, i80321_timer_devclass, 0, 0); + +int clockhandler(void *); + + +static __inline uint32_t +tmr1_read(void) +{ + uint32_t rv; + +#ifdef CPU_XSCALE_81342 + __asm __volatile("mrc p6, 0, %0, c1, c9, 0" +#else + __asm __volatile("mrc p6, 0, %0, c1, c1, 0" +#endif + : "=r" (rv)); + return (rv); +} + +static __inline void +tmr1_write(uint32_t val) +{ + + +#ifdef CPU_XSCALE_81342 + __asm __volatile("mcr p6, 0, %0, c1, c9, 0" +#else + __asm __volatile("mcr p6, 0, %0, c1, c1, 0" +#endif + : + : "r" (val)); +} + +static __inline uint32_t +tcr1_read(void) +{ + uint32_t rv; + +#ifdef CPU_XSCALE_81342 + __asm __volatile("mrc p6, 0, %0, c3, c9, 0" +#else + __asm __volatile("mrc p6, 0, %0, c3, c1, 0" +#endif + : "=r" (rv)); + return (rv); +} +static __inline void +tcr1_write(uint32_t val) +{ + +#ifdef CPU_XSCALE_81342 + __asm __volatile("mcr p6, 0, %0, c3, c9, 0" +#else + __asm __volatile("mcr p6, 0, %0, c3, c1, 0" +#endif + : + : "r" (val)); +} + +static __inline void +trr1_write(uint32_t val) +{ + +#ifdef CPU_XSCALE_81342 + __asm __volatile("mcr p6, 0, %0, c5, c9, 0" +#else + __asm __volatile("mcr p6, 0, %0, c5, c1, 0" +#endif + : + : "r" (val)); +} + +static __inline uint32_t +tmr0_read(void) +{ + uint32_t rv; + +#ifdef CPU_XSCALE_81342 + __asm __volatile("mrc p6, 0, %0, c0, c9, 0" +#else + __asm __volatile("mrc p6, 0, %0, c0, c1, 0" +#endif + : "=r" (rv)); + return (rv); +} + +static __inline void +tmr0_write(uint32_t val) +{ + +#ifdef CPU_XSCALE_81342 + __asm __volatile("mcr p6, 0, %0, c0, c9, 0" +#else + __asm __volatile("mcr p6, 0, %0, c0, c1, 0" +#endif + : + : "r" (val)); +} + +static __inline uint32_t +tcr0_read(void) +{ + uint32_t rv; + +#ifdef CPU_XSCALE_81342 + __asm __volatile("mrc p6, 0, %0, c2, c9, 0" +#else + __asm __volatile("mrc p6, 0, %0, c2, c1, 0" +#endif + : "=r" (rv)); + return (rv); +} +static __inline void +tcr0_write(uint32_t val) +{ + +#ifdef CPU_XSCALE_81342 + __asm __volatile("mcr p6, 0, %0, c2, c9, 0" +#else + __asm __volatile("mcr p6, 0, %0, c2, c1, 0" +#endif + : + : "r" (val)); +} + +static __inline void +trr0_write(uint32_t val) +{ + +#ifdef CPU_XSCALE_81342 + __asm __volatile("mcr p6, 0, %0, c4, c9, 0" +#else + __asm __volatile("mcr p6, 0, %0, c4, c1, 0" +#endif + : + : "r" (val)); +} + +static __inline void +tisr_write(uint32_t val) +{ + +#ifdef CPU_XSCALE_81342 + __asm __volatile("mcr p6, 0, %0, c6, c9, 0" +#else + __asm __volatile("mcr p6, 0, %0, c6, c1, 0" +#endif + : + : "r" (val)); +} + +static __inline uint32_t +tisr_read(void) +{ + int ret; + +#ifdef CPU_XSCALE_81342 + __asm __volatile("mrc p6, 0, %0, c6, c9, 0" : "=r" (ret)); +#else + __asm __volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (ret)); +#endif + return (ret); +} + +static unsigned +i80321_timer_get_timecount(struct timecounter *tc) +{ +#if defined(XSCALE_DISABLE_CCNT) || defined(CPU_XSCALE_81342) + uint32_t cur = tcr0_read(); + + if (cur > last && last != -1) { + offset += counts_per_hz; + if (ticked > 0) + ticked--; + } + if (ticked) { + offset += ticked * counts_per_hz; + ticked = 0; + } + return (counts_per_hz - cur + offset); +#else + uint32_t ret; + + __asm __volatile("mrc p14, 0, %0, c1, c0, 0\n" + : "=r" (ret)); + return (ret); +#endif +} + +/* + * i80321_calibrate_delay: + * + * Calibrate the delay loop. + */ +void +i80321_calibrate_delay(void) +{ + + /* + * Just use hz=100 for now -- we'll adjust it, if necessary, + * in cpu_initclocks(). + */ + counts_per_hz = COUNTS_PER_SEC / 100; + + tmr0_write(0); /* stop timer */ + tisr_write(TISR_TMR0); /* clear interrupt */ + trr0_write(counts_per_hz); /* reload value */ + tcr0_write(counts_per_hz); /* current value */ + + tmr0_write(TMRx_ENABLE|TMRx_RELOAD|TMRx_CSEL_CORE); +} + +/* + * cpu_initclocks: + * + * Initialize the clock and get them going. + */ +void +cpu_initclocks(void) +{ + u_int oldirqstate; + struct resource *irq; + int rid = 0; + void *ihl; + device_t dev = timer_softc.dev; + + if (hz < 50 || COUNTS_PER_SEC % hz) { + printf("Cannot get %d Hz clock; using 100 Hz\n", hz); + hz = 100; + } + tick = 1000000 / hz; /* number of microseconds between interrupts */ + + /* + * We only have one timer available; stathz and profhz are + * always left as 0 (the upper-layer clock code deals with + * this situation). + */ + if (stathz != 0) + printf("Cannot get %d Hz statclock\n", stathz); + stathz = 0; + + if (profhz != 0) + printf("Cannot get %d Hz profclock\n", profhz); + profhz = 0; + + /* Report the clock frequency. */ + + oldirqstate = disable_interrupts(PSR_I); + + irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, +#ifdef CPU_XSCALE_81342 + ICU_INT_TIMER0, ICU_INT_TIMER0, +#else + ICU_INT_TMR0, ICU_INT_TMR0, +#endif + 1, RF_ACTIVE); + if (!irq) + panic("Unable to setup the clock irq handler.\n"); + else + bus_setup_intr(dev, irq, INTR_TYPE_CLK, clockhandler, NULL, + NULL, &ihl); + tmr0_write(0); /* stop timer */ + tisr_write(TISR_TMR0); /* clear interrupt */ + + counts_per_hz = COUNTS_PER_SEC / hz; + + trr0_write(counts_per_hz); /* reload value */ + tcr0_write(counts_per_hz); /* current value */ + tmr0_write(TMRx_ENABLE|TMRx_RELOAD|TMRx_CSEL_CORE); + + tc_init(&i80321_timer_timecounter); + restore_interrupts(oldirqstate); + rid = 0; +#if !defined(XSCALE_DISABLE_CCNT) && !defined(CPU_XSCALE_81342) + /* Enable the clock count register. */ + __asm __volatile("mrc p14, 0, %0, c0, c0, 0\n" : "=r" (rid)); + rid &= ~(1 << 3); + rid |= (1 << 2) | 1; + __asm __volatile("mcr p14, 0, %0, c0, c0, 0\n" + : : "r" (rid)); +#endif +} + + +/* + * DELAY: + * + * Delay for at least N microseconds. + */ +void +DELAY(int n) +{ + uint32_t cur, last, delta, usecs; + + /* + * This works by polling the timer and counting the + * number of microseconds that go by. + */ + last = tcr0_read(); + delta = usecs = 0; + + while (n > usecs) { + cur = tcr0_read(); + + /* Check to see if the timer has wrapped around. */ + if (last < cur) + delta += (last + (counts_per_hz - cur)); + else + delta += (last - cur); + + last = cur; + + if (delta >= COUNTS_PER_USEC) { + usecs += delta / COUNTS_PER_USEC; + delta %= COUNTS_PER_USEC; + } + } +} + +/* + * clockhandler: + * + * Handle the hardclock interrupt. + */ +int +clockhandler(void *arg) +{ + struct trapframe *frame = arg; + + ticked++; + tisr_write(TISR_TMR0); + hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame)); + + if (i80321_hardclock_hook != NULL) + (*i80321_hardclock_hook)(); + return (FILTER_HANDLED); +} + +void +cpu_startprofclock(void) +{ +} + +void +cpu_stopprofclock(void) +{ + +} diff --git a/sys/arm/xscale/i8134x/i80321_wdog.c b/sys/arm/xscale/i8134x/i80321_wdog.c new file mode 100644 index 000000000000..c11c78a48e33 --- /dev/null +++ b/sys/arm/xscale/i8134x/i80321_wdog.c @@ -0,0 +1,154 @@ +/* $NetBSD: i80321_wdog.c,v 1.6 2003/07/15 00:24:54 lukem Exp $ */ + +/*- + * Copyright (c) 2005 Olivier Houchard + * 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. + */ + +/* + * Watchdog timer support for the Intel i80321 I/O processor. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + + +struct iopwdog_softc { + device_t dev; + int armed; + int wdog_period; +}; + +static __inline void +wdtcr_write(uint32_t val) +{ + +#ifdef CPU_XSCALE_81342 + __asm __volatile("mcr p6, 0, %0, c7, c9, 0" +#else + __asm __volatile("mcr p6, 0, %0, c7, c1, 0" +#endif + : + : "r" (val)); +} + +static void +iopwdog_tickle(void *arg) +{ + struct iopwdog_softc *sc = arg; + + if (!sc->armed) + return; + wdtcr_write(WDTCR_ENABLE1); + wdtcr_write(WDTCR_ENABLE2); +} + +static int +iopwdog_probe(device_t dev) +{ + struct iopwdog_softc *sc = device_get_softc(dev); + char buf[128]; + + /* + * XXX Should compute the period based on processor speed. + * For a 600MHz XScale core, the wdog must be tickled approx. + * every 7 seconds. + */ + + sc->wdog_period = 7; + sprintf(buf, "i80321 Watchdog, must be tickled every %d seconds", + sc->wdog_period); + device_set_desc_copy(dev, buf); + + return (0); +} + +static void +iopwdog_watchdog_fn(void *private, u_int cmd, int *error) +{ + struct iopwdog_softc *sc = private; + + cmd &= WD_INTERVAL; + if (cmd > 0 && cmd <= 63 + && (uint64_t)1<wdog_period * 1000000000) { + /* Valid value -> Enable watchdog */ + iopwdog_tickle(sc); + sc->armed = 1; + *error = 0; + } else { + /* Can't disable this watchdog! */ + if (sc->armed) + *error = EOPNOTSUPP; + } +} + +static int +iopwdog_attach(device_t dev) +{ + struct iopwdog_softc *sc = device_get_softc(dev); + + sc->dev = dev; + sc->armed = 0; + EVENTHANDLER_REGISTER(watchdog_list, iopwdog_watchdog_fn, sc, 0); + return (0); +} + +static device_method_t iopwdog_methods[] = { + DEVMETHOD(device_probe, iopwdog_probe), + DEVMETHOD(device_attach, iopwdog_attach), + {0, 0}, +}; + +static driver_t iopwdog_driver = { + "iopwdog", + iopwdog_methods, + sizeof(struct iopwdog_softc), +}; +static devclass_t iopwdog_devclass; + +DRIVER_MODULE(iopwdog, iq, iopwdog_driver, iopwdog_devclass, 0, 0); diff --git a/sys/arm/xscale/i8134x/i80321reg.h b/sys/arm/xscale/i8134x/i80321reg.h new file mode 100644 index 000000000000..53617f956582 --- /dev/null +++ b/sys/arm/xscale/i8134x/i80321reg.h @@ -0,0 +1,547 @@ +/* $NetBSD: i80321reg.h,v 1.14 2003/12/19 10:08:11 gavan 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 _ARM_XSCALE_I80321REG_H_ +#define _ARM_XSCALE_I80321REG_H_ + +/* + * Register definitions for the Intel 80321 (``Verde'') I/O processor, + * based on the XScale core. + */ + +/* + * Base i80321 memory map: + * + * 0x0000.0000 - 0x7fff.ffff ATU Outbound Direct Addressing Window + * 0x8000.0000 - 0x9001.ffff ATU Outbound Translation Windows + * 0x9002.0000 - 0xffff.dfff External Memory + * 0xffff.e000 - 0xffff.e8ff Peripheral Memory Mapped Registers + * 0xffff.e900 - 0xffff.ffff Reserved + */ + +#define VERDE_OUT_DIRECT_WIN_BASE 0x00000000UL +#define VERDE_OUT_DIRECT_WIN_SIZE 0x80000000UL + +#define VERDE_OUT_XLATE_MEM_WIN_SIZE 0x04000000UL +#define VERDE_OUT_XLATE_IO_WIN_SIZE 0x00010000UL + +#define VERDE_OUT_XLATE_MEM_WIN0_BASE 0x80000000UL +#define VERDE_OUT_XLATE_MEM_WIN1_BASE 0x84000000UL + +#define VERDE_OUT_XLATE_IO_WIN0_BASE 0x90000000UL + +#define VERDE_EXTMEM_BASE 0x90020000UL + +#define VERDE_PMMR_BASE 0xffffe000UL +#define VERDE_PMMR_SIZE 0x00001700UL + +/* + * Peripheral Memory Mapped Registers. Defined as offsets + * from the VERDE_PMMR_BASE. + */ +#define VERDE_ATU_BASE 0x0100 +#define VERDE_ATU_SIZE 0x0100 + +#define VERDE_MU_BASE 0x0300 +#define VERDE_MU_SIZE 0x0100 + +#define VERDE_DMA_BASE 0x0400 +#define VERDE_DMA_BASE0 (VERDE_DMA_BASE + 0x00) +#define VERDE_DMA_BASE1 (VERDE_DMA_BASE + 0x40) +#define VERDE_DMA_SIZE 0x0100 +#define VERDE_DMA_CHSIZE 0x0040 + +#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) +#define VERDE_I2C_SIZE 0x0080 +#define VERDE_I2C_CHSIZE 0x0020 + +/* + * Address Translation Unit + */ + /* 0x00 - 0x38 -- PCI configuration space header */ +#define ATU_IALR0 0x40 /* Inbound ATU Limit 0 */ +#define ATU_IATVR0 0x44 /* Inbound ATU Xlate Value 0 */ +#define ATU_ERLR 0x48 /* Expansion ROM Limit */ +#define ATU_ERTVR 0x4c /* Expansion ROM Xlate Value */ +#define ATU_IALR1 0x50 /* Inbound ATU Limit 1 */ +#define ATU_IALR2 0x54 /* Inbound ATU Limit 2 */ +#define ATU_IATVR2 0x58 /* Inbound ATU Xlate Value 2 */ +#define ATU_OIOWTVR 0x5c /* Outbound I/O Window Xlate Value */ +#define ATU_OMWTVR0 0x60 /* Outbound Mem Window Xlate Value 0 */ +#define ATU_OUMWTVR0 0x64 /* Outbound Mem Window Xlate Value 0 Upper */ +#define ATU_OMWTVR1 0x68 /* Outbound Mem Window Xlate Value 1 */ +#define ATU_OUMWTVR1 0x6c /* Outbound Mem Window Xlate Value 1 Upper */ +#define ATU_OUDWTVR 0x78 /* Outbound Mem Direct Xlate Value Upper */ +#define ATU_ATUCR 0x80 /* ATU Configuration */ +#define ATU_PCSR 0x84 /* PCI Configuration and Status */ +#define ATU_ATUISR 0x88 /* ATU Interrupt Status */ +#define ATU_ATUIMR 0x8c /* ATU Interrupt Mask */ +#define ATU_IABAR3 0x90 /* Inbound ATU Base Address 3 */ +#define ATU_IAUBAR3 0x94 /* Inbound ATU Base Address 3 Upper */ +#define ATU_IALR3 0x98 /* Inbound ATU Limit 3 */ +#define ATU_IATVR3 0x9c /* Inbound ATU Xlate Value 3 */ +#define ATU_OCCAR 0xa4 /* Outbound Configuration Cycle Address */ +#define ATU_OCCDR 0xac /* Outbound Configuration Cycle Data */ +#define ATU_MSI_PORT 0xb4 /* MSI port */ +#define ATU_PDSCR 0xbc /* PCI Bus Drive Strength Control */ +#define ATU_PCI_X_CAP_ID 0xe0 /* (1) */ +#define ATU_PCI_X_NEXT 0xe1 /* (1) */ +#define ATU_PCIXCMD 0xe2 /* PCI-X Command Register (2) */ +#define ATU_PCIXSR 0xe4 /* PCI-X Status Register */ + +#define ATUCR_DRC_ALIAS (1U << 19) +#define ATUCR_DAU2GXEN (1U << 18) +#define ATUCR_P_SERR_MA (1U << 16) +#define ATUCR_DTS (1U << 15) +#define ATUCR_P_SERR_DIE (1U << 9) +#define ATUCR_DAE (1U << 8) +#define ATUCR_BIST_IE (1U << 3) +#define ATUCR_OUT_EN (1U << 1) + +#define PCSR_DAAAPE (1U << 18) +#define PCSR_PCI_X_CAP (3U << 16) +#define PCSR_PCI_X_CAP_BORING (0 << 16) +#define PCSR_PCI_X_CAP_66 (1U << 16) +#define PCSR_PCI_X_CAP_100 (2U << 16) +#define PCSR_PCI_X_CAP_133 (3U << 16) +#define PCSR_OTQB (1U << 15) +#define PCSR_IRTQB (1U << 14) +#define PCSR_DTV (1U << 12) +#define PCSR_BUS66 (1U << 10) +#define PCSR_BUS64 (1U << 8) +#define PCSR_RIB (1U << 5) +#define PCSR_RPB (1U << 4) +#define PCSR_CCR (1U << 2) +#define PCSR_CPR (1U << 1) + +#define ATUISR_IMW1BU (1U << 14) +#define ATUISR_ISCEM (1U << 13) +#define ATUISR_RSCEM (1U << 12) +#define ATUISR_PST (1U << 11) +#define ATUISR_P_SERR_ASRT (1U << 10) +#define ATUISR_DPE (1U << 9) +#define ATUISR_BIST (1U << 8) +#define ATUISR_IBMA (1U << 7) +#define ATUISR_P_SERR_DET (1U << 4) +#define ATUISR_PMA (1U << 3) +#define ATUISR_PTAM (1U << 2) +#define ATUISR_PTAT (1U << 1) +#define ATUISR_PMPE (1U << 0) + +#define ATUIMR_IMW1BU (1U << 11) +#define ATUIMR_ISCEM (1U << 10) +#define ATUIMR_RSCEM (1U << 9) +#define ATUIMR_PST (1U << 8) +#define ATUIMR_DPE (1U << 7) +#define ATUIMR_P_SERR_ASRT (1U << 6) +#define ATUIMR_PMA (1U << 5) +#define ATUIMR_PTAM (1U << 4) +#define ATUIMR_PTAT (1U << 3) +#define ATUIMR_PMPE (1U << 2) +#define ATUIMR_IE_SERR_EN (1U << 1) +#define ATUIMR_ECC_TAE (1U << 0) + +#define PCIXCMD_MOST_1 (0 << 4) +#define PCIXCMD_MOST_2 (1 << 4) +#define PCIXCMD_MOST_3 (2 << 4) +#define PCIXCMD_MOST_4 (3 << 4) +#define PCIXCMD_MOST_8 (4 << 4) +#define PCIXCMD_MOST_12 (5 << 4) +#define PCIXCMD_MOST_16 (6 << 4) +#define PCIXCMD_MOST_32 (7 << 4) +#define PCIXCMD_MOST_MASK (7 << 4) +#define PCIXCMD_MMRBC_512 (0 << 2) +#define PCIXCMD_MMRBC_1024 (1 << 2) +#define PCIXCMD_MMRBC_2048 (2 << 2) +#define PCIXCMD_MMRBC_4096 (3 << 2) +#define PCIXCMD_MMRBC_MASK (3 << 2) +#define PCIXCMD_ERO (1U << 1) +#define PCIXCMD_DPERE (1U << 0) + +#define PCIXSR_RSCEM (1U << 29) +#define PCIXSR_DMCRS_MASK (7 << 26) +#define PCIXSR_DMOST_MASK (7 << 23) +#define PCIXSR_COMPLEX (1U << 20) +#define PCIXSR_USC (1U << 19) +#define PCIXSR_SCD (1U << 18) +#define PCIXSR_133_CAP (1U << 17) +#define PCIXSR_32PCI (1U << 16) /* 0 = 32, 1 = 64 */ +#define PCIXSR_BUSNO(x) (((x) & 0xff00) >> 8) +#define PCIXSR_DEVNO(x) (((x) & 0xf8) >> 3) +#define PCIXSR_FUNCNO(x) ((x) & 0x7) + +/* + * Memory Controller Unit + */ +#define MCU_SDIR 0x00 /* DDR SDRAM Init. Register */ +#define MCU_SDCR 0x04 /* DDR SDRAM Control Register */ +#define MCU_SDBR 0x08 /* SDRAM Base Register */ +#define MCU_SBR0 0x0c /* SDRAM Boundary 0 */ +#define MCU_SBR1 0x10 /* SDRAM Boundary 1 */ +#define MCU_ECCR 0x34 /* ECC Control Register */ +#define MCU_ELOG0 0x38 /* ECC Log 0 */ +#define MCU_ELOG1 0x3c /* ECC Log 1 */ +#define MCU_ECAR0 0x40 /* ECC address 0 */ +#define MCU_ECAR1 0x44 /* ECC address 1 */ +#define MCU_ECTST 0x48 /* ECC test register */ +#define MCU_MCISR 0x4c /* MCU Interrupt Status Register */ +#define MCU_RFR 0x50 /* Refresh Frequency Register */ +#define MCU_DBUDSR 0x54 /* Data Bus Pull-up Drive Strength */ +#define MCU_DBDDSR 0x58 /* Data Bus Pull-down Drive Strength */ +#define MCU_CUDSR 0x5c /* Clock Pull-up Drive Strength */ +#define MCU_CDDSR 0x60 /* Clock Pull-down Drive Strength */ +#define MCU_CEUDSR 0x64 /* Clock En Pull-up Drive Strength */ +#define MCU_CEDDSR 0x68 /* Clock En Pull-down Drive Strength */ +#define MCU_CSUDSR 0x6c /* Chip Sel Pull-up Drive Strength */ +#define MCU_CSDDSR 0x70 /* Chip Sel Pull-down Drive Strength */ +#define MCU_REUDSR 0x74 /* Rx En Pull-up Drive Strength */ +#define MCU_REDDSR 0x78 /* Rx En Pull-down Drive Strength */ +#define MCU_ABUDSR 0x7c /* Addr Bus Pull-up Drive Strength */ +#define MCU_ABDDSR 0x80 /* Addr Bus Pull-down Drive Strength */ +#define MCU_DSDR 0x84 /* Data Strobe Delay Register */ +#define MCU_REDR 0x88 /* Rx Enable Delay Register */ + +#define SDCR_DIMMTYPE (1U << 1) /* 0 = unbuf, 1 = reg */ +#define SDCR_BUSWIDTH (1U << 2) /* 0 = 64, 1 = 32 */ + +#define SBRx_TECH (1U << 31) +#define SBRx_BOUND 0x0000003f + +#define ECCR_SBERE (1U << 0) +#define ECCR_MBERE (1U << 1) +#define ECCR_SBECE (1U << 2) +#define ECCR_ECCEN (1U << 3) + +#define ELOGx_SYNDROME 0x000000ff +#define ELOGx_ERRTYPE (1U << 8) /* 1 = multi-bit */ +#define ELOGx_RW (1U << 12) /* 1 = write error */ + /* + * Dev ID Func Requester + * 2 0 XScale core + * 2 1 ATU + * 13 0 DMA channel 0 + * 13 1 DMA channel 1 + * 26 0 ATU + */ +#define ELOGx_REQ_DEV(x) (((x) >> 19) & 0x1f) +#define ELOGx_REQ_FUNC(x) (((x) >> 16) & 0x3) + +#define MCISR_ECC_ERR0 (1U << 0) +#define MCISR_ECC_ERR1 (1U << 1) +#define MCISR_ECC_ERRN (1U << 2) + +/* + * Timers + * + * The i80321 timer registers are available in both memory-mapped + * and coprocessor spaces. Most of the registers are read-only + * if memory-mapped, so we access them via coprocessor space. + * + * TMR0 cp6 c0,1 0xffffe7e0 + * TMR1 cp6 c1,1 0xffffe7e4 + * TCR0 cp6 c2,1 0xffffe7e8 + * TCR1 cp6 c3,1 0xffffe7ec + * TRR0 cp6 c4,1 0xffffe7f0 + * TRR1 cp6 c5,1 0xffffe7f4 + * TISR cp6 c6,1 0xffffe7f8 + * WDTCR cp6 c7,1 0xffffe7fc + */ + +#define TMRx_TC (1U << 0) +#define TMRx_ENABLE (1U << 1) +#define TMRx_RELOAD (1U << 2) +#define TMRx_CSEL_CORE (0 << 4) +#define TMRx_CSEL_CORE_div4 (1 << 4) +#define TMRx_CSEL_CORE_div8 (2 << 4) +#define TMRx_CSEL_CORE_div16 (3 << 4) + +#define TISR_TMR0 (1U << 0) +#define TISR_TMR1 (1U << 1) + +#define WDTCR_ENABLE1 0x1e1e1e1e +#define WDTCR_ENABLE2 0xe1e1e1e1 + +/* + * Interrupt Controller Unit. + * + * INTCTL cp6 c0,0 0xffffe7d0 + * INTSTR cp6 c4,0 0xffffe7d4 + * IINTSRC cp6 c8,0 0xffffe7d8 + * FINTSRC cp6 c9,0 0xffffe7dc + * PIRSR 0xffffe1ec + */ + +#define ICU_PIRSR 0x01ec +#define ICU_GPOE 0x07c4 +#define ICU_GPID 0x07c8 +#define ICU_GPOD 0x07cc + +/* + * NOTE: WE USE THE `bitXX' BITS TO INDICATE PENDING SOFTWARE + * INTERRUPTS. See i80321_icu.c + */ +#define ICU_INT_HPI 31 /* high priority interrupt */ +#define ICU_INT_XINT0 27 /* external interrupts */ +#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 */ +#define ICU_INT_DMA0E 20 /* DMA Ch 0 error */ +#define ICU_INT_MCUE 19 /* memory controller error */ +#define ICU_INT_ATUE 18 /* ATU error */ +#define ICU_INT_BIUE 17 /* bus interface unit error */ +#define ICU_INT_PMU 16 /* XScale PMU */ +#define ICU_INT_PPM 15 /* peripheral PMU */ +#define ICU_INT_BIST 14 /* ATU Start BIST */ +#define ICU_INT_MU 13 /* messaging unit */ +#define ICU_INT_I2C1 12 /* i2c unit 1 */ +#define ICU_INT_I2C0 11 /* i2c unit 0 */ +#define ICU_INT_TMR1 10 /* timer 1 */ +#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 +#define ICU_INT_DMA1_EOC 3 /* DMA1 end-of-chain */ +#define ICU_INT_DMA1_EOT 2 /* DMA1 end-of-transfer */ +#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 + */ + +#define PBIU_PBCR 0x00 /* PBIU Control Register */ +#define PBIU_PBBAR0 0x08 /* PBIU Base Address Register 0 */ +#define PBIU_PBLR0 0x0c /* PBIU Limit Register 0 */ +#define PBIU_PBBAR1 0x10 /* PBIU Base Address Register 1 */ +#define PBIU_PBLR1 0x14 /* PBIU Limit Register 1 */ +#define PBIU_PBBAR2 0x18 /* PBIU Base Address Register 2 */ +#define PBIU_PBLR2 0x1c /* PBIU Limit Register 2 */ +#define PBIU_PBBAR3 0x20 /* PBIU Base Address Register 3 */ +#define PBIU_PBLR3 0x24 /* PBIU Limit Register 3 */ +#define PBIU_PBBAR4 0x28 /* PBIU Base Address Register 4 */ +#define PBIU_PBLR4 0x2c /* PBIU Limit Register 4 */ +#define PBIU_PBBAR5 0x30 /* PBIU Base Address Register 5 */ +#define PBIU_PBLR5 0x34 /* PBIU Limit Register 5 */ +#define PBIU_DSCR 0x38 /* PBIU Drive Strength Control Reg. */ +#define PBIU_MBR0 0x40 /* PBIU Memory-less Boot Reg. 0 */ +#define PBIU_MBR1 0x60 /* PBIU Memory-less Boot Reg. 1 */ +#define PBIU_MBR2 0x64 /* PBIU Memory-less Boot Reg. 2 */ + +#define PBIU_PBCR_PBIEN (1 << 0) +#define PBIU_PBCR_PBI100 (1 << 1) +#define PBIU_PBCR_PBI66 (2 << 1) +#define PBIU_PBCR_PBI33 (3 << 1) +#define PBIU_PBCR_PBBEN (1 << 3) + +#define PBIU_PBARx_WIDTH8 (0 << 0) +#define PBIU_PBARx_WIDTH16 (1 << 0) +#define PBIU_PBARx_WIDTH32 (2 << 0) +#define PBIU_PBARx_ADWAIT4 (0 << 2) +#define PBIU_PBARx_ADWAIT8 (1 << 2) +#define PBIU_PBARx_ADWAIT12 (2 << 2) +#define PBIU_PBARx_ADWAIT16 (3 << 2) +#define PBIU_PBARx_ADWAIT20 (4 << 2) +#define PBIU_PBARx_RCWAIT1 (0 << 6) +#define PBIU_PBARx_RCWAIT4 (1 << 6) +#define PBIU_PBARx_RCWAIT8 (2 << 6) +#define PBIU_PBARx_RCWAIT12 (3 << 6) +#define PBIU_PBARx_RCWAIT16 (4 << 6) +#define PBIU_PBARx_RCWAIT20 (5 << 6) +#define PBIU_PBARx_FWE (1 << 9) +#define PBIU_BASE_MASK 0xfffff000U + +#define PBIU_PBLRx_SIZE(x) (~((x) - 1)) + +/* + * Messaging Unit + */ +#define MU_IMR0 0x0010 /* MU Inbound Message Register 0 */ +#define MU_IMR1 0x0014 /* MU Inbound Message Register 1 */ +#define MU_OMR0 0x0018 /* MU Outbound Message Register 0 */ +#define MU_OMR1 0x001c /* MU Outbound Message Register 1 */ +#define MU_IDR 0x0020 /* MU Inbound Doorbell Register */ +#define MU_IISR 0x0024 /* MU Inbound Interrupt Status Reg */ +#define MU_IIMR 0x0028 /* MU Inbound Interrupt Mask Reg */ +#define MU_ODR 0x002c /* MU Outbound Doorbell Register */ +#define MU_OISR 0x0030 /* MU Outbound Interrupt Status Reg */ +#define MU_OIMR 0x0034 /* MU Outbound Interrupt Mask Reg */ +#define MU_MUCR 0x0050 /* MU Configuration Register */ +#define MU_QBAR 0x0054 /* MU Queue Base Address Register */ +#define MU_IFHPR 0x0060 /* MU Inbound Free Head Pointer Reg */ +#define MU_IFTPR 0x0064 /* MU Inbound Free Tail Pointer Reg */ +#define MU_IPHPR 0x0068 /* MU Inbound Post Head Pointer Reg */ +#define MU_IPTPR 0x006c /* MU Inbound Post Tail Pointer Reg */ +#define MU_OFHPR 0x0070 /* MU Outbound Free Head Pointer Reg */ +#define MU_OFTPR 0x0074 /* MU Outbound Free Tail Pointer Reg */ +#define MU_OPHPR 0x0078 /* MU Outbound Post Head Pointer Reg */ +#define MU_OPTPR 0x007c /* MU Outbound Post Tail Pointer Reg */ +#define MU_IAR 0x0080 /* MU Index Address Register */ + +#define MU_IIMR_IRI (1 << 6) /* Index Register Interrupt */ +#define MU_IIMR_OFQFI (1 << 5) /* Outbound Free Queue Full Int. */ +#define MU_IIMR_IPQI (1 << 4) /* Inbound Post Queue Interrupt */ +#define MU_IIMR_EDI (1 << 3) /* Error Doorbell Interrupt */ +#define MU_IIMR_IDI (1 << 2) /* Inbound Doorbell Interrupt */ +#define MU_IIMR_IM1I (1 << 1) /* Inbound Message 1 Interrupt */ +#define MU_IIMR_IM0I (1 << 0) /* Inbound Message 0 Interrupt */ + +#endif /* _ARM_XSCALE_I80321REG_H_ */ diff --git a/sys/arm/xscale/i8134x/i80321var.h b/sys/arm/xscale/i8134x/i80321var.h new file mode 100644 index 000000000000..0fead2577a2e --- /dev/null +++ b/sys/arm/xscale/i8134x/i80321var.h @@ -0,0 +1,137 @@ +/* $NetBSD: i80321var.h,v 1.8 2003/10/06 16:06:06 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 _ARM_XSCALE_I80321VAR_H_ +#define _ARM_XSCALE_I80321VAR_H_ + +#include +#include +#include + +extern struct bus_space i80321_bs_tag; + +struct i80321_softc { + device_t dev; + bus_space_tag_t sc_st; + bus_space_handle_t sc_sh; + /* Handles for the various subregions. */ + bus_space_handle_t sc_atu_sh; + bus_space_handle_t sc_mcu_sh; + int sc_is_host; + + /* + * We expect the board-specific front-end to have already mapped + * the PCI I/O space .. it is only 64K, and I/O mappings tend to + * be smaller than a page size, so it's generally more efficient + * to map them all into virtual space in one fell swoop. + */ + vm_offset_t sc_iow_vaddr; /* I/O window vaddr */ + + /* + * Variables that define the Inbound windows. The base address of + * 0-2 are configured by a host via BARs. The xlate variable + * defines the start of the local address space that it maps to. + * The size variable defines the byte size. + * + * The first 3 windows are for incoming PCI memory read/write + * cycles from a host. The 4th window, not configured by the + * host (as it outside the normal BAR range) is the inbound + * window for PCI devices controlled by the i80321. + */ + struct { + uint32_t iwin_base_hi; + uint32_t iwin_base_lo; + uint32_t iwin_xlate; + uint32_t iwin_size; + } sc_iwin[4]; + + /* + * Variables that define the Outbound windows. + */ + struct { + uint32_t owin_xlate_lo; + uint32_t owin_xlate_hi; + } sc_owin[2]; + + /* + * This is the PCI address that the Outbound I/O + * window maps to. + */ + uint32_t sc_ioout_xlate; + + /* Bus space, DMA, and PCI tags for the PCI bus (private devices). */ + struct bus_space sc_pci_iot; + struct bus_space sc_pci_memt; + + /* GPIO state */ + uint8_t sc_gpio_dir; /* GPIO pin direction (1 == output) */ + uint8_t sc_gpio_val; /* GPIO output pin value */ + struct rman sc_irq_rman; + +}; + + +struct i80321_pci_softc { + device_t sc_dev; + bus_space_tag_t sc_st; + bus_space_handle_t sc_atu_sh; + bus_space_tag_t sc_pciio; + bus_space_tag_t sc_pcimem; + int sc_busno; + struct rman sc_mem_rman; + struct rman sc_io_rman; + struct rman sc_irq_rman; + uint32_t sc_mem; + uint32_t sc_io; +}; + +void i80321_sdram_bounds(bus_space_tag_t, bus_space_handle_t, + vm_paddr_t *, vm_size_t *); + +void i80321_attach(struct i80321_softc *); +void i80321_calibrate_delay(void); + +void i80321_bs_init(bus_space_tag_t, void *); +void i80321_io_bs_init(bus_space_tag_t, void *); +void i80321_mem_bs_init(bus_space_tag_t, void *); +extern int machdep_pci_route_interrupt(device_t pcib, device_t dev, int pin); + + +#endif /* _ARM_XSCALE_I80321VAR_H_ */ From 15baa0d59b98e699de5da7f35e19010d4fc8b4f0 Mon Sep 17 00:00:00 2001 From: mmel Date: Wed, 3 Feb 2016 09:15:44 +0000 Subject: [PATCH 016/129] ARM: Remove support for xscale i80219 and i80321 CPUs. We haven't single supported config/board with these CPUs. --- sys/arm/arm/cpufunc.c | 44 +- sys/arm/arm/elf_trampoline.c | 4 +- sys/arm/conf/NOTES | 2 - sys/arm/include/cpuconf.h | 14 +- sys/arm/include/cpufunc.h | 11 +- sys/arm/xscale/i80321/ep80219_machdep.c | 402 ----------------- sys/arm/xscale/i80321/files.ep80219 | 11 - sys/arm/xscale/i80321/files.i80219 | 11 - sys/arm/xscale/i80321/files.i80321 | 9 - sys/arm/xscale/i80321/files.iq31244 | 8 - sys/arm/xscale/i80321/i80321.c | 250 ----------- sys/arm/xscale/i80321/i80321_aau.c | 292 ------------- sys/arm/xscale/i80321/i80321_dma.c | 351 --------------- sys/arm/xscale/i80321/i80321_intr.h | 165 ------- sys/arm/xscale/i80321/i80321_mcu.c | 90 ---- sys/arm/xscale/i80321/i80321_pci.c | 401 ----------------- sys/arm/xscale/i80321/i80321_space.c | 209 --------- sys/arm/xscale/i80321/i80321_timer.c | 485 --------------------- sys/arm/xscale/i80321/i80321_wdog.c | 154 ------- sys/arm/xscale/i80321/i80321reg.h | 547 ------------------------ sys/arm/xscale/i80321/i80321var.h | 137 ------ sys/arm/xscale/i80321/iq31244_7seg.c | 390 ----------------- sys/arm/xscale/i80321/iq31244_machdep.c | 416 ------------------ sys/arm/xscale/i80321/iq80321.c | 394 ----------------- sys/arm/xscale/i80321/iq80321reg.h | 111 ----- sys/arm/xscale/i80321/iq80321var.h | 53 --- sys/arm/xscale/i80321/obio.c | 163 ------- sys/arm/xscale/i80321/obiovar.h | 58 --- sys/arm/xscale/i80321/std.ep80219 | 7 - sys/arm/xscale/i80321/std.i80219 | 5 - sys/arm/xscale/i80321/std.i80321 | 5 - sys/arm/xscale/i80321/std.iq31244 | 7 - sys/arm/xscale/i80321/uart_bus_i80321.c | 76 ---- sys/arm/xscale/i80321/uart_cpu_i80321.c | 67 --- sys/arm/xscale/i8134x/i80321reg.h | 110 +---- sys/conf/files.arm | 4 +- sys/conf/options.arm | 2 - 37 files changed, 29 insertions(+), 5436 deletions(-) delete mode 100644 sys/arm/xscale/i80321/ep80219_machdep.c delete mode 100644 sys/arm/xscale/i80321/files.ep80219 delete mode 100644 sys/arm/xscale/i80321/files.i80219 delete mode 100644 sys/arm/xscale/i80321/files.i80321 delete mode 100644 sys/arm/xscale/i80321/files.iq31244 delete mode 100644 sys/arm/xscale/i80321/i80321.c delete mode 100644 sys/arm/xscale/i80321/i80321_aau.c delete mode 100644 sys/arm/xscale/i80321/i80321_dma.c delete mode 100644 sys/arm/xscale/i80321/i80321_intr.h delete mode 100644 sys/arm/xscale/i80321/i80321_mcu.c delete mode 100644 sys/arm/xscale/i80321/i80321_pci.c delete mode 100644 sys/arm/xscale/i80321/i80321_space.c delete mode 100644 sys/arm/xscale/i80321/i80321_timer.c delete mode 100644 sys/arm/xscale/i80321/i80321_wdog.c delete mode 100644 sys/arm/xscale/i80321/i80321reg.h delete mode 100644 sys/arm/xscale/i80321/i80321var.h delete mode 100644 sys/arm/xscale/i80321/iq31244_7seg.c delete mode 100644 sys/arm/xscale/i80321/iq31244_machdep.c delete mode 100644 sys/arm/xscale/i80321/iq80321.c delete mode 100644 sys/arm/xscale/i80321/iq80321reg.h delete mode 100644 sys/arm/xscale/i80321/iq80321var.h delete mode 100644 sys/arm/xscale/i80321/obio.c delete mode 100644 sys/arm/xscale/i80321/obiovar.h delete mode 100644 sys/arm/xscale/i80321/std.ep80219 delete mode 100644 sys/arm/xscale/i80321/std.i80219 delete mode 100644 sys/arm/xscale/i80321/std.i80321 delete mode 100644 sys/arm/xscale/i80321/std.iq31244 delete mode 100644 sys/arm/xscale/i80321/uart_bus_i80321.c delete mode 100644 sys/arm/xscale/i80321/uart_cpu_i80321.c diff --git a/sys/arm/arm/cpufunc.c b/sys/arm/arm/cpufunc.c index 514a6b1a4059..2b226ef988c8 100644 --- a/sys/arm/arm/cpufunc.c +++ b/sys/arm/arm/cpufunc.c @@ -60,18 +60,7 @@ __FBSDID("$FreeBSD$"); #include #include -#if defined(CPU_XSCALE_80321) || defined(CPU_XSCALE_80219) -#include -#include -#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 #endif @@ -306,9 +295,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 */ @@ -359,8 +346,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 = { @@ -588,10 +574,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 +815,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; @@ -1207,9 +1181,8 @@ fa526_setup(void) } #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) { @@ -1276,5 +1249,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/elf_trampoline.c b/sys/arm/arm/elf_trampoline.c index 6c086ea6192c..e25a849c812b 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) diff --git a/sys/arm/conf/NOTES b/sys/arm/conf/NOTES index f4259f2324d7..db64f8ebb625 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/include/cpuconf.h b/sys/arm/include/cpuconf.h index ecee28088255..24a3b8f1c2cd 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 aad0febfa470..726c808dbedb 100644 --- a/sys/arm/include/cpufunc.h +++ b/sys/arm/include/cpufunc.h @@ -342,10 +342,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 +354,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 +393,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 diff --git a/sys/arm/xscale/i80321/ep80219_machdep.c b/sys/arm/xscale/i80321/ep80219_machdep.c deleted file mode 100644 index 6c0d1f5af410..000000000000 --- 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 -__FBSDID("$FreeBSD$"); - -#include "opt_kstack_pages.h" - -#define _ARM32_BUS_DMA_PRIVATE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#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 0eaf9db2872c..000000000000 --- 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 306376bbdd25..000000000000 --- 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 bd318af1f650..000000000000 --- 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 d28d49b3a6b1..000000000000 --- 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 e65f38df5873..000000000000 --- 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 -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include - -#define _ARM32_BUS_DMA_PRIVATE -#include -#include - -#include -#include -#include - -#include - -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 288411b71974..000000000000 --- 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 -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -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 abf7dcc970e8..000000000000 --- 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 -__FBSDID("$FreeBSD$"); -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -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 29003a05ce56..000000000000 --- 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 -#include - -#include - -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 a51a43348618..000000000000 --- 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 -__FBSDID("$FreeBSD$"); - -#include -#include -#include - -#include - -#include -#include - -/* - * 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 5f78577e8704..000000000000 --- 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 -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include "pcib_if.h" - -#include -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 64c222522cd2..000000000000 --- 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 -__FBSDID("$FreeBSD$"); - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -#include - -#include -#include - -/* 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/i80321_timer.c b/sys/arm/xscale/i80321/i80321_timer.c deleted file mode 100644 index 3b4e5a11b552..000000000000 --- a/sys/arm/xscale/i80321/i80321_timer.c +++ /dev/null @@ -1,485 +0,0 @@ -/* $NetBSD: i80321_timer.c,v 1.7 2003/07/27 04:52:28 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. - */ - -/* - * Timer/clock support for the Intel i80321 I/O processor. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CPU_XSCALE_81342 -#define ICU_INT_TIMER0 (8) /* XXX: Can't include i81342reg.h because - definitions overrides the ones from i80321reg.h - */ -#endif -#include "opt_timer.h" - -void (*i80321_hardclock_hook)(void) = NULL; -struct i80321_timer_softc { - device_t dev; -} timer_softc; - - -static unsigned i80321_timer_get_timecount(struct timecounter *tc); - - -static uint32_t counts_per_hz; - -#if defined(XSCALE_DISABLE_CCNT) || defined(CPU_XSCALE_81342) -static uint32_t offset; -static uint32_t last = -1; -#endif - -static int ticked = 0; - -#ifndef COUNTS_PER_SEC -#define COUNTS_PER_SEC 200000000 /* 200MHz */ -#endif - -#define COUNTS_PER_USEC (COUNTS_PER_SEC / 1000000) - -static struct timecounter i80321_timer_timecounter = { - i80321_timer_get_timecount, /* get_timecount */ - NULL, /* no poll_pps */ - ~0u, /* counter_mask */ -#if defined(XSCALE_DISABLE_CCNT) || defined(CPU_XSCALE_81342) - COUNTS_PER_SEC, -#else - COUNTS_PER_SEC * 3, /* frequency */ -#endif - "i80321 timer", /* name */ - 1000 /* quality */ -}; - -static int -i80321_timer_probe(device_t dev) -{ - - device_set_desc(dev, "i80321 timer"); - return (0); -} - -static int -i80321_timer_attach(device_t dev) -{ - timer_softc.dev = dev; - - return (0); -} - -static device_method_t i80321_timer_methods[] = { - DEVMETHOD(device_probe, i80321_timer_probe), - DEVMETHOD(device_attach, i80321_timer_attach), - {0, 0}, -}; - -static driver_t i80321_timer_driver = { - "itimer", - i80321_timer_methods, - sizeof(struct i80321_timer_softc), -}; -static devclass_t i80321_timer_devclass; - -DRIVER_MODULE(itimer, iq, i80321_timer_driver, i80321_timer_devclass, 0, 0); - -int clockhandler(void *); - - -static __inline uint32_t -tmr1_read(void) -{ - uint32_t rv; - -#ifdef CPU_XSCALE_81342 - __asm __volatile("mrc p6, 0, %0, c1, c9, 0" -#else - __asm __volatile("mrc p6, 0, %0, c1, c1, 0" -#endif - : "=r" (rv)); - return (rv); -} - -static __inline void -tmr1_write(uint32_t val) -{ - - -#ifdef CPU_XSCALE_81342 - __asm __volatile("mcr p6, 0, %0, c1, c9, 0" -#else - __asm __volatile("mcr p6, 0, %0, c1, c1, 0" -#endif - : - : "r" (val)); -} - -static __inline uint32_t -tcr1_read(void) -{ - uint32_t rv; - -#ifdef CPU_XSCALE_81342 - __asm __volatile("mrc p6, 0, %0, c3, c9, 0" -#else - __asm __volatile("mrc p6, 0, %0, c3, c1, 0" -#endif - : "=r" (rv)); - return (rv); -} -static __inline void -tcr1_write(uint32_t val) -{ - -#ifdef CPU_XSCALE_81342 - __asm __volatile("mcr p6, 0, %0, c3, c9, 0" -#else - __asm __volatile("mcr p6, 0, %0, c3, c1, 0" -#endif - : - : "r" (val)); -} - -static __inline void -trr1_write(uint32_t val) -{ - -#ifdef CPU_XSCALE_81342 - __asm __volatile("mcr p6, 0, %0, c5, c9, 0" -#else - __asm __volatile("mcr p6, 0, %0, c5, c1, 0" -#endif - : - : "r" (val)); -} - -static __inline uint32_t -tmr0_read(void) -{ - uint32_t rv; - -#ifdef CPU_XSCALE_81342 - __asm __volatile("mrc p6, 0, %0, c0, c9, 0" -#else - __asm __volatile("mrc p6, 0, %0, c0, c1, 0" -#endif - : "=r" (rv)); - return (rv); -} - -static __inline void -tmr0_write(uint32_t val) -{ - -#ifdef CPU_XSCALE_81342 - __asm __volatile("mcr p6, 0, %0, c0, c9, 0" -#else - __asm __volatile("mcr p6, 0, %0, c0, c1, 0" -#endif - : - : "r" (val)); -} - -static __inline uint32_t -tcr0_read(void) -{ - uint32_t rv; - -#ifdef CPU_XSCALE_81342 - __asm __volatile("mrc p6, 0, %0, c2, c9, 0" -#else - __asm __volatile("mrc p6, 0, %0, c2, c1, 0" -#endif - : "=r" (rv)); - return (rv); -} -static __inline void -tcr0_write(uint32_t val) -{ - -#ifdef CPU_XSCALE_81342 - __asm __volatile("mcr p6, 0, %0, c2, c9, 0" -#else - __asm __volatile("mcr p6, 0, %0, c2, c1, 0" -#endif - : - : "r" (val)); -} - -static __inline void -trr0_write(uint32_t val) -{ - -#ifdef CPU_XSCALE_81342 - __asm __volatile("mcr p6, 0, %0, c4, c9, 0" -#else - __asm __volatile("mcr p6, 0, %0, c4, c1, 0" -#endif - : - : "r" (val)); -} - -static __inline void -tisr_write(uint32_t val) -{ - -#ifdef CPU_XSCALE_81342 - __asm __volatile("mcr p6, 0, %0, c6, c9, 0" -#else - __asm __volatile("mcr p6, 0, %0, c6, c1, 0" -#endif - : - : "r" (val)); -} - -static __inline uint32_t -tisr_read(void) -{ - int ret; - -#ifdef CPU_XSCALE_81342 - __asm __volatile("mrc p6, 0, %0, c6, c9, 0" : "=r" (ret)); -#else - __asm __volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (ret)); -#endif - return (ret); -} - -static unsigned -i80321_timer_get_timecount(struct timecounter *tc) -{ -#if defined(XSCALE_DISABLE_CCNT) || defined(CPU_XSCALE_81342) - uint32_t cur = tcr0_read(); - - if (cur > last && last != -1) { - offset += counts_per_hz; - if (ticked > 0) - ticked--; - } - if (ticked) { - offset += ticked * counts_per_hz; - ticked = 0; - } - return (counts_per_hz - cur + offset); -#else - uint32_t ret; - - __asm __volatile("mrc p14, 0, %0, c1, c0, 0\n" - : "=r" (ret)); - return (ret); -#endif -} - -/* - * i80321_calibrate_delay: - * - * Calibrate the delay loop. - */ -void -i80321_calibrate_delay(void) -{ - - /* - * Just use hz=100 for now -- we'll adjust it, if necessary, - * in cpu_initclocks(). - */ - counts_per_hz = COUNTS_PER_SEC / 100; - - tmr0_write(0); /* stop timer */ - tisr_write(TISR_TMR0); /* clear interrupt */ - trr0_write(counts_per_hz); /* reload value */ - tcr0_write(counts_per_hz); /* current value */ - - tmr0_write(TMRx_ENABLE|TMRx_RELOAD|TMRx_CSEL_CORE); -} - -/* - * cpu_initclocks: - * - * Initialize the clock and get them going. - */ -void -cpu_initclocks(void) -{ - u_int oldirqstate; - struct resource *irq; - int rid = 0; - void *ihl; - device_t dev = timer_softc.dev; - - if (hz < 50 || COUNTS_PER_SEC % hz) { - printf("Cannot get %d Hz clock; using 100 Hz\n", hz); - hz = 100; - } - tick = 1000000 / hz; /* number of microseconds between interrupts */ - - /* - * We only have one timer available; stathz and profhz are - * always left as 0 (the upper-layer clock code deals with - * this situation). - */ - if (stathz != 0) - printf("Cannot get %d Hz statclock\n", stathz); - stathz = 0; - - if (profhz != 0) - printf("Cannot get %d Hz profclock\n", profhz); - profhz = 0; - - /* Report the clock frequency. */ - - oldirqstate = disable_interrupts(PSR_I); - - irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, -#ifdef CPU_XSCALE_81342 - ICU_INT_TIMER0, ICU_INT_TIMER0, -#else - ICU_INT_TMR0, ICU_INT_TMR0, -#endif - 1, RF_ACTIVE); - if (!irq) - panic("Unable to setup the clock irq handler.\n"); - else - bus_setup_intr(dev, irq, INTR_TYPE_CLK, clockhandler, NULL, - NULL, &ihl); - tmr0_write(0); /* stop timer */ - tisr_write(TISR_TMR0); /* clear interrupt */ - - counts_per_hz = COUNTS_PER_SEC / hz; - - trr0_write(counts_per_hz); /* reload value */ - tcr0_write(counts_per_hz); /* current value */ - tmr0_write(TMRx_ENABLE|TMRx_RELOAD|TMRx_CSEL_CORE); - - tc_init(&i80321_timer_timecounter); - restore_interrupts(oldirqstate); - rid = 0; -#if !defined(XSCALE_DISABLE_CCNT) && !defined(CPU_XSCALE_81342) - /* Enable the clock count register. */ - __asm __volatile("mrc p14, 0, %0, c0, c0, 0\n" : "=r" (rid)); - rid &= ~(1 << 3); - rid |= (1 << 2) | 1; - __asm __volatile("mcr p14, 0, %0, c0, c0, 0\n" - : : "r" (rid)); -#endif -} - - -/* - * DELAY: - * - * Delay for at least N microseconds. - */ -void -DELAY(int n) -{ - uint32_t cur, last, delta, usecs; - - /* - * This works by polling the timer and counting the - * number of microseconds that go by. - */ - last = tcr0_read(); - delta = usecs = 0; - - while (n > usecs) { - cur = tcr0_read(); - - /* Check to see if the timer has wrapped around. */ - if (last < cur) - delta += (last + (counts_per_hz - cur)); - else - delta += (last - cur); - - last = cur; - - if (delta >= COUNTS_PER_USEC) { - usecs += delta / COUNTS_PER_USEC; - delta %= COUNTS_PER_USEC; - } - } -} - -/* - * clockhandler: - * - * Handle the hardclock interrupt. - */ -int -clockhandler(void *arg) -{ - struct trapframe *frame = arg; - - ticked++; - tisr_write(TISR_TMR0); - hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame)); - - if (i80321_hardclock_hook != NULL) - (*i80321_hardclock_hook)(); - return (FILTER_HANDLED); -} - -void -cpu_startprofclock(void) -{ -} - -void -cpu_stopprofclock(void) -{ - -} diff --git a/sys/arm/xscale/i80321/i80321_wdog.c b/sys/arm/xscale/i80321/i80321_wdog.c deleted file mode 100644 index 9be98d2f7e25..000000000000 --- a/sys/arm/xscale/i80321/i80321_wdog.c +++ /dev/null @@ -1,154 +0,0 @@ -/* $NetBSD: i80321_wdog.c,v 1.6 2003/07/15 00:24:54 lukem Exp $ */ - -/*- - * Copyright (c) 2005 Olivier Houchard - * 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. - */ - -/* - * Watchdog timer support for the Intel i80321 I/O processor. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - - -struct iopwdog_softc { - device_t dev; - int armed; - int wdog_period; -}; - -static __inline void -wdtcr_write(uint32_t val) -{ - -#ifdef CPU_XSCALE_81342 - __asm __volatile("mcr p6, 0, %0, c7, c9, 0" -#else - __asm __volatile("mcr p6, 0, %0, c7, c1, 0" -#endif - : - : "r" (val)); -} - -static void -iopwdog_tickle(void *arg) -{ - struct iopwdog_softc *sc = arg; - - if (!sc->armed) - return; - wdtcr_write(WDTCR_ENABLE1); - wdtcr_write(WDTCR_ENABLE2); -} - -static int -iopwdog_probe(device_t dev) -{ - struct iopwdog_softc *sc = device_get_softc(dev); - char buf[128]; - - /* - * XXX Should compute the period based on processor speed. - * For a 600MHz XScale core, the wdog must be tickled approx. - * every 7 seconds. - */ - - sc->wdog_period = 7; - sprintf(buf, "i80321 Watchdog, must be tickled every %d seconds", - sc->wdog_period); - device_set_desc_copy(dev, buf); - - return (0); -} - -static void -iopwdog_watchdog_fn(void *private, u_int cmd, int *error) -{ - struct iopwdog_softc *sc = private; - - cmd &= WD_INTERVAL; - if (cmd > 0 && cmd <= 63 - && (uint64_t)1<wdog_period * 1000000000) { - /* Valid value -> Enable watchdog */ - iopwdog_tickle(sc); - sc->armed = 1; - *error = 0; - } else { - /* Can't disable this watchdog! */ - if (sc->armed) - *error = EOPNOTSUPP; - } -} - -static int -iopwdog_attach(device_t dev) -{ - struct iopwdog_softc *sc = device_get_softc(dev); - - sc->dev = dev; - sc->armed = 0; - EVENTHANDLER_REGISTER(watchdog_list, iopwdog_watchdog_fn, sc, 0); - return (0); -} - -static device_method_t iopwdog_methods[] = { - DEVMETHOD(device_probe, iopwdog_probe), - DEVMETHOD(device_attach, iopwdog_attach), - {0, 0}, -}; - -static driver_t iopwdog_driver = { - "iopwdog", - iopwdog_methods, - sizeof(struct iopwdog_softc), -}; -static devclass_t iopwdog_devclass; - -DRIVER_MODULE(iopwdog, iq, iopwdog_driver, iopwdog_devclass, 0, 0); diff --git a/sys/arm/xscale/i80321/i80321reg.h b/sys/arm/xscale/i80321/i80321reg.h deleted file mode 100644 index 53617f956582..000000000000 --- a/sys/arm/xscale/i80321/i80321reg.h +++ /dev/null @@ -1,547 +0,0 @@ -/* $NetBSD: i80321reg.h,v 1.14 2003/12/19 10:08:11 gavan 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 _ARM_XSCALE_I80321REG_H_ -#define _ARM_XSCALE_I80321REG_H_ - -/* - * Register definitions for the Intel 80321 (``Verde'') I/O processor, - * based on the XScale core. - */ - -/* - * Base i80321 memory map: - * - * 0x0000.0000 - 0x7fff.ffff ATU Outbound Direct Addressing Window - * 0x8000.0000 - 0x9001.ffff ATU Outbound Translation Windows - * 0x9002.0000 - 0xffff.dfff External Memory - * 0xffff.e000 - 0xffff.e8ff Peripheral Memory Mapped Registers - * 0xffff.e900 - 0xffff.ffff Reserved - */ - -#define VERDE_OUT_DIRECT_WIN_BASE 0x00000000UL -#define VERDE_OUT_DIRECT_WIN_SIZE 0x80000000UL - -#define VERDE_OUT_XLATE_MEM_WIN_SIZE 0x04000000UL -#define VERDE_OUT_XLATE_IO_WIN_SIZE 0x00010000UL - -#define VERDE_OUT_XLATE_MEM_WIN0_BASE 0x80000000UL -#define VERDE_OUT_XLATE_MEM_WIN1_BASE 0x84000000UL - -#define VERDE_OUT_XLATE_IO_WIN0_BASE 0x90000000UL - -#define VERDE_EXTMEM_BASE 0x90020000UL - -#define VERDE_PMMR_BASE 0xffffe000UL -#define VERDE_PMMR_SIZE 0x00001700UL - -/* - * Peripheral Memory Mapped Registers. Defined as offsets - * from the VERDE_PMMR_BASE. - */ -#define VERDE_ATU_BASE 0x0100 -#define VERDE_ATU_SIZE 0x0100 - -#define VERDE_MU_BASE 0x0300 -#define VERDE_MU_SIZE 0x0100 - -#define VERDE_DMA_BASE 0x0400 -#define VERDE_DMA_BASE0 (VERDE_DMA_BASE + 0x00) -#define VERDE_DMA_BASE1 (VERDE_DMA_BASE + 0x40) -#define VERDE_DMA_SIZE 0x0100 -#define VERDE_DMA_CHSIZE 0x0040 - -#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) -#define VERDE_I2C_SIZE 0x0080 -#define VERDE_I2C_CHSIZE 0x0020 - -/* - * Address Translation Unit - */ - /* 0x00 - 0x38 -- PCI configuration space header */ -#define ATU_IALR0 0x40 /* Inbound ATU Limit 0 */ -#define ATU_IATVR0 0x44 /* Inbound ATU Xlate Value 0 */ -#define ATU_ERLR 0x48 /* Expansion ROM Limit */ -#define ATU_ERTVR 0x4c /* Expansion ROM Xlate Value */ -#define ATU_IALR1 0x50 /* Inbound ATU Limit 1 */ -#define ATU_IALR2 0x54 /* Inbound ATU Limit 2 */ -#define ATU_IATVR2 0x58 /* Inbound ATU Xlate Value 2 */ -#define ATU_OIOWTVR 0x5c /* Outbound I/O Window Xlate Value */ -#define ATU_OMWTVR0 0x60 /* Outbound Mem Window Xlate Value 0 */ -#define ATU_OUMWTVR0 0x64 /* Outbound Mem Window Xlate Value 0 Upper */ -#define ATU_OMWTVR1 0x68 /* Outbound Mem Window Xlate Value 1 */ -#define ATU_OUMWTVR1 0x6c /* Outbound Mem Window Xlate Value 1 Upper */ -#define ATU_OUDWTVR 0x78 /* Outbound Mem Direct Xlate Value Upper */ -#define ATU_ATUCR 0x80 /* ATU Configuration */ -#define ATU_PCSR 0x84 /* PCI Configuration and Status */ -#define ATU_ATUISR 0x88 /* ATU Interrupt Status */ -#define ATU_ATUIMR 0x8c /* ATU Interrupt Mask */ -#define ATU_IABAR3 0x90 /* Inbound ATU Base Address 3 */ -#define ATU_IAUBAR3 0x94 /* Inbound ATU Base Address 3 Upper */ -#define ATU_IALR3 0x98 /* Inbound ATU Limit 3 */ -#define ATU_IATVR3 0x9c /* Inbound ATU Xlate Value 3 */ -#define ATU_OCCAR 0xa4 /* Outbound Configuration Cycle Address */ -#define ATU_OCCDR 0xac /* Outbound Configuration Cycle Data */ -#define ATU_MSI_PORT 0xb4 /* MSI port */ -#define ATU_PDSCR 0xbc /* PCI Bus Drive Strength Control */ -#define ATU_PCI_X_CAP_ID 0xe0 /* (1) */ -#define ATU_PCI_X_NEXT 0xe1 /* (1) */ -#define ATU_PCIXCMD 0xe2 /* PCI-X Command Register (2) */ -#define ATU_PCIXSR 0xe4 /* PCI-X Status Register */ - -#define ATUCR_DRC_ALIAS (1U << 19) -#define ATUCR_DAU2GXEN (1U << 18) -#define ATUCR_P_SERR_MA (1U << 16) -#define ATUCR_DTS (1U << 15) -#define ATUCR_P_SERR_DIE (1U << 9) -#define ATUCR_DAE (1U << 8) -#define ATUCR_BIST_IE (1U << 3) -#define ATUCR_OUT_EN (1U << 1) - -#define PCSR_DAAAPE (1U << 18) -#define PCSR_PCI_X_CAP (3U << 16) -#define PCSR_PCI_X_CAP_BORING (0 << 16) -#define PCSR_PCI_X_CAP_66 (1U << 16) -#define PCSR_PCI_X_CAP_100 (2U << 16) -#define PCSR_PCI_X_CAP_133 (3U << 16) -#define PCSR_OTQB (1U << 15) -#define PCSR_IRTQB (1U << 14) -#define PCSR_DTV (1U << 12) -#define PCSR_BUS66 (1U << 10) -#define PCSR_BUS64 (1U << 8) -#define PCSR_RIB (1U << 5) -#define PCSR_RPB (1U << 4) -#define PCSR_CCR (1U << 2) -#define PCSR_CPR (1U << 1) - -#define ATUISR_IMW1BU (1U << 14) -#define ATUISR_ISCEM (1U << 13) -#define ATUISR_RSCEM (1U << 12) -#define ATUISR_PST (1U << 11) -#define ATUISR_P_SERR_ASRT (1U << 10) -#define ATUISR_DPE (1U << 9) -#define ATUISR_BIST (1U << 8) -#define ATUISR_IBMA (1U << 7) -#define ATUISR_P_SERR_DET (1U << 4) -#define ATUISR_PMA (1U << 3) -#define ATUISR_PTAM (1U << 2) -#define ATUISR_PTAT (1U << 1) -#define ATUISR_PMPE (1U << 0) - -#define ATUIMR_IMW1BU (1U << 11) -#define ATUIMR_ISCEM (1U << 10) -#define ATUIMR_RSCEM (1U << 9) -#define ATUIMR_PST (1U << 8) -#define ATUIMR_DPE (1U << 7) -#define ATUIMR_P_SERR_ASRT (1U << 6) -#define ATUIMR_PMA (1U << 5) -#define ATUIMR_PTAM (1U << 4) -#define ATUIMR_PTAT (1U << 3) -#define ATUIMR_PMPE (1U << 2) -#define ATUIMR_IE_SERR_EN (1U << 1) -#define ATUIMR_ECC_TAE (1U << 0) - -#define PCIXCMD_MOST_1 (0 << 4) -#define PCIXCMD_MOST_2 (1 << 4) -#define PCIXCMD_MOST_3 (2 << 4) -#define PCIXCMD_MOST_4 (3 << 4) -#define PCIXCMD_MOST_8 (4 << 4) -#define PCIXCMD_MOST_12 (5 << 4) -#define PCIXCMD_MOST_16 (6 << 4) -#define PCIXCMD_MOST_32 (7 << 4) -#define PCIXCMD_MOST_MASK (7 << 4) -#define PCIXCMD_MMRBC_512 (0 << 2) -#define PCIXCMD_MMRBC_1024 (1 << 2) -#define PCIXCMD_MMRBC_2048 (2 << 2) -#define PCIXCMD_MMRBC_4096 (3 << 2) -#define PCIXCMD_MMRBC_MASK (3 << 2) -#define PCIXCMD_ERO (1U << 1) -#define PCIXCMD_DPERE (1U << 0) - -#define PCIXSR_RSCEM (1U << 29) -#define PCIXSR_DMCRS_MASK (7 << 26) -#define PCIXSR_DMOST_MASK (7 << 23) -#define PCIXSR_COMPLEX (1U << 20) -#define PCIXSR_USC (1U << 19) -#define PCIXSR_SCD (1U << 18) -#define PCIXSR_133_CAP (1U << 17) -#define PCIXSR_32PCI (1U << 16) /* 0 = 32, 1 = 64 */ -#define PCIXSR_BUSNO(x) (((x) & 0xff00) >> 8) -#define PCIXSR_DEVNO(x) (((x) & 0xf8) >> 3) -#define PCIXSR_FUNCNO(x) ((x) & 0x7) - -/* - * Memory Controller Unit - */ -#define MCU_SDIR 0x00 /* DDR SDRAM Init. Register */ -#define MCU_SDCR 0x04 /* DDR SDRAM Control Register */ -#define MCU_SDBR 0x08 /* SDRAM Base Register */ -#define MCU_SBR0 0x0c /* SDRAM Boundary 0 */ -#define MCU_SBR1 0x10 /* SDRAM Boundary 1 */ -#define MCU_ECCR 0x34 /* ECC Control Register */ -#define MCU_ELOG0 0x38 /* ECC Log 0 */ -#define MCU_ELOG1 0x3c /* ECC Log 1 */ -#define MCU_ECAR0 0x40 /* ECC address 0 */ -#define MCU_ECAR1 0x44 /* ECC address 1 */ -#define MCU_ECTST 0x48 /* ECC test register */ -#define MCU_MCISR 0x4c /* MCU Interrupt Status Register */ -#define MCU_RFR 0x50 /* Refresh Frequency Register */ -#define MCU_DBUDSR 0x54 /* Data Bus Pull-up Drive Strength */ -#define MCU_DBDDSR 0x58 /* Data Bus Pull-down Drive Strength */ -#define MCU_CUDSR 0x5c /* Clock Pull-up Drive Strength */ -#define MCU_CDDSR 0x60 /* Clock Pull-down Drive Strength */ -#define MCU_CEUDSR 0x64 /* Clock En Pull-up Drive Strength */ -#define MCU_CEDDSR 0x68 /* Clock En Pull-down Drive Strength */ -#define MCU_CSUDSR 0x6c /* Chip Sel Pull-up Drive Strength */ -#define MCU_CSDDSR 0x70 /* Chip Sel Pull-down Drive Strength */ -#define MCU_REUDSR 0x74 /* Rx En Pull-up Drive Strength */ -#define MCU_REDDSR 0x78 /* Rx En Pull-down Drive Strength */ -#define MCU_ABUDSR 0x7c /* Addr Bus Pull-up Drive Strength */ -#define MCU_ABDDSR 0x80 /* Addr Bus Pull-down Drive Strength */ -#define MCU_DSDR 0x84 /* Data Strobe Delay Register */ -#define MCU_REDR 0x88 /* Rx Enable Delay Register */ - -#define SDCR_DIMMTYPE (1U << 1) /* 0 = unbuf, 1 = reg */ -#define SDCR_BUSWIDTH (1U << 2) /* 0 = 64, 1 = 32 */ - -#define SBRx_TECH (1U << 31) -#define SBRx_BOUND 0x0000003f - -#define ECCR_SBERE (1U << 0) -#define ECCR_MBERE (1U << 1) -#define ECCR_SBECE (1U << 2) -#define ECCR_ECCEN (1U << 3) - -#define ELOGx_SYNDROME 0x000000ff -#define ELOGx_ERRTYPE (1U << 8) /* 1 = multi-bit */ -#define ELOGx_RW (1U << 12) /* 1 = write error */ - /* - * Dev ID Func Requester - * 2 0 XScale core - * 2 1 ATU - * 13 0 DMA channel 0 - * 13 1 DMA channel 1 - * 26 0 ATU - */ -#define ELOGx_REQ_DEV(x) (((x) >> 19) & 0x1f) -#define ELOGx_REQ_FUNC(x) (((x) >> 16) & 0x3) - -#define MCISR_ECC_ERR0 (1U << 0) -#define MCISR_ECC_ERR1 (1U << 1) -#define MCISR_ECC_ERRN (1U << 2) - -/* - * Timers - * - * The i80321 timer registers are available in both memory-mapped - * and coprocessor spaces. Most of the registers are read-only - * if memory-mapped, so we access them via coprocessor space. - * - * TMR0 cp6 c0,1 0xffffe7e0 - * TMR1 cp6 c1,1 0xffffe7e4 - * TCR0 cp6 c2,1 0xffffe7e8 - * TCR1 cp6 c3,1 0xffffe7ec - * TRR0 cp6 c4,1 0xffffe7f0 - * TRR1 cp6 c5,1 0xffffe7f4 - * TISR cp6 c6,1 0xffffe7f8 - * WDTCR cp6 c7,1 0xffffe7fc - */ - -#define TMRx_TC (1U << 0) -#define TMRx_ENABLE (1U << 1) -#define TMRx_RELOAD (1U << 2) -#define TMRx_CSEL_CORE (0 << 4) -#define TMRx_CSEL_CORE_div4 (1 << 4) -#define TMRx_CSEL_CORE_div8 (2 << 4) -#define TMRx_CSEL_CORE_div16 (3 << 4) - -#define TISR_TMR0 (1U << 0) -#define TISR_TMR1 (1U << 1) - -#define WDTCR_ENABLE1 0x1e1e1e1e -#define WDTCR_ENABLE2 0xe1e1e1e1 - -/* - * Interrupt Controller Unit. - * - * INTCTL cp6 c0,0 0xffffe7d0 - * INTSTR cp6 c4,0 0xffffe7d4 - * IINTSRC cp6 c8,0 0xffffe7d8 - * FINTSRC cp6 c9,0 0xffffe7dc - * PIRSR 0xffffe1ec - */ - -#define ICU_PIRSR 0x01ec -#define ICU_GPOE 0x07c4 -#define ICU_GPID 0x07c8 -#define ICU_GPOD 0x07cc - -/* - * NOTE: WE USE THE `bitXX' BITS TO INDICATE PENDING SOFTWARE - * INTERRUPTS. See i80321_icu.c - */ -#define ICU_INT_HPI 31 /* high priority interrupt */ -#define ICU_INT_XINT0 27 /* external interrupts */ -#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 */ -#define ICU_INT_DMA0E 20 /* DMA Ch 0 error */ -#define ICU_INT_MCUE 19 /* memory controller error */ -#define ICU_INT_ATUE 18 /* ATU error */ -#define ICU_INT_BIUE 17 /* bus interface unit error */ -#define ICU_INT_PMU 16 /* XScale PMU */ -#define ICU_INT_PPM 15 /* peripheral PMU */ -#define ICU_INT_BIST 14 /* ATU Start BIST */ -#define ICU_INT_MU 13 /* messaging unit */ -#define ICU_INT_I2C1 12 /* i2c unit 1 */ -#define ICU_INT_I2C0 11 /* i2c unit 0 */ -#define ICU_INT_TMR1 10 /* timer 1 */ -#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 -#define ICU_INT_DMA1_EOC 3 /* DMA1 end-of-chain */ -#define ICU_INT_DMA1_EOT 2 /* DMA1 end-of-transfer */ -#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 - */ - -#define PBIU_PBCR 0x00 /* PBIU Control Register */ -#define PBIU_PBBAR0 0x08 /* PBIU Base Address Register 0 */ -#define PBIU_PBLR0 0x0c /* PBIU Limit Register 0 */ -#define PBIU_PBBAR1 0x10 /* PBIU Base Address Register 1 */ -#define PBIU_PBLR1 0x14 /* PBIU Limit Register 1 */ -#define PBIU_PBBAR2 0x18 /* PBIU Base Address Register 2 */ -#define PBIU_PBLR2 0x1c /* PBIU Limit Register 2 */ -#define PBIU_PBBAR3 0x20 /* PBIU Base Address Register 3 */ -#define PBIU_PBLR3 0x24 /* PBIU Limit Register 3 */ -#define PBIU_PBBAR4 0x28 /* PBIU Base Address Register 4 */ -#define PBIU_PBLR4 0x2c /* PBIU Limit Register 4 */ -#define PBIU_PBBAR5 0x30 /* PBIU Base Address Register 5 */ -#define PBIU_PBLR5 0x34 /* PBIU Limit Register 5 */ -#define PBIU_DSCR 0x38 /* PBIU Drive Strength Control Reg. */ -#define PBIU_MBR0 0x40 /* PBIU Memory-less Boot Reg. 0 */ -#define PBIU_MBR1 0x60 /* PBIU Memory-less Boot Reg. 1 */ -#define PBIU_MBR2 0x64 /* PBIU Memory-less Boot Reg. 2 */ - -#define PBIU_PBCR_PBIEN (1 << 0) -#define PBIU_PBCR_PBI100 (1 << 1) -#define PBIU_PBCR_PBI66 (2 << 1) -#define PBIU_PBCR_PBI33 (3 << 1) -#define PBIU_PBCR_PBBEN (1 << 3) - -#define PBIU_PBARx_WIDTH8 (0 << 0) -#define PBIU_PBARx_WIDTH16 (1 << 0) -#define PBIU_PBARx_WIDTH32 (2 << 0) -#define PBIU_PBARx_ADWAIT4 (0 << 2) -#define PBIU_PBARx_ADWAIT8 (1 << 2) -#define PBIU_PBARx_ADWAIT12 (2 << 2) -#define PBIU_PBARx_ADWAIT16 (3 << 2) -#define PBIU_PBARx_ADWAIT20 (4 << 2) -#define PBIU_PBARx_RCWAIT1 (0 << 6) -#define PBIU_PBARx_RCWAIT4 (1 << 6) -#define PBIU_PBARx_RCWAIT8 (2 << 6) -#define PBIU_PBARx_RCWAIT12 (3 << 6) -#define PBIU_PBARx_RCWAIT16 (4 << 6) -#define PBIU_PBARx_RCWAIT20 (5 << 6) -#define PBIU_PBARx_FWE (1 << 9) -#define PBIU_BASE_MASK 0xfffff000U - -#define PBIU_PBLRx_SIZE(x) (~((x) - 1)) - -/* - * Messaging Unit - */ -#define MU_IMR0 0x0010 /* MU Inbound Message Register 0 */ -#define MU_IMR1 0x0014 /* MU Inbound Message Register 1 */ -#define MU_OMR0 0x0018 /* MU Outbound Message Register 0 */ -#define MU_OMR1 0x001c /* MU Outbound Message Register 1 */ -#define MU_IDR 0x0020 /* MU Inbound Doorbell Register */ -#define MU_IISR 0x0024 /* MU Inbound Interrupt Status Reg */ -#define MU_IIMR 0x0028 /* MU Inbound Interrupt Mask Reg */ -#define MU_ODR 0x002c /* MU Outbound Doorbell Register */ -#define MU_OISR 0x0030 /* MU Outbound Interrupt Status Reg */ -#define MU_OIMR 0x0034 /* MU Outbound Interrupt Mask Reg */ -#define MU_MUCR 0x0050 /* MU Configuration Register */ -#define MU_QBAR 0x0054 /* MU Queue Base Address Register */ -#define MU_IFHPR 0x0060 /* MU Inbound Free Head Pointer Reg */ -#define MU_IFTPR 0x0064 /* MU Inbound Free Tail Pointer Reg */ -#define MU_IPHPR 0x0068 /* MU Inbound Post Head Pointer Reg */ -#define MU_IPTPR 0x006c /* MU Inbound Post Tail Pointer Reg */ -#define MU_OFHPR 0x0070 /* MU Outbound Free Head Pointer Reg */ -#define MU_OFTPR 0x0074 /* MU Outbound Free Tail Pointer Reg */ -#define MU_OPHPR 0x0078 /* MU Outbound Post Head Pointer Reg */ -#define MU_OPTPR 0x007c /* MU Outbound Post Tail Pointer Reg */ -#define MU_IAR 0x0080 /* MU Index Address Register */ - -#define MU_IIMR_IRI (1 << 6) /* Index Register Interrupt */ -#define MU_IIMR_OFQFI (1 << 5) /* Outbound Free Queue Full Int. */ -#define MU_IIMR_IPQI (1 << 4) /* Inbound Post Queue Interrupt */ -#define MU_IIMR_EDI (1 << 3) /* Error Doorbell Interrupt */ -#define MU_IIMR_IDI (1 << 2) /* Inbound Doorbell Interrupt */ -#define MU_IIMR_IM1I (1 << 1) /* Inbound Message 1 Interrupt */ -#define MU_IIMR_IM0I (1 << 0) /* Inbound Message 0 Interrupt */ - -#endif /* _ARM_XSCALE_I80321REG_H_ */ diff --git a/sys/arm/xscale/i80321/i80321var.h b/sys/arm/xscale/i80321/i80321var.h deleted file mode 100644 index 0fead2577a2e..000000000000 --- a/sys/arm/xscale/i80321/i80321var.h +++ /dev/null @@ -1,137 +0,0 @@ -/* $NetBSD: i80321var.h,v 1.8 2003/10/06 16:06:06 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 _ARM_XSCALE_I80321VAR_H_ -#define _ARM_XSCALE_I80321VAR_H_ - -#include -#include -#include - -extern struct bus_space i80321_bs_tag; - -struct i80321_softc { - device_t dev; - bus_space_tag_t sc_st; - bus_space_handle_t sc_sh; - /* Handles for the various subregions. */ - bus_space_handle_t sc_atu_sh; - bus_space_handle_t sc_mcu_sh; - int sc_is_host; - - /* - * We expect the board-specific front-end to have already mapped - * the PCI I/O space .. it is only 64K, and I/O mappings tend to - * be smaller than a page size, so it's generally more efficient - * to map them all into virtual space in one fell swoop. - */ - vm_offset_t sc_iow_vaddr; /* I/O window vaddr */ - - /* - * Variables that define the Inbound windows. The base address of - * 0-2 are configured by a host via BARs. The xlate variable - * defines the start of the local address space that it maps to. - * The size variable defines the byte size. - * - * The first 3 windows are for incoming PCI memory read/write - * cycles from a host. The 4th window, not configured by the - * host (as it outside the normal BAR range) is the inbound - * window for PCI devices controlled by the i80321. - */ - struct { - uint32_t iwin_base_hi; - uint32_t iwin_base_lo; - uint32_t iwin_xlate; - uint32_t iwin_size; - } sc_iwin[4]; - - /* - * Variables that define the Outbound windows. - */ - struct { - uint32_t owin_xlate_lo; - uint32_t owin_xlate_hi; - } sc_owin[2]; - - /* - * This is the PCI address that the Outbound I/O - * window maps to. - */ - uint32_t sc_ioout_xlate; - - /* Bus space, DMA, and PCI tags for the PCI bus (private devices). */ - struct bus_space sc_pci_iot; - struct bus_space sc_pci_memt; - - /* GPIO state */ - uint8_t sc_gpio_dir; /* GPIO pin direction (1 == output) */ - uint8_t sc_gpio_val; /* GPIO output pin value */ - struct rman sc_irq_rman; - -}; - - -struct i80321_pci_softc { - device_t sc_dev; - bus_space_tag_t sc_st; - bus_space_handle_t sc_atu_sh; - bus_space_tag_t sc_pciio; - bus_space_tag_t sc_pcimem; - int sc_busno; - struct rman sc_mem_rman; - struct rman sc_io_rman; - struct rman sc_irq_rman; - uint32_t sc_mem; - uint32_t sc_io; -}; - -void i80321_sdram_bounds(bus_space_tag_t, bus_space_handle_t, - vm_paddr_t *, vm_size_t *); - -void i80321_attach(struct i80321_softc *); -void i80321_calibrate_delay(void); - -void i80321_bs_init(bus_space_tag_t, void *); -void i80321_io_bs_init(bus_space_tag_t, void *); -void i80321_mem_bs_init(bus_space_tag_t, void *); -extern int machdep_pci_route_interrupt(device_t pcib, device_t dev, int pin); - - -#endif /* _ARM_XSCALE_I80321VAR_H_ */ diff --git a/sys/arm/xscale/i80321/iq31244_7seg.c b/sys/arm/xscale/i80321/iq31244_7seg.c deleted file mode 100644 index 3737094b2172..000000000000 --- 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 -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#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 eb19f78d2a3e..000000000000 --- 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 -__FBSDID("$FreeBSD$"); - -#include "opt_kstack_pages.h" - -#define _ARM32_BUS_DMA_PRIVATE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#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 fb344556ccb0..000000000000 --- 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 -__FBSDID("$FreeBSD$"); - -#define _ARM32_BUS_DMA_PRIVATE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - - -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 d887fcd92663..000000000000 --- 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 4a035001bdf5..000000000000 --- 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 - -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 55218ccd20d1..000000000000 --- 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 -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include - -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 182b52f57f5a..000000000000 --- 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 - -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 9f5cbb755519..000000000000 --- 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 7cc8f377a876..000000000000 --- 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 8142bdf0803e..000000000000 --- 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 c4c23bf7d620..000000000000 --- 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 5bb903df64cd..000000000000 --- 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 -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#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 a3faec7289df..000000000000 --- 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 -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -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/i80321reg.h b/sys/arm/xscale/i8134x/i80321reg.h index 53617f956582..115900c58291 100644 --- a/sys/arm/xscale/i8134x/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_SSP 25 /* SSP serial port */ #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_AAUE 23 /* AAU error */ #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_AAU_EOC 7 /* AAU end-of-chain */ +//#define ICU_INT_AAU_EOT 6 /* AAU end-of-transfer */ #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 */ +//#define ICU_INT_HWMASK (0xffffffff & \ +// ~((1 << ICU_INT_bit26) | \ +// (1 << ICU_INT_bit22) | \ +// (1 << ICU_INT_bit5) | \ +// (1 << ICU_INT_bit4))) /* * Peripheral Bus Interface Unit diff --git a/sys/conf/files.arm b/sys/conf/files.arm index 9f3a6bffedc0..bc5d8a39fd6d 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.arm b/sys/conf/options.arm index ef664136547c..7beae5bd6833 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 From 71c4d79a10b7c1bad1feb0b4efaaca9c1c9ee341 Mon Sep 17 00:00:00 2001 From: mmel Date: Wed, 3 Feb 2016 10:39:29 +0000 Subject: [PATCH 017/129] ARM: Remove C++ comments erroneously committed in r295200. --- sys/arm/xscale/i8134x/i80321reg.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/sys/arm/xscale/i8134x/i80321reg.h b/sys/arm/xscale/i8134x/i80321reg.h index 115900c58291..b6dd4fea14da 100644 --- a/sys/arm/xscale/i8134x/i80321reg.h +++ b/sys/arm/xscale/i8134x/i80321reg.h @@ -331,12 +331,12 @@ #define ICU_INT_bit26 26 /* CPU_XSCALE_80321 */ -//#define ICU_INT_SSP 25 /* SSP serial port */ +#define ICU_INT_SSP 25 /* SSP serial port */ #define ICU_INT_MUE 24 /* msg unit error */ /* CPU_XSCALE_80321 */ -//#define ICU_INT_AAUE 23 /* AAU error */ +#define ICU_INT_AAUE 23 /* AAU error */ #define ICU_INT_bit22 22 #define ICU_INT_DMA1E 21 /* DMA Ch 1 error */ @@ -355,8 +355,8 @@ #define ICU_INT_CPPM 8 /* core processor PMU */ /* CPU_XSCALE_80321 */ -//#define ICU_INT_AAU_EOC 7 /* AAU end-of-chain */ -//#define ICU_INT_AAU_EOT 6 /* AAU end-of-transfer */ +#define ICU_INT_AAU_EOC 7 /* AAU end-of-chain */ +#define ICU_INT_AAU_EOT 6 /* AAU end-of-transfer */ #define ICU_INT_bit5 5 #define ICU_INT_bit4 4 @@ -366,11 +366,11 @@ #define ICU_INT_DMA0_EOT 0 /* DMA0 end-of-transfer */ /* CPU_XSCALE_80321 */ -//#define ICU_INT_HWMASK (0xffffffff & \ -// ~((1 << ICU_INT_bit26) | \ -// (1 << ICU_INT_bit22) | \ -// (1 << ICU_INT_bit5) | \ -// (1 << ICU_INT_bit4))) +#define ICU_INT_HWMASK (0xffffffff & \ + ~((1 << ICU_INT_bit26) | \ + (1 << ICU_INT_bit22) | \ + (1 << ICU_INT_bit5) | \ + (1 << ICU_INT_bit4))) /* * Peripheral Bus Interface Unit From 5b67986f72e761e7f1f2a034689457476a2357c3 Mon Sep 17 00:00:00 2001 From: bz Date: Wed, 3 Feb 2016 11:03:44 +0000 Subject: [PATCH 018/129] Try to fix a bug introduced in r228623. We started to copy the ifa_msghdr as otherwise platforms with strict alignment would break. It's unclear to me if there's also a problem with access to the address list following the structure. However we never copied the address list after the structure and thus are pointing at random memory. For now just use a pointer to the original memory for accessing the address list making it at least work on platforms with weak memory access. PR: 195445 Reported by: wolfgang lyxys.ka.sub.org Tested by: wolfgang lyxys.ka.sub.org (x86) MFC after: 3 days --- contrib/bsnmp/snmp_mibII/mibII.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/contrib/bsnmp/snmp_mibII/mibII.c b/contrib/bsnmp/snmp_mibII/mibII.c index b62ee66d6d61..9079d1d3b58c 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; From 9b1e69366637d18110038c26a3509bea536ae11a Mon Sep 17 00:00:00 2001 From: ume Date: Wed, 3 Feb 2016 11:44:43 +0000 Subject: [PATCH 019/129] The charset of NLS catalogs were converted to UTF-8 since r231990. --- bin/csh/Makefile | 55 ++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/bin/csh/Makefile b/bin/csh/Makefile index 51ef3dd9c306..18e266535e9a 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 +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_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 +NLSLINKS_de_DE.UTF-8 = de_AT.UTF-8 de_CH.UTF-8 de_DE.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 From 8fba5119d8c590b526917c91f673b02f4e5d6062 Mon Sep 17 00:00:00 2001 From: skra Date: Wed, 3 Feb 2016 12:11:07 +0000 Subject: [PATCH 020/129] Partly revert r295168 and define PTE_DEVICE in pmap-v6.h header again. It turned out that devmap.c is not only file in which PTE_DEVICE is used and simultaneously, built for both armv4 and armv6 platforms. When I tried to build all arm kernels before r295168 commit, it was hid by some other local changes in my tree. I hope that this is just temporary workaround before VM_MEMATTR_DEVICE could be used instead of PTE_DEVICE outside of pmap code for __ARM_ARCH < 6. --- sys/arm/arm/devmap.c | 3 --- sys/arm/include/pmap-v6.h | 2 ++ 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/sys/arm/arm/devmap.c b/sys/arm/arm/devmap.c index 4dffa8cc7a2b..011b5797881a 100644 --- a/sys/arm/arm/devmap.c +++ b/sys/arm/arm/devmap.c @@ -55,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/include/pmap-v6.h b/sys/arm/include/pmap-v6.h index d5223845fb02..b380c29dded0 100644 --- a/sys/arm/include/pmap-v6.h +++ b/sys/arm/include/pmap-v6.h @@ -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 */ // ----------------------------------------------------------------------------- From 3deeea8140f02e68d569a9d3e8f4f101d8fbdb49 Mon Sep 17 00:00:00 2001 From: mmel Date: Wed, 3 Feb 2016 13:47:50 +0000 Subject: [PATCH 021/129] ARM: Replace only once used cpu_icache_sync_all() by ranged equivalent. Remove it from cpu_functions table. --- sys/arm/arm/cpufunc.c | 9 --------- sys/arm/arm/cpufunc_asm_arm11x6.S | 6 ------ sys/arm/arm/cpufunc_asm_arm9.S | 4 +--- sys/arm/arm/cpufunc_asm_armv5_ec.S | 4 +--- sys/arm/arm/cpufunc_asm_armv7.S | 10 ---------- sys/arm/arm/cpufunc_asm_fa526.S | 13 ++++++------- sys/arm/arm/elf_machdep.c | 2 +- sys/arm/arm/genassym.c | 1 - sys/arm/include/cpufunc.h | 12 ++---------- 9 files changed, 11 insertions(+), 50 deletions(-) diff --git a/sys/arm/arm/cpufunc.c b/sys/arm/arm/cpufunc.c index 2b226ef988c8..370bab7c53dc 100644 --- a/sys/arm/arm/cpufunc.c +++ b/sys/arm/arm/cpufunc.c @@ -110,7 +110,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 */ @@ -162,7 +161,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 */ @@ -213,7 +211,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 */ @@ -264,7 +261,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 */ @@ -316,7 +312,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 */ @@ -368,7 +363,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 */ @@ -420,7 +414,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 */ @@ -472,7 +465,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 */ @@ -528,7 +520,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 */ diff --git a/sys/arm/arm/cpufunc_asm_arm11x6.S b/sys/arm/arm/cpufunc_asm_arm11x6.S index be6d5309d935..793c690c9fd3 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 9247b0c42b1c..aaadcfe6cc2b 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 31174c659377..29e22b0975f0 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 42ccc6dd47e2..affd52811282 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 38cb11ad5323..20530ac41951 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/elf_machdep.c b/sys/arm/arm/elf_machdep.c index 7dbdc912c821..2ec659aba802 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/genassym.c b/sys/arm/arm/genassym.c index eb4e51b81bba..31910b787903 100644 --- a/sys/arm/arm/genassym.c +++ b/sys/arm/arm/genassym.c @@ -101,7 +101,6 @@ 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)); diff --git a/sys/arm/include/cpufunc.h b/sys/arm/include/cpufunc.h index 726c808dbedb..85826f0b4dd8 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); @@ -173,7 +171,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() @@ -214,7 +211,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 +227,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 +270,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 +313,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 +322,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); From fcb93180f54ede665ea60822a8bd1766002246d0 Mon Sep 17 00:00:00 2001 From: pfg Date: Wed, 3 Feb 2016 14:31:23 +0000 Subject: [PATCH 022/129] Revert r294695: ext2fs: passthrough any extra timestamps to the dinode struct. While it passed the classic testing, the change appears to have caused some regression and still requires some more precautions. PR: 206820 MFC after: 3 days --- sys/fs/ext2fs/ext2_inode_cnv.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/sys/fs/ext2fs/ext2_inode_cnv.c b/sys/fs/ext2fs/ext2_inode_cnv.c index 78679cff0fdb..d62e9ba0a92e 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; From 960d14828b1b4d2b62d2fe8f0f67e4325b81cadf Mon Sep 17 00:00:00 2001 From: andrew Date: Wed, 3 Feb 2016 14:34:25 +0000 Subject: [PATCH 023/129] Still open the network interface when EFI_OPEN_PROTOCOL_EXCLUSIVE failed. Not all UEFI implementations support this protocol. --- sys/boot/efi/libefi/efinet.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/boot/efi/libefi/efinet.c b/sys/boot/efi/libefi/efinet.c index d9ecdcc45f1c..b7888aaed5fc 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; From dac55bd53a9f0a5723fd92b25c6b2be58c7c0142 Mon Sep 17 00:00:00 2001 From: jceel Date: Wed, 3 Feb 2016 15:45:13 +0000 Subject: [PATCH 024/129] Add an additional, libucl-based configuration file parser to ctld. Default ctld behavior remains unchanged - libucl parser can be selected explicitly by adding -u switch to ctld command line. Reviewed by: trasz Approved by: trasz (mentor) MFC after: 1 month Relnotes: yes Sponsored by: iXsystems, Inc. Differential Revision: https://reviews.freebsd.org/D4534 --- usr.sbin/ctld/Makefile | 7 +- usr.sbin/ctld/ctld.c | 112 ++++- usr.sbin/ctld/ctld.h | 4 +- usr.sbin/ctld/parse.y | 93 +--- usr.sbin/ctld/uclparse.c | 900 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 1023 insertions(+), 93 deletions(-) create mode 100644 usr.sbin/ctld/uclparse.c diff --git a/usr.sbin/ctld/Makefile b/usr.sbin/ctld/Makefile index 6169d308ef2c..664dc22efbb1 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 92fa5539f7f6..6c8b4a89fe93 100644 --- a/usr.sbin/ctld/ctld.c +++ b/usr.sbin/ctld/ctld.c @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -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 808b722aa542..e9152329121f 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 afbf315bf02d..820b4c7d4bc1 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 000000000000..fb2cce0a144e --- /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 + * 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 +#include +#include +#include +#include +#include +#include +#include + +#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); +} From 9ad64bd8b3b9fdd2ebb2e8a3ccfb22c26b054885 Mon Sep 17 00:00:00 2001 From: mmel Date: Wed, 3 Feb 2016 16:44:06 +0000 Subject: [PATCH 025/129] ARM: Consistently use cpu_setttb() instead of setttb(). Remove unused #define for drain_writebuf. --- sys/arm/arm/machdep.c | 6 +++--- sys/arm/at91/at91_machdep.c | 4 ++-- sys/arm/cavium/cns11xx/econa_machdep.c | 4 ++-- sys/arm/include/cpufunc.h | 3 --- sys/arm/xscale/i8134x/crb_machdep.c | 4 ++-- sys/arm/xscale/ixp425/avila_machdep.c | 4 ++-- sys/arm/xscale/pxa/pxa_machdep.c | 4 ++-- 7 files changed, 13 insertions(+), 16 deletions(-) diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c index 8d7c39c4d0b9..b4bfa6222c86 100644 --- a/sys/arm/arm/machdep.c +++ b/sys/arm/arm/machdep.c @@ -1622,7 +1622,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 +1675,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 +1867,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/at91/at91_machdep.c b/sys/arm/at91/at91_machdep.c index 936f145909de..e904780877f0 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/cavium/cns11xx/econa_machdep.c b/sys/arm/cavium/cns11xx/econa_machdep.c index 159105333f03..e212a100c97f 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/include/cpufunc.h b/sys/arm/include/cpufunc.h index 85826f0b4dd8..b5330021842f 100644 --- a/sys/arm/include/cpufunc.h +++ b/sys/arm/include/cpufunc.h @@ -412,9 +412,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/xscale/i8134x/crb_machdep.c b/sys/arm/xscale/i8134x/crb_machdep.c index e306a75a5b12..293696364a32 100644 --- a/sys/arm/xscale/i8134x/crb_machdep.c +++ b/sys/arm/xscale/i8134x/crb_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/arm/xscale/ixp425/avila_machdep.c b/sys/arm/xscale/ixp425/avila_machdep.c index e033e1357b64..f8632e10ad37 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 5cc8d46c0823..2bbb8350a577 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. From 1ef2c8adf6388662de306ad64df5252c02e3bfbd Mon Sep 17 00:00:00 2001 From: andrew Date: Wed, 3 Feb 2016 17:00:19 +0000 Subject: [PATCH 026/129] Handle a misaligned stack pointer exception from userspace. The exception still needs to be enabled, but this will help with testing. Sponsored by: ABT Systems Ltd --- sys/arm64/arm64/trap.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/arm64/arm64/trap.c b/sys/arm64/arm64/trap.c index 89d6d0c89f84..10e3f416c2a1 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); From 3e3f3a4c0f055b92e0b78acd779955c92fedeb74 Mon Sep 17 00:00:00 2001 From: bdrewery Date: Wed, 3 Feb 2016 20:24:21 +0000 Subject: [PATCH 027/129] Deduplicate distrib-dirs logic from r289086 in distribution. This does it correctly this time, rather than the incorrect version in r295167. Sponsored by: EMC / Isilon Storage Division --- Makefile.inc1 | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Makefile.inc1 b/Makefile.inc1 index 222d7ec2b74f..ccd25d001d60 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -1083,16 +1083,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 From ba8e82fa42143956086d2cc9170c750bd601dd2c Mon Sep 17 00:00:00 2001 From: glebius Date: Wed, 3 Feb 2016 20:39:52 +0000 Subject: [PATCH 028/129] Fix inverse logic. If this is zone_pack, then we shouldn't free the cluster ourselves. Found by review. Since this code is !386 and !amd64 and is executed on error path, pretty sure no one ever executed it. --- sys/dev/cxgb/cxgb_sge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/cxgb/cxgb_sge.c b/sys/dev/cxgb/cxgb_sge.c index d70a94877fcd..2cfad262673b 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; From 8f977b6c5c07cc8b9c845778b9b384d9e37482ee Mon Sep 17 00:00:00 2001 From: glebius Date: Wed, 3 Feb 2016 22:02:36 +0000 Subject: [PATCH 029/129] Move uma_dbg_alloc() and uma_dbg_free() into uma_core.c, which allows to make uma_dbg.h not depend on uma_int.h, which allows to uninclude uma_int.h from the mbuf(9) allocator. --- sys/kern/kern_mbuf.c | 1 - sys/vm/uma_core.c | 103 ++++++++++++++++++++++++++++++++++++++++++- sys/vm/uma_dbg.c | 97 ---------------------------------------- sys/vm/uma_dbg.h | 3 -- 4 files changed, 102 insertions(+), 102 deletions(-) diff --git a/sys/kern/kern_mbuf.c b/sys/kern/kern_mbuf.c index a864c946873c..779c62af32bd 100644 --- a/sys/kern/kern_mbuf.c +++ b/sys/kern/kern_mbuf.c @@ -52,7 +52,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include /* diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c index 4600589bd06d..89ed213e82e6 100644 --- a/sys/vm/uma_core.c +++ b/sys/vm/uma_core.c @@ -275,6 +275,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, @@ -3607,6 +3612,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 +3765,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 3fbd29b16dea..dcef5c9480cb 100644 --- a/sys/vm/uma_dbg.c +++ b/sys/vm/uma_dbg.c @@ -196,100 +196,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 341cecbf8de3..e3c9df02f2d3 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 */ From 953ea03018f155940b6a4b4d34edf9d5107822fe Mon Sep 17 00:00:00 2001 From: glebius Date: Wed, 3 Feb 2016 23:30:17 +0000 Subject: [PATCH 030/129] Redo r292484. Embed task(9) into zone, so that uz_maxaction is called in a context that can sleep, allowing consumers of the KPI to run their drain routines without any extra measures. Discussed with: jtl --- sys/amd64/amd64/uma_machdep.c | 1 + sys/kern/kern_malloc.c | 1 + sys/kern/kern_mbuf.c | 92 ++++------------------------------- sys/vm/memguard.c | 1 + sys/vm/uma.h | 2 +- sys/vm/uma_core.c | 9 ++-- sys/vm/uma_dbg.c | 1 + sys/vm/uma_int.h | 2 +- sys/vm/vm_page.c | 1 + 9 files changed, 22 insertions(+), 88 deletions(-) diff --git a/sys/amd64/amd64/uma_machdep.c b/sys/amd64/amd64/uma_machdep.c index db566ae89d47..fc343cabe52f 100644 --- a/sys/amd64/amd64/uma_machdep.c +++ b/sys/amd64/amd64/uma_machdep.c @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c index e7c81d67e936..f7c67f2d7610 100644 --- a/sys/kern/kern_malloc.c +++ b/sys/kern/kern_malloc.c @@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include diff --git a/sys/kern/kern_mbuf.c b/sys/kern/kern_mbuf.c index 779c62af32bd..55964398b6a1 100644 --- a/sys/kern/kern_mbuf.c +++ b/sys/kern/kern_mbuf.c @@ -273,12 +273,6 @@ uma_zone_t zone_jumbo9; 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. */ @@ -291,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); @@ -319,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, @@ -332,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); @@ -349,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, @@ -363,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, @@ -377,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 @@ -677,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/vm/memguard.c b/sys/vm/memguard.c index d4efc2b7123e..fb70a4186c73 100644 --- a/sys/vm/memguard.c +++ b/sys/vm/memguard.c @@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include diff --git a/sys/vm/uma.h b/sys/vm/uma.h index d218e60886dc..21c61214315d 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 89ed213e82e6..0d45046e7e51 100644 --- a/sys/vm/uma_core.c +++ b/sys/vm/uma_core.c @@ -78,6 +78,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -439,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 @@ -1590,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)); @@ -3027,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); } diff --git a/sys/vm/uma_dbg.c b/sys/vm/uma_dbg.c index dcef5c9480cb..7bf06d35b4e2 100644 --- a/sys/vm/uma_dbg.c +++ b/sys/vm/uma_dbg.c @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include diff --git a/sys/vm/uma_int.h b/sys/vm/uma_int.h index 5d7ecd331a7f..1b0d5d5dbf37 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 d27eb2d4eaf0..b510696ed170 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -102,6 +102,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include From 3cee84e03164f633467a8e2b0ea12df1c50bfa1a Mon Sep 17 00:00:00 2001 From: bdrewery Date: Wed, 3 Feb 2016 23:37:14 +0000 Subject: [PATCH 031/129] Don't let NLSLINKS contain itself. Sponsored by: EMC / Isilon Storage Division --- share/mk/bsd.nls.mk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/share/mk/bsd.nls.mk b/share/mk/bsd.nls.mk index c578361fdd53..d160a2bcf2d4 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}} From f053f5a5d6423c7e763945ddfc190f11a7a55efa Mon Sep 17 00:00:00 2001 From: bdrewery Date: Wed, 3 Feb 2016 23:37:24 +0000 Subject: [PATCH 032/129] Don't link /usr/share/nls/de_DE.UTF-8/tcsh.cat to itself. Sponsored by: EMC / Isilon Storage Division --- bin/csh/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/csh/Makefile b/bin/csh/Makefile index 18e266535e9a..deb63478727d 100644 --- a/bin/csh/Makefile +++ b/bin/csh/Makefile @@ -62,7 +62,7 @@ CATALOGS= et:et_EE.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 de_DE.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 From c805a3354e5316470ff02dc5d57d943e3d3860c4 Mon Sep 17 00:00:00 2001 From: glebius Date: Thu, 4 Feb 2016 00:23:21 +0000 Subject: [PATCH 033/129] Fix build. --- lib/libmemstat/memstat_uma.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/libmemstat/memstat_uma.c b/lib/libmemstat/memstat_uma.c index 8e89585300b0..20cd5208fdd6 100644 --- a/lib/libmemstat/memstat_uma.c +++ b/lib/libmemstat/memstat_uma.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include From e6b730a42a3781472e318742288f25b698b5db01 Mon Sep 17 00:00:00 2001 From: bdrewery Date: Thu, 4 Feb 2016 01:08:42 +0000 Subject: [PATCH 034/129] Stop hiding link install commands. This is no longer needed now that a .for loop is used rather than inline shell script. Sponsored by: EMC / Isilon Storage Division --- share/mk/bsd.incs.mk | 1 - share/mk/bsd.links.mk | 2 -- 2 files changed, 3 deletions(-) diff --git a/share/mk/bsd.incs.mk b/share/mk/bsd.incs.mk index 8ea97ba14fc8..57e08ffcf768 100644 --- a/share/mk/bsd.incs.mk +++ b/share/mk/bsd.incs.mk @@ -80,7 +80,6 @@ _${group}INS: ${_${group}INCS} .if defined(INCSLINKS) && !empty(INCSLINKS) installincludes: .for s t in ${INCSLINKS} - @${ECHO} "$t -> $s" ; \ ${INSTALL_SYMLINK} $s ${DESTDIR}$t .endfor .endif diff --git a/share/mk/bsd.links.mk b/share/mk/bsd.links.mk index 4f8565c255f9..38ceb42289d5 100644 --- a/share/mk/bsd.links.mk +++ b/share/mk/bsd.links.mk @@ -8,10 +8,8 @@ afterinstall: _installlinks .ORDER: realinstall _installlinks _installlinks: .for s t in ${LINKS} - @${ECHO} "$t -> $s" ;\ ${INSTALL_LINK} ${DESTDIR}$s ${DESTDIR}$t .endfor .for s t in ${SYMLINKS} - @${ECHO} "$t -> $s" ;\ ${INSTALL_SYMLINK} $s ${DESTDIR}/$t .endfor From 95aca9386107e5e0bc09887d1a22176e40351228 Mon Sep 17 00:00:00 2001 From: bdrewery Date: Thu, 4 Feb 2016 01:08:45 +0000 Subject: [PATCH 035/129] Fix cat files being installed to wrong place since r284685. Sponsored by: EMC / Isilon Storage Division --- share/mk/bsd.man.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/mk/bsd.man.mk b/share/mk/bsd.man.mk index d0992b630dfb..6be8e6476512 100644 --- a/share/mk/bsd.man.mk +++ b/share/mk/bsd.man.mk @@ -226,8 +226,8 @@ _maninstall: ${MAN} .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}; \ + @l=${DESTDIR}${CATDIR}${_osect}${MANSUBDIR}/${_oname}; \ + t=${DESTDIR}${CATDIR}${_dsect}${MANSUBDIR}/${_dname}; \ ${ECHO} $${t}${ZEXT} -\> $${l}${ZEXT}; \ rm -f $${t} $${t}${MCOMPRESS_EXT}; \ ${INSTALL_LINK} $${l}${ZEXT} $${t}${ZEXT} From 798fceb2c17744606d0117cac7d771a1e076f160 Mon Sep 17 00:00:00 2001 From: bdrewery Date: Thu, 4 Feb 2016 01:08:48 +0000 Subject: [PATCH 036/129] MLINKS: Deduplicate some of the logic, simplify, and unhide install commands. Sponsored by: EMC / Isilon Storage Division --- share/mk/bsd.man.mk | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/share/mk/bsd.man.mk b/share/mk/bsd.man.mk index 6be8e6476512..5cfada030949 100644 --- a/share/mk/bsd.man.mk +++ b/share/mk/bsd.man.mk @@ -171,6 +171,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) @@ -215,25 +226,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} $${l}${ZEXT} $${t}${ZEXT} +.for l t in ${_MANLINKS} + rm -f ${DESTDIR}${t} ${DESTDIR}${t}${MCOMPRESS_EXT}; \ + ${INSTALL_LINK} ${DESTDIR}${l}${ZEXT} ${DESTDIR}${t}${ZEXT} .endfor -.if defined(MANBUILDCAT) && !empty(MANBUILDCAT) -.for _oname _osect _dname _dsect in ${MLINKS:C/\.([^.]*)$/.\1 \1/} - @l=${DESTDIR}${CATDIR}${_osect}${MANSUBDIR}/${_oname}; \ - t=${DESTDIR}${CATDIR}${_dsect}${MANSUBDIR}/${_dname}; \ - ${ECHO} $${t}${ZEXT} -\> $${l}${ZEXT}; \ - rm -f $${t} $${t}${MCOMPRESS_EXT}; \ - ${INSTALL_LINK} $${l}${ZEXT} $${t}${ZEXT} -.endfor -.endif -.endif manlint: .if defined(MAN) && !empty(MAN) From c848707b796d017fa305da82177c3bf616e21322 Mon Sep 17 00:00:00 2001 From: bdrewery Date: Thu, 4 Feb 2016 01:08:51 +0000 Subject: [PATCH 037/129] Fix style and remove excess / for installing SYMLINKS. Sponsored by: EMC / Isilon Storage Division --- share/mk/bsd.incs.mk | 2 +- share/mk/bsd.links.mk | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/share/mk/bsd.incs.mk b/share/mk/bsd.incs.mk index 57e08ffcf768..0897e8d8ca35 100644 --- a/share/mk/bsd.incs.mk +++ b/share/mk/bsd.incs.mk @@ -80,7 +80,7 @@ _${group}INS: ${_${group}INCS} .if defined(INCSLINKS) && !empty(INCSLINKS) installincludes: .for s t in ${INCSLINKS} - ${INSTALL_SYMLINK} $s ${DESTDIR}$t + ${INSTALL_SYMLINK} ${s} ${DESTDIR}${t} .endfor .endif .endif # !target(installincludes) diff --git a/share/mk/bsd.links.mk b/share/mk/bsd.links.mk index 38ceb42289d5..9e24af86624f 100644 --- a/share/mk/bsd.links.mk +++ b/share/mk/bsd.links.mk @@ -8,8 +8,8 @@ afterinstall: _installlinks .ORDER: realinstall _installlinks _installlinks: .for s t in ${LINKS} - ${INSTALL_LINK} ${DESTDIR}$s ${DESTDIR}$t + ${INSTALL_LINK} ${DESTDIR}${s} ${DESTDIR}${t} .endfor .for s t in ${SYMLINKS} - ${INSTALL_SYMLINK} $s ${DESTDIR}/$t + ${INSTALL_SYMLINK} ${s} ${DESTDIR}${t} .endfor From e807599e3ffdfd1caaff4c43f3e2a3b7b6289440 Mon Sep 17 00:00:00 2001 From: glebius Date: Thu, 4 Feb 2016 03:55:41 +0000 Subject: [PATCH 038/129] Fix build. --- sys/arm64/arm64/uma_machdep.c | 1 + sys/mips/mips/uma_machdep.c | 1 + sys/powerpc/powerpc/uma_machdep.c | 1 + sys/riscv/riscv/uma_machdep.c | 1 + 4 files changed, 4 insertions(+) diff --git a/sys/arm64/arm64/uma_machdep.c b/sys/arm64/arm64/uma_machdep.c index 9b9df5c68ed4..a9dae0f42573 100644 --- a/sys/arm64/arm64/uma_machdep.c +++ b/sys/arm64/arm64/uma_machdep.c @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include diff --git a/sys/mips/mips/uma_machdep.c b/sys/mips/mips/uma_machdep.c index b4006e1ead12..7014703b712a 100644 --- a/sys/mips/mips/uma_machdep.c +++ b/sys/mips/mips/uma_machdep.c @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include diff --git a/sys/powerpc/powerpc/uma_machdep.c b/sys/powerpc/powerpc/uma_machdep.c index d5a458f37fa2..2e023965c95d 100644 --- a/sys/powerpc/powerpc/uma_machdep.c +++ b/sys/powerpc/powerpc/uma_machdep.c @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include diff --git a/sys/riscv/riscv/uma_machdep.c b/sys/riscv/riscv/uma_machdep.c index ba480713fc75..b3f2d82be13c 100644 --- a/sys/riscv/riscv/uma_machdep.c +++ b/sys/riscv/riscv/uma_machdep.c @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include From 9a7c585ab535448da4519e461a2216e335686144 Mon Sep 17 00:00:00 2001 From: mjg Date: Thu, 4 Feb 2016 04:22:18 +0000 Subject: [PATCH 039/129] fork: pass arguments to fork1 in a dedicated structure Suggested by: kib --- sys/compat/cloudabi/cloudabi_proc.c | 8 ++++- sys/compat/linux/linux_fork.c | 20 +++++++++--- sys/kern/init_main.c | 7 ++-- sys/kern/kern_fork.c | 50 ++++++++++++++++++++--------- sys/kern/kern_kthread.c | 8 +++-- sys/sys/proc.h | 12 +++++-- 6 files changed, 78 insertions(+), 27 deletions(-) diff --git a/sys/compat/cloudabi/cloudabi_proc.c b/sys/compat/cloudabi/cloudabi_proc.c index d91733760ceb..7320af01e7fc 100644 --- a/sys/compat/cloudabi/cloudabi_proc.c +++ b/sys/compat/cloudabi/cloudabi_proc.c @@ -75,12 +75,18 @@ 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_procp = &p2; + 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 d0f73adefd31..c12f198fe79b 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/kern/init_main.c b/sys/kern/init_main.c index 8d5580b6d046..d5f8f4ddbe31 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 e7d727619be0..d13a20c7cf46 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -101,10 +101,14 @@ struct fork_args { int sys_fork(struct thread *td, struct fork_args *uap) { + struct fork_req fr; int error; struct proc *p2; - error = fork1(td, RFFDG | RFPROC, 0, &p2, NULL, 0, NULL); + bzero(&fr, sizeof(fr)); + fr.fr_flags = RFFDG | RFPROC; + fr.fr_procp = &p2; + error = fork1(td, &fr); if (error == 0) { td->td_retval[0] = p2->p_pid; td->td_retval[1] = 0; @@ -118,16 +122,21 @@ sys_pdfork(td, uap) struct thread *td; struct pdfork_args *uap; { + struct fork_req fr; int error, fd; struct proc *p2; + bzero(&fr, sizeof(fr)); + fr.fr_flags = RFFDG | RFPROC | RFPROCDESC; + fr.fr_procp = &p2; + 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[1] = 0; @@ -140,11 +149,14 @@ sys_pdfork(td, uap) int sys_vfork(struct thread *td, struct vfork_args *uap) { - int error, flags; + struct fork_req fr; + int error; struct proc *p2; - 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_procp = &p2; + error = fork1(td, &fr); if (error == 0) { td->td_retval[0] = p2->p_pid; td->td_retval[1] = 0; @@ -155,6 +167,7 @@ sys_vfork(struct thread *td, struct vfork_args *uap) int sys_rfork(struct thread *td, struct rfork_args *uap) { + struct fork_req fr; struct proc *p2; int error; @@ -163,7 +176,10 @@ sys_rfork(struct thread *td, struct rfork_args *uap) 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_procp = &p2; + error = fork1(td, &fr); if (error == 0) { td->td_retval[0] = p2 ? p2->p_pid : 0; td->td_retval[1] = 0; @@ -761,8 +777,7 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2, } 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 +787,10 @@ 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; /* Check for the undefined or unimplemented flags. */ if ((flags & ~(RFFLAGS | RFTSIGFLAGS(RFTSIGMASK))) != 0) @@ -795,7 +814,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 +825,7 @@ fork1(struct thread *td, int flags, int pages, struct proc **procp, * certain parts of a process from itself. */ if ((flags & RFPROC) == 0) { - *procp = NULL; + *fr->fr_procp = NULL; return (fork_norfproc(td, flags)); } @@ -845,7 +864,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,12 +953,12 @@ 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); + do_fork(td, flags, newproc, td2, vm2, fr->fr_pd_flags); /* * Return child proc pointer to parent. */ - *procp = newproc; + *fr->fr_procp = newproc; if (flags & RFPROCDESC) { procdesc_finit(newproc->p_procdesc, fp_procdesc); fdrop(fp_procdesc, td); @@ -962,7 +982,7 @@ fork1(struct thread *td, int flags, int pages, struct proc **procp, 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 2072dc726b08..9cca255fef91 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/sys/proc.h b/sys/sys/proc.h index f2f4a9d17202..ac96566510ce 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -907,6 +907,15 @@ 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; + struct proc **fr_procp; + int *fr_pd_fd; + int fr_pd_flags; + struct filecaps *fr_pd_fcaps; +}; + /* * pget() flags. */ @@ -930,8 +939,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 *); From 027c9d90e38cc5d801ef8365d78332bebdbbb32b Mon Sep 17 00:00:00 2001 From: mjg Date: Thu, 4 Feb 2016 04:25:30 +0000 Subject: [PATCH 040/129] fork: plug a use after free of the returned process fork1 required its callers to pass a pointer to struct proc * which would be set to the new process (if any). procdesc and racct manipulation also used said pointer. However, the process could have exited prior to do_fork return and be automatically reaped, thus making this a use-after-free. Fix the problem by letting callers indicate whether they want the pid or the struct proc, return the process in stopped state for the latter case. Reviewed by: kib --- sys/compat/cloudabi/cloudabi_proc.c | 2 - sys/kern/kern_fork.c | 142 +++++++++++++++------------- sys/kern/kern_racct.c | 3 +- sys/sys/proc.h | 1 + 4 files changed, 76 insertions(+), 72 deletions(-) diff --git a/sys/compat/cloudabi/cloudabi_proc.c b/sys/compat/cloudabi/cloudabi_proc.c index 7320af01e7fc..8d0b6e76958a 100644 --- a/sys/compat/cloudabi/cloudabi_proc.c +++ b/sys/compat/cloudabi/cloudabi_proc.c @@ -77,13 +77,11 @@ cloudabi_sys_proc_fork(struct thread *td, { struct fork_req fr; struct filecaps fcaps = {}; - struct proc *p2; int error, fd; cap_rights_init(&fcaps.fc_rights, CAP_FSTAT, CAP_EVENT); bzero(&fr, sizeof(fr)); fr.fr_flags = RFFDG | RFPROC | RFPROCDESC; - fr.fr_procp = &p2; fr.fr_pd_fd = &fd; fr.fr_pd_fcaps = &fcaps; error = fork1(td, &fr); diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index d13a20c7cf46..baee954dc569 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -102,15 +102,14 @@ int sys_fork(struct thread *td, struct fork_args *uap) { struct fork_req fr; - int error; - struct proc *p2; + int error, pid; bzero(&fr, sizeof(fr)); fr.fr_flags = RFFDG | RFPROC; - fr.fr_procp = &p2; + 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); @@ -123,12 +122,11 @@ sys_pdfork(td, uap) struct pdfork_args *uap; { struct fork_req fr; - int error, fd; - struct proc *p2; + int error, fd, pid; bzero(&fr, sizeof(fr)); fr.fr_flags = RFFDG | RFPROC | RFPROCDESC; - fr.fr_procp = &p2; + fr.fr_pidp = &pid; fr.fr_pd_fd = &fd; fr.fr_pd_flags = uap->flags; /* @@ -138,7 +136,7 @@ sys_pdfork(td, uap) */ 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)); } @@ -150,15 +148,14 @@ int sys_vfork(struct thread *td, struct vfork_args *uap) { struct fork_req fr; - int error; - struct proc *p2; + int error, pid; bzero(&fr, sizeof(fr)); fr.fr_flags = RFFDG | RFPROC | RFPPWAIT | RFMEM; - fr.fr_procp = &p2; + 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); @@ -168,8 +165,7 @@ int sys_rfork(struct thread *td, struct rfork_args *uap) { struct fork_req fr; - struct proc *p2; - int error; + int error, pid; /* Don't allow kernel-only flags. */ if ((uap->flags & RFKERNELONLY) != 0) @@ -178,10 +174,10 @@ sys_rfork(struct thread *td, struct rfork_args *uap) AUDIT_ARG_FFLAGS(uap->flags); bzero(&fr, sizeof(fr)); fr.fr_flags = uap->flags; - fr.fr_procp = &p2; + 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); @@ -382,11 +378,11 @@ fork_norfproc(struct thread *td, int flags) } 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; @@ -394,10 +390,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); @@ -430,7 +425,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(); @@ -438,10 +433,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 { @@ -449,7 +444,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. @@ -517,16 +512,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; @@ -559,7 +554,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; @@ -606,7 +601,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; @@ -640,7 +635,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 { @@ -668,13 +663,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); @@ -693,14 +688,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. @@ -719,9 +714,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)) { /* @@ -734,24 +734,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. @@ -763,16 +751,36 @@ 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) cv_wait(&p2->p_dbgwait, &p2->p_mtx); - if (p2_held) - _PRELE(p2); + _PRELE(p2); + racct_proc_fork_done(p2); PROC_UNLOCK(p2); } @@ -792,6 +800,11 @@ fork1(struct thread *td, struct fork_req *fr) 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) return (EINVAL); @@ -825,7 +838,10 @@ fork1(struct thread *td, struct fork_req *fr) * certain parts of a process from itself. */ if ((flags & RFPROC) == 0) { - *fr->fr_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)); } @@ -953,17 +969,7 @@ fork1(struct thread *td, struct fork_req *fr) lim_cur(td, RLIMIT_NPROC)); } if (ok) { - do_fork(td, flags, newproc, td2, vm2, fr->fr_pd_flags); - - /* - * Return child proc pointer to parent. - */ - *fr->fr_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); } diff --git a/sys/kern/kern_racct.c b/sys/kern/kern_racct.c index 0c7c0c444382..ce7e2a4d92c8 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/sys/proc.h b/sys/sys/proc.h index ac96566510ce..039fd394d34a 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -910,6 +910,7 @@ 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; From 52d53d171566c2cd975d2db86a291e516d34d9fe Mon Sep 17 00:00:00 2001 From: ume Date: Thu, 4 Feb 2016 05:03:35 +0000 Subject: [PATCH 041/129] Make sure to enable aliases for SHIFT_JIS. MFC after: 3 days --- share/i18n/esdb/MISC/MISC.alias | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/share/i18n/esdb/MISC/MISC.alias b/share/i18n/esdb/MISC/MISC.alias index 90e2ccd6f126..6ffad5d45cf6 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 From 46763fd4ca8a37f836c9bf2333f9d687509278f3 Mon Sep 17 00:00:00 2001 From: mmel Date: Thu, 4 Feb 2016 06:39:20 +0000 Subject: [PATCH 042/129] ARM: Remove unused symbols from genassym.c. --- sys/arm/arm/genassym.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/sys/arm/arm/genassym.c b/sys/arm/arm/genassym.c index 31910b787903..4a60d9494331 100644 --- a/sys/arm/arm/genassym.c +++ b/sys/arm/arm/genassym.c @@ -59,7 +59,6 @@ __FBSDID("$FreeBSD$"); #include ASSYM(KERNBASE, KERNBASE); -ASSYM(PCB_NOALIGNFLT, PCB_NOALIGNFLT); #if __ARM_ARCH >= 6 ASSYM(CPU_ASID_KERNEL,CPU_ASID_KERNEL); #endif @@ -67,7 +66,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,23 +91,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(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)); @@ -146,10 +136,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); From ce2fb04a46c2cc3b31ab973bbde3bc7d5c609e5e Mon Sep 17 00:00:00 2001 From: kib Date: Thu, 4 Feb 2016 10:49:34 +0000 Subject: [PATCH 043/129] Guard against runnable td2 exiting and than being reused for unrelated process when the parent sleeps waiting for the debugger attach on fork. Diagnosed and reviewed by: mjg Sponsored by: The FreeBSD Foundation --- sys/kern/kern_fork.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index baee954dc569..5bb14e8b4adb 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -777,7 +777,7 @@ do_fork(struct thread *td, struct fork_req *fr, struct proc *p2, struct thread * /* * Wait until debugger is attached to child. */ - 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); _PRELE(p2); racct_proc_fork_done(p2); From 30a404b9164af3ef3de2f8f38e0050f6b71fb1aa Mon Sep 17 00:00:00 2001 From: br Date: Thu, 4 Feb 2016 11:52:53 +0000 Subject: [PATCH 044/129] Fix build. --- sys/arm64/arm64/vm_machdep.c | 1 + sys/mips/mips/vm_machdep.c | 1 + sys/riscv/riscv/vm_machdep.c | 1 + 3 files changed, 3 insertions(+) diff --git a/sys/arm64/arm64/vm_machdep.c b/sys/arm64/arm64/vm_machdep.c index 6794b1b411e2..3b6891496e68 100644 --- a/sys/arm64/arm64/vm_machdep.c +++ b/sys/arm64/arm64/vm_machdep.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include diff --git a/sys/mips/mips/vm_machdep.c b/sys/mips/mips/vm_machdep.c index f952eccbe777..03fc60e36ccc 100644 --- a/sys/mips/mips/vm_machdep.c +++ b/sys/mips/mips/vm_machdep.c @@ -56,6 +56,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include diff --git a/sys/riscv/riscv/vm_machdep.c b/sys/riscv/riscv/vm_machdep.c index 62e466f9e19a..0f652501a67a 100644 --- a/sys/riscv/riscv/vm_machdep.c +++ b/sys/riscv/riscv/vm_machdep.c @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include From 281991463be88ccea048efc7431bace6c07144f6 Mon Sep 17 00:00:00 2001 From: br Date: Thu, 4 Feb 2016 12:06:06 +0000 Subject: [PATCH 045/129] Fix build. --- sys/arm/arm/vm_machdep.c | 1 + sys/sparc64/sparc64/vm_machdep.c | 1 + 2 files changed, 2 insertions(+) diff --git a/sys/arm/arm/vm_machdep.c b/sys/arm/arm/vm_machdep.c index 6a70cbf403e0..601be0718d97 100644 --- a/sys/arm/arm/vm_machdep.c +++ b/sys/arm/arm/vm_machdep.c @@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include diff --git a/sys/sparc64/sparc64/vm_machdep.c b/sys/sparc64/sparc64/vm_machdep.c index df8be0b4e0c2..9780406ae0f0 100644 --- a/sys/sparc64/sparc64/vm_machdep.c +++ b/sys/sparc64/sparc64/vm_machdep.c @@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include From 444874ded476cb85cea4f20deced485f0aabf91c Mon Sep 17 00:00:00 2001 From: mmel Date: Thu, 4 Feb 2016 12:11:18 +0000 Subject: [PATCH 046/129] ARM: Don't use ugly (and hidden) global variable, control register is readable at any time. --- sys/arm/arm/cpufunc.c | 9 --------- sys/arm/arm/identcpu.c | 4 ++-- sys/arm/include/cpufunc.h | 1 + 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/sys/arm/arm/cpufunc.c b/sys/arm/arm/cpufunc.c index 370bab7c53dc..a2b8180e56a5 100644 --- a/sys/arm/arm/cpufunc.c +++ b/sys/arm/arm/cpufunc.c @@ -88,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 */ @@ -889,7 +887,6 @@ arm9_setup(void) /* Set the control register */ cpu_control(cpuctrlmask, cpuctrl); - ctrl = cpuctrl; } #endif /* CPU_ARM9 */ @@ -928,7 +925,6 @@ arm10_setup(void) cpuctrl |= CPU_CONTROL_VECRELOC; /* Set the control register */ - ctrl = cpuctrl; cpu_control(0xffffffff, cpuctrl); /* And again. */ @@ -1032,7 +1028,6 @@ arm11x6_setup(void) cp15_cpacr_set(0x0fffffff); /* Set the control register */ - ctrl = cpuctrl; cpu_control(~cpuctrl_wax, cpuctrl); tmp = cp15_actlr_get(); @@ -1074,7 +1069,6 @@ pj4bv7_setup(void) cpu_idcache_wbinv_all(); /* Set the control register */ - ctrl = cpuctrl; cpu_control(0xFFFFFFFF, cpuctrl); /* And again. */ @@ -1120,7 +1114,6 @@ cortexa_setup(void) cpu_idcache_wbinv_all(); /* Set the control register */ - ctrl = cpuctrl; cpu_control(cpuctrlmask, cpuctrl); /* And again. */ @@ -1167,7 +1160,6 @@ fa526_setup(void) cpu_idcache_wbinv_all(); /* Set the control register */ - ctrl = cpuctrl; cpu_control(0xffffffff, cpuctrl); } #endif /* CPU_FA526 */ @@ -1221,7 +1213,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); diff --git a/sys/arm/arm/identcpu.c b/sys/arm/arm/identcpu.c index 6c5764c297ce..2b7fec4d05dc 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/include/cpufunc.h b/sys/arm/include/cpufunc.h index b5330021842f..afbcac834f13 100644 --- a/sys/arm/include/cpufunc.h +++ b/sys/arm/include/cpufunc.h @@ -202,6 +202,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) From a6a53aa0dc541d11f006058c210249628072c55e Mon Sep 17 00:00:00 2001 From: br Date: Thu, 4 Feb 2016 12:49:28 +0000 Subject: [PATCH 047/129] Reuse gp register for pcpu pointer. gp (global pointer) is used by compiler in userland only, so re-use it for pcpup in kernel, save it on stack on switching out to userland and load back on return to kernel. Discussed with: jhb, andrew, kib Sponsored by: DARPA, AFRL Sponsored by: HEIF5 Differential Revision: https://reviews.freebsd.org/D5178 --- sys/riscv/include/pcpu.h | 7 +++++-- sys/riscv/riscv/exception.S | 17 ++++++++++++----- sys/riscv/riscv/genassym.c | 1 + sys/riscv/riscv/machdep.c | 11 +++++------ sys/riscv/riscv/swtch.S | 23 ++++++++++++++--------- sys/riscv/riscv/vm_machdep.c | 2 +- 6 files changed, 38 insertions(+), 23 deletions(-) diff --git a/sys/riscv/include/pcpu.h b/sys/riscv/include/pcpu.h index c60a95428fe1..7dfe23d991bf 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 07fcfc52787a..8bd9027313b3 100644 --- a/sys/riscv/riscv/exception.S +++ b/sys/riscv/riscv/exception.S @@ -41,12 +41,16 @@ __FBSDID("$FreeBSD$"); #include .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 diff --git a/sys/riscv/riscv/genassym.c b/sys/riscv/riscv/genassym.c index f5c971d178a7..bf6c8fb4c851 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 5f9bd1f283f2..79688e6f3009 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 945fce354972..5e9b3c986238 100644 --- a/sys/riscv/riscv/swtch.S +++ b/sys/riscv/riscv/swtch.S @@ -74,8 +74,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) @@ -120,8 +118,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 +172,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 +248,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/vm_machdep.c b/sys/riscv/riscv/vm_machdep.c index 0f652501a67a..fef626b9f2fa 100644 --- a/sys/riscv/riscv/vm_machdep.c +++ b/sys/riscv/riscv/vm_machdep.c @@ -218,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 From a235ff8242f112163b331a14d2ced14dd58250cf Mon Sep 17 00:00:00 2001 From: mmel Date: Thu, 4 Feb 2016 13:32:29 +0000 Subject: [PATCH 048/129] ARM: RPI-B kernel was broken by r294740. Make it functional again. --- sys/arm/arm/debug_monitor.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/arm/arm/debug_monitor.c b/sys/arm/arm/debug_monitor.c index e216e347597c..eaf88e9d1f07 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); From 855ee55df38fa7caca48484dc2530a3e7e06affc Mon Sep 17 00:00:00 2001 From: skra Date: Thu, 4 Feb 2016 13:35:40 +0000 Subject: [PATCH 049/129] Small rearrangement of abort_handler(). (1) Move cnt.v_trap increment to the beginning. There is cnt.v_vm_faults counter in vm_fault(), so a number of hardware emulation aborts may be get roughly as difference. (2) Move kdb_reenter() up to not be ignored if pmap_fault() has failed. (3) Update comments. --- sys/arm/arm/trap-v6.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/sys/arm/arm/trap-v6.c b/sys/arm/arm/trap-v6.c index adc29c6534e8..88aec53ab442 100644 --- a/sys/arm/arm/trap-v6.c +++ b/sys/arm/arm/trap-v6.c @@ -293,7 +293,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 +337,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 @@ -417,6 +419,14 @@ abort_handler(struct trapframe *tf, int prefetch) goto out; } + /* + * 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,16 +445,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; From b512e43ef25c82d0955c88efbebd614817b95e26 Mon Sep 17 00:00:00 2001 From: mmel Date: Thu, 4 Feb 2016 14:02:42 +0000 Subject: [PATCH 050/129] ARM: Set UNAL_ENABLE bit in SCTLR CP15 register. This bit is RAO/SBOP for ARMv7. For ARMv6, it controls ARMv5 compatible alignment support. This bit have no effect until unaligned access is enabled. --- sys/arm/arm/locore-v6.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/arm/arm/locore-v6.S b/sys/arm/arm/locore-v6.S index eda60146dd5b..b93af2c4b6b5 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) From 87f75655f47c981626c6195bef391c7b49efb7cf Mon Sep 17 00:00:00 2001 From: skra Date: Thu, 4 Feb 2016 14:15:24 +0000 Subject: [PATCH 051/129] Make VM_MEMATTR_xxx definitions independent on pmap internals for __ARM_ARCH >= 6. It's TEX class number now, so it still has some meaning. --- sys/arm/arm/pmap-v6.c | 129 ++++++++++++++++++++++++-------------- sys/arm/include/pmap-v6.h | 4 +- sys/arm/include/vm.h | 10 +-- 3 files changed, 89 insertions(+), 54 deletions(-) diff --git a/sys/arm/arm/pmap-v6.c b/sys/arm/arm/pmap-v6.c index d4ab9305b39d..95e4a5d5d2af 100644 --- a/sys/arm/arm/pmap-v6.c +++ b/sys/arm/arm/pmap-v6.c @@ -223,11 +223,13 @@ int pmap_debug_level = 1; /* * PTE2 descriptors creation macros. */ +#define PTE2_TEX_DEFAULT memattr_to_tex2(VM_MEMATTR_DEFAULT) + #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_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_KRW(pa) PTE2_KERN(pa, PTE2_AP_KRW, PTE2_TEX_DEFAULT) +#define PTE2_KRO(pa) PTE2_KERN(pa, PTE2_AP_KR, PTE2_TEX_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 tex_attr2[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 +memattr_to_tex2(vm_memattr_t ma) +{ + + KASSERT(ma < 5, ("%s: bad vm_memattr_t %d", __func__, ma)); + return (tex_attr2[(u_int)ma]); +} + +static inline uint32_t +page_tex2(vm_page_t m) +{ + + return (memattr_to_tex2(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_TEX_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 = memattr_to_tex2(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_TEX_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_TEX_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; } /* @@ -1561,8 +1594,7 @@ pmap_pt2pg_zero(vm_page_t m) mtx_lock(&sysmaps->lock); 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)); + pte2_store(sysmaps->CMAP2, PTE2_KERN_NG(pa, PTE2_AP_KRW, page_tex2(m))); /* Even VM_ALLOC_ZERO request is only advisory. */ if ((m->flags & PG_ZERO) == 0) pagezero(sysmaps->CADDR2); @@ -1586,7 +1618,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 +1749,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) != page_tex2(m))) { anychanged++; pte2_store(pte2p, PTE2_KERN(pa, PTE2_AP_KRW, - m->md.pat_mode)); + page_tex2(m))); } pte2p++; } @@ -3770,7 +3802,7 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, /* * Now validate mapping with desired protection/wiring. */ - npte2 = PTE2(pa, PTE2_NM, m->md.pat_mode); + npte2 = PTE2(pa, PTE2_NM, page_tex2(m)); if (prot & VM_PROT_WRITE) { if (pte2_is_managed(npte2)) vm_page_aflag_set(m, PGA_WRITEABLE); @@ -3795,7 +3827,7 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, */ 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 +3842,7 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, * (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 +4442,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, page_tex2(m))); return (mpt2pg); } @@ -4481,14 +4513,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(page_tex2(m)))); pmap_pte1_mappings++; CTR3(KTR_PMAP, "%s: success for va %#lx in pmap %p", __func__, va, @@ -4552,7 +4584,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 +4630,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(memattr_to_tex2(pat_mode)); PMAP_LOCK(pmap); for (pa = pte2_pa; pa < pte2_pa + size; pa += PTE1_SIZE) { pte1p = pmap_pte1(pmap, addr); @@ -5492,7 +5524,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, + memattr_to_tex2(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 +5616,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)); + page_tex2(m))); pagezero(sysmaps->CADDR2); pte2_clear(sysmaps->CMAP2); tlb_flush((vm_offset_t)sysmaps->CADDR2); @@ -5608,7 +5641,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)); + page_tex2(m))); if (off == 0 && size == PAGE_SIZE) pagezero(sysmaps->CADDR2); else @@ -5633,7 +5666,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)); + page_tex2(m))); pagezero(CADDR3); pte2_clear(CMAP3); tlb_flush((vm_offset_t)CADDR3); @@ -5659,9 +5692,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, page_tex2(src))); pte2_store(sysmaps->CMAP2, PTE2_KERN_NG(VM_PAGE_TO_PHYS(dst), - PTE2_AP_KRW, dst->md.pat_mode)); + PTE2_AP_KRW, page_tex2(dst))); bcopy(sysmaps->CADDR1, sysmaps->CADDR2, PAGE_SIZE); pte2_clear(sysmaps->CMAP1); tlb_flush((vm_offset_t)sysmaps->CADDR1); @@ -5698,10 +5731,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, page_tex2(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, page_tex2(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 +5764,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))); + page_tex2(m))); return (qmap_addr); } @@ -5993,13 +6026,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 = memattr_to_tex2(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; @@ -6073,7 +6108,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, page_tex2(m)); } /* * I-cache is VIPT. Only way how to flush all virtual mappings @@ -6101,7 +6136,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, page_tex2(m)); } } /* @@ -6298,7 +6333,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)); + page_tex2(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/include/pmap-v6.h b/sys/arm/include/pmap-v6.h index b380c29dded0..067897779a20 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) /* diff --git a/sys/arm/include/vm.h b/sys/arm/include/vm.h index 552460e9f9a9..eb670256f47c 100644 --- a/sys/arm/include/vm.h +++ b/sys/arm/include/vm.h @@ -34,11 +34,11 @@ #if __ARM_ARCH >= 6 #include -#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 */ From 996520c667b5c94ff6e02725612083dc93269da3 Mon Sep 17 00:00:00 2001 From: br Date: Thu, 4 Feb 2016 14:30:46 +0000 Subject: [PATCH 052/129] Access pcpup using gp register. --- sys/riscv/include/asm.h | 4 +--- sys/riscv/riscv/exception.S | 4 +--- sys/riscv/riscv/swtch.S | 14 ++++---------- 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/sys/riscv/include/asm.h b/sys/riscv/include/asm.h index fb0c8442fc4f..adcc23aa9501 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/riscv/exception.S b/sys/riscv/riscv/exception.S index 8bd9027313b3..814fcf67b9d8 100644 --- a/sys/riscv/riscv/exception.S +++ b/sys/riscv/riscv/exception.S @@ -182,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/swtch.S b/sys/riscv/riscv/swtch.S index 5e9b3c986238..c6336a968d15 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 @@ -103,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) From d3b54cd6b114f5967773ce8d87f268875ca5d31a Mon Sep 17 00:00:00 2001 From: mmel Date: Thu, 4 Feb 2016 14:32:48 +0000 Subject: [PATCH 053/129] ARM: For ARMv6/v7, code in locore.S initializes SCTLR and ACTRL registers. Don't duplicate this initialization in cpu_setup(). --- sys/arm/arm/cpufunc.c | 112 ------------------------------------------ 1 file changed, 112 deletions(-) diff --git a/sys/arm/arm/cpufunc.c b/sys/arm/arm/cpufunc.c index a2b8180e56a5..139899139346 100644 --- a/sys/arm/arm/cpufunc.c +++ b/sys/arm/arm/cpufunc.c @@ -966,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; @@ -1018,18 +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 */ - cpu_control(~cpuctrl_wax, cpuctrl); - tmp = cp15_actlr_get(); tmp2 = tmp; tmp &= auxctrl_wax; @@ -1037,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 */ @@ -1048,32 +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 */ - cpu_control(0xFFFFFFFF, cpuctrl); - - /* And again. */ - cpu_idcache_wbinv_all(); - cpu_scc_setup_ccnt(); } #endif /* CPU_MV_PJ4B */ @@ -1083,44 +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 */ - 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(); } From be3acaf3333f8339b4359538cd31ad24be8791f0 Mon Sep 17 00:00:00 2001 From: trasz Date: Thu, 4 Feb 2016 15:10:08 +0000 Subject: [PATCH 054/129] Reduce code duplication. MFC after: 1 month Sponsored by: The FreeBSD Foundation --- bin/dd/args.c | 82 +++++++++++++++++++++------------------------------ 1 file changed, 34 insertions(+), 48 deletions(-) diff --git a/bin/dd/args.c b/bin/dd/args.c index 2f197f8da505..21e4aa1cb089 100644 --- a/bin/dd/args.c +++ b/bin/dd/args.c @@ -360,6 +360,38 @@ 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 '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 +418,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 +468,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; From c73d67730ab2dedcdc1b171947392eecc94ba6dd Mon Sep 17 00:00:00 2001 From: trasz Date: Thu, 4 Feb 2016 15:21:01 +0000 Subject: [PATCH 055/129] Add 't' and 'p' postfixes to dd(1). MFC after: 1 month Sponsored by: The FreeBSD Foundation --- bin/dd/args.c | 8 ++++++++ bin/dd/dd.1 | 7 +++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/bin/dd/args.c b/bin/dd/args.c index 21e4aa1cb089..1cbf3b374cf1 100644 --- a/bin/dd/args.c +++ b/bin/dd/args.c @@ -383,6 +383,14 @@ postfix_to_mult(const char expr) 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); diff --git a/bin/dd/dd.1 b/bin/dd/dd.1 index 0908642dd1cf..4047cdca57f5 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 From 55fda5017767c3c7da549cc9a384bc668e70e185 Mon Sep 17 00:00:00 2001 From: kib Date: Thu, 4 Feb 2016 16:32:21 +0000 Subject: [PATCH 056/129] Do not copy by field when converting struct oexport_args to struct export_args on mount update, bzero() is consistent with vfs_oexport_conv(). Make the code structure more explicit by using switch. Return EINVAL if export option layout (deduced from size) is unknown. Based on the submission by: bde Sponsored by: The FreeBSD Foundation --- sys/kern/vfs_mount.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index 3ca995fea0d1..505da758ed4a 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; } } From 992d44365d2db42521c58f221c374be13f5c9e35 Mon Sep 17 00:00:00 2001 From: mmel Date: Thu, 4 Feb 2016 17:01:38 +0000 Subject: [PATCH 057/129] Replace broken implementation of fuswintr() and suswintr() by functions which return -1 as well as on tier 1 archs. Remove block_userspace_access used only in these implementations. (1) These functions may be called in interrupt context and pcb_onfault can be already set in this time. Thus, prior pcb_onfault must be saved and restored afterwards. (2) The check that an abort came either from nested interrupt or while in critical section or holding not sleepable lock must be avoided for this case. These functions are called only for profiling reason, so there will be only small gain by making the code more complex. --- sys/arm/arm/cpufunc_asm_xscale.S | 19 +----- sys/arm/arm/cpufunc_asm_xscale_c3.S | 20 +------ sys/arm/arm/elf_trampoline.c | 1 - sys/arm/arm/fusu.S | 91 +---------------------------- sys/arm/arm/trap-v6.c | 8 --- sys/arm/arm/trap.c | 9 --- 6 files changed, 6 insertions(+), 142 deletions(-) diff --git a/sys/arm/arm/cpufunc_asm_xscale.S b/sys/arm/arm/cpufunc_asm_xscale.S index 3031b8c150f9..8b9848ccb15f 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 cb770a8b873a..4e2c99999cac 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/elf_trampoline.c b/sys/arm/arm/elf_trampoline.c index e25a849c812b..22f0f44ae575 100644 --- a/sys/arm/arm/elf_trampoline.c +++ b/sys/arm/arm/elf_trampoline.c @@ -125,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/fusu.S b/sys/arm/arm/fusu.S index 54d263c7984a..ba50e67f8656 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/trap-v6.c b/sys/arm/arm/trap-v6.c index 88aec53ab442..9c0799950d1b 100644 --- a/sys/arm/arm/trap-v6.c +++ b/sys/arm/arm/trap-v6.c @@ -70,7 +70,6 @@ __FBSDID("$FreeBSD$"); #include #endif -extern char fusubailout[]; extern char cachebailout[]; #ifdef DEBUG @@ -445,13 +444,6 @@ abort_handler(struct trapframe *tf, int prefetch) goto out; } - /* 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 e43ec8eb3eb2..eb4d68304b33 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 From 1721d478e5d586aabc1829702996b4a44802fcad Mon Sep 17 00:00:00 2001 From: dteske Date: Thu, 4 Feb 2016 17:09:43 +0000 Subject: [PATCH 058/129] Fix grammar in error statement s/consider to migrate to jail.conf/consider migrating to jail.conf/ --- etc/rc.d/jail | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/rc.d/jail b/etc/rc.d/jail index fa0bc46be6ee..b33f1b9a2c23 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 } From 327df1a84adbc8d73c704c55a2b3ceaacb6cdd96 Mon Sep 17 00:00:00 2001 From: andrew Date: Thu, 4 Feb 2016 17:22:15 +0000 Subject: [PATCH 059/129] Enable checking of the stack alignment. The stack should be aligned to a 16-byte value. With this the hardware will check if a memory access uses an incorrectly aligned stack pointer as the base address. Sponsored by: ABT Systems Ltd --- sys/arm64/arm64/locore.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/arm64/arm64/locore.S b/sys/arm64/arm64/locore.S index 9909a42472d9..87abee18e483 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: From a4232236fc1def9db170b2b0c3f27704b202f294 Mon Sep 17 00:00:00 2001 From: jhb Date: Thu, 4 Feb 2016 17:43:56 +0000 Subject: [PATCH 060/129] Fix build of powerpc FPU emulator after changes in r295132 to restore the ABI of struct fpreg. The FPU emulator operates on the "raw" FPU state stored in the pcb rather than the "cooked" fpreg state used for ptrace() and cores. Reported by: bz --- sys/powerpc/fpu/fpu_emu.c | 42 +++++++++++++++++------------------ sys/powerpc/fpu/fpu_explode.c | 6 ++--- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/sys/powerpc/fpu/fpu_emu.c b/sys/powerpc/fpu/fpu_emu.c index 9056dca8aa23..011b9999db99 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<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 1ebd96eccdc4..84073a4edb26 100644 --- a/sys/powerpc/fpu/fpu_explode.c +++ b/sys/powerpc/fpu/fpu_explode.c @@ -53,7 +53,7 @@ __FBSDID("$FreeBSD$"); #include #include -#include +#include #include #include @@ -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; From 6c66e4feff3a0557cfef7a815c48885d2e8465e7 Mon Sep 17 00:00:00 2001 From: jgh Date: Thu, 4 Feb 2016 18:03:06 +0000 Subject: [PATCH 061/129] - connect(2) Clarify namelen PR: 206838 Submitted by: t@tobik.me Approved by: bcr (mentor) MFH: after 1 week Differential Revision: https://reviews.freebsd.org/D5194 --- lib/libc/sys/connect.2 | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/libc/sys/connect.2 b/lib/libc/sys/connect.2 index e3e57831475a..80f440715b83 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. From ad65b26786a9160789d37051277ea5c34c98113b Mon Sep 17 00:00:00 2001 From: tuexen Date: Thu, 4 Feb 2016 18:08:50 +0000 Subject: [PATCH 062/129] In FreeBSD 10 and higher the driver announces SCTP checksum offloading support also for 82598, which doesn't support it. The legacy code has a check for it, which was missed when the code for dealing with CSUM_IP6_* was added. Add the same check for FreeBSD 10 and higher. Differential Revision: https://reviews.freebsd.org/D5192 --- sys/dev/ixgbe/if_ix.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/sys/dev/ixgbe/if_ix.c b/sys/dev/ixgbe/if_ix.c index c6a50840d207..f0e218fab1ed 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; } From 90ae570ac2c2e37f4c958f0dc31bd40995034958 Mon Sep 17 00:00:00 2001 From: rpokala Date: Thu, 4 Feb 2016 19:53:54 +0000 Subject: [PATCH 063/129] Add defines for WRITE_UNCORRECTABLE ATA command, and improve command logging Add #defines for ATA_WRITE_UNCORRECTABLE48 and its features. Update the decoding in ATACAM to recognize the new values. Also improve command decoding for a few other commands (SMART, NOP, SET_FEATURES). Bring the decoding in ata(4) up to parity with ATACAM. Reviewed by: mav, imp MFC after: 1 month Sponsored by: Panasas, Inc. Differential Revision: https://reviews.freebsd.org/D5181 --- sys/cam/ata/ata_all.c | 60 ++++++++++++++++++------- sys/dev/ata/ata-all.c | 100 ++++++++++++++++++++++++++++++++++++++---- sys/sys/ata.h | 3 ++ 3 files changed, 138 insertions(+), 25 deletions(-) diff --git a/sys/cam/ata/ata_all.c b/sys/cam/ata/ata_all.c index d836e42d59d7..d5220e874c78 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/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index 118e38e30a19..8cefa9e09cd1 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/sys/ata.h b/sys/sys/ata.h index 272b46a553d5..5df610e0da09 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 */ From 977f53633ffa1e668405525673a702136b3c640d Mon Sep 17 00:00:00 2001 From: kib Date: Thu, 4 Feb 2016 20:55:49 +0000 Subject: [PATCH 064/129] When matching brand to the ELF binary by notes, try to find a brand with interpreter name exactly matching one wanted by the binary. If no such brand exists, return first brand which accepted the binary by note. The change fixes a regression after r292749, where e.g. our two ia32 compat brands, ia32_brand_info and ia32_brand_oinfo, only differ by the interpeter path and binary matches to a brand by linkage order. Then old binaries which require /usr/libexec/ld-elf.so.1 but matched against ia32_brand_info with interp_path /libexec/ld-elf.so.1, were considered requiring non-standard interpreter name, and magic to force ld-elf32.so.1 did not happen. Note that it might make sense to apply the same selection of brands for other matching criteria, SCO EI_OSABI and 3.x string. Reported and tested by: dwmalone Sponsored by: The FreeBSD Foundation MFC after: 3 days --- sys/kern/imgact_elf.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index 8a7a11a242d9..43d48000d140 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++) { From 143293cd0e96902ba910edb7b993a70502143f22 Mon Sep 17 00:00:00 2001 From: gnn Date: Thu, 4 Feb 2016 21:39:58 +0000 Subject: [PATCH 065/129] Summary: Remove discussion of fastforwarding. --- share/man/man4/inet.4 | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/share/man/man4/inet.4 b/share/man/man4/inet.4 index a1d0a1cf82e3..0130eec842ff 100644 --- a/share/man/man4/inet.4 +++ b/share/man/man4/inet.4 @@ -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 From 8f5a4a0c37a15b8926c68a84deed6a9239093d32 Mon Sep 17 00:00:00 2001 From: gnn Date: Thu, 4 Feb 2016 21:46:37 +0000 Subject: [PATCH 066/129] Summary: Update the date --- share/man/man4/inet.4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/man/man4/inet.4 b/share/man/man4/inet.4 index 0130eec842ff..07e7354e6083 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 From 1a98ff983495d0d6b92bcce40e94a080aa22bab7 Mon Sep 17 00:00:00 2001 From: adrian Date: Thu, 4 Feb 2016 22:39:27 +0000 Subject: [PATCH 067/129] Provide a workaround for setting the correct endianness when doing CFI on a mips big-endian board. This is (hopefully! ish!) a temporary change until a slightly better way can be found to express this without a config option. Tested: * BUFFALO WZR-HP-G300NH 1stGen (by submitter) Submitted by: Mori Hiroki --- sys/conf/options | 1 + sys/dev/cfi/cfi_core.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/sys/conf/options b/sys/conf/options index c7cd58181e8b..f1b2af473ceb 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/dev/cfi/cfi_core.c b/sys/dev/cfi/cfi_core.c index 5150b779f0e5..d292e1a4188b 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; } } From 3335a0f964ba16c7a46b893e3912aca5aca9e464 Mon Sep 17 00:00:00 2001 From: scottl Date: Thu, 4 Feb 2016 23:38:55 +0000 Subject: [PATCH 068/129] Add sysctls for dumping out the device mapping tables. I'm finding this useful for debugging device-target translation bugs. MFC after: 3 days Sponsored by: Netflix --- sys/dev/mps/mps.c | 8 ++++++ sys/dev/mps/mps_mapping.c | 59 +++++++++++++++++++++++++++++++++++++++ sys/dev/mps/mpsvar.h | 2 ++ 3 files changed, 69 insertions(+) diff --git a/sys/dev/mps/mps.c b/sys/dev/mps/mps.c index 4080fc678fc1..5f183416e5ea 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 d96f33cdd919..351625be4817 100644 --- a/sys/dev/mps/mps_mapping.c +++ b/sys/dev/mps/mps_mapping.c @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -2263,3 +2264,61 @@ mps_mapping_ir_config_change_event(struct mps_softc *sc, 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 96bb4e1cfa64..0cb51a0a3b19 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); From 4b1b0d73e2df6a6716d3b447b0e18133218ee66b Mon Sep 17 00:00:00 2001 From: sephe Date: Fri, 5 Feb 2016 03:46:53 +0000 Subject: [PATCH 069/129] hyperv/stor: Fix the NULL pointer dereference Reported by: Netapp Submitted by: Hongjiang Zhang Reviewed by: adrian, sephe, Dexuan Cui Approved by: adrian (mentor) MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D5097 --- sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c b/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c index 098c8c9fda70..9683ad8f4ec4 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); From 072319c51c99365ea0478266ce51c6192d07afa8 Mon Sep 17 00:00:00 2001 From: sephe Date: Fri, 5 Feb 2016 04:03:50 +0000 Subject: [PATCH 070/129] hyperv/hn: Avoid duplicate csum features settings - Record csum features in softc, so we don't need to duplicate the logic from attach path to ioctl path. - Protect if_capenable and if_hwassist changes by main lock. - Prefer turn on/off bits in if_hwassist explicitly instead of using XOR. Reviewed by: adrian, Hongjiang Zhang Approved by: adrian (mentor) MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D5085 --- sys/dev/hyperv/netvsc/hv_net_vsc.h | 2 + sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 64 +++++++++---------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.h b/sys/dev/hyperv/netvsc/hv_net_vsc.h index c19034043e38..de960cb1acd1 100644 --- a/sys/dev/hyperv/netvsc/hv_net_vsc.h +++ b/sys/dev/hyperv/netvsc/hv_net_vsc.h @@ -1043,6 +1043,8 @@ typedef struct hn_softc { u_long hn_txdma_failed; u_long hn_tx_collapsed; u_long hn_tx_chimney; + + uint64_t hn_csum_assist; } hn_softc_t; diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index ab88e367106d..2b752f55abaf 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -176,6 +176,14 @@ struct hn_txdesc { CSUM_IP_ISCSI|CSUM_IP6_UDP|CSUM_IP6_TCP|CSUM_IP6_SCTP| \ CSUM_IP6_TSO|CSUM_IP6_ISCSI) +/* + * Only enable UDP checksum offloading when it is on 2012R2 or + * later. UDP checksum offloading doesn't work on earlier + * Windows releases. + */ +#define HN_CSUM_ASSIST_WIN8 (CSUM_TCP) +#define HN_CSUM_ASSIST (CSUM_UDP | CSUM_TCP) + /* XXX move to netinet/tcp_lro.h */ #define HN_LRO_HIWAT_MAX 65535 #define HN_LRO_HIWAT_DEF HN_LRO_HIWAT_MAX @@ -444,15 +452,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) @@ -1506,47 +1511,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: From f74912c36af597a5dfb50308315ee2d73390dac3 Mon Sep 17 00:00:00 2001 From: sephe Date: Fri, 5 Feb 2016 04:10:04 +0000 Subject: [PATCH 071/129] hyperv/hn: Reorganize TX csum offloading - For non-TSO offloading, we don't need to access mbuf to know which csum offloading is requested, we can just use the CSUM_{IP,TCP,UDP} in the csum_flags. - For TSO offloading, we still can depend on CSUM_{TSO4,TSO6} in the csum_flags to tell whether the TSO packet is an IPv4 TSO packet or an IPv6 TSO packet. This streamlines csum offloading handling (remove the two goto) and allows us the nuke the unnecessary get_transport_proto_type(). Reviewed by: adrian, Hongjiang Zhang Approved by: adrian (mentor) MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D5098 --- sys/dev/hyperv/netvsc/hv_net_vsc.h | 3 +- sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 210 +++++------------- 2 files changed, 60 insertions(+), 153 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.h b/sys/dev/hyperv/netvsc/hv_net_vsc.h index de960cb1acd1..31d023ac7ef0 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; @@ -1043,8 +1044,6 @@ typedef struct hn_softc { u_long hn_txdma_failed; u_long hn_tx_collapsed; u_long hn_tx_chimney; - - uint64_t hn_csum_assist; } hn_softc_t; diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index 2b752f55abaf..ccfb8c39a084 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -166,16 +166,6 @@ struct hn_txdesc { #define HN_TXD_FLAG_ONLIST 0x1 #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. - */ -#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) - /* * Only enable UDP checksum offloading when it is on 2012R2 or * later. UDP checksum offloading doesn't work on earlier @@ -265,62 +255,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) { @@ -783,16 +717,13 @@ hn_start_locked(struct ifnet *ifp, int len) 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; 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; if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != IFF_DRV_RUNNING) @@ -872,101 +803,78 @@ hn_start_locked(struct ifnet *ifp, int len) 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)) { - ether_len = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN; - } 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; - } + struct ether_vlan_header *eh; + int ether_len; - /* 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); + 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; + } else { + ether_len = ETHER_HDR_LEN; + } - if (trans_proto_type & (TYPE_IPV4 << 16)) { - csum_info->xmit.is_ipv4 = 1; - } else { - csum_info->xmit.is_ipv6 = 1; - } + rndis_msg_size += RNDIS_TSO_PPI_SIZE; + rppi = hv_set_rppi_data(rndis_mesg, RNDIS_TSO_PPI_SIZE, + tcp_large_send_info); - 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; - } + tso_info = (rndis_tcp_tso_info *)((char *)rppi + + rppi->per_packet_info_offset); + tso_info->lso_v2_xmit.type = + RNDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE; - 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 + - 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)) { - 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)); - } + 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)); + } #endif #if defined(INET6) && defined(INET) - else + else #endif #ifdef INET6 - { - struct ip6_hdr *ip6 = - (struct ip6_hdr *)(m_head->m_data + ether_len); - struct tcphdr *th = (struct tcphdr *)(ip6 + 1); + { + 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 = - RNDIS_TCP_LARGE_SEND_OFFLOAD_IPV6; - ip6->ip6_plen = 0; - th->th_sum = in6_cksum_pseudo(ip6, 0, IPPROTO_TCP, 0); - } + tso_info->lso_v2_xmit.ip_version = + RNDIS_TCP_LARGE_SEND_OFFLOAD_IPV6; + ip6->ip6_plen = 0; + th->th_sum = + in6_cksum_pseudo(ip6, 0, IPPROTO_TCP, 0); + } #endif - tso_info->lso_v2_xmit.tcp_header_offset = 0; - tso_info->lso_v2_xmit.mss = m_head->m_pkthdr.tso_segsz; + 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_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); + + csum_info->xmit.is_ipv4 = 1; + 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; + } + } -pre_send: rndis_mesg->msg_len = packet->tot_data_buf_len + rndis_msg_size; packet->tot_data_buf_len = rndis_mesg->msg_len; From f8cf3cfcd0044ac1740e661a5bd94e2f10a684e8 Mon Sep 17 00:00:00 2001 From: sephe Date: Fri, 5 Feb 2016 05:01:02 +0000 Subject: [PATCH 072/129] hyperv/hn: Enable IP header checksum offloading So that: - TCP/IP stack will not do unnecessary IP header checksum for TSO packets. - Reduce guest load for non-TSO IP packets. Reviewed by: adrian Approved by: adrian (mentor) MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D5099 --- sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index ccfb8c39a084..b7bf1ef89710 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -172,7 +172,7 @@ struct hn_txdesc { * Windows releases. */ #define HN_CSUM_ASSIST_WIN8 (CSUM_TCP) -#define HN_CSUM_ASSIST (CSUM_UDP | 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 @@ -867,6 +867,9 @@ hn_start_locked(struct ifnet *ifp, int len) rppi->per_packet_info_offset); csum_info->xmit.is_ipv4 = 1; + if (m_head->m_pkthdr.csum_flags & CSUM_IP) + csum_info->xmit.ip_header_csum = 1; + if (m_head->m_pkthdr.csum_flags & CSUM_TCP) { csum_info->xmit.tcp_csum = 1; csum_info->xmit.tcp_header_offset = 0; From 25d1f76bed7e8e6f5df4963d9b9bb400cb494129 Mon Sep 17 00:00:00 2001 From: sephe Date: Fri, 5 Feb 2016 05:06:14 +0000 Subject: [PATCH 073/129] hyperv/hn: Enable UDP RXCSUM Reviewed by: adrian Approved by: adrian (mentor) MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D5102 --- sys/dev/hyperv/netvsc/hv_net_vsc.h | 1 + sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 14 ++++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.h b/sys/dev/hyperv/netvsc/hv_net_vsc.h index 31d023ac7ef0..b9dcb8597107 100644 --- a/sys/dev/hyperv/netvsc/hv_net_vsc.h +++ b/sys/dev/hyperv/netvsc/hv_net_vsc.h @@ -1036,6 +1036,7 @@ typedef struct hn_softc { 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; diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index b7bf1ef89710..95abed8a4120 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -456,6 +456,8 @@ netvsc_attach(device_t dev) 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"); @@ -1156,7 +1158,7 @@ netvsc_recv(struct hv_device *device_ctx, netvsc_packet *packet, m_new->m_pkthdr.rcvif = ifp; /* receive side checksum offload */ - if (NULL != csum_info) { + if (csum_info != NULL) { /* IP csum offload */ if (csum_info->receive.ip_csum_succeeded) { m_new->m_pkthdr.csum_flags |= @@ -1164,12 +1166,16 @@ netvsc_recv(struct hv_device *device_ctx, netvsc_packet *packet, 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) { 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 && From 2f57b75e686fe630f9eb8d2bcee5eb9463002c1a Mon Sep 17 00:00:00 2001 From: sephe Date: Fri, 5 Feb 2016 05:12:30 +0000 Subject: [PATCH 074/129] hyperv/hn: Add sysctls to trust host side UDP and IP csum verification Reviewed by: adrian, Hongjiang Zhang Approved by: adrian (mentor) MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D5103 --- sys/dev/hyperv/netvsc/hv_net_vsc.h | 7 +- sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 80 +++++++++++++++++-- 2 files changed, 80 insertions(+), 7 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.h b/sys/dev/hyperv/netvsc/hv_net_vsc.h index b9dcb8597107..920ce7e8d577 100644 --- a/sys/dev/hyperv/netvsc/hv_net_vsc.h +++ b/sys/dev/hyperv/netvsc/hv_net_vsc.h @@ -1031,8 +1031,8 @@ 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; @@ -1047,6 +1047,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 95abed8a4120..fcaffdd0e5c0 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -210,6 +210,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; @@ -239,6 +247,7 @@ 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); @@ -335,8 +344,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); @@ -448,10 +462,21 @@ 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", @@ -460,7 +485,7 @@ netvsc_attach(device_t dev) 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", @@ -503,6 +528,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"); @@ -1206,7 +1239,7 @@ 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 (sc->hn_trust_hcsum & HN_TRUST_HCSUM_TCP) { sc->hn_csum_trusted++; m_new->m_pkthdr.csum_flags |= (CSUM_IP_CHECKED | CSUM_IP_VALID | @@ -1215,6 +1248,19 @@ 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 (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 && + (sc->hn_trust_hcsum & HN_TRUST_HCSUM_IP)) { + sc->hn_csum_trusted++; + m_new->m_pkthdr.csum_flags |= + (CSUM_IP_CHECKED | CSUM_IP_VALID); } } } @@ -1649,6 +1695,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) { From 0f6048195a8cbc8c5077108f37514f9c77145c4a Mon Sep 17 00:00:00 2001 From: sephe Date: Fri, 5 Feb 2016 05:17:48 +0000 Subject: [PATCH 075/129] hyperv/hn: Obey IFCAP_RXCSUM configure Reviewed by: adrian Approved by: adrian (mentor) MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D5104 --- sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index fcaffdd0e5c0..7f6e5d33eb91 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -1142,7 +1142,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! */ @@ -1190,18 +1190,21 @@ 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 (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/UDP csum offload */ - if (csum_info->receive.tcp_csum_succeeded || - csum_info->receive.udp_csum_succeeded) { + 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; @@ -1239,7 +1242,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_hcsum & HN_TRUST_HCSUM_TCP) { + 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 | @@ -1249,14 +1253,15 @@ 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 (sc->hn_trust_hcsum & HN_TRUST_HCSUM_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 && + } 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 |= From 3ebbdfb23a21faaa68626895a808fcdce3cc5fce Mon Sep 17 00:00:00 2001 From: sephe Date: Fri, 5 Feb 2016 05:25:11 +0000 Subject: [PATCH 076/129] hyperv/hn: Factor out hn_encap() from hn_start_locked() It will be shared w/ upcoming ifnet.if_transmit implementaion. No functional changes. Reviewed by: adrian Approved by: adrian (mentor) MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D5158 --- sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 434 +++++++++--------- 1 file changed, 220 insertions(+), 214 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index 7f6e5d33eb91..69aa20a4ddc7 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -254,6 +254,7 @@ 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) @@ -743,32 +744,236 @@ netvsc_channel_rollup(struct hv_device *device_ctx) hn_start_txeof(sc->hn_ifp); } +/* + * NOTE: + * This this function fails, then both txd and m_head0 will be freed + */ +static int +hn_encap(struct hn_softc *sc, struct hn_txdesc *txd, struct mbuf **m_head0) +{ + 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; + uint32_t rndis_msg_size; + + packet = &txd->netvsc_pkt; + packet->is_data_pkt = TRUE; + packet->tot_data_buf_len = m_head->m_pkthdr.len; + + /* + * 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_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); + + rndis_msg_size = RNDIS_MESSAGE_SIZE(rndis_packet); + + if (m_head->m_flags & M_VLANTAG) { + ndis_8021q_info *rppi_vlan_info; + + rndis_msg_size += RNDIS_VLAN_PPI_SIZE; + rppi = hv_set_rppi_data(rndis_mesg, RNDIS_VLAN_PPI_SIZE, + ieee_8021q_info); + + 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; + } + + if (m_head->m_pkthdr.csum_flags & CSUM_TSO) { + rndis_tcp_tso_info *tso_info; + struct ether_vlan_header *eh; + int ether_len; + + /* + * XXX need m_pullup and use mtodo + */ + 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; + else + ether_len = ETHER_HDR_LEN; + + 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 *)((uint8_t *)rppi + + rppi->per_packet_info_offset); + tso_info->lso_v2_xmit.type = + RNDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE; + +#ifdef INET + 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)); + } +#endif +#if defined(INET6) && defined(INET) + else +#endif +#ifdef INET6 + { + 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 = + RNDIS_TCP_LARGE_SEND_OFFLOAD_IPV6; + ip6->ip6_plen = 0; + th->th_sum = in6_cksum_pseudo(ip6, 0, IPPROTO_TCP, 0); + } +#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; + + 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); + + csum_info->xmit.is_ipv4 = 1; + if (m_head->m_pkthdr.csum_flags & CSUM_IP) + csum_info->xmit.ip_header_csum = 1; + + 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; + + /* + * 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; + } + } + + error = hn_txdesc_dmamap_load(sc, txd, &m_head, segs, &nsegs); + if (error) { + int freed; + + /* + * This mbuf is not linked w/ the txd yet, so free it now. + */ + m_freem(m_head); + *m_head0 = NULL; + + freed = hn_txdesc_put(sc, txd); + KASSERT(freed != 0, + ("fail to free txd upon txdma error")); + + 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; + + /* + * 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) { - hn_softc_t *sc = ifp->if_softc; + struct hn_softc *sc = ifp->if_softc; struct hv_device *device_ctx = vmbus_get_devctx(sc->hn_dev); - netvsc_dev *net_dev = sc->net_dev; - 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; - uint32_t rndis_msg_size = 0; if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != IFF_DRV_RUNNING) return 0; 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; + int error, send_failed = 0; struct hn_txdesc *txd; - netvsc_packet *packet; struct mbuf *m_head; IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head); @@ -793,216 +998,17 @@ hn_start_locked(struct ifnet *ifp, int len) break; } - packet = &txd->netvsc_pkt; - packet->is_data_pkt = TRUE; - /* Initialize it from the mbuf */ - packet->tot_data_buf_len = m_head->m_pkthdr.len; - - /* - * 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_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); - - rndis_msg_size = RNDIS_MESSAGE_SIZE(rndis_packet); - - /* - * If the Hyper-V infrastructure needs to embed a VLAN tag, - * initialize netvsc_packet and rppi struct values as needed. - */ - 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; - } - - if (m_head->m_pkthdr.csum_flags & CSUM_TSO) { - struct ether_vlan_header *eh; - int ether_len; - - 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; - } else { - ether_len = ETHER_HDR_LEN; - } - - 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 + - rppi->per_packet_info_offset); - tso_info->lso_v2_xmit.type = - RNDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE; - -#ifdef INET - 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)); - } -#endif -#if defined(INET6) && defined(INET) - else -#endif -#ifdef INET6 - { - 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 = - RNDIS_TCP_LARGE_SEND_OFFLOAD_IPV6; - ip6->ip6_plen = 0; - th->th_sum = - in6_cksum_pseudo(ip6, 0, IPPROTO_TCP, 0); - } -#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_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); - - csum_info->xmit.is_ipv4 = 1; - if (m_head->m_pkthdr.csum_flags & CSUM_IP) - csum_info->xmit.ip_header_csum = 1; - - 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; - - /* 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); + error = hn_encap(sc, txd, &m_head); if (error) { - int freed; - - /* - * 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")); - - sc->hn_txdma_failed++; - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + /* Both txd and m_head are freed */ continue; } - - 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; - - /* - * 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; - -do_send: - 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; - 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); From 3652c35a2d3ff5c1dd4988bb765c0007e0e950a6 Mon Sep 17 00:00:00 2001 From: sephe Date: Fri, 5 Feb 2016 05:31:31 +0000 Subject: [PATCH 077/129] hyperv/hn: Recover half of the chimney sending space We lost half of the chimney sending space, because we mis-used ffs() on a 64 bits mask, where ffsl() should be used. While I'm here: - Use system atomic operation instead. - Stringent chimney sending index assertion. Reviewed by: adrian Approved by: adrian (mentor) MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D5159 --- sys/dev/hyperv/netvsc/hv_net_vsc.c | 31 ++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.c b/sys/dev/hyperv/netvsc/hv_net_vsc.c index 8bf34a85c783..300704ff1059 100644 --- a/sys/dev/hyperv/netvsc/hv_net_vsc.c +++ b/sys/dev/hyperv/netvsc/hv_net_vsc.c @@ -136,15 +136,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; @@ -789,8 +789,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 */ From 20bba3d409e4485f894baa5adf473c71e506e05d Mon Sep 17 00:00:00 2001 From: sephe Date: Fri, 5 Feb 2016 05:38:01 +0000 Subject: [PATCH 078/129] hyperv/hn: Increase LRO entry count to 128 by default hn(4) only has one RX ring currently, so default 8 LRO entries are too small. Reviewed by: adrian Approved by: adrian (mentor) MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D5166 --- sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index 69aa20a4ddc7..81a63f20cf57 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 + \ @@ -232,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 */ @@ -334,6 +343,11 @@ netvsc_attach(device_t dev) int error; #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); @@ -417,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 @@ -547,6 +569,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); From 7430ccc0b2ffdfeff940e281d6587c8b43711180 Mon Sep 17 00:00:00 2001 From: sephe Date: Fri, 5 Feb 2016 05:44:31 +0000 Subject: [PATCH 079/129] hyperv/hn: Move LRO flush to the channel processing rollup This significantly increases LRO aggregation ratio when there are large amount of connections (improves reception performance a lot). Reviewed by: adrian Approved by: adrian (mentor) MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D5167 --- sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index 81a63f20cf57..907f3740211e 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -764,6 +764,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; @@ -1338,18 +1347,8 @@ netvsc_recv(struct hv_device *device_ctx, netvsc_packet *packet, } 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 } /* From 43993ba1f9ee4bff5c7ee1666dde2f5fc919456b Mon Sep 17 00:00:00 2001 From: sephe Date: Fri, 5 Feb 2016 05:50:53 +0000 Subject: [PATCH 080/129] hyperv/hn: Add an option to always do transmission scheduling It is off by default. This eases more experiment on hn(4). Reviewed by: adrian, Hongjiang Zhang Approved by: adrian (mentor) MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D5175 --- sys/dev/hyperv/netvsc/hv_net_vsc.h | 1 + sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.h b/sys/dev/hyperv/netvsc/hv_net_vsc.h index 920ce7e8d577..4f52e0d7c7f9 100644 --- a/sys/dev/hyperv/netvsc/hv_net_vsc.h +++ b/sys/dev/hyperv/netvsc/hv_net_vsc.h @@ -1023,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; diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index 907f3740211e..be43bf413302 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -534,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; @@ -1602,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; @@ -1613,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; @@ -1633,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 From 241c7a11bd40d303492821ebef545ea3ffbca849 Mon Sep 17 00:00:00 2001 From: sephe Date: Fri, 5 Feb 2016 07:09:58 +0000 Subject: [PATCH 081/129] hyperv: Use standard taskqueue instead of hv_work_queue HyperV code was ported from Linux. There is an implementation of work queue called hv_work_queue. In FreeBSD, taskqueue could be used for the same purpose. Convert all the consumer of hv_work_queue to use taskqueue, and remove work queue implementation. Submitted by: Jun Su Reviewed by: adrian, Hongjiang Zhang Approved by: adrian (mentor) MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D4963 --- sys/dev/hyperv/include/hyperv.h | 33 +-- sys/dev/hyperv/utilities/hv_kvp.c | 35 +-- sys/dev/hyperv/utilities/hv_util.c | 58 ++--- sys/dev/hyperv/vmbus/hv_channel_mgmt.c | 231 ++++++-------------- sys/dev/hyperv/vmbus/hv_connection.c | 7 - sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c | 22 +- sys/dev/hyperv/vmbus/hv_vmbus_priv.h | 6 +- 7 files changed, 101 insertions(+), 291 deletions(-) diff --git a/sys/dev/hyperv/include/hyperv.h b/sys/dev/hyperv/include/hyperv.h index 852e14ea5690..8e2ca57aa3ca 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/utilities/hv_kvp.c b/sys/dev/hyperv/utilities/hv_kvp.c index 58d565c44bfb..86e037ab7e79 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 dc4b1e2537ba..38054ca566ba 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_sync_data* time_msg = service_table[HV_TIME_SYNCH].task.ta_context; - time_msg = malloc(sizeof(time_sync_data), M_DEVBUF, M_NOWAIT); - - 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_mgmt.c b/sys/dev/hyperv/vmbus/hv_channel_mgmt.c index 93008aad857e..21f7d956d39c 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); @@ -234,16 +148,6 @@ hv_vmbus_allocate_channel(void) return (channel); } -/** - * @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 */ @@ -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); } /** @@ -708,35 +631,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. */ @@ -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 05b16120f303..c76028e21817 100644 --- a/sys/dev/hyperv/vmbus/hv_connection.c +++ b/sys/dev/hyperv/vmbus/hv_connection.c @@ -164,8 +164,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", @@ -269,8 +267,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); @@ -323,9 +319,6 @@ hv_vmbus_disconnect(void) { 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; diff --git a/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c b/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c index 7eac11679290..cf69c38ac998 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; diff --git a/sys/dev/hyperv/vmbus/hv_vmbus_priv.h b/sys/dev/hyperv/vmbus/hv_vmbus_priv.h index 538ab1e7222e..c1fdc40d1dae 100644 --- a/sys/dev/hyperv/vmbus/hv_vmbus_priv.h +++ b/sys/dev/hyperv/vmbus/hv_vmbus_priv.h @@ -362,10 +362,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 +630,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 +679,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); From 9cc4c0881fabfdb6aa445c5bcb5bbb01f5b801f4 Mon Sep 17 00:00:00 2001 From: sephe Date: Fri, 5 Feb 2016 07:20:31 +0000 Subject: [PATCH 082/129] hyperv: Use WAITOK in the places where we can wait And convert rndis non-hot path spinlock to mutex. Submitted by: Jun Su Reviewed by: adrian, sephe Approved by: adrian (mentor) MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D5081 --- sys/dev/hyperv/netvsc/hv_net_vsc.c | 17 ++------ sys/dev/hyperv/netvsc/hv_rndis_filter.c | 24 +++++------ sys/dev/hyperv/vmbus/hv_connection.c | 44 ++++----------------- sys/dev/hyperv/vmbus/hv_hv.c | 6 +-- sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c | 14 +------ 5 files changed, 22 insertions(+), 83 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.c b/sys/dev/hyperv/netvsc/hv_net_vsc.c index 300704ff1059..cd60b4969fd4 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; @@ -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; diff --git a/sys/dev/hyperv/netvsc/hv_rndis_filter.c b/sys/dev/hyperv/netvsc/hv_rndis_filter.c index dfd0b4727938..9fb78eeeb406 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/vmbus/hv_connection.c b/sys/dev/hyperv/vmbus/hv_connection.c index c76028e21817..2ea372f1a4c9 100644 --- a/sys/dev/hyperv/vmbus/hv_connection.c +++ b/sys/dev/hyperv/vmbus/hv_connection.c @@ -88,8 +88,7 @@ hv_vmbus_negotiate_version(hv_vmbus_channel_msg_info *msg_info, msg->monitor_page_1 = hv_get_phys_addr( hv_vmbus_g_connection.monitor_pages); - msg->monitor_page_2 = - hv_get_phys_addr( + msg->monitor_page_2 = hv_get_phys_addr( ((uint8_t *) hv_vmbus_g_connection.monitor_pages + PAGE_SIZE)); @@ -179,16 +178,9 @@ hv_vmbus_connect(void) { */ hv_vmbus_g_connection.interrupt_page = contigmalloc( PAGE_SIZE, M_DEVBUF, - M_NOWAIT | M_ZERO, 0UL, + M_WAITOK | 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; - } hv_vmbus_g_connection.recv_interrupt_page = hv_vmbus_g_connection.interrupt_page; @@ -204,28 +196,16 @@ hv_vmbus_connect(void) { hv_vmbus_g_connection.monitor_pages = contigmalloc( 2 * PAGE_SIZE, M_DEVBUF, - M_NOWAIT | M_ZERO, + M_WAITOK | M_ZERO, 0UL, BUS_SPACE_MAXADDR, 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; - } 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, @@ -301,19 +281,11 @@ hv_vmbus_connect(void) { int hv_vmbus_disconnect(void) { int ret = 0; - hv_vmbus_channel_unload* msg; + 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); - - 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); @@ -322,8 +294,6 @@ hv_vmbus_disconnect(void) { 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 ca5641f620bf..6afc2b8542bb 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 cf69c38ac998..8a1e4126f13e 100644 --- a/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c +++ b/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c @@ -291,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)); @@ -548,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); } } From 53270ee78850775ed6b7c609013336e470e9c5fc Mon Sep 17 00:00:00 2001 From: sephe Date: Fri, 5 Feb 2016 07:29:11 +0000 Subject: [PATCH 083/129] hyperv: Use malloc for page allocation. We will eventually convert them to use busdma. Submitted by: Jun Su Reviewed by: adrian, sephe, Dexuan Cui Approved by: adrian (mentor) MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D5087 --- sys/dev/hyperv/vmbus/hv_channel.c | 4 +--- sys/dev/hyperv/vmbus/hv_connection.c | 34 +++++++++++----------------- sys/dev/hyperv/vmbus/hv_vmbus_priv.h | 3 ++- 3 files changed, 16 insertions(+), 25 deletions(-) diff --git a/sys/dev/hyperv/vmbus/hv_channel.c b/sys/dev/hyperv/vmbus/hv_channel.c index 762ace4fe423..af7395b445f5 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_connection.c b/sys/dev/hyperv/vmbus/hv_connection.c index 2ea372f1a4c9..e60c55709fc0 100644 --- a/sys/dev/hyperv/vmbus/hv_connection.c +++ b/sys/dev/hyperv/vmbus/hv_connection.c @@ -86,11 +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)); + hv_vmbus_g_connection.monitor_page_2); /** * Add to list before we send the request since we may receive the @@ -176,11 +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_WAITOK | M_ZERO, 0UL, - BUS_SPACE_MAXADDR, - PAGE_SIZE, 0); + M_WAITOK | M_ZERO); hv_vmbus_g_connection.recv_interrupt_page = hv_vmbus_g_connection.interrupt_page; @@ -193,14 +190,14 @@ 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, - M_DEVBUF, - M_WAITOK | M_ZERO, - 0UL, - BUS_SPACE_MAXADDR, + hv_vmbus_g_connection.monitor_page_1 = malloc( PAGE_SIZE, - 0); + M_DEVBUF, + M_WAITOK | M_ZERO); + hv_vmbus_g_connection.monitor_page_2 = malloc( + PAGE_SIZE, + M_DEVBUF, + M_WAITOK | M_ZERO); msg_info = (hv_vmbus_channel_msg_info*) malloc(sizeof(hv_vmbus_channel_msg_info) + @@ -258,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); diff --git a/sys/dev/hyperv/vmbus/hv_vmbus_priv.h b/sys/dev/hyperv/vmbus/hv_vmbus_priv.h index c1fdc40d1dae..5f6207217ecc 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; /** From 7589b2ecfc389751f478e6d2c0d3f89d12676cc7 Mon Sep 17 00:00:00 2001 From: mmel Date: Fri, 5 Feb 2016 09:46:24 +0000 Subject: [PATCH 084/129] ARM: Introduce new cpu-v4.h header and move all ARMv4 specific code from cpu-v6.h to it. Remove unneeded cpu-v6.h includes. --- sys/arm/arm/cpuinfo.c | 7 +- sys/arm/arm/genassym.c | 1 - sys/arm/arm/machdep.c | 1 - sys/arm/arm/pmap-v6.c | 1 - sys/arm/arm/sys_machdep.c | 2 +- sys/arm/arm/trap-v6.c | 1 - sys/arm/include/cpu-v4.h | 154 ++++++++++++++++++++++++++++++++++++++ sys/arm/include/cpu-v6.h | 72 +++++------------- sys/arm/include/cpu.h | 8 +- 9 files changed, 181 insertions(+), 66 deletions(-) create mode 100644 sys/arm/include/cpu-v4.h diff --git a/sys/arm/arm/cpuinfo.c b/sys/arm/arm/cpuinfo.c index 5e96cae90775..b2d96a7b3ef1 100644 --- a/sys/arm/arm/cpuinfo.c +++ b/sys/arm/arm/cpuinfo.c @@ -31,8 +31,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include -#include 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/genassym.c b/sys/arm/arm/genassym.c index 4a60d9494331..41497714619f 100644 --- a/sys/arm/arm/genassym.c +++ b/sys/arm/arm/genassym.c @@ -45,7 +45,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c index b4bfa6222c86..26109d4aa521 100644 --- a/sys/arm/arm/machdep.c +++ b/sys/arm/arm/machdep.c @@ -123,7 +123,6 @@ __FBSDID("$FreeBSD$"); #include #if __ARM_ARCH >= 6 -#include DB_SHOW_COMMAND(cp15, db_show_cp15) { diff --git a/sys/arm/arm/pmap-v6.c b/sys/arm/arm/pmap-v6.c index 95e4a5d5d2af..23447d5839fe 100644 --- a/sys/arm/arm/pmap-v6.c +++ b/sys/arm/arm/pmap-v6.c @@ -141,7 +141,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #ifdef SMP diff --git a/sys/arm/arm/sys_machdep.c b/sys/arm/arm/sys_machdep.c index efebda32262e..cad26ec42974 100644 --- a/sys/arm/arm/sys_machdep.c +++ b/sys/arm/arm/sys_machdep.c @@ -45,7 +45,7 @@ __FBSDID("$FreeBSD$"); #include #include -#include +#include #include #include diff --git a/sys/arm/arm/trap-v6.c b/sys/arm/arm/trap-v6.c index 9c0799950d1b..81a6ee428f6f 100644 --- a/sys/arm/arm/trap-v6.c +++ b/sys/arm/arm/trap-v6.c @@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include #include #include diff --git a/sys/arm/include/cpu-v4.h b/sys/arm/include/cpu-v4.h new file mode 100644 index 000000000000..503ed56a698a --- /dev/null +++ b/sys/arm/include/cpu-v4.h @@ -0,0 +1,154 @@ +/*- + * Copyright 2016 Svatopluk Kraus + * Copyright 2016 Michal Meloun + * 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 +#include +#include +#include +#include + +#if __ARM_ARCH >= 6 +#error Newer 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 +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 /* _KERNEL */ + +#endif /* MACHINE_CPU_V4_H */ diff --git a/sys/arm/include/cpu-v6.h b/sys/arm/include/cpu-v6.h index bb8649ab30ba..40a7f400ba36 100644 --- a/sys/arm/include/cpu-v6.h +++ b/sys/arm/include/cpu-v6.h @@ -32,19 +32,33 @@ /* 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 -#include "machine/atomic.h" -#include "machine/cpufunc.h" -#include "machine/cpuinfo.h" -#include "machine/sysreg.h" +#include +#include +#include +#include + +#if __ARM_ARCH < 6 +#error Only include this file for ARMv6 +#else + + #define CPU_ASID_KERNEL 0 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 +#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 +291,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 +585,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 782471e725d3..0d79e68dc2b8 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 -#ifdef DEV_PMU -#include -#define PMU_OVSR_C 0x80000000 /* Cycle Counter */ -extern uint32_t ccnt_hi[MAXCPU]; -extern int pmu_attched; -#endif /* DEV_PMU */ +#else +#include #endif /* __ARM_ARCH >= 6 */ static __inline uint64_t From c0682f3da4d309573d6b42105f0f4f77766122e7 Mon Sep 17 00:00:00 2001 From: skra Date: Fri, 5 Feb 2016 10:40:01 +0000 Subject: [PATCH 085/129] Follow up r295257 and convert also pt_memattr. This did not break anything as both VM_MEMATTR_WB_WA and PTE2_ATTR_WB_WA are zero. Correct also type of pmap_dcache_wb_pou() last argument. --- sys/arm/arm/pmap-v6.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/sys/arm/arm/pmap-v6.c b/sys/arm/arm/pmap-v6.c index 23447d5839fe..cc4d3b29e453 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 - * Copyright (c) 2014 Svatopluk Kraus - * Copyright (c) 2014 Michal Meloun + * Copyright (c) 2014-2016 Svatopluk Kraus + * Copyright (c) 2014-2016 Michal Meloun * All rights reserved. * * This code is derived from software contributed to Berkeley by @@ -223,9 +223,10 @@ int pmap_debug_level = 1; * PTE2 descriptors creation macros. */ #define PTE2_TEX_DEFAULT memattr_to_tex2(VM_MEMATTR_DEFAULT) +#define PTE2_TEX_PT memattr_to_tex2(pt_memattr) -#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_KPT(pa) PTE2_KERN(pa, PTE2_AP_KRW, PTE2_TEX_PT) +#define PTE2_KPT_NG(pa) PTE2_KERN_NG(pa, PTE2_AP_KRW, PTE2_TEX_PT) #define PTE2_KRW(pa) PTE2_KERN(pa, PTE2_AP_KRW, PTE2_TEX_DEFAULT) #define PTE2_KRO(pa) PTE2_KERN(pa, PTE2_AP_KR, PTE2_TEX_DEFAULT) @@ -6071,7 +6072,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; @@ -6083,7 +6084,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); From f58eb974cee99ed66fc09089b6d118039edfc098 Mon Sep 17 00:00:00 2001 From: skra Date: Fri, 5 Feb 2016 11:28:35 +0000 Subject: [PATCH 086/129] Follow up r295257 and replace bad reference to TEX in defines, variables and functions. This stuff is named properly now. Thus, the VM_MEMATTR_xxx is an index to PTE2 attribute table. Pointy hat to: skra --- sys/arm/arm/pmap-v6.c | 73 ++++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/sys/arm/arm/pmap-v6.c b/sys/arm/arm/pmap-v6.c index cc4d3b29e453..525280c6d822 100644 --- a/sys/arm/arm/pmap-v6.c +++ b/sys/arm/arm/pmap-v6.c @@ -222,14 +222,14 @@ int pmap_debug_level = 1; /* * PTE2 descriptors creation macros. */ -#define PTE2_TEX_DEFAULT memattr_to_tex2(VM_MEMATTR_DEFAULT) -#define PTE2_TEX_PT memattr_to_tex2(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_KPT(pa) PTE2_KERN(pa, PTE2_AP_KRW, PTE2_TEX_PT) -#define PTE2_KPT_NG(pa) PTE2_KERN_NG(pa, PTE2_AP_KRW, PTE2_TEX_PT) +#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_TEX_DEFAULT) -#define PTE2_KRO(pa) PTE2_KERN(pa, PTE2_AP_KR, PTE2_TEX_DEFAULT) +#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 @@ -397,7 +397,7 @@ static uint32_t tex_class[8] = { }; #undef TEX -static uint32_t tex_attr2[8] = { +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 */ @@ -414,18 +414,18 @@ CTASSERT(VM_MEMATTR_SO == 3); CTASSERT(VM_MEMATTR_WRITE_THROUGH == 4); static inline uint32_t -memattr_to_tex2(vm_memattr_t ma) +vm_memattr_to_pte2(vm_memattr_t ma) { - KASSERT(ma < 5, ("%s: bad vm_memattr_t %d", __func__, ma)); - return (tex_attr2[(u_int)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 -page_tex2(vm_page_t m) +vm_page_pte2_attr(vm_page_t m) { - return (memattr_to_tex2(m->md.pat_mode)); + return (vm_memattr_to_pte2(m->md.pat_mode)); } /* @@ -805,7 +805,7 @@ pmap_bootstrap_prepare(vm_paddr_t last) pte1_store(pte1p++, PTE1_LINK(pa)); /* Make section mappings for kernel. */ - l1_attr = ATTR_TO_L1(PTE2_TEX_DEFAULT); + 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, l1_attr)); @@ -1022,7 +1022,7 @@ pmap_preboot_map_attr(vm_paddr_t pa, vm_offset_t va, vm_size_t size, pt2_entry_t *pte2p; l2_prot = prot & VM_PROT_WRITE ? PTE2_AP_KRW : PTE2_AP_KR; - l2_attr = memattr_to_tex2(attr); + l2_attr = vm_memattr_to_pte2(attr); l1_prot = ATTR_TO_L1(l2_prot); l1_attr = ATTR_TO_L1(l2_attr); @@ -1277,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_TEX_DEFAULT); + pmap_kenter_prot_attr(va, pa, PTE2_AP_KRW, PTE2_ATTR_DEFAULT); } /* @@ -1360,7 +1360,7 @@ 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_TEX_DEFAULT; + l2attr = PTE2_ATTR_DEFAULT; l1attr = ATTR_TO_L1(l2attr); va = *virt; @@ -1594,7 +1594,8 @@ pmap_pt2pg_zero(vm_page_t m) mtx_lock(&sysmaps->lock); if (pte2_load(sysmaps->CMAP2) != 0) panic("%s: CMAP2 busy", __func__); - pte2_store(sysmaps->CMAP2, PTE2_KERN_NG(pa, PTE2_AP_KRW, page_tex2(m))); + pte2_store(sysmaps->CMAP2, PTE2_KERN_NG(pa, PTE2_AP_KRW, + vm_page_pte2_attr(m))); /* Even VM_ALLOC_ZERO request is only advisory. */ if ((m->flags & PG_ZERO) == 0) pagezero(sysmaps->CADDR2); @@ -1749,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) != page_tex2(m))) { + (pte2_attr(pte2) != vm_page_pte2_attr(m))) { anychanged++; pte2_store(pte2p, PTE2_KERN(pa, PTE2_AP_KRW, - page_tex2(m))); + vm_page_pte2_attr(m))); } pte2p++; } @@ -3802,7 +3803,7 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, /* * Now validate mapping with desired protection/wiring. */ - npte2 = PTE2(pa, PTE2_NM, page_tex2(m)); + 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); @@ -4449,7 +4450,7 @@ pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, */ cache_icache_sync_fresh(va, pa, PAGE_SIZE); } - pte2_store(pte2p, PTE2(pa, l2prot, page_tex2(m))); + pte2_store(pte2p, PTE2(pa, l2prot, vm_page_pte2_attr(m))); return (mpt2pg); } @@ -4520,7 +4521,7 @@ pmap_enter_pte1(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot) */ cache_icache_sync_fresh(va, pa, PTE1_SIZE); } - pte1_store(pte1p, PTE1(pa, l1prot, ATTR_TO_L1(page_tex2(m)))); + 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, @@ -4630,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(memattr_to_tex2(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); @@ -5525,7 +5526,7 @@ pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma) if (*sysmaps->CMAP2) panic("%s: CMAP2 busy", __func__); pte2_store(sysmaps->CMAP2, PTE2_KERN_NG(pa, PTE2_AP_KRW, - memattr_to_tex2(ma))); + 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); @@ -5616,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, - page_tex2(m))); + vm_page_pte2_attr(m))); pagezero(sysmaps->CADDR2); pte2_clear(sysmaps->CMAP2); tlb_flush((vm_offset_t)sysmaps->CADDR2); @@ -5641,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, - page_tex2(m))); + vm_page_pte2_attr(m))); if (off == 0 && size == PAGE_SIZE) pagezero(sysmaps->CADDR2); else @@ -5666,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, - page_tex2(m))); + vm_page_pte2_attr(m))); pagezero(CADDR3); pte2_clear(CMAP3); tlb_flush((vm_offset_t)CADDR3); @@ -5692,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, page_tex2(src))); + 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, page_tex2(dst))); + 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); @@ -5731,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, page_tex2(a_pg))); + 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, page_tex2(b_pg))); + 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; @@ -5764,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, - page_tex2(m))); + vm_page_pte2_attr(m))); return (qmap_addr); } @@ -6032,7 +6033,7 @@ pmap_kenter_device(vm_offset_t va, vm_size_t size, vm_paddr_t pa) ("%s: device mapping not page-sized", __func__)); sva = va; - l2attr = memattr_to_tex2(VM_MEMATTR_DEVICE); + l2attr = vm_memattr_to_pte2(VM_MEMATTR_DEVICE); while (size != 0) { pmap_kenter_prot_attr(va, pa, PTE2_AP_KRW, l2attr); va += PAGE_SIZE; @@ -6108,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, page_tex2(m)); + pmap_dcache_wb_pou(pa, len, vm_page_pte2_attr(m)); } /* * I-cache is VIPT. Only way how to flush all virtual mappings @@ -6136,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, page_tex2(m)); + pmap_dcache_wb_pou(pa, len, vm_page_pte2_attr(m)); } } /* @@ -6333,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, - page_tex2(m))); + vm_page_pte2_attr(m))); end = (uint32_t*)(sysmaps->CADDR2 + PAGE_SIZE); for (p = (uint32_t*)sysmaps->CADDR2; p < end; p++) if (*p != 0) From fd38ead294ac15adc73d80d72d44517a82502ac2 Mon Sep 17 00:00:00 2001 From: mmel Date: Fri, 5 Feb 2016 14:57:41 +0000 Subject: [PATCH 087/129] ARM: Use new ARMv6 naming conventions for cache and TLB functions in all but ARMv4 specific files. Expand ARMv6 compatibility stubs in cpu-v4.h. Use physical address in L2 cache functions if ARM_L2_PIPT is defined. --- sys/arm/allwinner/a20/a20_mp.c | 4 +-- sys/arm/altera/socfpga/socfpga_mp.c | 4 +-- sys/arm/amlogic/aml8726/aml8726_mp.c | 3 +- sys/arm/arm/db_interface.c | 10 +++--- sys/arm/arm/dump_machdep.c | 3 +- sys/arm/arm/fiq.c | 2 +- sys/arm/arm/machdep.c | 9 ++--- sys/arm/arm/minidump_machdep.c | 7 ++-- sys/arm/arm/mp_machdep.c | 8 ++--- sys/arm/arm/sys_machdep.c | 7 +++- sys/arm/broadcom/bcm2835/bcm2836_mp.c | 4 +-- sys/arm/freescale/imx/imx6_mp.c | 3 +- sys/arm/include/cpu-v4.h | 34 ++++++++++++++++++- sys/arm/include/cpu-v6.h | 3 +- sys/arm/include/cpufunc.h | 6 ++++ sys/arm/include/kdb.h | 6 ++-- sys/arm/mv/armada38x/pmsu.c | 5 +-- sys/arm/mv/armadaxp/armadaxp_mp.c | 3 +- sys/arm/rockchip/rk30xx_mp.c | 4 +-- sys/arm/samsung/exynos/exynos5_mp.c | 4 +-- sys/arm/ti/omap4/omap4_mp.c | 5 +-- sys/arm/xilinx/zy7_mp.c | 4 +-- .../interface/vchiq_arm/vchiq_2835_arm.c | 5 ++- 23 files changed, 92 insertions(+), 51 deletions(-) diff --git a/sys/arm/allwinner/a20/a20_mp.c b/sys/arm/allwinner/a20/a20_mp.c index 27cbb3d32280..ba9ce9af0b35 100644 --- a/sys/arm/allwinner/a20/a20_mp.c +++ b/sys/arm/allwinner/a20/a20_mp.c @@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -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 46977f6f4804..e057eb3d706a 100644 --- a/sys/arm/altera/socfpga/socfpga_mp.c +++ b/sys/arm/altera/socfpga/socfpga_mp.c @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -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 779a793e3008..c5081350df09 100644 --- a/sys/arm/amlogic/aml8726/aml8726_mp.c +++ b/sys/arm/amlogic/aml8726/aml8726_mp.c @@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -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/db_interface.c b/sys/arm/arm/db_interface.c index 613dc08149cc..bc49dc6e49c0 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 +#include #include #include #include /* just for boothowto */ @@ -53,9 +54,9 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include -#include #include #include @@ -63,7 +64,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include + 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/dump_machdep.c b/sys/arm/arm/dump_machdep.c index e87d3e7c835d..2c11141c4b0e 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/fiq.c b/sys/arm/arm/fiq.c index 94231dea22c8..f475a303d3c4 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/machdep.c b/sys/arm/arm/machdep.c index 26109d4aa521..4e7cb70c84bb 100644 --- a/sys/arm/arm/machdep.c +++ b/sys/arm/arm/machdep.c @@ -396,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; @@ -478,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. */ diff --git a/sys/arm/arm/minidump_machdep.c b/sys/arm/arm/minidump_machdep.c index a351fb76095c..2eb4bfd01f86 100644 --- a/sys/arm/arm/minidump_machdep.c +++ b/sys/arm/arm/minidump_machdep.c @@ -45,11 +45,11 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include -#include #include -#include +#include 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 6cedd46e2bb5..8643860792d5 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/sys_machdep.c b/sys/arm/arm/sys_machdep.c index cad26ec42974..b893a9028561 100644 --- a/sys/arm/arm/sys_machdep.c +++ b/sys/arm/arm/sys_machdep.c @@ -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/broadcom/bcm2835/bcm2836_mp.c b/sys/arm/broadcom/bcm2835/bcm2836_mp.c index 93cc0d862d86..d6c84cbd1244 100644 --- a/sys/arm/broadcom/bcm2835/bcm2836_mp.c +++ b/sys/arm/broadcom/bcm2835/bcm2836_mp.c @@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -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/freescale/imx/imx6_mp.c b/sys/arm/freescale/imx/imx6_mp.c index 3208f676e6ff..7aa9aab708d1 100644 --- a/sys/arm/freescale/imx/imx6_mp.c +++ b/sys/arm/freescale/imx/imx6_mp.c @@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -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 index 503ed56a698a..0d66dee42bc3 100644 --- a/sys/arm/include/cpu-v4.h +++ b/sys/arm/include/cpu-v4.h @@ -41,7 +41,7 @@ #include #if __ARM_ARCH >= 6 -#error Newer include this file for ARMv6 +#error Never include this file for ARMv6 #else #define CPU_ASID_KERNEL 0 @@ -124,12 +124,29 @@ _RF0(cp15_tlbtr_get, CP15_TLBTR(%0)) * 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 @@ -137,7 +154,11 @@ 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); } @@ -146,7 +167,18 @@ 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 */ diff --git a/sys/arm/include/cpu-v6.h b/sys/arm/include/cpu-v6.h index 40a7f400ba36..e537c10b4d4e 100644 --- a/sys/arm/include/cpu-v6.h +++ b/sys/arm/include/cpu-v6.h @@ -44,10 +44,9 @@ #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); diff --git a/sys/arm/include/cpufunc.h b/sys/arm/include/cpufunc.h index afbcac834f13..eb445b49abcf 100644 --- a/sys/arm/include/cpufunc.h +++ b/sys/arm/include/cpufunc.h @@ -161,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() @@ -181,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() diff --git a/sys/arm/include/kdb.h b/sys/arm/include/kdb.h index fb50c78ef94e..c7968ab6e8b2 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 +#include #include #include -#include -#include #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/mv/armada38x/pmsu.c b/sys/arm/mv/armada38x/pmsu.c index a84ede02a4a3..110278b4f181 100644 --- a/sys/arm/mv/armada38x/pmsu.c +++ b/sys/arm/mv/armada38x/pmsu.c @@ -36,10 +36,12 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include +#include #include #include @@ -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 4ccf7e3ef360..52f35084a4bd 100644 --- a/sys/arm/mv/armadaxp/armadaxp_mp.c +++ b/sys/arm/mv/armadaxp/armadaxp_mp.c @@ -40,6 +40,7 @@ #include +#include #include #include #include @@ -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 38b6b41e13c7..5de2eff14757 100644 --- a/sys/arm/rockchip/rk30xx_mp.c +++ b/sys/arm/rockchip/rk30xx_mp.c @@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -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 8eb0d29fcedd..44b2844ce254 100644 --- a/sys/arm/samsung/exynos/exynos5_mp.c +++ b/sys/arm/samsung/exynos/exynos5_mp.c @@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -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 1a095ab6444c..6cea1cc697d2 100644 --- a/sys/arm/ti/omap4/omap4_mp.c +++ b/sys/arm/ti/omap4/omap4_mp.c @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -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 f71740ce395c..74528ef870b2 100644 --- a/sys/arm/xilinx/zy7_mp.c +++ b/sys/arm/xilinx/zy7_mp.c @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -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/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c index 753e8e510631..e325f6ed777a 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 #include +#include #include #include @@ -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); From 277002da84c3e33d12853e5396d1cddb7389b400 Mon Sep 17 00:00:00 2001 From: smh Date: Fri, 5 Feb 2016 15:35:33 +0000 Subject: [PATCH 088/129] Fix EFI multi device boot support Fix EFI boot support when presented with multiple valid boot partitions across multiple devices. It now prefers to boot from partitions that are present on the underlying device that the boot1 image was loaded from. This means that it will boot from the partitions on device the user chose from EFI boot menu in preference to those on other devices. Also fixed is the recovery from a failed attempt to boot, from a seemingly valid partition, by continuing to trying all other available partitions no matter what the error. boot1 now use * to signify a partition what was accepted from the preferred device and + otherwise. Finally some error messages where improved and DPRINTF's with slowed boot to aid debugging. ZFS will still be preferred over UFS when both are available on the boot device. Reviewed by: imp MFC after: 1 week Sponsored by: Multiplay Differential Revision: https://reviews.freebsd.org/D5108 --- sys/boot/efi/boot1/boot1.c | 560 ++++++++++++++++++++++++------- sys/boot/efi/boot1/boot_module.h | 13 +- sys/boot/efi/boot1/ufs_module.c | 55 ++- sys/boot/efi/boot1/zfs_module.c | 59 ++-- sys/boot/efi/include/efidevp.h | 13 +- 5 files changed, 518 insertions(+), 182 deletions(-) diff --git a/sys/boot/efi/boot1/boot1.c b/sys/boot/efi/boot1/boot1.c index c326c79d77ad..1161b0a1e58a 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) { - size_t bufsize, cmdsize; - void *buf; + 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) +{ + 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 2c158f6dd821..296d5a67a10b 100644 --- a/sys/boot/efi/boot1/boot_module.h +++ b/sys/boot/efi/boot1/boot_module.h @@ -36,9 +36,11 @@ #include #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 07c7152f342c..63087ea22fa7 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) - return (EFI_UNSUPPORTED); + DPRINTF("Loading '%s' from %s\n", filepath, devpath_str(dev->devpath)); - if ((ino = lookup(loader_path)) == 0) + if (init_dev(dev) < 0) { + DPRINTF("Failed to init device\n"); + return (EFI_UNSUPPORTED); + } + + 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 96eec332f16a..4e2c5c4681c1 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 %zu 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 f0f49efc3fff..dda79de7af13 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 From a718ec05809255deb93481e75282825de5dc21b5 Mon Sep 17 00:00:00 2001 From: andrew Date: Fri, 5 Feb 2016 15:38:28 +0000 Subject: [PATCH 089/129] Implement kdb_cpu_sync_icache on arm64. Sponsored by: ABT Systems Ltd --- sys/arm64/include/kdb.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/arm64/include/kdb.h b/sys/arm64/include/kdb.h index e4f4f70a4a71..2f7306ef669b 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 From 9accef3f0f76cde9f02a5d55f391aa02355ddc2b Mon Sep 17 00:00:00 2001 From: erj Date: Fri, 5 Feb 2016 17:14:37 +0000 Subject: [PATCH 090/129] Update em(4) to 7.6.1; update igb(4) to 2.5.3. Major changes: - Add i219/i219(2) hardware support. (Found on Skylake generation and newer chipsets.) - Further to the last Skylake support diff, this one also includes support for the Lewisburg chipset (i219(3)). - Add a workaround to an igb hardware errata. All 1G server products need to have IPv6 extension header parsing turned off. This should be listed in the specification updates for current 1G server products, e.g. for i350 it's errata #37 in this document: http://www.intel.com/content/dam/www/public/us/en/documents/specification-updates/ethernet-controller-i350-spec-update.pdf - Avoton (i354) PHY errata workaround added And a bunch of minor fixes, as well as #defines for things that the current em(4)/igb(4) drivers don't implement. Differential Revision: https://reviews.freebsd.org/D3162 Reviewed by: sbruno, marius, gnn Approved by: gnn MFC after: 2 weeks Sponsored by: Intel Corporation --- sys/dev/e1000/e1000_80003es2lan.c | 33 +- sys/dev/e1000/e1000_82540.c | 10 +- sys/dev/e1000/e1000_82541.c | 7 +- sys/dev/e1000/e1000_82542.c | 4 +- sys/dev/e1000/e1000_82543.c | 4 +- sys/dev/e1000/e1000_82571.h | 5 +- sys/dev/e1000/e1000_82575.c | 169 +++++- sys/dev/e1000/e1000_82575.h | 5 +- sys/dev/e1000/e1000_api.c | 8 + sys/dev/e1000/e1000_defines.h | 11 +- sys/dev/e1000/e1000_hw.h | 8 +- sys/dev/e1000/e1000_i210.c | 30 + sys/dev/e1000/e1000_ich8lan.c | 952 +++++++++++++++++++++++++++--- sys/dev/e1000/e1000_ich8lan.h | 30 +- sys/dev/e1000/e1000_mac.h | 2 - sys/dev/e1000/e1000_mbx.c | 36 +- sys/dev/e1000/e1000_nvm.h | 2 - sys/dev/e1000/e1000_osdep.h | 25 +- sys/dev/e1000/e1000_phy.c | 10 +- sys/dev/e1000/e1000_regs.h | 9 + sys/dev/e1000/if_em.c | 166 +++++- sys/dev/e1000/if_em.h | 3 + sys/dev/e1000/if_igb.c | 14 +- 23 files changed, 1348 insertions(+), 195 deletions(-) diff --git a/sys/dev/e1000/e1000_80003es2lan.c b/sys/dev/e1000/e1000_80003es2lan.c index b948bb4e3198..e7c42d5386eb 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 68f92c619afe..2d03b8ff8e3f 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 @@ static s32 e1000_setup_fiber_serdes_link_82540(struct e1000_hw *hw) **/ 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 @@ static s32 e1000_adjust_serdes_amplitude_82540(struct e1000_hw *hw) **/ 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 59615556fa32..55d51087b7b3 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 b2d676eca8c5..4cca9b2b2c61 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 b9a53bd6081c..474387d2cb75 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 1d7718eda12c..8e5ca56ae88c 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 10653f8824c8..38770a327b16 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) { @@ -2891,14 +2908,115 @@ s32 e1000_initialize_M88E1512_phy(struct e1000_hw *hw) return ret_val; } +/** + * 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 @@ s32 e1000_set_eee_i350(struct e1000_hw *hw) /** * 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 503fdce305d6..45fe132e4a40 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 5db22db16f0d..28379cc572d3 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 9472ca4c4d4d..e33fe0fb7982 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 8ae4b202fd1e..1792e14ef38a 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 563f11a1d27e..cd8d7c7e1f56 100644 --- a/sys/dev/e1000/e1000_i210.c +++ b/sys/dev/e1000/e1000_i210.c @@ -882,6 +882,35 @@ static s32 e1000_pll_workaround_i210(struct e1000_hw *hw) return ret_val; } +/** + * 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 75fcade3703b..9b9a090422e9 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,37 +635,58 @@ 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; + + 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; + } + + gfpreg = E1000_READ_FLASH_REG(hw, ICH_FLASH_GFPREG); + + /* 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; + + /* 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); } - gfpreg = E1000_READ_FLASH_REG(hw, ICH_FLASH_GFPREG); - - /* 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; - - /* 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; /* Clear shadow ram */ @@ -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 @@ static s32 e1000_k1_workaround_lpt_lp(struct e1000_hw *hw, bool link) /* 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, ®); @@ -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 @@ s32 e1000_disable_ulp_lpt_lp(struct e1000_hw *hw, bool force) 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,33 +1577,117 @@ 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; - - 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, 0); - - hw->phy.ops.release(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); + + 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 + phy_reg |= 0xFA; + hw->phy.ops.write_reg_locked(hw, + I217_PLL_CLOCK_GATE_REG, + phy_reg); + } + hw->phy.ops.release(hw); + + 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 */ @@ -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); @@ -3268,6 +3480,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 @@ -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 { @@ -3438,6 +3763,29 @@ static s32 e1000_flash_cycle_ich8lan(struct e1000_hw *hw, u32 timeout) return -E1000_ERR_NVM; } +/** + * 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 @@ -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 @@ -3598,6 +4029,175 @@ static s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, return E1000_SUCCESS; } +/** + * 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 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw) * 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 @@ void e1000_resume_workarounds_pchlan(struct e1000_hw *hw) 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 9cb79c0b0c99..edc1dd14ccc9 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 1daed9bc9472..ef9789bbb537 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 d9fb9acdce17..1de19a4df77c 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 31f2180a0b6b..64a4083eb209 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 fc46f48df6cc..c0bf4182ec62 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 0c8ccd2ba627..b2bec3e5fe6b 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 7c81a8988243..37d701722da1 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 b6c98b160e25..1f6746c5cdae 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -95,15 +95,10 @@ #include "e1000_82571.h" #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 @@ em_setup_msix(struct adapter *adapter) } +/* +** 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 362df49442a7..3b280b33401c 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 5be7836cb8f8..c84dfc2be007 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); } } From c212e48d5be4c79d408a59189b0eddbaed1585bc Mon Sep 17 00:00:00 2001 From: mav Date: Fri, 5 Feb 2016 17:28:11 +0000 Subject: [PATCH 091/129] Add error check to not leak logs with syntax errors in case of failed `zpool history`. MFC after: 1 month --- etc/periodic/daily/800.scrub-zfs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/etc/periodic/daily/800.scrub-zfs b/etc/periodic/daily/800.scrub-zfs index 359be13b227a..b7a009d2c1e9 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) - \ From d6ed13470ae8ba961478892aefbc84081c8ece1b Mon Sep 17 00:00:00 2001 From: mav Date: Fri, 5 Feb 2016 18:17:37 +0000 Subject: [PATCH 092/129] Update script for modern `zpool status` output. --- etc/periodic/daily/800.scrub-zfs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/etc/periodic/daily/800.scrub-zfs b/etc/periodic/daily/800.scrub-zfs index b7a009d2c1e9..64eac99c38a1 100755 --- a/etc/periodic/daily/800.scrub-zfs +++ b/etc/periodic/daily/800.scrub-zfs @@ -78,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} From f611a6573503c119077126cc01f2444b3cd0db13 Mon Sep 17 00:00:00 2001 From: markj Date: Fri, 5 Feb 2016 19:35:53 +0000 Subject: [PATCH 093/129] Plug a vm_page leak introduced in r292373. Reported by: vangyzen --- sys/vm/sg_pager.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sys/vm/sg_pager.c b/sys/vm/sg_pager.c index 84bfa49f11a4..2cccb7ea1598 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; From 21434c7a701096dfe0b99fcfe37d637fae83cb2b Mon Sep 17 00:00:00 2001 From: jhb Date: Fri, 5 Feb 2016 20:38:09 +0000 Subject: [PATCH 094/129] Rename aiocblist to kaiocb and use consistent variable names. Typically list is used for a structure that holds a list head in FreeBSD, not for members of a list. As such, rename 'struct aiocblist' to 'struct kaiocb' (the kernel version of 'struct aiocb'). While here, use more consistent variable names for AIO control blocks: - Use 'job' instead of 'aiocbe', 'cb', 'cbe', or 'iocb' for kernel job objects. - Use 'jobn' instead of 'cbn' for use with TAILQ_FOREACH_SAFE(). - Use 'sjob' and 'sjobn' instead of 'scb' and 'scbn' for fsync jobs. - Use 'ujob' instead of 'aiocbp', 'job', 'uaiocb', or 'uuaiocb' to hold a user pointer to a 'struct aiocb'. - Use 'ujobp' instead of 'aiocbp' for a user pointer to a 'struct aiocb *'. Reviewed by: kib Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D5125 --- sys/kern/vfs_aio.c | 644 ++++++++++++++++++++++---------------------- sys/sys/event.h | 2 +- sys/sys/socketvar.h | 2 +- 3 files changed, 324 insertions(+), 324 deletions(-) diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c index 14a66c3bb7d7..5b2083c65312 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 @@ aio_proc_rundown(void *arg, struct proc *p) * 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 @@ aio_proc_rundown(void *arg, struct proc *p) } /* 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 @@ aio_proc_rundown(void *arg, struct proc *p) /* * 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 @@ aio_fsync_vnode(struct thread *td, struct vnode *vp) * 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 @@ aio_bio_done_notify(struct proc *userp, struct aiocblist *aiocbe, int type) } 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 @@ aio_qphysio(struct proc *p, struct aiocblist *aiocbe) 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 @@ aio_qphysio(struct proc *p, struct aiocblist *aiocbe) 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 @@ aio_aqueue(struct thread *td, struct aiocb *job, struct aioliojob *lj, * 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 @@ aio_aqueue(struct thread *td, struct aiocb *job, struct aioliojob *lj, 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 @@ aio_aqueue(struct thread *td, struct aiocb *job, struct aioliojob *lj, 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 @@ aio_aqueue(struct thread *td, struct aiocb *job, struct aioliojob *lj, 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 @@ sys_aio_cancel(struct thread *td, struct aio_cancel_args *uap) * 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/sys/event.h b/sys/sys/event.h index 35aad99899e3..7897c818cb0e 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/socketvar.h b/sys/sys/socketvar.h index 55a7950cebb7..f101849eb92d 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; From 860ed9e53f6883401334547dea3fcede88e39d50 Mon Sep 17 00:00:00 2001 From: emaste Date: Fri, 5 Feb 2016 20:54:51 +0000 Subject: [PATCH 095/129] readelf: avoid accidental fallthrough in RISC-V relocations This would have printed an unknown RISC-V relocation type as a SPARC relocation. CID: 1331398 Obtained from: ELF Tool Chain r3283 Sponsored by: The FreeBSD Foundation --- contrib/elftoolchain/readelf/readelf.c | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/elftoolchain/readelf/readelf.c b/contrib/elftoolchain/readelf/readelf.c index 6902024725af..7e9343e30d08 100644 --- a/contrib/elftoolchain/readelf/readelf.c +++ b/contrib/elftoolchain/readelf/readelf.c @@ -1452,6 +1452,7 @@ r_type(unsigned int mach, unsigned int type) case 43: return "R_RISCV_ALIGN"; case 44: return "R_RISCV_RVC_BRANCH"; case 45: return "R_RISCV_RVC_JUMP"; + default: return ""; } case EM_SPARC: case EM_SPARCV9: From e76c56eec876ba994cae09d2d465992d9be5d093 Mon Sep 17 00:00:00 2001 From: emaste Date: Fri, 5 Feb 2016 20:56:11 +0000 Subject: [PATCH 096/129] readelf: report value of unknown relocation types Obtained from: ELF Tool Chain r3387 Sponsored by: The FreeBSD Foundation --- contrib/elftoolchain/readelf/readelf.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/contrib/elftoolchain/readelf/readelf.c b/contrib/elftoolchain/readelf/readelf.c index 7e9343e30d08..c2779ba16c4e 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"; @@ -1154,8 +1155,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 +1207,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 +1291,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 +1325,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 +1406,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"; @@ -1452,8 +1452,8 @@ r_type(unsigned int mach, unsigned int type) case 43: return "R_RISCV_ALIGN"; case 44: return "R_RISCV_RVC_BRANCH"; case 45: return "R_RISCV_RVC_JUMP"; - default: return ""; } + break; case EM_SPARC: case EM_SPARCV9: switch(type) { @@ -1537,8 +1537,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"; @@ -1579,10 +1579,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), "", type); + return (s_type); } static const char * From 752d332a4b9c16a487f568188302b49395f489b5 Mon Sep 17 00:00:00 2001 From: emaste Date: Fri, 5 Feb 2016 20:57:21 +0000 Subject: [PATCH 097/129] readelf: decode AArch64 TLS descriptor relocations From ELF for the ARM(R) 64-bit Architecture, table 4-19. Obtained from: ELF Tool Chain r3386 Sponsored by: The FreeBSD Foundation --- contrib/elftoolchain/readelf/readelf.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/contrib/elftoolchain/readelf/readelf.c b/contrib/elftoolchain/readelf/readelf.c index c2779ba16c4e..a0170234fb07 100644 --- a/contrib/elftoolchain/readelf/readelf.c +++ b/contrib/elftoolchain/readelf/readelf.c @@ -1146,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"; From e7ca06fef133f827bef89f564ac7e91b6d423ee7 Mon Sep 17 00:00:00 2001 From: glebius Date: Fri, 5 Feb 2016 21:57:50 +0000 Subject: [PATCH 098/129] Provide a future release as an example, instead of a historical one. --- usr.sbin/freebsd-update/freebsd-update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.sbin/freebsd-update/freebsd-update.sh b/usr.sbin/freebsd-update/freebsd-update.sh index cce2af574f61..feb8db6a6b3c 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 From ebde2e6348e8c51b90136123557364880f072efb Mon Sep 17 00:00:00 2001 From: ngie Date: Fri, 5 Feb 2016 23:50:15 +0000 Subject: [PATCH 099/129] Require /bin/getfacl and /bin/setfacl when running the acl tests For cases where these utilities aren't installed, the tests would fail today in a non-intuitive manner on sub-testcase #3 in each of the test scripts MFC after: 1 week Reviewed by: markj Sponsored by: EMC / Isilon Storage Division --- tests/sys/acl/Makefile | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/sys/acl/Makefile b/tests/sys/acl/Makefile index 298b0a27c91d..3f40bb2eb5d2 100644 --- a/tests/sys/acl/Makefile +++ b/tests/sys/acl/Makefile @@ -22,8 +22,14 @@ TAP_TESTS_SH+= 04 TEST_METADATA.$t+= required_user="root" .endfor +_ACL_PROGS= /bin/getfacl /bin/setfacl + .for t in 01 03 04 -TEST_METADATA.$t+= required_programs="/sbin/zpool" +TEST_METADATA.$t+= required_programs="/sbin/zpool ${_ACL_PROGS}" +.endfor + +.for t in 00 02 +TEST_METADATA.$t+= required_programs="${_ACL_PROGS}" .endfor .include From 0e082dce884fa04860090796745506c7bbcfadca Mon Sep 17 00:00:00 2001 From: dteske Date: Sat, 6 Feb 2016 02:16:48 +0000 Subject: [PATCH 100/129] Allow rc_conf_files to be redefined in rc.conf(5) With this change, it's possible to redefine rc_conf_files (e.g., sysrc rc_conf_files+=/etc/rc.conf.other) and have the boot process pick up settings in extra files. The sysrc(8) tool can be used to query/enumerate/find/manage extra files configured in this manner. Relnotes: yes --- etc/defaults/rc.conf | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf index a674acb97532..f8ca47fbf917 100644 --- a/etc/defaults/rc.conf +++ b/etc/defaults/rc.conf @@ -716,5 +716,17 @@ if [ -z "${source_rc_confs_defined}" ]; then ;; esac done + 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 From d6e962f26838a991c43b1f03ba2051ebb6eb8e3a Mon Sep 17 00:00:00 2001 From: dteske Date: Sat, 6 Feb 2016 02:32:13 +0000 Subject: [PATCH 101/129] Add comment to explain functionality of code Thanks to: rpokala --- etc/defaults/rc.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf index f8ca47fbf917..5e412914a284 100644 --- a/etc/defaults/rc.conf +++ b/etc/defaults/rc.conf @@ -716,6 +716,7 @@ if [ -z "${source_rc_confs_defined}" ]; then ;; esac done + # Re-do process to pick up [possibly] redined $rc_conf_files for i in ${rc_conf_files}; do case ${sourced_files} in *:$i:*) From 4bbbf067b6deab87d1277c494cd3381f2e946d20 Mon Sep 17 00:00:00 2001 From: dteske Date: Sat, 6 Feb 2016 02:35:52 +0000 Subject: [PATCH 102/129] Fix typo in a comment; s/redined/redefined/ Thanks to: rpokala --- etc/defaults/rc.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf index 5e412914a284..69b6d0f77bd0 100644 --- a/etc/defaults/rc.conf +++ b/etc/defaults/rc.conf @@ -716,7 +716,7 @@ if [ -z "${source_rc_confs_defined}" ]; then ;; esac done - # Re-do process to pick up [possibly] redined $rc_conf_files + # Re-do process to pick up [possibly] redefined $rc_conf_files for i in ${rc_conf_files}; do case ${sourced_files} in *:$i:*) From 226a73a2862dc1daac539ae5c5c774fde539b95d Mon Sep 17 00:00:00 2001 From: ngie Date: Sat, 6 Feb 2016 04:13:20 +0000 Subject: [PATCH 103/129] Use basenames for getfacl, setfacl, and zpool to work around the fact that Jenkins hardcodes image sizes to 2GB with the FreeBSD_HEAD job This is to stop the unnecessary failure emails because we've gone over the 2GB limit MFC after: 1 week X-MFC with: r295341 Sponsored by: EMC / Isilon Storage Division --- tests/sys/acl/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/sys/acl/Makefile b/tests/sys/acl/Makefile index 3f40bb2eb5d2..d101088dcd3f 100644 --- a/tests/sys/acl/Makefile +++ b/tests/sys/acl/Makefile @@ -22,10 +22,10 @@ TAP_TESTS_SH+= 04 TEST_METADATA.$t+= required_user="root" .endfor -_ACL_PROGS= /bin/getfacl /bin/setfacl +_ACL_PROGS= getfacl setfacl .for t in 01 03 04 -TEST_METADATA.$t+= required_programs="/sbin/zpool ${_ACL_PROGS}" +TEST_METADATA.$t+= required_programs="zpool ${_ACL_PROGS}" .endfor .for t in 00 02 From 8d5e31f3ba87dc161a50367594ff6db3941b9a0d Mon Sep 17 00:00:00 2001 From: mjg Date: Sat, 6 Feb 2016 09:01:03 +0000 Subject: [PATCH 104/129] fork: ansify sys_pdfork No functional changes. --- sys/kern/kern_fork.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 5bb14e8b4adb..9abe08c037c5 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -117,9 +117,7 @@ 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) { struct fork_req fr; int error, fd, pid; From 1cb81502033e8887257dd52c0b57721abdd24839 Mon Sep 17 00:00:00 2001 From: mmel Date: Sat, 6 Feb 2016 11:16:15 +0000 Subject: [PATCH 105/129] ARM: Rename remaining ARMv4 specific function in DTrace code. I missed it in r295319. Pointed by: tuexen --- sys/cddl/dev/fbt/arm/fbt_isa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/cddl/dev/fbt/arm/fbt_isa.c b/sys/cddl/dev/fbt/arm/fbt_isa.c index 0e948dd90979..2e0e5a5eae10 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 From ec36b5bf6457a82c80c259ad36edf68826ade8e7 Mon Sep 17 00:00:00 2001 From: kib Date: Sat, 6 Feb 2016 15:39:04 +0000 Subject: [PATCH 106/129] Do not call vn_fullpath(9) (through the pmc_getfilename() wrapper) when its result is immediately ignored, i.e. for kernel processes forked from the user process. Do not test for non-null before freeing string. Sponsored by: The FreeBSD Foundation MFC after: 2 weeks --- sys/dev/hwpmc/hwpmc_mod.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c index 7f46573e22a6..3f56f12c65d9 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); } From 5b12d896ba622682f675117c93a7da3a68c78190 Mon Sep 17 00:00:00 2001 From: pfg Date: Sat, 6 Feb 2016 21:54:02 +0000 Subject: [PATCH 107/129] msdosfs_rename: Unused value Assigned value to pmp, is immediatedly overwritten before it can be used. CID: 1304892 --- sys/fs/msdosfs/msdosfs_vnops.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c index 5a2a6a9600c1..0486bbe728f2 100644 --- a/sys/fs/msdosfs/msdosfs_vnops.c +++ b/sys/fs/msdosfs/msdosfs_vnops.c @@ -947,7 +947,6 @@ msdosfs_rename(struct vop_rename_args *ap) struct buf *bp; fddep = VTODE(ap->a_fdvp); - pmp = fddep->de_pmp; pmp = VFSTOMSDOSFS(fdvp->v_mount); From 993c2695aa5e66d4379e155446baeeb4d6c9c8c0 Mon Sep 17 00:00:00 2001 From: smh Date: Sat, 6 Feb 2016 22:01:25 +0000 Subject: [PATCH 108/129] Fix EFI platform build failures With warnings now enabled some plaforms where failing due to warnings. * Fix st_size printed as a size_t when its actually an off_t. * Fix pointer conversion in load_elf for some 32bit platforms due to 64bit off in ef. MFC after: 2 days X-MFC-With: Sponsored by: Multiplay --- sys/boot/common/load_elf.c | 2 +- sys/boot/efi/boot1/zfs_module.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/boot/common/load_elf.c b/sys/boot/common/load_elf.c index 0ff1a15be880..3207f73e91ad 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/zfs_module.c b/sys/boot/efi/boot1/zfs_module.c index 4e2c5c4681c1..925f0b28c1b0 100644 --- a/sys/boot/efi/boot1/zfs_module.c +++ b/sys/boot/efi/boot1/zfs_module.c @@ -135,7 +135,7 @@ load(const char *filepath, dev_info_t *devinfo, void **bufp, size_t *bufsize) if ((status = bs->AllocatePool(EfiLoaderData, (UINTN)st.st_size, &buf)) != EFI_SUCCESS) { - printf("Failed to allocate load buffer %zu for pool '%s' for '%s' " + 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); } From 66ca079836f33725c8ee76ed154ed176e165a5bc Mon Sep 17 00:00:00 2001 From: allanjude Date: Sun, 7 Feb 2016 00:49:15 +0000 Subject: [PATCH 109/129] Do not set vfs.root.mountfrom unnecessarily This causes boot from external media (installer USB image) to mount / from the default ZFS BE, rather than the USB device. Reported by: kmoore MFC after: 5 days Sponsored by: ScaleEngine Inc. --- sys/boot/zfs/zfs.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/boot/zfs/zfs.c b/sys/boot/zfs/zfs.c index 8e6d420b4e92..bf2fc6f8e090 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++; From 3ddfa78dde28358bb798cba9a030c1246dd138ab Mon Sep 17 00:00:00 2001 From: mckusick Date: Sun, 7 Feb 2016 01:04:47 +0000 Subject: [PATCH 110/129] Clarify a comment in kern_openat() about the use of falloc_noinstall(). Suggested by: Steve Jacobson --- sys/kern/vfs_syscalls.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index c246b9e1f6be..0762ca7a73fd 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) From 0bbadbe82bfe904f4b7d74ea8805c36bcd91a919 Mon Sep 17 00:00:00 2001 From: pfg Date: Sun, 7 Feb 2016 01:09:38 +0000 Subject: [PATCH 111/129] fdesc_setattr: unitialized pointer read CID: 1018688 --- sys/fs/fdescfs/fdesc_vnops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/fs/fdescfs/fdesc_vnops.c b/sys/fs/fdescfs/fdesc_vnops.c index 1b0e56928271..a90f4dcaab48 100644 --- a/sys/fs/fdescfs/fdesc_vnops.c +++ b/sys/fs/fdescfs/fdesc_vnops.c @@ -465,7 +465,7 @@ fdesc_setattr(ap) { struct vattr *vap = ap->a_vap; struct vnode *vp; - struct mount *mp; + struct mount *mp = NULL; struct file *fp; struct thread *td = curthread; cap_rights_t rights; From 29ef016884d212b509f8947c5112cc7da1c0b6c7 Mon Sep 17 00:00:00 2001 From: pfg Date: Sun, 7 Feb 2016 03:48:40 +0000 Subject: [PATCH 112/129] cd9660: Drop an unnecessary check for NULL. This was unnecessary and also confused Coverity. Confirmed on: NetBSD CID: 978558 --- sys/fs/cd9660/cd9660_vfsops.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sys/fs/cd9660/cd9660_vfsops.c b/sys/fs/cd9660/cd9660_vfsops.c index a1f8780b4607..983b869d8b32 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)); From 370e6e316494079080b3597bc6f38489f41505b9 Mon Sep 17 00:00:00 2001 From: adrian Date: Sun, 7 Feb 2016 04:28:03 +0000 Subject: [PATCH 113/129] Remove the hard-coded 'ath0' strings and use ATH_DEFAULT. Remove the duplicate ATH_DEFAULT fields. The build bits should be including ../Makefile.inc as appropriate. --- tools/tools/ath/athaggrstats/main.c | 2 +- tools/tools/ath/athdebug/athdebug.c | 4 ++-- tools/tools/ath/athradar/athradar.c | 4 ---- tools/tools/ath/athratestats/main.c | 2 +- tools/tools/ath/athspectral/athspectral.c | 4 ---- tools/tools/ath/athstats/main.c | 2 +- 6 files changed, 5 insertions(+), 13 deletions(-) diff --git a/tools/tools/ath/athaggrstats/main.c b/tools/tools/ath/athaggrstats/main.c index 95e7917455ba..6a0de98b0069 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 bcdbcc8aae47..b28f0432f435 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 @@ -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 f40e1bd09be5..69f441658a85 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 #include #include diff --git a/tools/tools/ath/athratestats/main.c b/tools/tools/ath/athratestats/main.c index 3881e8543be0..b3f85f758577 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/athspectral/athspectral.c b/tools/tools/ath/athspectral/athspectral.c index 1ec908562aba..91045d022443 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 #include #include diff --git a/tools/tools/ath/athstats/main.c b/tools/tools/ath/athstats/main.c index bf0323d8715c..29e86365c83b 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) { From 0bd7c2b97b8718b5ed39bda14af532daf342faa4 Mon Sep 17 00:00:00 2001 From: dteske Date: Sun, 7 Feb 2016 13:33:18 +0000 Subject: [PATCH 114/129] Add missing comma --- share/man/man4/bridge.4 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/man/man4/bridge.4 b/share/man/man4/bridge.4 index cecffc595e0d..d3410d5f9440 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" From f7a59d1c75b675ed57e2ef99e5cb05151fb5a7db Mon Sep 17 00:00:00 2001 From: pfg Date: Sun, 7 Feb 2016 15:26:21 +0000 Subject: [PATCH 115/129] MFV r295360 Sync our libedit with NetBSD's libedit 2016-01-16 Obtained from: NetBSD --- lib/libedit/editline.3 | 61 +++++++++++++++++++++++------------------ lib/libedit/el.c | 7 +++-- lib/libedit/hist.h | 6 ++-- lib/libedit/keymacro.h | 4 +-- lib/libedit/search.c | 6 ++-- lib/libedit/tokenizer.c | 6 ++-- lib/libedit/tty.c | 7 +++-- 7 files changed, 54 insertions(+), 43 deletions(-) diff --git a/lib/libedit/editline.3 b/lib/libedit/editline.3 index 1e0ff5da7f84..05ee76eb7769 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 57ea6e55cffd..65bd86b7b130 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 @@ -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 1cd7d9df397f..6ca6877301f0 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 57a7a5d2ea8d..139cda2722e7 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 3cd205a9453e..df9999cf373e 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 @@ -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 e61ecaf41e40..f5171c46d2ec 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 @@ -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 ecf2e2a21335..a508e43ef37c 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 @@ -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, From b42dfac65547da9f8e3778f95d4af3448f362dda Mon Sep 17 00:00:00 2001 From: pfg Date: Sun, 7 Feb 2016 15:36:16 +0000 Subject: [PATCH 116/129] msdosfs_rename: yet another unused value. As with r295355, it seems to be left over from a cleanup in r33548. The code is not in NetBSD either. Thanks to bde for checking out the history. --- sys/fs/msdosfs/msdosfs_vnops.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c index 0486bbe728f2..74a7e32cd5cd 100644 --- a/sys/fs/msdosfs/msdosfs_vnops.c +++ b/sys/fs/msdosfs/msdosfs_vnops.c @@ -941,13 +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 = VFSTOMSDOSFS(fdvp->v_mount); #ifdef DIAGNOSTIC From d7b2b433b412071b70e0ec74bb4e2b5885c3c93e Mon Sep 17 00:00:00 2001 From: pfg Date: Sun, 7 Feb 2016 15:40:01 +0000 Subject: [PATCH 117/129] Revert r295359: CID 1018688 is a false positive. The initialization is done by calling vn_start_write(... &mp, flags). mp is only an output parameter unless (flags & V_MNTREF), and fdesc doesn't put V_MNTREF in flags. Pointed out by: bde --- sys/fs/fdescfs/fdesc_vnops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/fs/fdescfs/fdesc_vnops.c b/sys/fs/fdescfs/fdesc_vnops.c index a90f4dcaab48..1b0e56928271 100644 --- a/sys/fs/fdescfs/fdesc_vnops.c +++ b/sys/fs/fdescfs/fdesc_vnops.c @@ -465,7 +465,7 @@ fdesc_setattr(ap) { struct vattr *vap = ap->a_vap; struct vnode *vp; - struct mount *mp = NULL; + struct mount *mp; struct file *fp; struct thread *td = curthread; cap_rights_t rights; From 8d82ef5201892faa72d60e53b799fe44526e7fb7 Mon Sep 17 00:00:00 2001 From: pfg Date: Sun, 7 Feb 2016 16:18:12 +0000 Subject: [PATCH 118/129] Minor grammar fix in comment. --- sys/kern/vfs_bio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index eb392cb1b834..e272f9de557a 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) From 42c40e4f6e7c0c374aaab288e10b845f799892ca Mon Sep 17 00:00:00 2001 From: dteske Date: Sun, 7 Feb 2016 16:41:54 +0000 Subject: [PATCH 119/129] Add two scripts for vnet jails One for if_bridge(4) back-end, another for ng_bridge(4) back-end Sponsored by: FIS Global, Inc. --- share/examples/jails/jib | 367 ++++++++++++++++++++++++++++++++++ share/examples/jails/jng | 416 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 783 insertions(+) create mode 100755 share/examples/jails/jib create mode 100755 share/examples/jails/jng diff --git a/share/examples/jails/jib b/share/examples/jails/jib new file mode 100755 index 000000000000..540df097176f --- /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 000000000000..605db90d4dd1 --- /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 +################################################################################ From 569810426dcb2d1386c368aae016ca4cb0241bd9 Mon Sep 17 00:00:00 2001 From: imp Date: Sun, 7 Feb 2016 16:43:55 +0000 Subject: [PATCH 120/129] Various fixups: o Make sure we create bsd label for MBR scheme (though we don't really need it for the efi case, and boot1 can't read it). Add notes about why we have to do this, at least for BIOS. o Make the BIOS / UEFI with gpt config work. o Remove now-moribund packaging stuff --- tools/tools/nanobsd/embedded/common | 154 +++++++--------------------- 1 file changed, 36 insertions(+), 118 deletions(-) diff --git a/tools/tools/nanobsd/embedded/common b/tools/tools/nanobsd/embedded/common index bbac16205304..d10a36f35a92 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 @@ -180,105 +180,14 @@ 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}" + + create_diskimage_mbr $* ) -# 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 -) - -# 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}" @@ -319,10 +228,20 @@ create_diskimage_mbr ( ) ( # 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_OBJ}/_.${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_OBJ}/_.${NANO_ROOT} \ + -o ${NANO_OBJ}/_.${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 @@ -341,18 +260,7 @@ 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 + # 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 @@ -662,11 +570,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 +614,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 +630,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 From 77e64f60dfb7d864245771488b781c0efd0cf8ca Mon Sep 17 00:00:00 2001 From: imp Date: Sun, 7 Feb 2016 16:44:04 +0000 Subject: [PATCH 121/129] Add simple config for i386 BIOS boot. --- tools/tools/nanobsd/embedded/i386.cfg | 34 +++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 tools/tools/nanobsd/embedded/i386.cfg diff --git a/tools/tools/nanobsd/embedded/i386.cfg b/tools/tools/nanobsd/embedded/i386.cfg new file mode 100644 index 000000000000..7fd9a5282acd --- /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 From 0b1b9fdab4a2bd75d016d9f6b07262f4a22e35dc Mon Sep 17 00:00:00 2001 From: imp Date: Sun, 7 Feb 2016 16:44:06 +0000 Subject: [PATCH 122/129] Use NANO_LOG instead of NANO_OBJ for log file locations. Have it default to NANO_OBJ. --- tools/tools/nanobsd/defaults.sh | 46 +++++++++++++++++---------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/tools/tools/nanobsd/defaults.sh b/tools/tools/nanobsd/defaults.sh index a0e6be580b9b..9a5c5cbe3608 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 } From 3c1575b1354d0e382a785faaf0ecbc66a8ea11f5 Mon Sep 17 00:00:00 2001 From: imp Date: Sun, 7 Feb 2016 16:44:13 +0000 Subject: [PATCH 123/129] Use new NANO_LOG to put the logs some place reasonable. Also, share the object directory among all builds where it makes sense. When building with NANO_CPUTYPE, separate that out to its own object directory. Put disk files in their own directories. This should make having multiple variants of the same architecture saner. --- tools/tools/nanobsd/embedded/common | 85 ++++++++++++++++------------- 1 file changed, 47 insertions(+), 38 deletions(-) diff --git a/tools/tools/nanobsd/embedded/common b/tools/tools/nanobsd/embedded/common index d10a36f35a92..9e02dccafe9d 100644 --- a/tools/tools/nanobsd/embedded/common +++ b/tools/tools/nanobsd/embedded/common @@ -88,23 +88,30 @@ 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}) -NANO_FAT_DIR=${NANO_OBJ}/_.fat +NANO_FAT_DIR=${NANO_LOG}/_.fat customize_cmd cust_allow_ssh_root @@ -191,7 +198,7 @@ create_diskimage_gpt ( ) ( 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 @@ -204,36 +211,36 @@ 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_ROOT}" \ + eval "${NANO_MAKEFS_UFS}" ${extra} $sz "${NANO_LOG}/_.${NANO_ROOT}" \ "${NANO_WORLDDIR}" case ${NANO_DISK_SCHEME} in mbr) - mkimg -s bsd ${bootbsd} -p freebsd-ufs:=${NANO_OBJ}/_.${NANO_ROOT} \ - -o ${NANO_OBJ}/_.${NANO_SLICE_ROOT} + 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 ;; @@ -246,12 +253,12 @@ create_diskimage_mbr ( ) ( # 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 @@ -261,31 +268,32 @@ create_diskimage_mbr ( ) ( eval $NANO_SLICE_FAT=fat16b fi + 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 / @@ -293,9 +301,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 @@ -304,13 +312,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( ) { From 464f9f537837fb00673e5efebbb22ceb4ee5291c Mon Sep 17 00:00:00 2001 From: ngie Date: Sun, 7 Feb 2016 18:40:04 +0000 Subject: [PATCH 124/129] Simplify running the FreeBSD test suite Replace `make regress` (legacy test make target) and `make test` (incomplete test make target added with the FreeBSD test suite) with make check as it's consistent with other open source projects. `make check` defaults to running tests from `.OBJDIR`, but can be overridden with the `CHECKDIR` variable. Add `make checkworld` target to simplify running the FreeBSD test suite from `TESTSBASE` (i.e. the top-level tests directory), similar to buildworld. Document `make check` and `make checkworld` in build(7). Other minor changes: - Rename intermediate file (`Kyuafile.auto`) to `Kyuafile` to simplify `make check`. - Remove terse warnings attached to `beforetest`/`aftertest`. - Add kyua binary check to check target in suite.test.mk; error out if it's not found The MFC is [partly] contingent on other build related changes being MFCed. Differential Revision: https://reviews.freebsd.org/D4406 MFC after: 2 months X-MFC to: stable/10 Relnotes: yes Reviewed by: bdrewery, Evan Cramer Sponsored by: EMC / Isilon Storage Division --- Makefile | 11 ++++++--- Makefile.inc1 | 15 ++++++++++++ share/man/man7/build.7 | 13 ++++++++++- share/mk/bsd.README | 21 ++++++++++++----- share/mk/bsd.subdir.mk | 4 ++-- share/mk/bsd.sys.mk | 6 ++--- share/mk/bsd.test.mk | 19 +++++++-------- share/mk/suite.test.mk | 53 +++++++++++++----------------------------- 8 files changed, 80 insertions(+), 62 deletions(-) diff --git a/Makefile b/Makefile index 988d9cc683d8..fbf14e9a8ecb 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 \ @@ -329,6 +330,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 ccd25d001d60..173f70e526be 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) # @@ -1322,6 +1323,20 @@ packagekernel: .endif .endif +# +# +# 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 # diff --git a/share/man/man7/build.7 b/share/man/man7/build.7 index be6fe09e8252..b32d7ed8460e 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 b1a68e8b538e..1ae151064b93 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.subdir.mk b/share/mk/bsd.subdir.mk index dbe74f4c7179..8631e656c0f1 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 diff --git a/share/mk/bsd.sys.mk b/share/mk/bsd.sys.mk index 7ac7917e9e89..2ce5beb67cd4 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 9c5961972086..d5936b9103d7 100644 --- a/share/mk/bsd.test.mk +++ b/share/mk/bsd.test.mk @@ -60,11 +60,15 @@ _TESTS= .include .include +# 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) @@ -79,19 +83,14 @@ PROGS_TARGETS+= install .include .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 2b87d7fba602..646d2ebc6d83 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 From 6e7e5621d9b1fb2151c468d82074db9c0e91b6ee Mon Sep 17 00:00:00 2001 From: jilles Date: Sun, 7 Feb 2016 21:25:08 +0000 Subject: [PATCH 125/129] semget(2): Add missing [EINVAL] conditions. PR: 206927 --- lib/libc/sys/semget.2 | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/libc/sys/semget.2 b/lib/libc/sys/semget.2 index 945044da65bb..debcf11224ae 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 From b2791f185cba92ad0c81fd19ad5ab4d88fd2681c Mon Sep 17 00:00:00 2001 From: jilles Date: Sun, 7 Feb 2016 22:12:39 +0000 Subject: [PATCH 126/129] semget(): Check for [EEXIST] error first. Although POSIX literally permits failing with [EINVAL] if IPC_CREAT and IPC_EXCL were both passed, the semaphore set already exists and has fewer semaphores than nsems, this does not allow an application to retry safely: if the [EINVAL] is actually because of the semmsl limit, an infinite loop would result. PR: 206927 --- sys/kern/sysv_sem.c | 10 +++++----- tools/regression/sysvsem/semtest.c | 9 +++++++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/sys/kern/sysv_sem.c b/sys/kern/sysv_sem.c index d9324f46d0df..22616b988d88 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/tools/regression/sysvsem/semtest.c b/tools/regression/sysvsem/semtest.c index 8a997d0bf6a4..39c416403c63 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: From 0935e66dd993404cb819bc7ac4ac1a195663a2ab Mon Sep 17 00:00:00 2001 From: imp Date: Sun, 7 Feb 2016 23:20:44 +0000 Subject: [PATCH 127/129] Make sure NANO_DISKIMGDIR exists. --- tools/tools/nanobsd/embedded/common | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/tools/nanobsd/embedded/common b/tools/tools/nanobsd/embedded/common index 9e02dccafe9d..50e507f809a3 100644 --- a/tools/tools/nanobsd/embedded/common +++ b/tools/tools/nanobsd/embedded/common @@ -110,6 +110,8 @@ 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_LOG}/_.fat From beb14a6c3998f2655cff7a42ac5aa16a29620bd0 Mon Sep 17 00:00:00 2001 From: adrian Date: Mon, 8 Feb 2016 02:11:34 +0000 Subject: [PATCH 128/129] Add a format string to the err() calls. --- tools/tools/ath/athregs/dumpregs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/tools/ath/athregs/dumpregs.c b/tools/tools/ath/athregs/dumpregs.c index 4a50726829d6..472df052c489 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 From 2ed1e2991e3970aeffef7be33b91401f0aeca84d Mon Sep 17 00:00:00 2001 From: kib Date: Mon, 8 Feb 2016 10:54:27 +0000 Subject: [PATCH 129/129] Remove the assert which outlived its usefulness, and, by default, disable compilation of the code which made it possible to call stop_all_proc() from usermode at all. Move the comment to the preamble of stop_all_proc() and reword it to give overview of the function intent. proc0 has P_HADTHREADS flag set due to kthread_add(), but no P_KTHREAD, which triggered the assert, which does not serve a purpose now. Reported by: Oliver Pinter Sponsored by: The FreeBSD Foundation MFC after: 2 weeks --- sys/kern/kern_proc.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index a4f8576dfb73..729d7f08a79f 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