From f2be5817e9c3cb98a81689acb42dc6549ae0448f Mon Sep 17 00:00:00 2001 From: Peter Wemm Date: Sun, 28 Jul 2013 05:06:53 +0000 Subject: Import Apache apr-1.4.8 to vendor staging area. --- CHANGES | 66 +++++- Makefile.win | 2 +- apr.spec | 2 +- atomic/unix/ia32.c | 2 +- atomic/unix/ppc.c | 134 ++++++------ atomic/unix/s390.c | 34 +-- configure | 471 +++++++++++++++++++++--------------------- docs/pool-design.html | 2 +- file_io/unix/seek.c | 2 +- include/apr.hw | 10 +- include/apr_allocator.h | 27 ++- include/apr_general.h | 2 +- include/apr_network_io.h | 2 + include/apr_pools.h | 111 ++++++---- include/apr_strings.h | 12 +- include/apr_thread_proc.h | 4 +- include/apr_version.h | 7 +- libapr.rc | 3 - network_io/unix/multicast.c | 21 +- network_io/unix/sendrecv.c | 14 +- network_io/unix/sockaddr.c | 44 +++- network_io/unix/sockopt.c | 29 ++- random/unix/sha2.c | 488 +------------------------------------------- random/unix/sha2.h | 31 +-- random/unix/sha2_glue.c | 34 ++- tables/apr_tables.c | 7 +- threadproc/unix/thread.c | 2 +- 27 files changed, 619 insertions(+), 944 deletions(-) diff --git a/CHANGES b/CHANGES index f3213bfc09f2..51d12367195a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,11 +1,73 @@ -*- coding: utf-8 -*- +Changes for APR 1.4.8 + + *) Fix compiltation with FreeBSD on ARM. [Olli Hauer ] + + *) Fix 1.4.7 regression in apr_mcast_hops() and apr_mcast_loopback() + for AF_INET (IPv4) sockets on most Unix platforms. [Joe Orton] + + *) Fix the return value of apr_threadattr_detach_get() on some + platforms like OS X and Solaris. [Rainer Jung, ] + +Changes for APR 1.4.7 + + *) Fix apr_sockaddr_info_get() not returning an error in some cases. + PR 54779. [Jan Kaluža ] + + *) Fix amd64 assembler version of apr_atomic_xchgptr(). PR 51851. [Mattias + Engdegård ] + + *) Fix PPC atomics to work with gcc 4.0. PR 54840. [Mattias Engdegård + ] + + *) configure: Fix detection of O_NONBLOCK inheritance on busy + systems. [Rainer Jung] + + *) Remove unused code, fix strict C compliance bug in SHA-256 + implementation. [Jan Kaluza ] + + *) Fix apr_ipsubnet_test() false positives when comparing IPv4 + subnet representation against an IPv6 address. PR 54047. [Joe Orton] + + *) apr_socket_accept_filter: Return success when trying to again set + the filter to the same value as before, avoiding an unhelpful + APR_EINVAL. PR 37863. [Jeff Trawick] + + *) configure: Fix Linux 3.x detection. PR 54001. [Gilles Espinasse + ] + + *) apr_time_exp_*() on Windows: Fix error in the tm_yday field of + apr_time_exp_t for times within leap years. PR 53175. + [Jeff Trawick] + + *) Improve platform detection by updating config.guess and config.sub. + [Rainer Jung] + + *) Add support for OSX Mountain Lion (10.8) [Jim Jagielski] + + *) Add various gcc function attributes. [Stefan Fritsch] + + *) Fix some problems in apr_sockaddr_info_get() when trying to resolve + the loopback addresses of a protocol family that is not otherwise + configured on the system. PR 52709. [Nirgal Vourgère + , Stefan Fritsch] + + *) Fix file not being unlocked if truncate call on a file fails. + [Mladen Turk] + + *) apr_mcast_hops: Fix EINVAL for IPv6 sockets caused by using byte + instead integer for setsockopt. [Mladen Turk] + + *) Windows: Fix compile-time checks for 64-bit builds, resolving a + crash in httpd's mod_rewrite. PR 49155. [] + Changes for APR 1.4.6 *) Flush write buffer before truncate call on a file. [Mladen Turk] - *) Security: oCERT-2011-003 - Randomise hashes by providing a seed. + *) Randomise hashes by providing a seed. + Assigned CVE-2012-0840, oCERT-2011-003, but not known to be exploitable. [Bojan Smojver, Branko Čibej, Ruediger Pluem et al.] *) apr_random: Prevent segfault if pool used to initialize apr_random is diff --git a/Makefile.win b/Makefile.win index d2090f3f8fef..5f9c3133f452 100644 --- a/Makefile.win +++ b/Makefile.win @@ -25,7 +25,7 @@ # # For example; # -# nmake -f Makefile.win PREFIX=C:\APR buildall checkall installall clean +# nmake -f Makefile.win PREFIX=C:\APR buildall checkall install clean # !IF EXIST("apr.sln") && ([devenv /help > NUL 2>&1] == 0) \ diff --git a/apr.spec b/apr.spec index abecbdfd6761..40204ffa049a 100644 --- a/apr.spec +++ b/apr.spec @@ -3,7 +3,7 @@ Summary: Apache Portable Runtime library Name: apr -Version: 1.4.6 +Version: 1.4.8 Release: 1 License: Apache Software License Group: System Environment/Libraries diff --git a/atomic/unix/ia32.c b/atomic/unix/ia32.c index 3826f9275509..63f48a753a9f 100644 --- a/atomic/unix/ia32.c +++ b/atomic/unix/ia32.c @@ -117,7 +117,7 @@ APR_DECLARE(void*) apr_atomic_xchgptr(volatile void **mem, void *with) #elif APR_SIZEOF_VOIDP == 8 asm volatile ("xchgq %q2, %1" : "=a" (prev), "+m" (*mem) - : "r" ((unsigned long)with)); + : "0" (with)); #else #error APR_SIZEOF_VOIDP value not supported #endif diff --git a/atomic/unix/ppc.c b/atomic/unix/ppc.c index db9fca934d3e..ae8d503cc4d2 100644 --- a/atomic/unix/ppc.c +++ b/atomic/unix/ppc.c @@ -19,7 +19,7 @@ #ifdef USE_ATOMICS_PPC #ifdef PPC405_ERRATA -# define PPC405_ERR77_SYNC " sync\n" +# define PPC405_ERR77_SYNC " sync\n" #else # define PPC405_ERR77_SYNC #endif @@ -43,12 +43,12 @@ APR_DECLARE(apr_uint32_t) apr_atomic_add32(volatile apr_uint32_t *mem, apr_uint3 { apr_uint32_t prev, temp; - asm volatile ("loop_%=:\n" /* lost reservation */ - " lwarx %0,0,%3\n" /* load and reserve */ - " add %1,%0,%4\n" /* add val and prev */ - PPC405_ERR77_SYNC /* ppc405 Erratum 77 */ - " stwcx. %1,0,%3\n" /* store new value */ - " bne- loop_%=\n" /* loop if lost */ + asm volatile ("1:\n" /* lost reservation */ + " lwarx %0,0,%3\n" /* load and reserve */ + " add %1,%0,%4\n" /* add val and prev */ + PPC405_ERR77_SYNC /* ppc405 Erratum 77 */ + " stwcx. %1,0,%3\n" /* store new value */ + " bne- 1b\n" /* loop if lost */ : "=&r" (prev), "=&r" (temp), "=m" (*mem) : "b" (mem), "r" (val) : "cc", "memory"); @@ -60,12 +60,12 @@ APR_DECLARE(void) apr_atomic_sub32(volatile apr_uint32_t *mem, apr_uint32_t val) { apr_uint32_t temp; - asm volatile ("loop_%=:\n" /* lost reservation */ - " lwarx %0,0,%2\n" /* load and reserve */ - " subf %0,%3,%0\n" /* subtract val */ - PPC405_ERR77_SYNC /* ppc405 Erratum 77 */ - " stwcx. %0,0,%2\n" /* store new value */ - " bne- loop_%=\n" /* loop if lost */ + asm volatile ("1:\n" /* lost reservation */ + " lwarx %0,0,%2\n" /* load and reserve */ + " subf %0,%3,%0\n" /* subtract val */ + PPC405_ERR77_SYNC /* ppc405 Erratum 77 */ + " stwcx. %0,0,%2\n" /* store new value */ + " bne- 1b\n" /* loop if lost */ : "=&r" (temp), "=m" (*mem) : "b" (mem), "r" (val) : "cc", "memory"); @@ -75,13 +75,13 @@ APR_DECLARE(apr_uint32_t) apr_atomic_inc32(volatile apr_uint32_t *mem) { apr_uint32_t prev; - asm volatile ("loop_%=:\n" /* lost reservation */ - " lwarx %0,0,%2\n" /* load and reserve */ - " addi %0,%0,1\n" /* add immediate */ - PPC405_ERR77_SYNC /* ppc405 Erratum 77 */ - " stwcx. %0,0,%2\n" /* store new value */ - " bne- loop_%=\n" /* loop if lost */ - " subi %0,%0,1\n" /* return old value */ + asm volatile ("1:\n" /* lost reservation */ + " lwarx %0,0,%2\n" /* load and reserve */ + " addi %0,%0,1\n" /* add immediate */ + PPC405_ERR77_SYNC /* ppc405 Erratum 77 */ + " stwcx. %0,0,%2\n" /* store new value */ + " bne- 1b\n" /* loop if lost */ + " subi %0,%0,1\n" /* return old value */ : "=&b" (prev), "=m" (*mem) : "b" (mem), "m" (*mem) : "cc", "memory"); @@ -93,12 +93,12 @@ APR_DECLARE(int) apr_atomic_dec32(volatile apr_uint32_t *mem) { apr_uint32_t prev; - asm volatile ("loop_%=:\n" /* lost reservation */ - " lwarx %0,0,%2\n" /* load and reserve */ - " subi %0,%0,1\n" /* subtract immediate */ - PPC405_ERR77_SYNC /* ppc405 Erratum 77 */ - " stwcx. %0,0,%2\n" /* store new value */ - " bne- loop_%=\n" /* loop if lost */ + asm volatile ("1:\n" /* lost reservation */ + " lwarx %0,0,%2\n" /* load and reserve */ + " subi %0,%0,1\n" /* subtract immediate */ + PPC405_ERR77_SYNC /* ppc405 Erratum 77 */ + " stwcx. %0,0,%2\n" /* store new value */ + " bne- 1b\n" /* loop if lost */ : "=&b" (prev), "=m" (*mem) : "b" (mem), "m" (*mem) : "cc", "memory"); @@ -111,14 +111,14 @@ APR_DECLARE(apr_uint32_t) apr_atomic_cas32(volatile apr_uint32_t *mem, apr_uint3 { apr_uint32_t prev; - asm volatile ("loop_%=:\n" /* lost reservation */ - " lwarx %0,0,%1\n" /* load and reserve */ - " cmpw %0,%3\n" /* compare operands */ - " bne- exit_%=\n" /* skip if not equal */ - PPC405_ERR77_SYNC /* ppc405 Erratum 77 */ - " stwcx. %2,0,%1\n" /* store new value */ - " bne- loop_%=\n" /* loop if lost */ - "exit_%=:\n" /* not equal */ + asm volatile ("1:\n" /* lost reservation */ + " lwarx %0,0,%1\n" /* load and reserve */ + " cmpw %0,%3\n" /* compare operands */ + " bne- exit_%=\n" /* skip if not equal */ + PPC405_ERR77_SYNC /* ppc405 Erratum 77 */ + " stwcx. %2,0,%1\n" /* store new value */ + " bne- 1b\n" /* loop if lost */ + "exit_%=:\n" /* not equal */ : "=&r" (prev) : "b" (mem), "r" (with), "r" (cmp) : "cc", "memory"); @@ -130,11 +130,11 @@ APR_DECLARE(apr_uint32_t) apr_atomic_xchg32(volatile apr_uint32_t *mem, apr_uint { apr_uint32_t prev; - asm volatile ("loop_%=:\n" /* lost reservation */ - " lwarx %0,0,%1\n" /* load and reserve */ - PPC405_ERR77_SYNC /* ppc405 Erratum 77 */ - " stwcx. %2,0,%1\n" /* store new value */ - " bne- loop_%=" /* loop if lost */ + asm volatile ("1:\n" /* lost reservation */ + " lwarx %0,0,%1\n" /* load and reserve */ + PPC405_ERR77_SYNC /* ppc405 Erratum 77 */ + " stwcx. %2,0,%1\n" /* store new value */ + " bne- 1b" /* loop if lost */ : "=&r" (prev) : "b" (mem), "r" (val) : "cc", "memory"); @@ -146,26 +146,26 @@ APR_DECLARE(void*) apr_atomic_casptr(volatile void **mem, void *with, const void { void *prev; #if APR_SIZEOF_VOIDP == 4 - asm volatile ("loop_%=:\n" /* lost reservation */ - " lwarx %0,0,%1\n" /* load and reserve */ - " cmpw %0,%3\n" /* compare operands */ - " bne- exit_%=\n" /* skip if not equal */ - PPC405_ERR77_SYNC /* ppc405 Erratum 77 */ - " stwcx. %2,0,%1\n" /* store new value */ - " bne- loop_%=\n" /* loop if lost */ - "exit_%=:\n" /* not equal */ + asm volatile ("1:\n" /* lost reservation */ + " lwarx %0,0,%1\n" /* load and reserve */ + " cmpw %0,%3\n" /* compare operands */ + " bne- 2f\n" /* skip if not equal */ + PPC405_ERR77_SYNC /* ppc405 Erratum 77 */ + " stwcx. %2,0,%1\n" /* store new value */ + " bne- 1b\n" /* loop if lost */ + "2:\n" /* not equal */ : "=&r" (prev) : "b" (mem), "r" (with), "r" (cmp) : "cc", "memory"); #elif APR_SIZEOF_VOIDP == 8 - asm volatile ("loop_%=:\n" /* lost reservation */ - " ldarx %0,0,%1\n" /* load and reserve */ - " cmpd %0,%3\n" /* compare operands */ - " bne- exit_%=\n" /* skip if not equal */ - PPC405_ERR77_SYNC /* ppc405 Erratum 77 */ - " stdcx. %2,0,%1\n" /* store new value */ - " bne- loop_%=\n" /* loop if lost */ - "exit_%=:\n" /* not equal */ + asm volatile ("1:\n" /* lost reservation */ + " ldarx %0,0,%1\n" /* load and reserve */ + " cmpd %0,%3\n" /* compare operands */ + " bne- 2f\n" /* skip if not equal */ + PPC405_ERR77_SYNC /* ppc405 Erratum 77 */ + " stdcx. %2,0,%1\n" /* store new value */ + " bne- 1b\n" /* loop if lost */ + "2:\n" /* not equal */ : "=&r" (prev) : "b" (mem), "r" (with), "r" (cmp) : "cc", "memory"); @@ -179,22 +179,22 @@ APR_DECLARE(void*) apr_atomic_xchgptr(volatile void **mem, void *with) { void *prev; #if APR_SIZEOF_VOIDP == 4 - asm volatile ("loop_%=:\n" /* lost reservation */ - " lwarx %0,0,%1\n" /* load and reserve */ - PPC405_ERR77_SYNC /* ppc405 Erratum 77 */ - " stwcx. %2,0,%1\n" /* store new value */ - " bne- loop_%=\n" /* loop if lost */ - " isync\n" /* memory barrier */ + asm volatile ("1:\n" /* lost reservation */ + " lwarx %0,0,%1\n" /* load and reserve */ + PPC405_ERR77_SYNC /* ppc405 Erratum 77 */ + " stwcx. %2,0,%1\n" /* store new value */ + " bne- 1b\n" /* loop if lost */ + " isync\n" /* memory barrier */ : "=&r" (prev) : "b" (mem), "r" (with) : "cc", "memory"); #elif APR_SIZEOF_VOIDP == 8 - asm volatile ("loop_%=:\n" /* lost reservation */ - " ldarx %0,0,%1\n" /* load and reserve */ - PPC405_ERR77_SYNC /* ppc405 Erratum 77 */ - " stdcx. %2,0,%1\n" /* store new value */ - " bne- loop_%=\n" /* loop if lost */ - " isync\n" /* memory barrier */ + asm volatile ("1:\n" /* lost reservation */ + " ldarx %0,0,%1\n" /* load and reserve */ + PPC405_ERR77_SYNC /* ppc405 Erratum 77 */ + " stdcx. %2,0,%1\n" /* store new value */ + " bne- 1b\n" /* loop if lost */ + " isync\n" /* memory barrier */ : "=&r" (prev) : "b" (mem), "r" (with) : "cc", "memory"); diff --git a/atomic/unix/s390.c b/atomic/unix/s390.c index 3e2332077f43..b6b6f42de02d 100644 --- a/atomic/unix/s390.c +++ b/atomic/unix/s390.c @@ -38,10 +38,10 @@ static APR_INLINE apr_uint32_t atomic_add(volatile apr_uint32_t *mem, apr_uint32 apr_uint32_t prev = *mem, temp; asm volatile ("loop_%=:\n" - " lr %1,%0\n" - " alr %1,%3\n" - " cs %0,%1,%2\n" - " jl loop_%=\n" + " lr %1,%0\n" + " alr %1,%3\n" + " cs %0,%1,%2\n" + " jl loop_%=\n" : "+d" (prev), "+d" (temp), "=Q" (*mem) : "d" (val), "m" (*mem) : "cc", "memory"); @@ -64,10 +64,10 @@ static APR_INLINE apr_uint32_t atomic_sub(volatile apr_uint32_t *mem, apr_uint32 apr_uint32_t prev = *mem, temp; asm volatile ("loop_%=:\n" - " lr %1,%0\n" - " slr %1,%3\n" - " cs %0,%1,%2\n" - " jl loop_%=\n" + " lr %1,%0\n" + " slr %1,%3\n" + " cs %0,%1,%2\n" + " jl loop_%=\n" : "+d" (prev), "+d" (temp), "=Q" (*mem) : "d" (val), "m" (*mem) : "cc", "memory"); @@ -88,7 +88,7 @@ APR_DECLARE(int) apr_atomic_dec32(volatile apr_uint32_t *mem) APR_DECLARE(apr_uint32_t) apr_atomic_cas32(volatile apr_uint32_t *mem, apr_uint32_t with, apr_uint32_t cmp) { - asm volatile (" cs %0,%2,%1\n" + asm volatile (" cs %0,%2,%1\n" : "+d" (cmp), "=Q" (*mem) : "d" (with), "m" (*mem) : "cc", "memory"); @@ -101,8 +101,8 @@ APR_DECLARE(apr_uint32_t) apr_atomic_xchg32(volatile apr_uint32_t *mem, apr_uint apr_uint32_t prev = *mem; asm volatile ("loop_%=:\n" - " cs %0,%2,%1\n" - " jl loop_%=\n" + " cs %0,%2,%1\n" + " jl loop_%=\n" : "+d" (prev), "=Q" (*mem) : "d" (val), "m" (*mem) : "cc", "memory"); @@ -114,12 +114,12 @@ APR_DECLARE(void*) apr_atomic_casptr(volatile void **mem, void *with, const void { void *prev = (void *) cmp; #if APR_SIZEOF_VOIDP == 4 - asm volatile (" cs %0,%2,%1\n" + asm volatile (" cs %0,%2,%1\n" : "+d" (prev), "=Q" (*mem) : "d" (with), "m" (*mem) : "cc", "memory"); #elif APR_SIZEOF_VOIDP == 8 - asm volatile (" csg %0,%2,%1\n" + asm volatile (" csg %0,%2,%1\n" : "+d" (prev), "=Q" (*mem) : "d" (with), "m" (*mem) : "cc", "memory"); @@ -134,15 +134,15 @@ APR_DECLARE(void*) apr_atomic_xchgptr(volatile void **mem, void *with) void *prev = (void *) *mem; #if APR_SIZEOF_VOIDP == 4 asm volatile ("loop_%=:\n" - " cs %0,%2,%1\n" - " jl loop_%=\n" + " cs %0,%2,%1\n" + " jl loop_%=\n" : "+d" (prev), "=Q" (*mem) : "d" (with), "m" (*mem) : "cc", "memory"); #elif APR_SIZEOF_VOIDP == 8 asm volatile ("loop_%=:\n" - " csg %0,%2,%1\n" - " jl loop_%=\n" + " csg %0,%2,%1\n" + " jl loop_%=\n" : "+d" (prev), "=Q" (*mem) : "d" (with), "m" (*mem) : "cc", "memory"); diff --git a/configure b/configure index cee0f0e635db..00122df8871f 100755 --- a/configure +++ b/configure @@ -1,11 +1,9 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68. +# Generated by GNU Autoconf 2.69. # # -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software -# Foundation, Inc. +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation @@ -134,6 +132,31 @@ export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh @@ -167,7 +190,8 @@ if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi -test x\$exitcode = x0 || exit 1" +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && @@ -220,21 +244,25 @@ IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : - # We cannot yet assume a decent shell, so we have to provide a - # neutralization value for shells without unset; and this also - # works around shells that cannot unset nonexistent variables. - # Preserve -v and -x to the replacement shell. - BASH_ENV=/dev/null - ENV=/dev/null - (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV - export CONFIG_SHELL - case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; - esac - exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 fi if test x$as_have_required = xno; then : @@ -336,6 +364,14 @@ $as_echo X"$as_dir" | } # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take @@ -457,6 +493,10 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). @@ -491,16 +531,16 @@ if (echo >conf$$.file) 2>/dev/null; then # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. + # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' + as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null @@ -512,28 +552,8 @@ else as_mkdir_p=false fi -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in #( - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x +as_test_x='test -x' +as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -1371,8 +1391,6 @@ target=$target_alias if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe - $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used" >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi @@ -1642,9 +1660,9 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF configure -generated by GNU Autoconf 2.68 +generated by GNU Autoconf 2.69 -Copyright (C) 2010 Free Software Foundation, Inc. +Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF @@ -1917,7 +1935,7 @@ $as_echo "$ac_try_echo"; } >&5 test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext + test -x conftest$ac_exeext }; then : ac_retval=0 else @@ -2074,7 +2092,8 @@ int main () { static int test_array [1 - 2 * !(($2) >= 0)]; -test_array [0] = 0 +test_array [0] = 0; +return test_array [0]; ; return 0; @@ -2090,7 +2109,8 @@ int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; -test_array [0] = 0 +test_array [0] = 0; +return test_array [0]; ; return 0; @@ -2116,7 +2136,8 @@ int main () { static int test_array [1 - 2 * !(($2) < 0)]; -test_array [0] = 0 +test_array [0] = 0; +return test_array [0]; ; return 0; @@ -2132,7 +2153,8 @@ int main () { static int test_array [1 - 2 * !(($2) >= $ac_mid)]; -test_array [0] = 0 +test_array [0] = 0; +return test_array [0]; ; return 0; @@ -2166,7 +2188,8 @@ int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; -test_array [0] = 0 +test_array [0] = 0; +return test_array [0]; ; return 0; @@ -2342,7 +2365,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was -generated by GNU Autoconf 2.68. Invocation command line was +generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3192,14 +3215,6 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # _LT_LANG - -############################################################ -# NOTE: This macro has been submitted for inclusion into # -# GNU Autoconf as AC_PROG_GO. When it is available in # -# a released version of Autoconf we should remove this # -# macro and use it instead. # -############################################################ -#m4_defun #m4_ifndef @@ -5069,7 +5084,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5109,7 +5124,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5162,7 +5177,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5203,7 +5218,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue @@ -5261,7 +5276,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5305,7 +5320,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5751,8 +5766,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include -#include -#include +struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); @@ -5860,7 +5874,7 @@ do for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue + as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in @@ -6444,83 +6458,12 @@ if test "x$apr_preload_done" != "xyes" ; then ;; *-linux*) - case `uname -r` in - 2.* ) - if test "x$CPPFLAGS" = "x"; then - test "x$silent" != "xyes" && echo " setting CPPFLAGS to \"-DLINUX=2\"" - CPPFLAGS="-DLINUX=2" - else - apr_addto_bugger="-DLINUX=2" - for i in $apr_addto_bugger; do - apr_addto_duplicate="0" - for j in $CPPFLAGS; do - if test "x$i" = "x$j"; then - apr_addto_duplicate="1" - break - fi - done - if test $apr_addto_duplicate = "0"; then - test "x$silent" != "xyes" && echo " adding \"$i\" to CPPFLAGS" - CPPFLAGS="$CPPFLAGS $i" - fi - done - fi - - ;; - 1.* ) - if test "x$CPPFLAGS" = "x"; then - test "x$silent" != "xyes" && echo " setting CPPFLAGS to \"-DLINUX=1\"" - CPPFLAGS="-DLINUX=1" - else - apr_addto_bugger="-DLINUX=1" - for i in $apr_addto_bugger; do - apr_addto_duplicate="0" - for j in $CPPFLAGS; do - if test "x$i" = "x$j"; then - apr_addto_duplicate="1" - break - fi - done - if test $apr_addto_duplicate = "0"; then - test "x$silent" != "xyes" && echo " adding \"$i\" to CPPFLAGS" - CPPFLAGS="$CPPFLAGS $i" - fi - done - fi - - ;; - * ) - ;; - esac if test "x$CPPFLAGS" = "x"; then - test "x$silent" != "xyes" && echo " setting CPPFLAGS to \"-D_REENTRANT -D_GNU_SOURCE\"" - CPPFLAGS="-D_REENTRANT -D_GNU_SOURCE" + test "x$silent" != "xyes" && echo " setting CPPFLAGS to \"-DLINUX -D_REENTRANT -D_GNU_SOURCE\"" + CPPFLAGS="-DLINUX -D_REENTRANT -D_GNU_SOURCE" else - apr_addto_bugger="-D_REENTRANT -D_GNU_SOURCE" - for i in $apr_addto_bugger; do - apr_addto_duplicate="0" - for j in $CPPFLAGS; do - if test "x$i" = "x$j"; then - apr_addto_duplicate="1" - break - fi - done - if test $apr_addto_duplicate = "0"; then - test "x$silent" != "xyes" && echo " adding \"$i\" to CPPFLAGS" - CPPFLAGS="$CPPFLAGS $i" - fi - done - fi - - ;; - *-GNU*) - - if test "x$CPPFLAGS" = "x"; then - test "x$silent" != "xyes" && echo " setting CPPFLAGS to \"-DHURD -D_GNU_SOURCE\"" - CPPFLAGS="-DHURD -D_GNU_SOURCE" - else - apr_addto_bugger="-DHURD -D_GNU_SOURCE" + apr_addto_bugger="-DLINUX -D_REENTRANT -D_GNU_SOURCE" for i in $apr_addto_bugger; do apr_addto_duplicate="0" for j in $CPPFLAGS; do @@ -6769,6 +6712,29 @@ if test "x$apr_preload_done" != "xyes" ; then done fi + ;; + *-gnu*|*-GNU*) + + if test "x$CPPFLAGS" = "x"; then + test "x$silent" != "xyes" && echo " setting CPPFLAGS to \"-D_REENTRANT -D_GNU_SOURCE -DHURD\"" + CPPFLAGS="-D_REENTRANT -D_GNU_SOURCE -DHURD" + else + apr_addto_bugger="-D_REENTRANT -D_GNU_SOURCE -DHURD" + for i in $apr_addto_bugger; do + apr_addto_duplicate="0" + for j in $CPPFLAGS; do + if test "x$i" = "x$j"; then + apr_addto_duplicate="1" + break + fi + done + if test $apr_addto_duplicate = "0"; then + test "x$silent" != "xyes" && echo " adding \"$i\" to CPPFLAGS" + CPPFLAGS="$CPPFLAGS $i" + fi + done + fi + ;; *-next-nextstep*) @@ -6898,7 +6864,7 @@ if test "x$apr_preload_done" != "xyes" ; then fi # See issue 34332 ;; - *-apple-darwin1[01].*) + *-apple-darwin1?.*) if test "x$CPPFLAGS" = "x"; then test "x$silent" != "xyes" && echo " setting CPPFLAGS to \"-DDARWIN_10\"" @@ -9512,7 +9478,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -9564,7 +9530,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -9604,7 +9570,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -9676,7 +9642,7 @@ case $as_dir/ in #(( # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. @@ -9748,7 +9714,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RM="rm" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -9785,7 +9751,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AS="as" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -9822,7 +9788,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ASCPP="cpp" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -9860,7 +9826,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="${ac_tool_prefix}ar" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -9900,7 +9866,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="ar" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -9955,7 +9921,7 @@ do for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue + as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in @@ -10021,7 +9987,7 @@ do for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue + as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in @@ -10228,8 +10194,8 @@ else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -# define __EXTENSIONS__ 1 - $ac_includes_default +# define __EXTENSIONS__ 1 + $ac_includes_default int main () { @@ -10421,7 +10387,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AS="${ac_tool_prefix}as" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -10461,7 +10427,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AS="as" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -10513,7 +10479,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -10553,7 +10519,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -10605,7 +10571,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -10645,7 +10611,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -10819,7 +10785,7 @@ do for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue + as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in @@ -10898,7 +10864,7 @@ do for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue + as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in @@ -11154,7 +11120,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -11198,7 +11164,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -11611,7 +11577,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -11651,7 +11617,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -11954,7 +11920,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -11994,7 +11960,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -12094,7 +12060,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -12138,7 +12104,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -12263,7 +12229,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -12303,7 +12269,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -12362,7 +12328,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -12402,7 +12368,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -13051,7 +13017,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -13091,7 +13057,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -13171,7 +13137,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -13211,7 +13177,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -13263,7 +13229,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -13303,7 +13269,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -13355,7 +13321,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -13395,7 +13361,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -13447,7 +13413,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -13487,7 +13453,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -13539,7 +13505,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -13579,7 +13545,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -21805,23 +21771,20 @@ else /* end confdefs.h. */ $ac_includes_default int -find_stack_direction () +find_stack_direction (int *addr, int depth) { - static char *addr = 0; - auto char dummy; - if (addr == 0) - { - addr = &dummy; - return find_stack_direction (); - } - else - return (&dummy > addr) ? 1 : -1; + int dir, dummy = 0; + if (! addr) + addr = &dummy; + *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1; + dir = depth ? find_stack_direction (addr, depth - 1) : 0; + return dir + dummy; } int -main () +main (int argc, char **argv) { - return find_stack_direction () < 0; + return find_stack_direction (0, argc + !argv + 20) < 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : @@ -22960,11 +22923,11 @@ else int main () { -/* FIXME: Include the comments suggested by Paul. */ + #ifndef __cplusplus - /* Ultrix mips cc rejects this. */ + /* Ultrix mips cc rejects this sort of thing. */ typedef int charset[2]; - const charset cs; + const charset cs = { 0, 0 }; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; @@ -22981,8 +22944,9 @@ main () ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; - { /* SCO 3.2v4 cc rejects this. */ - char *t; + { /* SCO 3.2v4 cc rejects this sort of thing. */ + char tx; + char *t = &tx; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; @@ -22998,10 +22962,10 @@ main () iptr p = 0; ++p; } - { /* AIX XL C 1.02.0.0 rejects this saying + { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ - struct s { int j; const int *ap[3]; }; - struct s *b; b->j = 5; + struct s { int j; const int *ap[3]; } bx; + struct s *b = &bx; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; @@ -27149,13 +27113,24 @@ else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ +#ifdef HAVE_STDLIB_H +#include +#endif +#ifdef HAVE_STRING_H +#include +#endif +#ifdef HAVE_STDIO_H #include +#endif #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif +#ifdef HAVE_SYS_SELECT_H +#include +#endif #ifdef HAVE_NETINET_IN_H #include #endif @@ -27226,6 +27201,26 @@ int main(void) { exit(1); } sa_len = sizeof sa; + /* 1 second select timeout */ + tv.tv_sec = 1; + tv.tv_usec = 0; + /* Set up fd set */ + FD_ZERO(&fds); + FD_SET(listen_s, &fds); + /* Wait for socket to become readable */ + rc = select(listen_s + 1, &fds, NULL, NULL, &tv); + if (rc < 0) { + perror("select"); + exit(1); + } + if (rc == 0) { + fprintf(stderr, "Socket failed to become readable (timeout)\n"); + exit(1); + } + if (!FD_ISSET(listen_s, &fds)) { + fprintf(stderr, "Socket failed to become readable (selected another fd)\n"); + exit(1); + } connected_s = accept(listen_s, (struct sockaddr *)&sa, &sa_len); if (connected_s < 0) { perror("accept"); @@ -28875,16 +28870,16 @@ if (echo >conf$$.file) 2>/dev/null; then # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. + # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' + as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null @@ -28944,28 +28939,16 @@ else as_mkdir_p=false fi -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in #( - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -28987,7 +28970,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # values after options handling. ac_log=" This file was extended by $as_me, which was -generated by GNU Autoconf 2.68. Invocation command line was +generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -29053,10 +29036,10 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ config.status -configured by $0, generated by GNU Autoconf 2.68, +configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" -Copyright (C) 2010 Free Software Foundation, Inc. +Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." @@ -29146,7 +29129,7 @@ fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then - set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' diff --git a/docs/pool-design.html b/docs/pool-design.html index f039d46552de..90d845257c1a 100644 --- a/docs/pool-design.html +++ b/docs/pool-design.html @@ -4,7 +4,7 @@
- Last modified at [$Date: 2004-11-25 09:51:51 +1100 (Thu, 25 Nov 2004) $] + Last modified at [$Date: 2004-11-24 17:51:51 -0500 (Wed, 24 Nov 2004) $]

Using APR Pools

diff --git a/file_io/unix/seek.c b/file_io/unix/seek.c index e70805d7f5d7..3f5aa00e9567 100644 --- a/file_io/unix/seek.c +++ b/file_io/unix/seek.c @@ -117,10 +117,10 @@ apr_status_t apr_file_trunc(apr_file_t *fp, apr_off_t offset) /* Reset buffer positions for write mode */ fp->bufpos = fp->direction = fp->dataRead = 0; } + file_unlock(fp); if (rc) { return rc; } - file_unlock(fp); } if (ftruncate(fp->filedes, offset) == -1) { return errno; diff --git a/include/apr.hw b/include/apr.hw index 0aaa62c63ee6..a75bc602943d 100644 --- a/include/apr.hw +++ b/include/apr.hw @@ -36,6 +36,12 @@ * for Win32 or Netware by those build environments, respectively. */ +/* Make sure we have our platform identifier macro defined we ask for later. + */ +#if defined(_WIN32) && !defined(WIN32) +#define WIN32 1 +#endif + #if defined(WIN32) || defined(DOXYGEN) /* Ignore most warnings (back down to /W3) for poorly constructed headers @@ -377,7 +383,7 @@ typedef int apr_off_t; typedef int apr_socklen_t; typedef apr_uint64_t apr_ino_t; -#ifdef WIN64 +#ifdef _WIN64 #define APR_SIZEOF_VOIDP 8 #else #define APR_SIZEOF_VOIDP 4 @@ -552,7 +558,7 @@ typedef apr_uint32_t apr_uintptr_t; #define APR_DECLARE_DATA __declspec(dllimport) #endif -#ifdef WIN64 +#ifdef _WIN64 #define APR_SSIZE_T_FMT "I64d" #define APR_SIZE_T_FMT "I64u" #else diff --git a/include/apr_allocator.h b/include/apr_allocator.h index 5aaeb1b2faf9..5d6677645db7 100644 --- a/include/apr_allocator.h +++ b/include/apr_allocator.h @@ -71,7 +71,8 @@ struct apr_memnode_t { * @param allocator The allocator we have just created. * */ -APR_DECLARE(apr_status_t) apr_allocator_create(apr_allocator_t **allocator); +APR_DECLARE(apr_status_t) apr_allocator_create(apr_allocator_t **allocator) + __attribute__((nonnull(1))); /** * Destroy an allocator @@ -79,7 +80,8 @@ APR_DECLARE(apr_status_t) apr_allocator_create(apr_allocator_t **allocator); * @remark Any memnodes not given back to the allocator prior to destroying * will _not_ be free()d. */ -APR_DECLARE(void) apr_allocator_destroy(apr_allocator_t *allocator); +APR_DECLARE(void) apr_allocator_destroy(apr_allocator_t *allocator) + __attribute__((nonnull(1))); /** * Allocate a block of mem from the allocator @@ -88,7 +90,8 @@ APR_DECLARE(void) apr_allocator_destroy(apr_allocator_t *allocator); * memnode structure) */ APR_DECLARE(apr_memnode_t *) apr_allocator_alloc(apr_allocator_t *allocator, - apr_size_t size); + apr_size_t size) + __attribute__((nonnull(1))); /** * Free a list of blocks of mem, giving them back to the allocator. @@ -98,7 +101,8 @@ APR_DECLARE(apr_memnode_t *) apr_allocator_alloc(apr_allocator_t *allocator, * @param memnode The memory node to return */ APR_DECLARE(void) apr_allocator_free(apr_allocator_t *allocator, - apr_memnode_t *memnode); + apr_memnode_t *memnode) + __attribute__((nonnull(1,2))); #include "apr_pools.h" @@ -114,13 +118,15 @@ APR_DECLARE(void) apr_allocator_free(apr_allocator_t *allocator, * the allocator will never be destroyed. */ APR_DECLARE(void) apr_allocator_owner_set(apr_allocator_t *allocator, - apr_pool_t *pool); + apr_pool_t *pool) + __attribute__((nonnull(1))); /** * Get the current owner of the allocator * @param allocator The allocator to get the owner from */ -APR_DECLARE(apr_pool_t *) apr_allocator_owner_get(apr_allocator_t *allocator); +APR_DECLARE(apr_pool_t *) apr_allocator_owner_get(apr_allocator_t *allocator) + __attribute__((nonnull(1))); /** * Set the current threshold at which the allocator should start @@ -129,7 +135,8 @@ APR_DECLARE(apr_pool_t *) apr_allocator_owner_get(apr_allocator_t *allocator); * @param size The threshold. 0 == unlimited. */ APR_DECLARE(void) apr_allocator_max_free_set(apr_allocator_t *allocator, - apr_size_t size); + apr_size_t size) + __attribute__((nonnull(1))); #include "apr_thread_mutex.h" @@ -140,14 +147,16 @@ APR_DECLARE(void) apr_allocator_max_free_set(apr_allocator_t *allocator, * @param mutex The mutex */ APR_DECLARE(void) apr_allocator_mutex_set(apr_allocator_t *allocator, - apr_thread_mutex_t *mutex); + apr_thread_mutex_t *mutex) + __attribute__((nonnull(1))); /** * Get the mutex currently set for the allocator * @param allocator The allocator */ APR_DECLARE(apr_thread_mutex_t *) apr_allocator_mutex_get( - apr_allocator_t *allocator); + apr_allocator_t *allocator) + __attribute__((nonnull(1))); #endif /* APR_HAS_THREADS */ diff --git a/include/apr_general.h b/include/apr_general.h index 1ead8b665657..c7389ec92969 100644 --- a/include/apr_general.h +++ b/include/apr_general.h @@ -76,7 +76,7 @@ typedef int apr_signum_t; * @return offset */ -#if defined(CRAY) || (defined(__arm) && !defined(LINUX)) +#if defined(CRAY) || (defined(__arm) && !(defined(LINUX) || defined(__FreeBSD__))) #ifdef __STDC__ #define APR_OFFSET(p_type,field) _Offsetof(p_type,field) #else diff --git a/include/apr_network_io.h b/include/apr_network_io.h index 0335da9d7010..8b9209efd703 100644 --- a/include/apr_network_io.h +++ b/include/apr_network_io.h @@ -756,6 +756,8 @@ APR_DECLARE(int) apr_ipsubnet_test(apr_ipsubnet_t *ipsub, apr_sockaddr_t *sa); * @param name The accept filter * @param args Any extra args to the accept filter. Passing NULL here removes * the accept filter. + * @bug name and args should have been declared as const char *, as they are in + * APR 2.0 */ apr_status_t apr_socket_accept_filter(apr_socket_t *sock, char *name, char *args); diff --git a/include/apr_pools.h b/include/apr_pools.h index 7ae1ed6b61fa..0f0b95e56adc 100644 --- a/include/apr_pools.h +++ b/include/apr_pools.h @@ -196,7 +196,8 @@ APR_DECLARE(void) apr_pool_terminate(void); APR_DECLARE(apr_status_t) apr_pool_create_ex(apr_pool_t **newpool, apr_pool_t *parent, apr_abortfunc_t abort_fn, - apr_allocator_t *allocator); + apr_allocator_t *allocator) + __attribute__((nonnull(1))); /** * Create a new pool. @@ -220,7 +221,8 @@ APR_DECLARE(apr_status_t) apr_pool_create_core_ex(apr_pool_t **newpool, */ APR_DECLARE(apr_status_t) apr_pool_create_unmanaged_ex(apr_pool_t **newpool, apr_abortfunc_t abort_fn, - apr_allocator_t *allocator); + apr_allocator_t *allocator) + __attribute__((nonnull(1))); /** * Debug version of apr_pool_create_ex. @@ -242,7 +244,8 @@ APR_DECLARE(apr_status_t) apr_pool_create_ex_debug(apr_pool_t **newpool, apr_pool_t *parent, apr_abortfunc_t abort_fn, apr_allocator_t *allocator, - const char *file_line); + const char *file_line) + __attribute__((nonnull(1))); #if APR_POOL_DEBUG #define apr_pool_create_ex(newpool, parent, abort_fn, allocator) \ @@ -277,7 +280,8 @@ APR_DECLARE(apr_status_t) apr_pool_create_core_ex_debug(apr_pool_t **newpool, APR_DECLARE(apr_status_t) apr_pool_create_unmanaged_ex_debug(apr_pool_t **newpool, apr_abortfunc_t abort_fn, apr_allocator_t *allocator, - const char *file_line); + const char *file_line) + __attribute__((nonnull(1))); #if APR_POOL_DEBUG #define apr_pool_create_core_ex(newpool, abort_fn, allocator) \ @@ -343,7 +347,8 @@ APR_DECLARE(apr_status_t) apr_pool_create_unmanaged(apr_pool_t **newpool); * Find the pool's allocator * @param pool The pool to get the allocator from. */ -APR_DECLARE(apr_allocator_t *) apr_pool_allocator_get(apr_pool_t *pool); +APR_DECLARE(apr_allocator_t *) apr_pool_allocator_get(apr_pool_t *pool) + __attribute__((nonnull(1))); /** * Clear all memory in the pool and run all the cleanups. This also destroys all @@ -353,7 +358,7 @@ APR_DECLARE(apr_allocator_t *) apr_pool_allocator_get(apr_pool_t *pool); * to re-use this memory for the next allocation. * @see apr_pool_destroy() */ -APR_DECLARE(void) apr_pool_clear(apr_pool_t *p); +APR_DECLARE(void) apr_pool_clear(apr_pool_t *p) __attribute__((nonnull(1))); /** * Debug version of apr_pool_clear. @@ -369,7 +374,8 @@ APR_DECLARE(void) apr_pool_clear(apr_pool_t *p); * and don't call apr_pool_destroy_clear directly. */ APR_DECLARE(void) apr_pool_clear_debug(apr_pool_t *p, - const char *file_line); + const char *file_line) + __attribute__((nonnull(1))); #if APR_POOL_DEBUG #define apr_pool_clear(p) \ @@ -382,7 +388,7 @@ APR_DECLARE(void) apr_pool_clear_debug(apr_pool_t *p, * @param p The pool to destroy * @remark This will actually free the memory */ -APR_DECLARE(void) apr_pool_destroy(apr_pool_t *p); +APR_DECLARE(void) apr_pool_destroy(apr_pool_t *p) __attribute__((nonnull(1))); /** * Debug version of apr_pool_destroy. @@ -398,7 +404,8 @@ APR_DECLARE(void) apr_pool_destroy(apr_pool_t *p); * and don't call apr_pool_destroy_debug directly. */ APR_DECLARE(void) apr_pool_destroy_debug(apr_pool_t *p, - const char *file_line); + const char *file_line) + __attribute__((nonnull(1))); #if APR_POOL_DEBUG #define apr_pool_destroy(p) \ @@ -416,7 +423,11 @@ APR_DECLARE(void) apr_pool_destroy_debug(apr_pool_t *p, * @param size The amount of memory to allocate * @return The allocated memory */ -APR_DECLARE(void *) apr_palloc(apr_pool_t *p, apr_size_t size); +APR_DECLARE(void *) apr_palloc(apr_pool_t *p, apr_size_t size) +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) + __attribute__((alloc_size(2))) +#endif + __attribute__((nonnull(1))); /** * Debug version of apr_palloc @@ -427,7 +438,11 @@ APR_DECLARE(void *) apr_palloc(apr_pool_t *p, apr_size_t size); * @return See: apr_palloc */ APR_DECLARE(void *) apr_palloc_debug(apr_pool_t *p, apr_size_t size, - const char *file_line); + const char *file_line) +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) + __attribute__((alloc_size(2))) +#endif + __attribute__((nonnull(1))); #if APR_POOL_DEBUG #define apr_palloc(p, size) \ @@ -455,7 +470,8 @@ APR_DECLARE(void *) apr_pcalloc(apr_pool_t *p, apr_size_t size); * @return See: apr_pcalloc */ APR_DECLARE(void *) apr_pcalloc_debug(apr_pool_t *p, apr_size_t size, - const char *file_line); + const char *file_line) + __attribute__((nonnull(1))); #if APR_POOL_DEBUG #define apr_pcalloc(p, size) \ @@ -476,21 +492,24 @@ APR_DECLARE(void *) apr_pcalloc_debug(apr_pool_t *p, apr_size_t size, * deal with the error accordingly. */ APR_DECLARE(void) apr_pool_abort_set(apr_abortfunc_t abortfunc, - apr_pool_t *pool); + apr_pool_t *pool) + __attribute__((nonnull(2))); /** * Get the abort function associated with the specified pool. * @param pool The pool for retrieving the abort function. * @return The abort function for the given pool. */ -APR_DECLARE(apr_abortfunc_t) apr_pool_abort_get(apr_pool_t *pool); +APR_DECLARE(apr_abortfunc_t) apr_pool_abort_get(apr_pool_t *pool) + __attribute__((nonnull(1))); /** * Get the parent pool of the specified pool. * @param pool The pool for retrieving the parent pool. * @return The parent of the given pool. */ -APR_DECLARE(apr_pool_t *) apr_pool_parent_get(apr_pool_t *pool); +APR_DECLARE(apr_pool_t *) apr_pool_parent_get(apr_pool_t *pool) + __attribute__((nonnull(1))); /** * Determine if pool a is an ancestor of pool b. @@ -510,7 +529,8 @@ APR_DECLARE(int) apr_pool_is_ancestor(apr_pool_t *a, apr_pool_t *b); * @param pool The pool to tag * @param tag The tag */ -APR_DECLARE(void) apr_pool_tag(apr_pool_t *pool, const char *tag); +APR_DECLARE(void) apr_pool_tag(apr_pool_t *pool, const char *tag) + __attribute__((nonnull(1))); /* @@ -536,11 +556,11 @@ APR_DECLARE(void) apr_pool_tag(apr_pool_t *pool, const char *tag); * key names is a typical way to help ensure this uniqueness. * */ -APR_DECLARE(apr_status_t) apr_pool_userdata_set( - const void *data, - const char *key, - apr_status_t (*cleanup)(void *), - apr_pool_t *pool); +APR_DECLARE(apr_status_t) apr_pool_userdata_set(const void *data, + const char *key, + apr_status_t (*cleanup)(void *), + apr_pool_t *pool) + __attribute__((nonnull(2,4))); /** * Set the data associated with the current pool @@ -562,10 +582,10 @@ APR_DECLARE(apr_status_t) apr_pool_userdata_set( * */ APR_DECLARE(apr_status_t) apr_pool_userdata_setn( - const void *data, - const char *key, - apr_status_t (*cleanup)(void *), - apr_pool_t *pool); + const void *data, const char *key, + apr_status_t (*cleanup)(void *), + apr_pool_t *pool) + __attribute__((nonnull(2,4))); /** * Return the data associated with the current pool. @@ -574,7 +594,8 @@ APR_DECLARE(apr_status_t) apr_pool_userdata_setn( * @param pool The current pool. */ APR_DECLARE(apr_status_t) apr_pool_userdata_get(void **data, const char *key, - apr_pool_t *pool); + apr_pool_t *pool) + __attribute__((nonnull(1,2,3))); /** @@ -601,10 +622,10 @@ APR_DECLARE(apr_status_t) apr_pool_userdata_get(void **data, const char *key, * to exec - this function is called in the child, obviously! */ APR_DECLARE(void) apr_pool_cleanup_register( - apr_pool_t *p, - const void *data, - apr_status_t (*plain_cleanup)(void *), - apr_status_t (*child_cleanup)(void *)); + apr_pool_t *p, const void *data, + apr_status_t (*plain_cleanup)(void *), + apr_status_t (*child_cleanup)(void *)) + __attribute__((nonnull(3,4))); /** * Register a function to be called when a pool is cleared or destroyed. @@ -619,9 +640,9 @@ APR_DECLARE(void) apr_pool_cleanup_register( * or destroyed */ APR_DECLARE(void) apr_pool_pre_cleanup_register( - apr_pool_t *p, - const void *data, - apr_status_t (*plain_cleanup)(void *)); + apr_pool_t *p, const void *data, + apr_status_t (*plain_cleanup)(void *)) + __attribute__((nonnull(3))); /** * Remove a previously registered cleanup function. @@ -636,7 +657,8 @@ APR_DECLARE(void) apr_pool_pre_cleanup_register( * function */ APR_DECLARE(void) apr_pool_cleanup_kill(apr_pool_t *p, const void *data, - apr_status_t (*cleanup)(void *)); + apr_status_t (*cleanup)(void *)) + __attribute__((nonnull(3))); /** * Replace the child cleanup function of a previously registered cleanup. @@ -651,10 +673,10 @@ APR_DECLARE(void) apr_pool_cleanup_kill(apr_pool_t *p, const void *data, * @param child_cleanup The function to register as the child cleanup */ APR_DECLARE(void) apr_pool_child_cleanup_set( - apr_pool_t *p, - const void *data, - apr_status_t (*plain_cleanup)(void *), - apr_status_t (*child_cleanup)(void *)); + apr_pool_t *p, const void *data, + apr_status_t (*plain_cleanup)(void *), + apr_status_t (*child_cleanup)(void *)) + __attribute__((nonnull(3,4))); /** * Run the specified cleanup function immediately and unregister it. @@ -667,10 +689,9 @@ APR_DECLARE(void) apr_pool_child_cleanup_set( * @param data The data to remove from cleanup * @param cleanup The function to remove from cleanup */ -APR_DECLARE(apr_status_t) apr_pool_cleanup_run( - apr_pool_t *p, - void *data, - apr_status_t (*cleanup)(void *)); +APR_DECLARE(apr_status_t) apr_pool_cleanup_run(apr_pool_t *p, void *data, + apr_status_t (*cleanup)(void *)) + __attribute__((nonnull(3))); /** * An empty cleanup function. @@ -739,7 +760,8 @@ APR_DECLARE(void) apr_pool_cleanup_for_exec(void); * @param p The parent pool * @param sub The subpool */ -APR_DECLARE(void) apr_pool_join(apr_pool_t *p, apr_pool_t *sub); +APR_DECLARE(void) apr_pool_join(apr_pool_t *p, apr_pool_t *sub) + __attribute__((nonnull(2))); /** * Find a pool from something allocated in it. @@ -754,7 +776,8 @@ APR_DECLARE(apr_pool_t *) apr_pool_find(const void *mem); * @param recurse Recurse/include the subpools' sizes * @return The number of bytes */ -APR_DECLARE(apr_size_t) apr_pool_num_bytes(apr_pool_t *p, int recurse); +APR_DECLARE(apr_size_t) apr_pool_num_bytes(apr_pool_t *p, int recurse) + __attribute__((nonnull(1))); /** * Lock a pool diff --git a/include/apr_strings.h b/include/apr_strings.h index 6b71ff17eb6f..457217358c8e 100644 --- a/include/apr_strings.h +++ b/include/apr_strings.h @@ -106,7 +106,11 @@ APR_DECLARE(char *) apr_pstrdup(apr_pool_t *p, const char *s); * has 'n' or more characters. If the string might contain * fewer characters, use apr_pstrndup. */ -APR_DECLARE(char *) apr_pstrmemdup(apr_pool_t *p, const char *s, apr_size_t n); +APR_DECLARE(char *) apr_pstrmemdup(apr_pool_t *p, const char *s, apr_size_t n) +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) + __attribute__((alloc_size(3))) +#endif + ; /** * Duplicate at most n characters of a string into memory allocated @@ -128,7 +132,11 @@ APR_DECLARE(char *) apr_pstrndup(apr_pool_t *p, const char *s, apr_size_t n); * @param n The number of bytes to duplicate * @return The new block of memory */ -APR_DECLARE(void *) apr_pmemdup(apr_pool_t *p, const void *m, apr_size_t n); +APR_DECLARE(void *) apr_pmemdup(apr_pool_t *p, const void *m, apr_size_t n) +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) + __attribute__((alloc_size(3))) +#endif + ; /** * Concatenate multiple strings, allocating memory out a pool diff --git a/include/apr_thread_proc.h b/include/apr_thread_proc.h index 7df84ef32abb..0a97c955c4b6 100644 --- a/include/apr_thread_proc.h +++ b/include/apr_thread_proc.h @@ -315,7 +315,7 @@ APR_DECLARE(apr_status_t) apr_thread_once(apr_thread_once_t *control, APR_DECLARE(apr_status_t) apr_thread_detach(apr_thread_t *thd); /** - * Return the pool associated with the current thread. + * Return user data associated with the current thread. * @param data The user data associated with the thread. * @param key The key to associate with the data * @param thread The currently open thread. @@ -324,7 +324,7 @@ APR_DECLARE(apr_status_t) apr_thread_data_get(void **data, const char *key, apr_thread_t *thread); /** - * Return the pool associated with the current thread. + * Set user data associated with the current thread. * @param data The user data to associate with the thread. * @param key The key to use for associating the data with the thread * @param cleanup The cleanup routine to use when the thread is destroyed. diff --git a/include/apr_version.h b/include/apr_version.h index 81223207ac8b..4b06508eecba 100644 --- a/include/apr_version.h +++ b/include/apr_version.h @@ -38,6 +38,9 @@ */ +#define APR_COPYRIGHT "Copyright (c) 2013 The Apache Software " \ + "Foundation or its licensors, as applicable." + /* The numeric compile-time version constants. These constants are the * authoritative version numbers for APR. */ @@ -59,7 +62,7 @@ * The Patch Level never includes API changes, simply bug fixes. * Reset to 0 when upgrading APR_MINOR_VERSION */ -#define APR_PATCH_VERSION 6 +#define APR_PATCH_VERSION 8 /** * The symbol APR_IS_DEV_VERSION is only defined for internal, @@ -87,7 +90,9 @@ #if defined(APR_IS_DEV_VERSION) || defined(DOXYGEN) /** Internal: string form of the "is dev" flag */ +#ifndef APR_IS_DEV_STRING #define APR_IS_DEV_STRING "-dev" +#endif #else #define APR_IS_DEV_STRING "" #endif diff --git a/libapr.rc b/libapr.rc index 098b5f15240f..604fc7c06e4f 100644 --- a/libapr.rc +++ b/libapr.rc @@ -1,8 +1,5 @@ #include "apr_version.h" -#define APR_COPYRIGHT "Copyright (c) 2011 The Apache Software " \ - "Foundation or its licensors, as applicable." - #define APR_LICENSE \ "Licensed to the Apache Software Foundation (ASF) under one or more " \ "contributor license agreements. See the NOTICE file distributed with " \ diff --git a/network_io/unix/multicast.c b/network_io/unix/multicast.c index 67ab24574038..3767bfdd15c1 100644 --- a/network_io/unix/multicast.c +++ b/network_io/unix/multicast.c @@ -193,36 +193,39 @@ static apr_status_t do_mcast(int type, apr_socket_t *sock, return rv; } +/* Set the IP_MULTICAST_TTL or IP_MULTICAST_LOOP option, or IPv6 + * equivalents, for the socket, to the given value. Note that this + * function *only works* for those particular option types. */ static apr_status_t do_mcast_opt(int type, apr_socket_t *sock, apr_byte_t value) { apr_status_t rv = APR_SUCCESS; if (sock_is_ipv4(sock)) { + /* For the IP_MULTICAST_* options, this must be a (char *) + * pointer. */ if (setsockopt(sock->socketdes, IPPROTO_IP, type, (const void *) &value, sizeof(value)) == -1) { rv = errno; } } #if APR_HAVE_IPV6 - else if (sock_is_ipv6(sock) && type == IP_MULTICAST_LOOP) { - unsigned int loopopt = value; - type = IPV6_MULTICAST_LOOP; - if (setsockopt(sock->socketdes, IPPROTO_IPV6, type, - (const void *) &loopopt, sizeof(loopopt)) == -1) { - rv = errno; - } - } else if (sock_is_ipv6(sock)) { + /* For the IPV6_* options, an (int *) pointer must be used. */ + int ivalue = value; + if (type == IP_MULTICAST_TTL) { type = IPV6_MULTICAST_HOPS; } + else if (type == IP_MULTICAST_LOOP) { + type = IPV6_MULTICAST_LOOP; + } else { return APR_ENOTIMPL; } if (setsockopt(sock->socketdes, IPPROTO_IPV6, type, - &value, sizeof(value)) == -1) { + (const void *) &ivalue, sizeof(ivalue)) == -1) { rv = errno; } } diff --git a/network_io/unix/sendrecv.c b/network_io/unix/sendrecv.c index c133a26d9c7b..6b14643cd58b 100644 --- a/network_io/unix/sendrecv.c +++ b/network_io/unix/sendrecv.c @@ -174,7 +174,14 @@ apr_status_t apr_socket_recvfrom(apr_sockaddr_t *from, apr_socket_t *sock, return errno; } - apr_sockaddr_vars_set(from, from->sa.sin.sin_family, ntohs(from->sa.sin.sin_port)); + /* + * Check if we have a valid address. recvfrom() with MSG_PEEK may return + * success without filling in the address. + */ + if (from->salen > APR_OFFSETOF(struct sockaddr_in, sin_port)) { + apr_sockaddr_vars_set(from, from->sa.sin.sin_family, + ntohs(from->sa.sin.sin_port)); + } (*len) = rv; if (rv == 0 && sock->type == SOCK_STREAM) { @@ -245,7 +252,7 @@ do_select: /* Define a structure to pass in when we have a NULL header value */ static apr_hdtr_t no_hdtr; -#if defined(__linux__) && defined(HAVE_WRITEV) +#if (defined(__linux__) || defined(__GNU__)) && defined(HAVE_WRITEV) apr_status_t apr_socket_sendfile(apr_socket_t *sock, apr_file_t *file, apr_hdtr_t *hdtr, apr_off_t *offset, @@ -285,9 +292,6 @@ apr_status_t apr_socket_sendfile(apr_socket_t *sock, apr_file_t *file, hdtr = &no_hdtr; } - /* Ignore flags for now. */ - flags = 0; - if (hdtr->numheaders > 0) { apr_size_t hdrbytes; diff --git a/network_io/unix/sockaddr.c b/network_io/unix/sockaddr.c index ed4c474dc63d..9253a27461fb 100644 --- a/network_io/unix/sockaddr.c +++ b/network_io/unix/sockaddr.c @@ -356,9 +356,27 @@ static apr_status_t call_resolver(apr_sockaddr_t **sa, } error = getaddrinfo(hostname, servname, &hints, &ai_list); #ifdef HAVE_GAI_ADDRCONFIG - if (error == EAI_BADFLAGS && family == APR_UNSPEC) { - /* Retry with no flags if AI_ADDRCONFIG was rejected. */ - hints.ai_flags = 0; + /* + * Using AI_ADDRCONFIG involves some unfortunate guesswork because it + * does not consider loopback addresses when trying to determine if + * IPv4 or IPv6 is configured on a system (see RFC 3493). + * This is a problem if one actually wants to listen on or connect to + * the loopback address of a protocol family that is not otherwise + * configured on the system. See PR 52709. + * To work around some of the problems, retry without AI_ADDRCONFIG + * in case of EAI_ADDRFAMILY. + * XXX: apr_sockaddr_info_get() should really accept a flag to determine + * XXX: if AI_ADDRCONFIG's guesswork is wanted and if the address is + * XXX: to be used for listen() or connect(). + * + * In case of EAI_BADFLAGS, AI_ADDRCONFIG is not supported. + */ + if ((family == APR_UNSPEC) && (error == EAI_BADFLAGS +#ifdef EAI_ADDRFAMILY + || error == EAI_ADDRFAMILY +#endif + )) { + hints.ai_flags &= ~AI_ADDRCONFIG; error = getaddrinfo(hostname, servname, &hints, &ai_list); } #endif @@ -367,7 +385,7 @@ static apr_status_t call_resolver(apr_sockaddr_t **sa, return apr_get_netos_error(); #else if (error == EAI_SYSTEM) { - return errno; + return errno ? errno : APR_EGENERAL; } else { @@ -422,6 +440,15 @@ static apr_status_t call_resolver(apr_sockaddr_t **sa, ai = ai->ai_next; } freeaddrinfo(ai_list); + + if (prev_sa == NULL) { + /* + * getaddrinfo returned only useless entries and *sa is still empty. + * This should be treated as an error. + */ + return APR_EGENERAL; + } + return APR_SUCCESS; } @@ -555,6 +582,11 @@ static apr_status_t find_addresses(apr_sockaddr_t **sa, ++curaddr; } + if (prev_sa == NULL) { + /* this should not happen but no result should be treated as error */ + return APR_EGENERAL; + } + return APR_SUCCESS; } @@ -1010,7 +1042,7 @@ APR_DECLARE(int) apr_ipsubnet_test(apr_ipsubnet_t *ipsub, apr_sockaddr_t *sa) /* XXX This line will segv on Win32 build with APR_HAVE_IPV6, * but without the IPV6 drivers installed. */ - if (sa->sa.sin.sin_family == AF_INET) { + if (sa->family == AF_INET) { if (ipsub->family == AF_INET && ((sa->sa.sin.sin_addr.s_addr & ipsub->mask[0]) == ipsub->sub[0])) { return 1; @@ -1022,7 +1054,7 @@ APR_DECLARE(int) apr_ipsubnet_test(apr_ipsubnet_t *ipsub, apr_sockaddr_t *sa) return 1; } } - else { + else if (sa->family == AF_INET6 && ipsub->family == AF_INET6) { apr_uint32_t *addr = (apr_uint32_t *)sa->ipaddr_ptr; if ((addr[0] & ipsub->mask[0]) == ipsub->sub[0] && diff --git a/network_io/unix/sockopt.c b/network_io/unix/sockopt.c index 3fc932f42f5e..7b67c2ec13a1 100644 --- a/network_io/unix/sockopt.c +++ b/network_io/unix/sockopt.c @@ -381,12 +381,33 @@ apr_status_t apr_gethostname(char *buf, apr_int32_t len, apr_pool_t *cont) } #if APR_HAS_SO_ACCEPTFILTER -apr_status_t apr_socket_accept_filter(apr_socket_t *sock, char *name, - char *args) +apr_status_t apr_socket_accept_filter(apr_socket_t *sock, char *nonconst_name, + char *nonconst_args) { + /* these should have been const; act like they are */ + const char *name = nonconst_name; + const char *args = nonconst_args; + struct accept_filter_arg af; - strncpy(af.af_name, name, 16); - strncpy(af.af_arg, args, 256 - 16); + socklen_t optlen = sizeof(af); + + /* FreeBSD returns an error if the filter is already set; ignore + * this call if we previously set it to the same value. + */ + if ((getsockopt(sock->socketdes, SOL_SOCKET, SO_ACCEPTFILTER, + &af, &optlen)) == 0) { + if (!strcmp(name, af.af_name) && !strcmp(args, af.af_arg)) { + return APR_SUCCESS; + } + } + + /* Uhh, at least in FreeBSD 9 the fields are declared as arrays of + * these lengths; did sizeof not work in some ancient release? + * + * FreeBSD kernel sets the last byte to a '\0'. + */ + apr_cpystrn(af.af_name, name, 16); + apr_cpystrn(af.af_arg, args, 256 - 16); if ((setsockopt(sock->socketdes, SOL_SOCKET, SO_ACCEPTFILTER, &af, sizeof(af))) < 0) { diff --git a/random/unix/sha2.c b/random/unix/sha2.c index 212c1b732a4e..12c257d1fa1b 100644 --- a/random/unix/sha2.c +++ b/random/unix/sha2.c @@ -52,8 +52,6 @@ typedef apr_uint64_t sha2_word64; /* Exactly 8 bytes */ /*** SHA-256/384/512 Various Length Definitions ***********************/ /* NOTE: Most of these are in sha2.h */ #define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8) -#define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16) -#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16) /*** ENDIAN REVERSAL MACROS *******************************************/ @@ -150,9 +148,7 @@ typedef apr_uint64_t sha2_word64; /* Exactly 8 bytes */ * library -- they are intended for private internal visibility/use * only. */ -void apr__SHA512_Last(SHA512_CTX*); void apr__SHA256_Transform(SHA256_CTX*, const sha2_word32*); -void apr__SHA512_Transform(SHA512_CTX*, const sha2_word64*); /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ @@ -188,74 +184,6 @@ static const sha2_word32 sha256_initial_hash_value[8] = { 0x5be0cd19UL }; -/* Hash constant words K for SHA-384 and SHA-512: */ -static const sha2_word64 K512[80] = { - APR_UINT64_C(0x428a2f98d728ae22), APR_UINT64_C(0x7137449123ef65cd), - APR_UINT64_C(0xb5c0fbcfec4d3b2f), APR_UINT64_C(0xe9b5dba58189dbbc), - APR_UINT64_C(0x3956c25bf348b538), APR_UINT64_C(0x59f111f1b605d019), - APR_UINT64_C(0x923f82a4af194f9b), APR_UINT64_C(0xab1c5ed5da6d8118), - APR_UINT64_C(0xd807aa98a3030242), APR_UINT64_C(0x12835b0145706fbe), - APR_UINT64_C(0x243185be4ee4b28c), APR_UINT64_C(0x550c7dc3d5ffb4e2), - APR_UINT64_C(0x72be5d74f27b896f), APR_UINT64_C(0x80deb1fe3b1696b1), - APR_UINT64_C(0x9bdc06a725c71235), APR_UINT64_C(0xc19bf174cf692694), - APR_UINT64_C(0xe49b69c19ef14ad2), APR_UINT64_C(0xefbe4786384f25e3), - APR_UINT64_C(0x0fc19dc68b8cd5b5), APR_UINT64_C(0x240ca1cc77ac9c65), - APR_UINT64_C(0x2de92c6f592b0275), APR_UINT64_C(0x4a7484aa6ea6e483), - APR_UINT64_C(0x5cb0a9dcbd41fbd4), APR_UINT64_C(0x76f988da831153b5), - APR_UINT64_C(0x983e5152ee66dfab), APR_UINT64_C(0xa831c66d2db43210), - APR_UINT64_C(0xb00327c898fb213f), APR_UINT64_C(0xbf597fc7beef0ee4), - APR_UINT64_C(0xc6e00bf33da88fc2), APR_UINT64_C(0xd5a79147930aa725), - APR_UINT64_C(0x06ca6351e003826f), APR_UINT64_C(0x142929670a0e6e70), - APR_UINT64_C(0x27b70a8546d22ffc), APR_UINT64_C(0x2e1b21385c26c926), - APR_UINT64_C(0x4d2c6dfc5ac42aed), APR_UINT64_C(0x53380d139d95b3df), - APR_UINT64_C(0x650a73548baf63de), APR_UINT64_C(0x766a0abb3c77b2a8), - APR_UINT64_C(0x81c2c92e47edaee6), APR_UINT64_C(0x92722c851482353b), - APR_UINT64_C(0xa2bfe8a14cf10364), APR_UINT64_C(0xa81a664bbc423001), - APR_UINT64_C(0xc24b8b70d0f89791), APR_UINT64_C(0xc76c51a30654be30), - APR_UINT64_C(0xd192e819d6ef5218), APR_UINT64_C(0xd69906245565a910), - APR_UINT64_C(0xf40e35855771202a), APR_UINT64_C(0x106aa07032bbd1b8), - APR_UINT64_C(0x19a4c116b8d2d0c8), APR_UINT64_C(0x1e376c085141ab53), - APR_UINT64_C(0x2748774cdf8eeb99), APR_UINT64_C(0x34b0bcb5e19b48a8), - APR_UINT64_C(0x391c0cb3c5c95a63), APR_UINT64_C(0x4ed8aa4ae3418acb), - APR_UINT64_C(0x5b9cca4f7763e373), APR_UINT64_C(0x682e6ff3d6b2b8a3), - APR_UINT64_C(0x748f82ee5defb2fc), APR_UINT64_C(0x78a5636f43172f60), - APR_UINT64_C(0x84c87814a1f0ab72), APR_UINT64_C(0x8cc702081a6439ec), - APR_UINT64_C(0x90befffa23631e28), APR_UINT64_C(0xa4506cebde82bde9), - APR_UINT64_C(0xbef9a3f7b2c67915), APR_UINT64_C(0xc67178f2e372532b), - APR_UINT64_C(0xca273eceea26619c), APR_UINT64_C(0xd186b8c721c0c207), - APR_UINT64_C(0xeada7dd6cde0eb1e), APR_UINT64_C(0xf57d4f7fee6ed178), - APR_UINT64_C(0x06f067aa72176fba), APR_UINT64_C(0x0a637dc5a2c898a6), - APR_UINT64_C(0x113f9804bef90dae), APR_UINT64_C(0x1b710b35131c471b), - APR_UINT64_C(0x28db77f523047d84), APR_UINT64_C(0x32caab7b40c72493), - APR_UINT64_C(0x3c9ebe0a15c9bebc), APR_UINT64_C(0x431d67c49c100d4c), - APR_UINT64_C(0x4cc5d4becb3e42b6), APR_UINT64_C(0x597f299cfc657e2a), - APR_UINT64_C(0x5fcb6fab3ad6faec), APR_UINT64_C(0x6c44198c4a475817) -}; - -/* Initial hash value H for SHA-384 */ -static const sha2_word64 sha384_initial_hash_value[8] = { - APR_UINT64_C(0xcbbb9d5dc1059ed8), - APR_UINT64_C(0x629a292a367cd507), - APR_UINT64_C(0x9159015a3070dd17), - APR_UINT64_C(0x152fecd8f70e5939), - APR_UINT64_C(0x67332667ffc00b31), - APR_UINT64_C(0x8eb44a8768581511), - APR_UINT64_C(0xdb0c2e0d64f98fa7), - APR_UINT64_C(0x47b5481dbefa4fa4) -}; - -/* Initial hash value H for SHA-512 */ -static const sha2_word64 sha512_initial_hash_value[8] = { - APR_UINT64_C(0x6a09e667f3bcc908), - APR_UINT64_C(0xbb67ae8584caa73b), - APR_UINT64_C(0x3c6ef372fe94f82b), - APR_UINT64_C(0xa54ff53a5f1d36f1), - APR_UINT64_C(0x510e527fade682d1), - APR_UINT64_C(0x9b05688c2b3e6c1f), - APR_UINT64_C(0x1f83d9abfb41bd6b), - APR_UINT64_C(0x5be0cd19137e2179) -}; - /* * Constant used by SHA256/384/512_End() functions for converting the * digest to a readable hexadecimal character string: @@ -537,7 +465,14 @@ void apr__SHA256_Final(sha2_byte digest[], SHA256_CTX* context) { *context->buffer = 0x80; } /* Set the bit count: */ - *(sha2_word64*)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount; + { + union dummy { + apr_uint64_t bitcount; + apr_byte_t bytes[8]; + } bitcount; + bitcount.bitcount = context->bitcount; + MEMCPY_BCOPY(&context->buffer[SHA256_SHORT_BLOCK_LENGTH], bitcount.bytes, 8); + } /* Final transform: */ apr__SHA256_Transform(context, (sha2_word32*)context->buffer); @@ -591,410 +526,3 @@ char* apr__SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIG apr__SHA256_Update(&context, data, len); return apr__SHA256_End(&context, digest); } - - -/*** SHA-512: *********************************************************/ -void apr__SHA512_Init(SHA512_CTX* context) { - if (context == (SHA512_CTX*)0) { - return; - } - MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH); - MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH); - context->bitcount[0] = context->bitcount[1] = 0; -} - -#ifdef SHA2_UNROLL_TRANSFORM - -/* Unrolled SHA-512 round macros: */ -#if !APR_IS_BIGENDIAN - -#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ - REVERSE64(*data++, W512[j]); \ - T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ - K512[j] + W512[j]; \ - (d) += T1, \ - (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \ - j++ - - -#else /* APR_IS_BIGENDIAN */ - -#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ - T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ - K512[j] + (W512[j] = *data++); \ - (d) += T1; \ - (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ - j++ - -#endif /* APR_IS_BIGENDIAN */ - -#define ROUND512(a,b,c,d,e,f,g,h) \ - s0 = W512[(j+1)&0x0f]; \ - s0 = sigma0_512(s0); \ - s1 = W512[(j+14)&0x0f]; \ - s1 = sigma1_512(s1); \ - T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \ - (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \ - (d) += T1; \ - (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ - j++ - -void apr__SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { - sha2_word64 a, b, c, d, e, f, g, h, s0, s1; - sha2_word64 T1, *W512 = (sha2_word64*)context->buffer; - int j; - - /* Initialize registers with the prev. intermediate value */ - a = context->state[0]; - b = context->state[1]; - c = context->state[2]; - d = context->state[3]; - e = context->state[4]; - f = context->state[5]; - g = context->state[6]; - h = context->state[7]; - - j = 0; - do { - ROUND512_0_TO_15(a,b,c,d,e,f,g,h); - ROUND512_0_TO_15(h,a,b,c,d,e,f,g); - ROUND512_0_TO_15(g,h,a,b,c,d,e,f); - ROUND512_0_TO_15(f,g,h,a,b,c,d,e); - ROUND512_0_TO_15(e,f,g,h,a,b,c,d); - ROUND512_0_TO_15(d,e,f,g,h,a,b,c); - ROUND512_0_TO_15(c,d,e,f,g,h,a,b); - ROUND512_0_TO_15(b,c,d,e,f,g,h,a); - } while (j < 16); - - /* Now for the remaining rounds up to 79: */ - do { - ROUND512(a,b,c,d,e,f,g,h); - ROUND512(h,a,b,c,d,e,f,g); - ROUND512(g,h,a,b,c,d,e,f); - ROUND512(f,g,h,a,b,c,d,e); - ROUND512(e,f,g,h,a,b,c,d); - ROUND512(d,e,f,g,h,a,b,c); - ROUND512(c,d,e,f,g,h,a,b); - ROUND512(b,c,d,e,f,g,h,a); - } while (j < 80); - - /* Compute the current intermediate hash value */ - context->state[0] += a; - context->state[1] += b; - context->state[2] += c; - context->state[3] += d; - context->state[4] += e; - context->state[5] += f; - context->state[6] += g; - context->state[7] += h; - - /* Clean up */ - a = b = c = d = e = f = g = h = T1 = 0; -} - -#else /* SHA2_UNROLL_TRANSFORM */ - -void apr__SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { - sha2_word64 a, b, c, d, e, f, g, h, s0, s1; - sha2_word64 T1, T2, *W512 = (sha2_word64*)context->buffer; - int j; - - /* Initialize registers with the prev. intermediate value */ - a = context->state[0]; - b = context->state[1]; - c = context->state[2]; - d = context->state[3]; - e = context->state[4]; - f = context->state[5]; - g = context->state[6]; - h = context->state[7]; - - j = 0; - do { -#if !APR_IS_BIGENDIAN - /* Convert TO host byte order */ - REVERSE64(*data++, W512[j]); - /* Apply the SHA-512 compression function to update a..h */ - T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j]; -#else /* APR_IS_BIGENDIAN */ - /* Apply the SHA-512 compression function to update a..h with copy */ - T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++); -#endif /* APR_IS_BIGENDIAN */ - T2 = Sigma0_512(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - - j++; - } while (j < 16); - - do { - /* Part of the message block expansion: */ - s0 = W512[(j+1)&0x0f]; - s0 = sigma0_512(s0); - s1 = W512[(j+14)&0x0f]; - s1 = sigma1_512(s1); - - /* Apply the SHA-512 compression function to update a..h */ - T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + - (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); - T2 = Sigma0_512(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - - j++; - } while (j < 80); - - /* Compute the current intermediate hash value */ - context->state[0] += a; - context->state[1] += b; - context->state[2] += c; - context->state[3] += d; - context->state[4] += e; - context->state[5] += f; - context->state[6] += g; - context->state[7] += h; - - /* Clean up */ - a = b = c = d = e = f = g = h = T1 = T2 = 0; -} - -#endif /* SHA2_UNROLL_TRANSFORM */ - -void apr__SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { - unsigned int freespace, usedspace; - - if (len == 0) { - /* Calling with no data is valid - we do nothing */ - return; - } - - /* Sanity check: */ - assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0); - - usedspace = (unsigned int)((context->bitcount[0] >> 3) - % SHA512_BLOCK_LENGTH); - if (usedspace > 0) { - /* Calculate how much free space is available in the buffer */ - freespace = SHA512_BLOCK_LENGTH - usedspace; - - if (len >= freespace) { - /* Fill the buffer completely and process it */ - MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); - ADDINC128(context->bitcount, freespace << 3); - len -= freespace; - data += freespace; - apr__SHA512_Transform(context, (sha2_word64*)context->buffer); - } else { - /* The buffer is not yet full */ - MEMCPY_BCOPY(&context->buffer[usedspace], data, len); - ADDINC128(context->bitcount, len << 3); - /* Clean up: */ - usedspace = freespace = 0; - return; - } - } - while (len >= SHA512_BLOCK_LENGTH) { - /* Process as many complete blocks as we can */ - apr__SHA512_Transform(context, (sha2_word64*)data); - ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); - len -= SHA512_BLOCK_LENGTH; - data += SHA512_BLOCK_LENGTH; - } - if (len > 0) { - /* There's left-overs, so save 'em */ - MEMCPY_BCOPY(context->buffer, data, len); - ADDINC128(context->bitcount, len << 3); - } - /* Clean up: */ - usedspace = freespace = 0; -} - -void apr__SHA512_Last(SHA512_CTX* context) { - unsigned int usedspace; - - usedspace = (unsigned int)((context->bitcount[0] >> 3) - % SHA512_BLOCK_LENGTH); -#if !APR_IS_BIGENDIAN - /* Convert FROM host byte order */ - REVERSE64(context->bitcount[0],context->bitcount[0]); - REVERSE64(context->bitcount[1],context->bitcount[1]); -#endif - if (usedspace > 0) { - /* Begin padding with a 1 bit: */ - context->buffer[usedspace++] = 0x80; - - if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) { - /* Set-up for the last transform: */ - MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace); - } else { - if (usedspace < SHA512_BLOCK_LENGTH) { - MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace); - } - /* Do second-to-last transform: */ - apr__SHA512_Transform(context, (sha2_word64*)context->buffer); - - /* And set-up for the last transform: */ - MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2); - } - } else { - /* Prepare for final transform: */ - MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH); - - /* Begin padding with a 1 bit: */ - *context->buffer = 0x80; - } - /* Store the length of input data (in bits): */ - *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1]; - *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0]; - - /* Final transform: */ - apr__SHA512_Transform(context, (sha2_word64*)context->buffer); -} - -void apr__SHA512_Final(sha2_byte digest[], SHA512_CTX* context) { - sha2_word64 *d = (sha2_word64*)digest; - - /* Sanity check: */ - assert(context != (SHA512_CTX*)0); - - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != (sha2_byte*)0) { - apr__SHA512_Last(context); - - /* Save the hash data for output: */ -#if !APR_IS_BIGENDIAN - { - /* Convert TO host byte order */ - int j; - for (j = 0; j < 8; j++) { - REVERSE64(context->state[j],context->state[j]); - *d++ = context->state[j]; - } - } -#else /* APR_IS_BIGENDIAN */ - MEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LENGTH); -#endif /* APR_IS_BIGENDIAN */ - } - - /* Zero out state data */ - MEMSET_BZERO(context, sizeof(*context)); -} - -char *apr__SHA512_End(SHA512_CTX* context, char buffer[]) { - sha2_byte digest[SHA512_DIGEST_LENGTH], *d = digest; - int i; - - /* Sanity check: */ - assert(context != (SHA512_CTX*)0); - - if (buffer != (char*)0) { - apr__SHA512_Final(digest, context); - - for (i = 0; i < SHA512_DIGEST_LENGTH; i++) { - *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; - *buffer++ = sha2_hex_digits[*d & 0x0f]; - d++; - } - *buffer = (char)0; - } else { - MEMSET_BZERO(context, sizeof(*context)); - } - MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH); - return buffer; -} - -char* apr__SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) { - SHA512_CTX context; - - apr__SHA512_Init(&context); - apr__SHA512_Update(&context, data, len); - return apr__SHA512_End(&context, digest); -} - - -/*** SHA-384: *********************************************************/ -void apr__SHA384_Init(SHA384_CTX* context) { - if (context == (SHA384_CTX*)0) { - return; - } - MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH); - MEMSET_BZERO(context->buffer, SHA384_BLOCK_LENGTH); - context->bitcount[0] = context->bitcount[1] = 0; -} - -void apr__SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) { - apr__SHA512_Update((SHA512_CTX*)context, data, len); -} - -void apr__SHA384_Final(sha2_byte digest[], SHA384_CTX* context) { - sha2_word64 *d = (sha2_word64*)digest; - - /* Sanity check: */ - assert(context != (SHA384_CTX*)0); - - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != (sha2_byte*)0) { - apr__SHA512_Last((SHA512_CTX*)context); - - /* Save the hash data for output: */ -#if !APR_IS_BIGENDIAN - { - /* Convert TO host byte order */ - int j; - for (j = 0; j < 6; j++) { - REVERSE64(context->state[j],context->state[j]); - *d++ = context->state[j]; - } - } -#else /* APR_IS_BIGENDIAN */ - MEMCPY_BCOPY(d, context->state, SHA384_DIGEST_LENGTH); -#endif /* APR_IS_BIGENDIAN */ - } - - /* Zero out state data */ - MEMSET_BZERO(context, sizeof(*context)); -} - -char *apr__SHA384_End(SHA384_CTX* context, char buffer[]) { - sha2_byte digest[SHA384_DIGEST_LENGTH], *d = digest; - int i; - - /* Sanity check: */ - assert(context != (SHA384_CTX*)0); - - if (buffer != (char*)0) { - apr__SHA384_Final(digest, context); - - for (i = 0; i < SHA384_DIGEST_LENGTH; i++) { - *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; - *buffer++ = sha2_hex_digits[*d & 0x0f]; - d++; - } - *buffer = (char)0; - } else { - MEMSET_BZERO(context, sizeof(*context)); - } - MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH); - return buffer; -} - -char* apr__SHA384_Data(const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) { - SHA384_CTX context; - - apr__SHA384_Init(&context); - apr__SHA384_Update(&context, data, len); - return apr__SHA384_End(&context, digest); -} - diff --git a/random/unix/sha2.h b/random/unix/sha2.h index 9f0d93e1e015..0a030d7dbae0 100644 --- a/random/unix/sha2.h +++ b/random/unix/sha2.h @@ -29,16 +29,10 @@ extern "C" { #include "apr.h" -/*** SHA-256/384/512 Various Length Definitions ***********************/ +/*** SHA-256 Various Length Definitions ***********************/ #define SHA256_BLOCK_LENGTH 64 #define SHA256_DIGEST_LENGTH 32 #define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) -#define SHA384_BLOCK_LENGTH 128 -#define SHA384_DIGEST_LENGTH 48 -#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1) -#define SHA512_BLOCK_LENGTH 128 -#define SHA512_DIGEST_LENGTH 64 -#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) /*** SHA-256/384/512 Context Structures *******************************/ @@ -47,13 +41,6 @@ typedef struct _SHA256_CTX { apr_uint64_t bitcount; apr_byte_t buffer[SHA256_BLOCK_LENGTH]; } SHA256_CTX; -typedef struct _SHA512_CTX { - apr_uint64_t state[8]; - apr_uint64_t bitcount[2]; - apr_byte_t buffer[SHA512_BLOCK_LENGTH]; -} SHA512_CTX; - -typedef SHA512_CTX SHA384_CTX; /*** SHA-256/384/512 Function Prototypes ******************************/ @@ -63,21 +50,7 @@ void apr__SHA256_Final(apr_byte_t [SHA256_DIGEST_LENGTH], SHA256_CTX *); char* apr__SHA256_End(SHA256_CTX *, char [SHA256_DIGEST_STRING_LENGTH]); char* apr__SHA256_Data(const apr_byte_t *, size_t, char [SHA256_DIGEST_STRING_LENGTH]); - -void apr__SHA384_Init(SHA384_CTX *); -void apr__SHA384_Update(SHA384_CTX *, const apr_byte_t *, size_t); -void apr__SHA384_Final(apr_byte_t [SHA384_DIGEST_LENGTH], SHA384_CTX *); -char* apr__SHA384_End(SHA384_CTX *, char [SHA384_DIGEST_STRING_LENGTH]); -char* apr__SHA384_Data(const apr_byte_t *, size_t, - char [SHA384_DIGEST_STRING_LENGTH]); - -void apr__SHA512_Init(SHA512_CTX *); -void apr__SHA512_Update(SHA512_CTX *, const apr_byte_t *, size_t); -void apr__SHA512_Final(apr_byte_t [SHA512_DIGEST_LENGTH], SHA512_CTX *); -char* apr__SHA512_End(SHA512_CTX *, char [SHA512_DIGEST_STRING_LENGTH]); -char* apr__SHA512_Data(const apr_byte_t *, size_t, - char [SHA512_DIGEST_STRING_LENGTH]); - + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/random/unix/sha2_glue.c b/random/unix/sha2_glue.c index 4909a8fe1f83..cb6e897802f3 100644 --- a/random/unix/sha2_glue.c +++ b/random/unix/sha2_glue.c @@ -1,26 +1,42 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #include #include #include #include "sha2.h" static void sha256_init(apr_crypto_hash_t *h) - { +{ apr__SHA256_Init(h->data); - } +} static void sha256_add(apr_crypto_hash_t *h,const void *data, - apr_size_t bytes) - { + apr_size_t bytes) +{ apr__SHA256_Update(h->data,data,bytes); - } +} static void sha256_finish(apr_crypto_hash_t *h,unsigned char *result) - { +{ apr__SHA256_Final(result,h->data); - } +} APR_DECLARE(apr_crypto_hash_t *) apr_crypto_sha256_new(apr_pool_t *p) - { +{ apr_crypto_hash_t *h=apr_palloc(p,sizeof *h); h->data=apr_palloc(p,sizeof(SHA256_CTX)); @@ -30,4 +46,4 @@ APR_DECLARE(apr_crypto_hash_t *) apr_crypto_sha256_new(apr_pool_t *p) h->size=256/8; return h; - } +} diff --git a/tables/apr_tables.c b/tables/apr_tables.c index 51b23407cc0e..7479ef47c7ae 100644 --- a/tables/apr_tables.c +++ b/tables/apr_tables.c @@ -734,11 +734,14 @@ APR_DECLARE(void) apr_table_mergen(apr_table_t *t, const char *key, #if APR_POOL_DEBUG { - if (!apr_pool_is_ancestor(apr_pool_find(key), t->a.pool)) { + apr_pool_t *pool; + pool = apr_pool_find(key); + if ((pool != key) && (!apr_pool_is_ancestor(pool, t->a.pool))) { fprintf(stderr, "apr_table_mergen: key not in ancestor pool of t\n"); abort(); } - if (!apr_pool_is_ancestor(apr_pool_find(val), t->a.pool)) { + pool = apr_pool_find(val); + if ((pool != val) && (!apr_pool_is_ancestor(pool, t->a.pool))) { fprintf(stderr, "apr_table_mergen: val not in ancestor pool of t\n"); abort(); } diff --git a/threadproc/unix/thread.c b/threadproc/unix/thread.c index 5639ac706873..6d060be55e7e 100644 --- a/threadproc/unix/thread.c +++ b/threadproc/unix/thread.c @@ -96,7 +96,7 @@ APR_DECLARE(apr_status_t) apr_threadattr_detach_get(apr_threadattr_t *attr) #else pthread_attr_getdetachstate(&attr->attr, &state); #endif - if (state == 1) + if (state == DETACH_ARG(1)) return APR_DETACH; return APR_NOTDETACH; } -- cgit v1.2.3 From 512b84fc6c12bc496cef739e69bfaaf27e7ccc8e Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Wed, 1 Jan 2014 00:36:21 +0000 Subject: Vendor import of llvm RELEASE_34/final tag r197956 (effectively, 3.4 release): https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_34/final@197956 --- docs/ReleaseNotes.rst | 27 ++++++++++++++------------- lib/ExecutionEngine/RTDyldMemoryManager.cpp | 2 +- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index 0874f3a3c522..94663c4aa09b 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -47,9 +47,9 @@ Non-comprehensive list of changes in this release * The R600 backend is not marked experimental anymore and is built by default. -* APFloat::isNormal() was renamed to APFloat::isFiniteNonZero() and - APFloat::isIEEENormal() was renamed to APFloat::isNormal(). This ensures that - APFloat::isNormal() conforms to IEEE-754R-2008. +* ``APFloat::isNormal()`` was renamed to ``APFloat::isFiniteNonZero()`` and + ``APFloat::isIEEENormal()`` was renamed to ``APFloat::isNormal()``. This + ensures that ``APFloat::isNormal()`` conforms to IEEE-754R-2008. * The library call simplification pass has been removed. Its functionality has been integrated into the instruction combiner and function attribute @@ -59,20 +59,20 @@ Non-comprehensive list of changes in this release or later instead. For more information, see the `Getting Started using Visual Studio `_ page. -* The Loop Vectorizer that was previously enabled for -O3 is now enabled for - -Os and -O2. +* The Loop Vectorizer that was previously enabled for ``-O3`` is now enabled + for ``-Os`` and ``-O2``. * The new SLP Vectorizer is now enabled by default. -* llvm-ar now uses the new Object library and produces archives and +* ``llvm-ar`` now uses the new Object library and produces archives and symbol tables in the gnu format. -* FileCheck now allows specifing -check-prefix multiple times. This +* FileCheck now allows specifing ``-check-prefix`` multiple times. This helps reduce duplicate check lines when using multiple RUN lines. * The bitcast instruction no longer allows casting between pointers - with different address spaces. To achieve this, use the new - addrspacecast instruction. + with different address spaces. To achieve this, use the new addrspacecast + instruction. * Different sized pointers for different address spaces should now generally work. This is primarily useful for GPU targets. @@ -84,8 +84,8 @@ Mips Target ----------- Support for the MIPS SIMD Architecture (MSA) has been added. MSA is supported -through inline assembly, intrinsics with the prefix '__builtin_msa', and normal -code generation. +through inline assembly, intrinsics with the prefix '``__builtin_msa``', and +normal code generation. For more information on MSA (including documentation for the instruction set), see the `MIPS SIMD page at Imagination Technologies @@ -96,11 +96,12 @@ PowerPC Target Changes in the PowerPC backend include: -* fast-isel support (for faster -O0 code generation) +* fast-isel support (for faster ``-O0`` code generation) * many improvements to the builtin assembler * support for generating unaligned (Altivec) vector loads * support for generating the fcpsgn instruction -* generate frin for round() (not nearbyint() and rint(), which had been done only in fast-math mode) +* generate ``frin`` for ``round()`` (not ``nearbyint()`` and ``rint()``, which + had been done only in fast-math mode) * improved instruction scheduling for embedded cores (such as the A2) * improved prologue/epilogue generation (especially in 32-bit mode) * support for dynamic stack alignment (and dynamic stack allocations with large alignments) diff --git a/lib/ExecutionEngine/RTDyldMemoryManager.cpp b/lib/ExecutionEngine/RTDyldMemoryManager.cpp index 58a64609b9bc..26e1fddd7695 100644 --- a/lib/ExecutionEngine/RTDyldMemoryManager.cpp +++ b/lib/ExecutionEngine/RTDyldMemoryManager.cpp @@ -34,7 +34,7 @@ RTDyldMemoryManager::~RTDyldMemoryManager() {} // Determine whether we can register EH tables. #if (defined(__GNUC__) && !defined(__ARM_EABI__) && !defined(__ia64__) && \ - !defined(__USING_SJLJ_EXCEPTIONS__)) + !defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__)) #define HAVE_EHTABLE_SUPPORT 1 #else #define HAVE_EHTABLE_SUPPORT 0 -- cgit v1.2.3 From 33fa48314f06936f83859852feb3c0ce68b08c0c Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Wed, 1 Jan 2014 00:37:42 +0000 Subject: Vendor import of clang RELEASE_34/final tag r197956 (effectively, 3.4 release): https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_34/final@197956 --- docs/ReleaseNotes.rst | 29 ++++++++++++++--------------- lib/Basic/Version.cpp | 2 +- lib/Parse/ParseDeclCXX.cpp | 8 +++++++- test/Parser/recovery.cpp | 6 ++++++ 4 files changed, 28 insertions(+), 17 deletions(-) diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index ec0dbffed079..453110e650aa 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -18,23 +18,22 @@ documentation `_. All LLVM releases may be downloaded from the `LLVM releases web site `_. -For more information about Clang or LLVM, including information about -the latest release, please check out the main `Clang Web -Site `_ or the `LLVM Web -Site `_. +For more information about Clang or LLVM, including information about the +latest release, please check out the main `Clang Web Site +`_ or the `LLVM Web Site `_. -Note that if you are reading this file from a Subversion checkout or the -main Clang web page, this document applies to the *next* release, not -the current one. To see the release notes for a specific release, please -see the `releases page `_. +Note that if you are reading this file from a Subversion checkout or the main +Clang web page, this document applies to the *next* release, not the current +one. To see the release notes for a specific release, please see the `releases +page `_. What's New in Clang 3.4? ======================== -Some of the major new features and improvements to Clang are listed -here. Generic improvements to Clang as a whole or to its underlying -infrastructure are described first, followed by language-specific -sections with improvements to Clang's support for those languages. +Some of the major new features and improvements to Clang are listed here. +Generic improvements to Clang as a whole or to its underlying infrastructure +are described first, followed by language-specific sections with improvements +to Clang's support for those languages. Last release which will build as C++98 -------------------------------------- @@ -58,9 +57,9 @@ Major New Features Improvements to Clang's diagnostics ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Clang's diagnostics are constantly being improved to catch more issues, -explain them more clearly, and provide more accurate source information -about them. The improvements since the 3.3 release include: +Clang's diagnostics are constantly being improved to catch more issues, explain +them more clearly, and provide more accurate source information about them. The +improvements since the 3.3 release include: - -Wheader-guard warns on mismatches between the #ifndef and #define lines in a header guard. diff --git a/lib/Basic/Version.cpp b/lib/Basic/Version.cpp index 4a2b1fccb24e..77e4ad5bc4aa 100644 --- a/lib/Basic/Version.cpp +++ b/lib/Basic/Version.cpp @@ -36,7 +36,7 @@ std::string getClangRepositoryPath() { // If the SVN_REPOSITORY is empty, try to use the SVN keyword. This helps us // pick up a tag in an SVN export, for example. - StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/branches/release_34/lib/Basic/Version.cpp $"); + StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_34/final/lib/Basic/Version.cpp $"); if (URL.empty()) { URL = SVNRepository.slice(SVNRepository.find(':'), SVNRepository.find("/lib/Basic")); diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 16d06d7d152c..dd29f99ffc71 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -1427,7 +1427,13 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, << DeclSpec::getSpecifierName(TagType); } - SkipUntil(tok::comma, StopAtSemi); + // If we are parsing a definition and stop at a base-clause, continue on + // until the semicolon. Continuing from the comma will just trick us into + // thinking we are seeing a variable declaration. + if (TUK == Sema::TUK_Definition && Tok.is(tok::colon)) + SkipUntil(tok::semi, StopBeforeMatch); + else + SkipUntil(tok::comma, StopAtSemi); return; } diff --git a/test/Parser/recovery.cpp b/test/Parser/recovery.cpp index b5b09484ad9e..4bed2570fcba 100644 --- a/test/Parser/recovery.cpp +++ b/test/Parser/recovery.cpp @@ -119,3 +119,9 @@ void MissingSemiInFunction() { struct Inner4 {} // ok, no missing ';' here Inner5; } + +namespace PR17084 { +enum class EnumID {}; +template struct TempID; +template <> struct TempID : BadType, EnumID::Garbage; // expected-error{{use of undeclared identifier 'BadType'}} +} -- cgit v1.2.3 From 0ac59027e941d4ebc8e9a049f1319cbbeffe36f6 Mon Sep 17 00:00:00 2001 From: Glen Barber Date: Fri, 9 May 2014 04:14:37 +0000 Subject: Add 9.3 to mdoc.local. Sponsored by: The FreeBSD Foundation --- gnu/usr.bin/groff/tmac/mdoc.local | 1 + 1 file changed, 1 insertion(+) diff --git a/gnu/usr.bin/groff/tmac/mdoc.local b/gnu/usr.bin/groff/tmac/mdoc.local index bbab70478255..4d56befd9d73 100644 --- a/gnu/usr.bin/groff/tmac/mdoc.local +++ b/gnu/usr.bin/groff/tmac/mdoc.local @@ -58,6 +58,7 @@ .ds doc-operating-system-FreeBSD-8.4 8.4 .ds doc-operating-system-FreeBSD-9.1 9.1 .ds doc-operating-system-FreeBSD-9.2 9.2 +.ds doc-operating-system-FreeBSD-9.3 9.3 .ds doc-operating-system-FreeBSD-10.0 10.0 .ds doc-operating-system-FreeBSD-10.1 10.1 .ds doc-operating-system-FreeBSD-11.0 11.0 -- cgit v1.2.3 From 3ceb1e5386d5292e53452be07cfc67530fe0c2c1 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 9 May 2014 04:49:43 +0000 Subject: Spell always the more traditional way. --- share/mk/bsd.mkopt.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/mk/bsd.mkopt.mk b/share/mk/bsd.mkopt.mk index 3f22bc8aac9a..c3054cdb7771 100644 --- a/share/mk/bsd.mkopt.mk +++ b/share/mk/bsd.mkopt.mk @@ -42,7 +42,7 @@ MK_${var}:= yes # .for var in ${__DEFAULT_NO_OPTIONS} .if !defined(MK_${var}) -.if defined(WITH_${var}) && !defined(WITHOUT_${var}) # WITHOUT aways wins +.if defined(WITH_${var}) && !defined(WITHOUT_${var}) # WITHOUT always wins MK_${var}:= yes .else MK_${var}:= no -- cgit v1.2.3 From f9798cc7eb28b98b3beed8e5a2c9ef380d2e131e Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 9 May 2014 04:49:48 +0000 Subject: We have to include bsd.opts.mk (included in bsd.own.mk) after /etc/src.conf so that options set there will affect the options defined in bsd.opts.mk. Fix a few comments while I'm here. --- share/mk/src.opts.mk | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk index f82167b87bf6..72d13c058241 100644 --- a/share/mk/src.opts.mk +++ b/share/mk/src.opts.mk @@ -30,17 +30,15 @@ .if !target(____) ____: -# Compat -- needed still? -.include - -# Allow user to configure things, but in the future this will move -# elsehwere... - +# Allow user to configure things that only effect src tree builds. SRCCONF?= /etc/src.conf .if exists(${SRCCONF}) || ${SRCCONF} != "/etc/src.conf" .include "${SRCCONF}" .endif +# Must be included after src.conf +.include + # # Define MK_* variables (which are either "yes" or "no") for users # to set via WITH_*/WITHOUT_* in /etc/src.conf and override in the -- cgit v1.2.3 From 08d56ebf0ae9118acc4f460f34966edcba413ea7 Mon Sep 17 00:00:00 2001 From: Ganbold Tsagaankhuu Date: Fri, 9 May 2014 05:39:57 +0000 Subject: Add the codes for enabling CPU cores of Rockchip RK3188 SoC. Enable SMP for Radxa Rock board. Approved by: stas (mentor) --- sys/arm/conf/RADXA | 1 + sys/arm/rockchip/files.rk30xx | 1 + sys/arm/rockchip/rk30xx_machdep.c | 1 + sys/arm/rockchip/rk30xx_mp.c | 192 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 195 insertions(+) create mode 100644 sys/arm/rockchip/rk30xx_mp.c diff --git a/sys/arm/conf/RADXA b/sys/arm/conf/RADXA index 997efc378772..fc316de2831a 100644 --- a/sys/arm/conf/RADXA +++ b/sys/arm/conf/RADXA @@ -121,3 +121,4 @@ options FDT options FDT_DTB_STATIC makeoptions FDT_DTS_FILE=rk3188-radxa.dts +options SMP # Enable multiple cores diff --git a/sys/arm/rockchip/files.rk30xx b/sys/arm/rockchip/files.rk30xx index 98e3d413757c..e1b2a543e168 100644 --- a/sys/arm/rockchip/files.rk30xx +++ b/sys/arm/rockchip/files.rk30xx @@ -19,3 +19,4 @@ arm/rockchip/rk30xx_grf.c standard arm/rockchip/rk30xx_wdog.c standard arm/rockchip/rk30xx_gpio.c optional gpio dev/usb/controller/dwc_otg_fdt.c optional dwcotg +arm/rockchip/rk30xx_mp.c optional smp diff --git a/sys/arm/rockchip/rk30xx_machdep.c b/sys/arm/rockchip/rk30xx_machdep.c index 0cb9bca6871f..43160738b956 100644 --- a/sys/arm/rockchip/rk30xx_machdep.c +++ b/sys/arm/rockchip/rk30xx_machdep.c @@ -85,6 +85,7 @@ int initarm_devmap_init(void) { + arm_devmap_add_entry(0x10000000, 0x00200000); arm_devmap_add_entry(0x20000000, 0x00100000); return (0); diff --git a/sys/arm/rockchip/rk30xx_mp.c b/sys/arm/rockchip/rk30xx_mp.c new file mode 100644 index 000000000000..54457a357f97 --- /dev/null +++ b/sys/arm/rockchip/rk30xx_mp.c @@ -0,0 +1,192 @@ +/*- + * Copyright (c) 2014 Ganbold Tsagaankhuu + * 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 + +#define SCU_PHYSBASE 0x1013c000 +#define SCU_SIZE 0x100 + +#define SCU_CONTROL_REG 0x00 +#define SCU_CONTROL_ENABLE (1 << 0) +#define SCU_STANDBY_EN (1 << 5) +#define SCU_CONFIG_REG 0x04 +#define SCU_CONFIG_REG_NCPU_MASK 0x03 +#define SCU_CPUPOWER_REG 0x08 +#define SCU_INV_TAGS_REG 0x0c + +#define SCU_FILTER_START_REG 0x10 +#define SCU_FILTER_END_REG 0x14 +#define SCU_SECURE_ACCESS_REG 0x18 +#define SCU_NONSECURE_ACCESS_REG 0x1c + +#define IMEM_PHYSBASE 0x10080000 +#define IMEM_SIZE 0x20 + +#define PMU_PHYSBASE 0x20004000 +#define PMU_SIZE 0x100 +#define PMU_PWRDN_CON 0x08 +#define PMU_PWRDN_SCU (1 << 4) + +extern char *mpentry_addr; +static void rk30xx_boot2(void); + +static void +rk30xx_boot2(void) +{ + + __asm __volatile( + "ldr pc, 1f\n" + ".globl mpentry_addr\n" + "mpentry_addr:\n" + "1: .space 4\n"); +} + +void +platform_mp_init_secondary(void) +{ + + gic_init_secondary(); +} + +void +platform_mp_setmaxid(void) +{ + bus_space_handle_t scu; + int ncpu; + uint32_t val; + + if (mp_ncpus != 0) + return; + + if (bus_space_map(fdtbus_bs_tag, SCU_PHYSBASE, SCU_SIZE, 0, &scu) != 0) + panic("Could not map the SCU"); + + val = bus_space_read_4(fdtbus_bs_tag, scu, SCU_CONFIG_REG); + ncpu = (val & SCU_CONFIG_REG_NCPU_MASK) + 1; + bus_space_unmap(fdtbus_bs_tag, scu, SCU_SIZE); + + mp_ncpus = ncpu; + mp_maxid = ncpu - 1; +} + +int +platform_mp_probe(void) +{ + + if (mp_ncpus == 0) + platform_mp_setmaxid(); + + return (mp_ncpus > 1); +} + +void +platform_mp_start_ap(void) +{ + bus_space_handle_t scu; + bus_space_handle_t imem; + bus_space_handle_t pmu; + uint32_t val; + int i; + + if (bus_space_map(fdtbus_bs_tag, SCU_PHYSBASE, SCU_SIZE, 0, &scu) != 0) + panic("Could not map the SCU"); + if (bus_space_map(fdtbus_bs_tag, IMEM_PHYSBASE, + IMEM_SIZE, 0, &imem) != 0) + panic("Could not map the IMEM"); + if (bus_space_map(fdtbus_bs_tag, PMU_PHYSBASE, PMU_SIZE, 0, &pmu) != 0) + panic("Could not map the PMU"); + + /* + * Invalidate SCU cache tags. The 0x0000ffff constant invalidates all + * ways on all cores 0-3. Per the ARM docs, it's harmless to write to + * the bits for cores that are not present. + */ + bus_space_write_4(fdtbus_bs_tag, scu, SCU_INV_TAGS_REG, 0x0000ffff); + + /* Make sure all cores except the first are off */ + val = bus_space_read_4(fdtbus_bs_tag, pmu, PMU_PWRDN_CON); + for (i = 1; i < mp_ncpus; i++) + val |= 1 << i; + bus_space_write_4(fdtbus_bs_tag, pmu, PMU_PWRDN_CON, val); + + /* Enable SCU power domain */ + val = bus_space_read_4(fdtbus_bs_tag, pmu, PMU_PWRDN_CON); + val &= ~PMU_PWRDN_SCU; + bus_space_write_4(fdtbus_bs_tag, pmu, PMU_PWRDN_CON, val); + + /* Enable SCU */ + 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); + + /* + * Cores will execute the code which resides at the start of + * the on-chip bootram/sram after power-on. This sram region + * should be reserved and the trampoline code that directs + * the core to the real startup code in ram should be copied + * into this sram region. + * + * First set boot function for the sram code. + */ + mpentry_addr = (char *)pmap_kextract((vm_offset_t)mpentry); + + /* Copy trampoline to sram, that runs during startup of the core */ + bus_space_write_region_4(fdtbus_bs_tag, imem, 0, + (uint32_t *)&rk30xx_boot2, 8); + + cpu_idcache_wbinv_all(); + cpu_l2cache_wbinv_all(); + + /* Start all cores */ + val = bus_space_read_4(fdtbus_bs_tag, pmu, PMU_PWRDN_CON); + for (i = 1; i < mp_ncpus; i++) + val &= ~(1 << i); + bus_space_write_4(fdtbus_bs_tag, pmu, PMU_PWRDN_CON, val); + + armv7_sev(); + + bus_space_unmap(fdtbus_bs_tag, scu, SCU_SIZE); + bus_space_unmap(fdtbus_bs_tag, imem, IMEM_SIZE); + bus_space_unmap(fdtbus_bs_tag, pmu, PMU_SIZE); +} + +void +platform_ipi_send(cpuset_t cpus, u_int ipi) +{ + + pic_ipi_send(cpus, ipi); +} -- cgit v1.2.3 From 3fd18f39459ba924b2f4cd8dd1c1d6fa76282bda Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Fri, 9 May 2014 12:59:38 +0000 Subject: Adjust the register layout to allow for 64bit registers in the future for nf10bmac(4). Also, add support for and enable RX interrupts. MFC after: 2 weeks --- sys/boot/fdt/dts/mips/beri-netfpga.dts | 13 ++- sys/dev/netfpga10g/nf10bmac/if_nf10bmac.c | 153 ++++++++++++++++++++++---- sys/dev/netfpga10g/nf10bmac/if_nf10bmac_fdt.c | 60 +++++++--- sys/dev/netfpga10g/nf10bmac/if_nf10bmacreg.h | 9 +- 4 files changed, 189 insertions(+), 46 deletions(-) diff --git a/sys/boot/fdt/dts/mips/beri-netfpga.dts b/sys/boot/fdt/dts/mips/beri-netfpga.dts index c0fdf23a3e53..605392192d19 100644 --- a/sys/boot/fdt/dts/mips/beri-netfpga.dts +++ b/sys/boot/fdt/dts/mips/beri-netfpga.dts @@ -135,13 +135,14 @@ ethernet@7f005000 { compatible = "netfpag10g,nf10bmac"; - // TX, RX, LOOP - reg = <0x7f005010 0xc - 0x7f005020 0xc - 0x7f005030 0x4>; + // LOOP, TX, RX, INTR + reg = <0x7f005000 0x20 + 0x7f005020 0x30 + 0x7f005050 0x30 + 0x7f005100 0x10>; // RX - #interrupts = <1>; - #interrupt-parent = <&beripic>; + interrupts = <1>; + interrupt-parent = <&beripic>; }; }; diff --git a/sys/dev/netfpga10g/nf10bmac/if_nf10bmac.c b/sys/dev/netfpga10g/nf10bmac/if_nf10bmac.c index f6130b72937e..7076b7346e24 100644 --- a/sys/dev/netfpga10g/nf10bmac/if_nf10bmac.c +++ b/sys/dev/netfpga10g/nf10bmac/if_nf10bmac.c @@ -92,13 +92,15 @@ static poll_handler_t nf10bmac_poll; #define NF10BMAC_LOCK_ASSERT(_sc) \ mtx_assert(&(_sc)->nf10bmac_mtx, MA_OWNED) -#define NF10BMAC_TX_LEN 0x08 -#define NF10BMAC_TX_META 0x04 +#define NF10BMAC_CTRL0 0x00 #define NF10BMAC_TX_DATA 0x00 -#define NF10BMAC_RX_LEN 0x08 -#define NF10BMAC_RX_META 0x04 +#define NF10BMAC_TX_META 0x08 +#define NF10BMAC_TX_LEN 0x10 #define NF10BMAC_RX_DATA 0x00 -#define NF10BMAC_CTRL0 0x00 +#define NF10BMAC_RX_META 0x08 +#define NF10BMAC_RX_LEN 0x10 +#define NF10BMAC_INTR_CLEAR_DIS 0x00 +#define NF10BMAC_INTR_CTRL 0x08 #define NF10BMAC_TUSER_MAC0 (1 << 0) #define NF10BMAC_TUSER_CPU0 (1 << 1) @@ -109,11 +111,12 @@ static poll_handler_t nf10bmac_poll; #define NF10BMAC_TUSER_MAC3 (1 << 6) #define NF10BMAC_TUSER_CPU3 (1 << 7) +#define NF10BMAC_DATA_LEN_MASK 0x0000ffff #define NF10BMAC_DATA_DPORT_MASK 0xff000000 #define NF10BMAC_DATA_DPORT_SHIFT 24 #define NF10BMAC_DATA_SPORT_MASK 0x00ff0000 #define NF10BMAC_DATA_SPORT_SHIFT 16 -#define NF10BMAC_DATA_LAST 0x00000080 +#define NF10BMAC_DATA_LAST 0x00008000 #define NF10BMAC_DATA_STRB 0x0000000f @@ -151,7 +154,7 @@ nf10bmac_read_4_be(struct resource *res, uint32_t reg, } #define NF10BMAC_WRITE_CTRL_4(sc, reg, val) \ - nf10bmac_write_4((sc)->nf10bmac_mem_res, (reg), (val), \ + nf10bmac_write_4((sc)->nf10bmac_ctrl_res, (reg), (val), \ __func__, __LINE__) #define NF10BMAC_WRITE_4(sc, reg, val) \ nf10bmac_write_4((sc)->nf10bmac_tx_mem_res, (reg), (val), \ @@ -166,6 +169,21 @@ nf10bmac_read_4_be(struct resource *res, uint32_t reg, nf10bmac_read_4_be((sc)->nf10bmac_rx_mem_res, (reg), \ __func__, __LINE__) +#define NF10BMAC_WRITE_INTR_4(sc, reg, val, _f, _l) \ + nf10bmac_write_4((sc)->nf10bmac_intr_res, (reg), (val), \ + (_f), (_l)) + +#define NF10BMAC_RX_INTR_CLEAR_DIS(sc) \ + NF10BMAC_WRITE_INTR_4((sc), NF10BMAC_INTR_CLEAR_DIS, 1, \ + __func__, __LINE__) +#define NF10BMAC_RX_INTR_ENABLE(sc) \ + NF10BMAC_WRITE_INTR_4((sc), NF10BMAC_INTR_CTRL, 1, \ + __func__, __LINE__) +#define NF10BMAC_RX_INTR_DISABLE(sc) \ + NF10BMAC_WRITE_INTR_4((sc), NF10BMAC_INTR_CTRL, 0, \ + __func__, __LINE__) + + #ifdef ENABLE_WATCHDOG static void nf10bmac_tick(void *); #endif @@ -318,7 +336,7 @@ nf10bmac_rx_locked(struct nf10bmac_softc *sc) * skip to tlast). */ - len = NF10BMAC_READ_4(sc, NF10BMAC_RX_LEN); + len = NF10BMAC_READ_4(sc, NF10BMAC_RX_LEN) & NF10BMAC_DATA_LEN_MASK; if (len > (MCLBYTES - ETHER_ALIGN)) { nf10bmac_eat_packet_munch_munch(sc); return (0); @@ -435,6 +453,7 @@ nf10bmac_stop_locked(struct nf10bmac_softc *sc) ifp = sc->nf10bmac_ifp; ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + NF10BMAC_RX_INTR_CLEAR_DIS(sc); sc->nf10bmac_flags &= ~NF10BMAC_FLAGS_LINK; if_link_state_change(ifp, LINK_STATE_DOWN); @@ -498,6 +517,16 @@ nf10bmac_init_locked(struct nf10bmac_softc *sc) /* Instead drain the FIFO; or at least a possible first packet.. */ nf10bmac_eat_packet_munch_munch(sc); +#ifdef DEVICE_POLLING + /* Only enable interrupts if we are not polling. */ + if (ifp->if_capenable & IFCAP_POLLING) { + NF10BMAC_RX_INTR_CLEAR_DIS(sc); + } else +#endif + { + NF10BMAC_RX_INTR_ENABLE(sc); + } + ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; @@ -556,6 +585,49 @@ nf10bmac_tick(void *xsc) } #endif +static void +nf10bmac_intr(void *arg) +{ + struct nf10bmac_softc *sc; + struct ifnet *ifp; + int rx_npkts; + + sc = (struct nf10bmac_softc *)arg; + ifp = sc->nf10bmac_ifp; + + NF10BMAC_LOCK(sc); +#ifdef DEVICE_POLLING + if (ifp->if_capenable & IFCAP_POLLING) { + NF10BMAC_UNLOCK(sc); + return; + } +#endif + + /* NF10BMAC_RX_INTR_DISABLE(sc); */ + NF10BMAC_RX_INTR_CLEAR_DIS(sc); + + /* We only have an RX interrupt and no status information. */ + rx_npkts = 0; + while (rx_npkts < NF10BMAC_MAX_PKTS) { + int c; + + c = nf10bmac_rx_locked(sc); + rx_npkts += c; + if (c == 0) + break; + } + + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + /* Re-enable interrupts. */ + NF10BMAC_RX_INTR_ENABLE(sc); + + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + nf10bmac_start_locked(ifp); + } + NF10BMAC_UNLOCK(sc); +} + + #ifdef DEVICE_POLLING static int nf10bmac_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) @@ -649,10 +721,16 @@ nf10bmac_ioctl(struct ifnet *ifp, u_long command, caddr_t data) break; } + NF10BMAC_RX_INTR_CLEAR_DIS(sc); + /* * Do not allow disabling of polling if we do * not have interrupts. */ + } else if (sc->nf10bmac_rx_irq_res != NULL) { + error = ether_poll_deregister(ifp); + /* Enable interrupts. */ + NF10BMAC_RX_INTR_ENABLE(sc); } else { ifp->if_capenable ^= IFCAP_POLLING; error = EINVAL; @@ -673,7 +751,6 @@ nf10bmac_ioctl(struct ifnet *ifp, u_long command, caddr_t data) return (error); } - /* * Generic device handling routines. */ @@ -733,18 +810,40 @@ nf10bmac_attach(device_t dev) ifmedia_add(&sc->nf10bmac_media, IFM_ETHER | IFM_10G_T, 0, NULL); ifmedia_set(&sc->nf10bmac_media, IFM_ETHER | IFM_10G_T); - /* Interrupts would go here. */ + /* Initialise. */ + error = 0; + + /* Hook up interrupts. Well the one. */ + if (sc->nf10bmac_rx_irq_res != NULL) { + error = bus_setup_intr(dev, sc->nf10bmac_rx_irq_res, + INTR_TYPE_NET | INTR_MPSAFE, NULL, nf10bmac_intr, + sc, &sc->nf10bmac_rx_intrhand); + if (error != 0) { + device_printf(dev, "enabling RX IRQ failed\n"); + ether_ifdetach(ifp); + goto err; + } + } + if ((ifp->if_capenable & IFCAP_POLLING) != 0 || + sc->nf10bmac_rx_irq_res == NULL) { #ifdef DEVICE_POLLING - ifp->if_capenable |= IFCAP_POLLING; - device_printf(dev, "forcing to polling due to no interrupts\n"); - error = ether_poll_register(nf10bmac_poll, ifp); - if (error != 0) - goto err; + /* If not on and no IRQs force it on. */ + if (sc->nf10bmac_rx_irq_res == NULL) { + ifp->if_capenable |= IFCAP_POLLING; + device_printf(dev, + "forcing to polling due to no interrupts\n"); + } + error = ether_poll_register(nf10bmac_poll, ifp); + if (error != 0) + goto err; #else - device_printf(dev, "no DEVICE_POLLING in kernel and no IRQs\n"); - error = ENXIO; + device_printf(dev, "no DEVICE_POLLING in kernel and no IRQs\n"); + error = ENXIO; #endif + } else { + NF10BMAC_RX_INTR_ENABLE(sc); + } err: if (error != 0) @@ -780,6 +879,10 @@ nf10bmac_detach(device_t dev) ether_ifdetach(ifp); } + if (sc->nf10bmac_rx_intrhand) + bus_teardown_intr(dev, sc->nf10bmac_rx_irq_res, + sc->nf10bmac_rx_intrhand); + if (ifp != NULL) if_free(ifp); ifmedia_removeall(&sc->nf10bmac_media); @@ -797,10 +900,15 @@ nf10bmac_detach_resources(device_t dev) sc = device_get_softc(dev); - if (sc->nf10bmac_mem_res != NULL) { + if (sc->nf10bmac_rx_irq_res != NULL) { + bus_release_resource(dev, SYS_RES_IRQ, sc->nf10bmac_rx_irq_rid, + sc->nf10bmac_rx_irq_res); + sc->nf10bmac_rx_irq_res = NULL; + } + if (sc->nf10bmac_intr_res != NULL) { bus_release_resource(dev, SYS_RES_MEMORY, - sc->nf10bmac_mem_rid, sc->nf10bmac_mem_res); - sc->nf10bmac_mem_res = NULL; + sc->nf10bmac_intr_rid, sc->nf10bmac_intr_res); + sc->nf10bmac_intr_res = NULL; } if (sc->nf10bmac_rx_mem_res != NULL) { bus_release_resource(dev, SYS_RES_MEMORY, @@ -812,6 +920,11 @@ nf10bmac_detach_resources(device_t dev) sc->nf10bmac_tx_mem_rid, sc->nf10bmac_tx_mem_res); sc->nf10bmac_tx_mem_res = NULL; } + if (sc->nf10bmac_ctrl_res != NULL) { + bus_release_resource(dev, SYS_RES_MEMORY, + sc->nf10bmac_ctrl_rid, sc->nf10bmac_ctrl_res); + sc->nf10bmac_ctrl_res = NULL; + } } int diff --git a/sys/dev/netfpga10g/nf10bmac/if_nf10bmac_fdt.c b/sys/dev/netfpga10g/nf10bmac/if_nf10bmac_fdt.c index 3eff8473d96e..4245da4170c2 100644 --- a/sys/dev/netfpga10g/nf10bmac/if_nf10bmac_fdt.c +++ b/sys/dev/netfpga10g/nf10bmac/if_nf10bmac_fdt.c @@ -85,16 +85,34 @@ nf10bmac_attach_fdt(device_t dev) /* * FDT lists our resources. For convenience we use three different * mappings. We need to attach them in the oder specified in .dts: - * TX (size 0xc), RX (size 0xc), LOOP (size 0x4). + * LOOP (size 0x1f), TX (0x2f), RX (0x2f), INTR (0xf). */ + /* + * LOOP memory region (this could be a general control region). + * 0x00: 32bit register to enable a Y-"lopback". + */ + sc->nf10bmac_ctrl_rid = 0; + sc->nf10bmac_ctrl_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, + &sc->nf10bmac_ctrl_rid, RF_ACTIVE); + if (sc->nf10bmac_ctrl_res == NULL) { + device_printf(dev, "failed to map memory for CTRL region\n"); + error = ENXIO; + goto err; + } + if (bootverbose) + device_printf(sc->nf10bmac_dev, "CTRL region at mem %p-%p\n", + (void *)rman_get_start(sc->nf10bmac_ctrl_res), + (void *)(rman_get_start(sc->nf10bmac_ctrl_res) + + rman_get_size(sc->nf10bmac_ctrl_res))); + /* * TX and TX metadata FIFO memory region. * 0x00: 32bit FIFO data, - * 0x04: 32bit FIFO metadata, - * 0x08: 32bit packet length. + * 0x08: 32bit FIFO metadata, + * 0x10: 32bit packet length. */ - sc->nf10bmac_tx_mem_rid = 0; + sc->nf10bmac_tx_mem_rid = 1; sc->nf10bmac_tx_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->nf10bmac_tx_mem_rid, RF_ACTIVE); if (sc->nf10bmac_tx_mem_res == NULL) { @@ -111,10 +129,10 @@ nf10bmac_attach_fdt(device_t dev) /* * RX and RXC metadata FIFO memory region. * 0x00: 32bit FIFO data, - * 0x04: 32bit FIFO metadata, - * 0x08: 32bit packet length. + * 0x08: 32bit FIFO metadata, + * 0x10: 32bit packet length. */ - sc->nf10bmac_rx_mem_rid = 1; + sc->nf10bmac_rx_mem_rid = 2; sc->nf10bmac_rx_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->nf10bmac_rx_mem_rid, RF_ACTIVE); if (sc->nf10bmac_rx_mem_res == NULL) { @@ -129,22 +147,28 @@ nf10bmac_attach_fdt(device_t dev) rman_get_size(sc->nf10bmac_rx_mem_res))); /* - * LOOP memory region (this could be a general control region). - * 0x00: 32bit register to enable a Y-"lopback". + * Interrupt handling registers. + * 0x00: 32bit register to clear (and disable) the RX interrupt. + * 0x08: 32bit register to enable or disable the RX interrupt. */ - sc->nf10bmac_mem_rid = 2; - sc->nf10bmac_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, - &sc->nf10bmac_mem_rid, RF_ACTIVE); - if (sc->nf10bmac_mem_res == NULL) { - device_printf(dev, "failed to map memory for CTRL region\n"); + sc->nf10bmac_intr_rid = 3; + sc->nf10bmac_intr_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, + &sc->nf10bmac_intr_rid, RF_ACTIVE); + if (sc->nf10bmac_intr_res == NULL) { + device_printf(dev, "failed to map memory for INTR region\n"); error = ENXIO; goto err; } if (bootverbose) - device_printf(sc->nf10bmac_dev, "CTRL region at mem %p-%p\n", - (void *)rman_get_start(sc->nf10bmac_mem_res), - (void *)(rman_get_start(sc->nf10bmac_mem_res) + - rman_get_size(sc->nf10bmac_mem_res))); + device_printf(sc->nf10bmac_dev, "INTR region at mem %p-%p\n", + (void *)rman_get_start(sc->nf10bmac_intr_res), + (void *)(rman_get_start(sc->nf10bmac_intr_res) + + rman_get_size(sc->nf10bmac_intr_res))); + + /* (Optional) RX and TX IRQ. */ + sc->nf10bmac_rx_irq_rid = 0; + sc->nf10bmac_rx_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, + &sc->nf10bmac_rx_irq_rid, RF_ACTIVE | RF_SHAREABLE); error = nf10bmac_attach(dev); if (error) diff --git a/sys/dev/netfpga10g/nf10bmac/if_nf10bmacreg.h b/sys/dev/netfpga10g/nf10bmac/if_nf10bmacreg.h index 725cf3b5a263..fa581161415e 100644 --- a/sys/dev/netfpga10g/nf10bmac/if_nf10bmacreg.h +++ b/sys/dev/netfpga10g/nf10bmac/if_nf10bmacreg.h @@ -35,15 +35,20 @@ struct nf10bmac_softc { struct ifnet *nf10bmac_ifp; + struct resource *nf10bmac_ctrl_res; struct resource *nf10bmac_tx_mem_res; struct resource *nf10bmac_rx_mem_res; - struct resource *nf10bmac_mem_res; + struct resource *nf10bmac_intr_res; + struct resource *nf10bmac_rx_irq_res; + void *nf10bmac_rx_intrhand; uint8_t *nf10bmac_tx_buf; device_t nf10bmac_dev; int nf10bmac_unit; + int nf10bmac_ctrl_rid; int nf10bmac_tx_mem_rid; int nf10bmac_rx_mem_rid; - int nf10bmac_mem_rid; + int nf10bmac_intr_rid; + int nf10bmac_rx_irq_rid; int nf10bmac_if_flags; uint32_t nf10bmac_flags; #define NF10BMAC_FLAGS_LINK 0x00000001 -- cgit v1.2.3 From 6a7a25af3f0e8f7031492992957dab1a233de652 Mon Sep 17 00:00:00 2001 From: Luiz Otavio O Souza Date: Fri, 9 May 2014 13:07:39 +0000 Subject: Fix a bug on ip17x switch initialization which will fail as soon as you disable the debug and diagnosis options from current. We must wait 2ms after the switch reset and not 2us. Tested on RB433UAH. --- sys/dev/etherswitch/ip17x/ip175c.c | 2 +- sys/dev/etherswitch/ip17x/ip175d.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/etherswitch/ip17x/ip175c.c b/sys/dev/etherswitch/ip17x/ip175c.c index ced23c0c548d..f78705203359 100644 --- a/sys/dev/etherswitch/ip17x/ip175c.c +++ b/sys/dev/etherswitch/ip17x/ip175c.c @@ -63,7 +63,7 @@ ip175c_reset(struct ip17x_softc *sc) if (ip17x_writephy(sc->sc_dev, IP175C_RESET_PHY, IP175C_RESET_REG, 0x175c)) return (-1); - DELAY(2); + DELAY(2000); /* Force IP175C mode. */ data = ip17x_readphy(sc->sc_dev, IP175C_MODE_PHY, IP175C_MODE_REG); diff --git a/sys/dev/etherswitch/ip17x/ip175d.c b/sys/dev/etherswitch/ip17x/ip175d.c index 1e6eee201d1c..4962ac23b785 100644 --- a/sys/dev/etherswitch/ip17x/ip175d.c +++ b/sys/dev/etherswitch/ip17x/ip175d.c @@ -62,7 +62,7 @@ ip175d_reset(struct ip17x_softc *sc) /* Reset all the switch settings. */ ip17x_writephy(sc->sc_dev, IP175D_RESET_PHY, IP175D_RESET_REG, 0x175d); - DELAY(2); + DELAY(2000); /* Disable the special tagging mode. */ ip17x_updatephy(sc->sc_dev, 21, 22, 0x3, 0x0); -- cgit v1.2.3 From 8237ba8ab394657acac6f4af6f2d61867649c334 Mon Sep 17 00:00:00 2001 From: Luiz Otavio O Souza Date: Fri, 9 May 2014 13:21:34 +0000 Subject: Fix the build with debug enabled and remove a variable used only at switch initialization, it is nonsense keep it around without futher use. --- sys/dev/etherswitch/ip17x/ip17x.c | 14 ++++---------- sys/dev/etherswitch/ip17x/ip17x_var.h | 1 - 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/sys/dev/etherswitch/ip17x/ip17x.c b/sys/dev/etherswitch/ip17x/ip17x.c index cfe8323c5dcb..2f51217c7363 100644 --- a/sys/dev/etherswitch/ip17x/ip17x.c +++ b/sys/dev/etherswitch/ip17x/ip17x.c @@ -141,9 +141,7 @@ ip17x_attach_phys(struct ip17x_softc *sc) sc->ifp[port]->if_softc = sc; sc->ifp[port]->if_flags |= IFF_UP | IFF_BROADCAST | IFF_DRV_RUNNING | IFF_SIMPLEX; - sc->ifname[port] = malloc(strlen(name)+1, M_IP17X, M_WAITOK); - bcopy(name, sc->ifname[port], strlen(name)+1); - if_initname(sc->ifp[port], sc->ifname[port], port); + if_initname(sc->ifp[port], name, port); sc->miibus[port] = malloc(sizeof(device_t), M_IP17X, M_WAITOK | M_ZERO); err = mii_attach(sc->sc_dev, sc->miibus[port], sc->ifp[port], @@ -204,8 +202,6 @@ ip17x_attach(device_t dev) M_WAITOK | M_ZERO); sc->pvid = malloc(sizeof(uint32_t) * sc->numports, M_IP17X, M_WAITOK | M_ZERO); - sc->ifname = malloc(sizeof(char *) * sc->numports, M_IP17X, - M_WAITOK | M_ZERO); sc->miibus = malloc(sizeof(device_t *) * sc->numports, M_IP17X, M_WAITOK | M_ZERO); sc->portphy = malloc(sizeof(int) * sc->numports, M_IP17X, @@ -257,13 +253,11 @@ ip17x_detach(device_t dev) device_delete_child(dev, (*sc->miibus[port])); if (sc->ifp[port] != NULL) if_free(sc->ifp[port]); - free(sc->ifname[port], M_IP17X); free(sc->miibus[port], M_IP17X); } free(sc->portphy, M_IP17X); free(sc->miibus, M_IP17X); - free(sc->ifname, M_IP17X); free(sc->pvid, M_IP17X); free(sc->ifp, M_IP17X); @@ -490,12 +484,13 @@ ip17x_ifmedia_upd(struct ifnet *ifp) struct ip17x_softc *sc; struct mii_data *mii; - DPRINTF(sc->sc_dev, "%s\n", __func__); sc = ifp->if_softc; + DPRINTF(sc->sc_dev, "%s\n", __func__); mii = ip17x_miiforport(sc, ifp->if_dunit); if (mii == NULL) return (ENXIO); mii_mediachg(mii); + return (0); } @@ -505,9 +500,8 @@ ip17x_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) struct ip17x_softc *sc; struct mii_data *mii; - DPRINTF(sc->sc_dev, "%s\n", __func__); - sc = ifp->if_softc; + DPRINTF(sc->sc_dev, "%s\n", __func__); mii = ip17x_miiforport(sc, ifp->if_dunit); if (mii == NULL) return; diff --git a/sys/dev/etherswitch/ip17x/ip17x_var.h b/sys/dev/etherswitch/ip17x/ip17x_var.h index 2259a655eb01..a1f418754d96 100644 --- a/sys/dev/etherswitch/ip17x/ip17x_var.h +++ b/sys/dev/etherswitch/ip17x/ip17x_var.h @@ -52,7 +52,6 @@ struct ip17x_softc { int phyport[MII_NPHY]; int numports; /* number of ports */ int *portphy; - char **ifname; device_t **miibus; etherswitch_info_t info; ip17x_switch_type sc_switchtype; -- cgit v1.2.3 From bc7f6652ddb8df1eda9fc2795c60660ee322a3c5 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Fri, 9 May 2014 13:27:30 +0000 Subject: sh: Add more necessary INTOFF/INTON. --- bin/sh/main.c | 2 ++ bin/sh/options.c | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/bin/sh/main.c b/bin/sh/main.c index e4974ea7f455..08f234e5ee5f 100644 --- a/bin/sh/main.c +++ b/bin/sh/main.c @@ -140,11 +140,13 @@ main(int argc, char *argv[]) #endif rootpid = getpid(); rootshell = 1; + INTOFF; initvar(); setstackmark(&smark); setstackmark(&smark2); procargs(argc, argv); pwd_init(iflag); + INTON; if (iflag) chkmail(1); if (argv[0] && argv[0][0] == '-') { diff --git a/bin/sh/options.c b/bin/sh/options.c index ad0291e73a39..2fb801013879 100644 --- a/bin/sh/options.c +++ b/bin/sh/options.c @@ -475,7 +475,9 @@ atend: } else { out1fmt("Illegal option -%c\n", c); + INTOFF; (void) unsetvar("OPTARG"); + INTON; } c = '?'; goto bad; @@ -494,7 +496,9 @@ atend: } else { out1fmt("No arg for -%c option\n", c); + INTOFF; (void) unsetvar("OPTARG"); + INTON; c = '?'; } goto bad; -- cgit v1.2.3 From 8c4e5fc061d49ec2ac3233b1c67d99bf792af28e Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Fri, 9 May 2014 13:32:36 +0000 Subject: sh: Send getopts error messages to stderr, not stdout. Adjust a testcase for this change. --- bin/sh/options.c | 4 ++-- bin/sh/tests/builtins/getopts1.0 | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/sh/options.c b/bin/sh/options.c index 2fb801013879..caaa88461056 100644 --- a/bin/sh/options.c +++ b/bin/sh/options.c @@ -474,7 +474,7 @@ atend: err |= setvarsafe("OPTARG", s, 0); } else { - out1fmt("Illegal option -%c\n", c); + out2fmt_flush("Illegal option -%c\n", c); INTOFF; (void) unsetvar("OPTARG"); INTON; @@ -495,7 +495,7 @@ atend: c = ':'; } else { - out1fmt("No arg for -%c option\n", c); + out2fmt_flush("No arg for -%c option\n", c); INTOFF; (void) unsetvar("OPTARG"); INTON; diff --git a/bin/sh/tests/builtins/getopts1.0 b/bin/sh/tests/builtins/getopts1.0 index af31d5599118..64763bc462c1 100644 --- a/bin/sh/tests/builtins/getopts1.0 +++ b/bin/sh/tests/builtins/getopts1.0 @@ -15,7 +15,7 @@ printf -- '-2-\n' set -- -ab getopts "ab:" OPTION echo ${OPTION} -getopts "ab:" OPTION +getopts "ab:" OPTION 3>&2 2>&1 >&3 3>&- echo ${OPTION} # The 'shift' is aimed at causing an error. -- cgit v1.2.3 From 3010d2256a4b8db91937f187faf288657a5119ae Mon Sep 17 00:00:00 2001 From: Luiz Otavio O Souza Date: Fri, 9 May 2014 13:44:42 +0000 Subject: When a GPIO pin is set to be turned on by kernel hints (hint.gpio.X.pinon) make sure the GPIO pin is configured as an output as this is not always the case. --- sys/mips/atheros/ar71xx_gpio.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/mips/atheros/ar71xx_gpio.c b/sys/mips/atheros/ar71xx_gpio.c index c6933bc1b067..1a2d1e997ed2 100644 --- a/sys/mips/atheros/ar71xx_gpio.c +++ b/sys/mips/atheros/ar71xx_gpio.c @@ -437,10 +437,13 @@ ar71xx_gpio_attach(device_t dev) ar71xx_gpio_pin_configure(sc, &sc->gpio_pins[i], DEFAULT_CAPS); i++; } + /* Turn on the hinted pins. */ for (i = 0; i < sc->gpio_npins; i++) { j = sc->gpio_pins[i].gp_pin; - if ((pinon & (1 << j)) != 0) + if ((pinon & (1 << j)) != 0) { + ar71xx_gpio_pin_setflags(dev, j, GPIO_PIN_OUTPUT); ar71xx_gpio_pin_set(dev, j, 1); + } } device_add_child(dev, "gpioc", device_get_unit(dev)); device_add_child(dev, "gpiobus", device_get_unit(dev)); -- cgit v1.2.3 From b7c74331507e1d855c75fea328a52309e9aa1c20 Mon Sep 17 00:00:00 2001 From: Luiz Otavio O Souza Date: Fri, 9 May 2014 14:02:18 +0000 Subject: Add support for reading RouterBoard's memory which is passed by the loader (RouterBOOT). Tested on RouterBoards, various and on RSPRO, TP-Link MR3x20 (for regressions). --- sys/conf/options.mips | 1 + sys/mips/atheros/ar71xx_machdep.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/sys/conf/options.mips b/sys/conf/options.mips index 911e74b2c635..eec1ca41b7bb 100644 --- a/sys/conf/options.mips +++ b/sys/conf/options.mips @@ -104,6 +104,7 @@ ARGE_MDIO opt_arge.h AR71XX_REALMEM opt_ar71xx.h AR71XX_ENV_UBOOT opt_ar71xx.h AR71XX_ENV_REDBOOT opt_ar71xx.h +AR71XX_ENV_ROUTERBOOT opt_ar71xx.h AR71XX_ATH_EEPROM opt_ar71xx.h # diff --git a/sys/mips/atheros/ar71xx_machdep.c b/sys/mips/atheros/ar71xx_machdep.c index f0b3026d0d91..22d089d2fff8 100644 --- a/sys/mips/atheros/ar71xx_machdep.c +++ b/sys/mips/atheros/ar71xx_machdep.c @@ -140,6 +140,34 @@ ar71xx_redboot_get_macaddr(void) } } +#ifdef AR71XX_ENV_ROUTERBOOT +/* + * RouterBoot gives us the board memory in a command line argument. + */ +static int +ar71xx_routerboot_get_mem(int argc, char **argv) +{ + int i, board_mem; + + /* + * Protect ourselves from garbage in registers. + */ + if (!MIPS_IS_VALID_PTR(argv)) + return (0); + + for (i = 0; i < argc; i++) { + if (argv[i] == NULL) + continue; + if (strncmp(argv[i], "mem=", 4) == 0) { + if (sscanf(argv[i] + 4, "%dM", &board_mem) == 1) + return (btoc(board_mem * 1024 * 1024)); + } + } + + return (0); +} +#endif + void platform_start(__register_t a0 __unused, __register_t a1 __unused, __register_t a2 __unused, __register_t a3 __unused) @@ -183,6 +211,14 @@ platform_start(__register_t a0 __unused, __register_t a1 __unused, } } +#ifdef AR71XX_ENV_ROUTERBOOT + /* + * RouterBoot informs the board memory as a command line argument. + */ + if (realmem == 0) + realmem = ar71xx_routerboot_get_mem(argc, argv); +#endif + /* * Just wild guess. RedBoot let us down and didn't reported * memory size -- cgit v1.2.3 From d58c15339b2cbd5b282b93061cb9afc78fe83204 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Fri, 9 May 2014 14:15:48 +0000 Subject: Fix a logic bug which prevented the sending of UDP packet with 0 checksum. This bug was introduced in r264212 and should be X-MFCed with that revision, if UDP-Lite support if MFCed. --- sys/netinet/udp_usrreq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index fb248c6efaa1..8cae36a6ddc6 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -1375,7 +1375,8 @@ udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr, faddr.s_addr = INADDR_BROADCAST; if ((ui->ui_sum = in_cksum(m, sizeof(struct ip) + cscov)) == 0) ui->ui_sum = 0xffff; - } else if (V_udp_cksum || !cscov_partial) { + } else if (V_udp_cksum || pr == IPPROTO_UDPLITE) { + /* for UDP-Lite full checksum coverage is requested */ if (inp->inp_flags & INP_ONESBCAST) faddr.s_addr = INADDR_BROADCAST; ui->ui_sum = in_pseudo(ui->ui_src.s_addr, faddr.s_addr, -- cgit v1.2.3 From db4300da10a965c7478aea49f3283be7c284cb7d Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Fri, 9 May 2014 14:23:06 +0000 Subject: Multiple DWC OTG host mode related fixes and improvements: - Rework how we allocate and free USB host channels, so that we only allocate a channel if there is a real packet going out on the USB cable. - Use BULK type for control data and status, due to instabilities in the HW it appears. - Split FIFO TX levels into one for the periodic FIFO and one for the non-periodic FIFO. - Use correct HFNUM mask when scheduling host transactions. The HFNUM register does not count the full 16-bit range. - Correct START/COMPLETION slot for TT transactions. For INTERRUPT and ISOCHRONOUS type transactions the hardware always respects the ODDFRM bit, which means we need to allocate multiple host channels when processing such endpoints, to not miss any so-called complete split opportunities. - When doing ISOCHRONOUS OUT transfers through a TT send all data payload in a single ALL-burst. This deacreases the likelyhood for isochronous data underruns. - Fixed unbalanced unlock in case of "dwc_otg_init_fifo()" failure. - Increase interrupt priority. MFC after: 2 weeks --- sys/dev/usb/controller/dwc_otg.c | 1291 +++++++++++++++------------------- sys/dev/usb/controller/dwc_otg.h | 27 +- sys/dev/usb/controller/dwc_otg_fdt.c | 2 +- sys/dev/usb/controller/dwc_otgreg.h | 5 +- 4 files changed, 597 insertions(+), 728 deletions(-) diff --git a/sys/dev/usb/controller/dwc_otg.c b/sys/dev/usb/controller/dwc_otg.c index d8bf7ea39be7..3f4d3a00047c 100644 --- a/sys/dev/usb/controller/dwc_otg.c +++ b/sys/dev/usb/controller/dwc_otg.c @@ -92,6 +92,9 @@ #define DWC_OTG_PC2SC(pc) \ DWC_OTG_BUS2SC(USB_DMATAG_TO_XROOT((pc)->tag_parent)->bus) +#define DWC_OTG_PC2UDEV(pc) \ + (USB_DMATAG_TO_XROOT((pc)->tag_parent)->udev) + #define DWC_OTG_MSK_GINT_ENABLED \ (GINTMSK_ENUMDONEMSK | \ GINTMSK_USBRSTMSK | \ @@ -136,8 +139,8 @@ static dwc_otg_cmd_t dwc_otg_host_data_rx; static void dwc_otg_device_done(struct usb_xfer *, usb_error_t); static void dwc_otg_do_poll(struct usb_bus *); static void dwc_otg_standard_done(struct usb_xfer *); -static void dwc_otg_root_intr(struct dwc_otg_softc *sc); -static void dwc_otg_interrupt_poll(struct dwc_otg_softc *sc); +static void dwc_otg_root_intr(struct dwc_otg_softc *); +static void dwc_otg_interrupt_poll(struct dwc_otg_softc *); /* * Here is a configuration that the chip supports. @@ -177,26 +180,33 @@ dwc_otg_init_fifo(struct dwc_otg_softc *sc, uint8_t mode) fifo_size = sc->sc_fifo_size; - fifo_regs = 4 * (sc->sc_dev_ep_max + sc->sc_dev_in_ep_max); + /* + * NOTE: Reserved fixed size area at end of RAM, which must + * not be allocated to the FIFOs: + */ + fifo_regs = 4 * 16; - if (fifo_size >= fifo_regs) - fifo_size -= fifo_regs; - else - fifo_size = 0; + if (fifo_size < fifo_regs) { + DPRINTF("Too little FIFO\n"); + return (EINVAL); + } + + /* subtract FIFO regs from total once */ + fifo_size -= fifo_regs; /* split equally for IN and OUT */ fifo_size /= 2; - DWC_OTG_WRITE_4(sc, DOTG_GRXFSIZ, fifo_size / 4); - - /* align to 4-bytes */ + /* align to 4 bytes boundary */ fifo_size &= ~3; + /* set global receive FIFO size */ + DWC_OTG_WRITE_4(sc, DOTG_GRXFSIZ, fifo_size / 4); + tx_start = fifo_size; - if (fifo_size < 0x40) { + if (fifo_size < 64) { DPRINTFN(-1, "Not enough data space for EP0 FIFO.\n"); - USB_BUS_UNLOCK(&sc->sc_bus); return (EINVAL); } @@ -205,14 +215,12 @@ dwc_otg_init_fifo(struct dwc_otg_softc *sc, uint8_t mode) /* reset active endpoints */ sc->sc_active_rx_ep = 0; - /* reset TX size */ - sc->sc_tx_cur_size = 0; - - /* reset TT info */ - memset(sc->sc_tt_info, 0, sizeof(sc->sc_tt_info)); - + /* split equally for periodic and non-periodic */ fifo_size /= 2; + /* align to 4 bytes boundary */ + fifo_size &= ~3; + DWC_OTG_WRITE_4(sc, DOTG_GNPTXFSIZ, ((fifo_size / 4) << 16) | (tx_start / 4)); @@ -228,7 +236,11 @@ dwc_otg_init_fifo(struct dwc_otg_softc *sc, uint8_t mode) ((fifo_size / 4) << 16) | (tx_start / 4)); - /* store maximum TX FIFO size */ + /* reset FIFO TX levels */ + sc->sc_tx_cur_p_level = 0; + sc->sc_tx_cur_np_level = 0; + + /* store maximum periodic and non-periodic FIFO TX size */ sc->sc_tx_max_size = fifo_size; /* disable all host channel interrupts */ @@ -311,11 +323,12 @@ dwc_otg_init_fifo(struct dwc_otg_softc *sc, uint8_t mode) /* reset active endpoints */ sc->sc_active_rx_ep = 0; - /* reset TX size */ - sc->sc_tx_cur_size = 0; + /* reset periodic and non-periodic FIFO TX size */ + sc->sc_tx_max_size = fifo_size; - /* reset TT info */ - memset(sc->sc_tt_info, 0, sizeof(sc->sc_tt_info)); + /* reset FIFO TX levels */ + sc->sc_tx_cur_p_level = 0; + sc->sc_tx_cur_np_level = 0; } return (0); } @@ -555,125 +568,70 @@ dwc_otg_clear_hcint(struct dwc_otg_softc *sc, uint8_t x) sc->sc_chan_state[x].hcint = 0; } -/* - * This function waits until a DWC OTG host channel is ready to be - * used again: - */ static uint8_t -dwc_otg_host_channel_wait(struct dwc_otg_td *td) +dwc_otg_host_channel_alloc(struct dwc_otg_td *td, uint8_t which) { struct dwc_otg_softc *sc; + uint32_t tx_p_size; + uint32_t tx_np_size; uint8_t x; - x = td->channel; - - DPRINTF("CH=%d\n", x); - - /* get pointer to softc */ - sc = DWC_OTG_PC2SC(td->pc); - - if (sc->sc_chan_state[x].wait_sof == 0) { - dwc_otg_clear_hcint(sc, x); - return (1); /* done */ - } - - if (x == 0) - return (0); /* wait */ - - /* find new disabled channel */ - for (x = 1; x != sc->sc_host_ch_max; x++) { - - if (sc->sc_chan_state[x].allocated) - continue; - if (sc->sc_chan_state[x].wait_sof != 0) - continue; - - sc->sc_chan_state[td->channel].allocated = 0; - sc->sc_chan_state[x].allocated = 1; - - sc->sc_chan_state[x].tx_size = - sc->sc_chan_state[td->channel].tx_size; - - if (sc->sc_chan_state[td->channel].suspended) { - sc->sc_chan_state[td->channel].suspended = 0; - sc->sc_chan_state[x].suspended = 1; - } - - /* clear interrupts */ - dwc_otg_clear_hcint(sc, x); - - DPRINTF("CH=%d HCCHAR=0x%08x " - "HCSPLT=0x%08x\n", x, td->hcchar, td->hcsplt); - - /* ack any pending messages */ - if (sc->sc_last_rx_status != 0 && - GRXSTSRD_CHNUM_GET(sc->sc_last_rx_status) == td->channel) { - /* get rid of message */ - dwc_otg_common_rx_ack(sc); - } - - /* move active channel */ - sc->sc_active_rx_ep &= ~(1 << td->channel); - sc->sc_active_rx_ep |= (1 << x); - - /* set channel */ - td->channel = x; - - return (1); /* new channel allocated */ - } - return (0); /* wait */ -} - -static uint8_t -dwc_otg_host_channel_alloc(struct dwc_otg_td *td) -{ - struct dwc_otg_softc *sc; - uint32_t tx_size; - uint8_t x; - uint8_t max_channel; - - if (td->channel < DWC_OTG_MAX_CHANNELS) + if (td->channel[which] < DWC_OTG_MAX_CHANNELS) return (0); /* already allocated */ + /* check if device is suspended */ + if (DWC_OTG_PC2UDEV(td->pc)->flags.self_suspended != 0) + return (1); /* busy - cannot transfer data */ + /* get pointer to softc */ sc = DWC_OTG_PC2SC(td->pc); - if ((td->hcchar & HCCHAR_EPNUM_MASK) == 0) { - max_channel = 1; - x = 0; - tx_size = td->max_packet_size; - if ((sc->sc_tx_cur_size + tx_size) > sc->sc_tx_max_size) { - DPRINTF("Too little FIFO space\n"); - return (1); /* too little FIFO */ - } - } else { - max_channel = sc->sc_host_ch_max; - x = 1; - if ((td->hcchar & HCCHAR_EPDIR) == HCCHAR_EPDIR_OUT) { - tx_size = td->max_packet_size; - if (td->hcsplt != 0 && tx_size > HCSPLT_XACTLEN_MAX) - tx_size = HCSPLT_XACTLEN_MAX; - if ((sc->sc_tx_cur_size + tx_size) > sc->sc_tx_max_size) { + /* compute needed TX FIFO size */ + if (td->ep_type == UE_CONTROL) { + /* RX and TX transactions */ + tx_p_size = 0; + tx_np_size = td->max_packet_size; + } else if ((td->hcchar & HCCHAR_EPDIR) == HCCHAR_EPDIR_OUT) { + if (td->ep_type == UE_INTERRUPT || + td->ep_type == UE_ISOCHRONOUS) { + tx_p_size = td->max_packet_size; + tx_np_size = 0; + if (td->hcsplt != 0 && tx_p_size > HCSPLT_XACTLEN_BURST) + tx_p_size = HCSPLT_XACTLEN_BURST; + if ((sc->sc_tx_cur_p_level + tx_p_size) > sc->sc_tx_max_size) { DPRINTF("Too little FIFO space\n"); return (1); /* too little FIFO */ } } else { - tx_size = 0; + tx_p_size = 0; + tx_np_size = td->max_packet_size; + if (td->hcsplt != 0 && tx_np_size > HCSPLT_XACTLEN_BURST) + tx_np_size = HCSPLT_XACTLEN_BURST; + if ((sc->sc_tx_cur_np_level + tx_np_size) > sc->sc_tx_max_size) { + DPRINTF("Too little FIFO space\n"); + return (1); /* too little FIFO */ + } } + } else { + /* not a TX transaction */ + tx_p_size = 0; + tx_np_size = 0; } - for (; x != max_channel; x++) { - - if (sc->sc_chan_state[x].allocated) + for (x = 0; x != sc->sc_host_ch_max; x++) { + if (sc->sc_chan_state[x].allocated != 0) continue; + /* check if channel is still enabled */ if (sc->sc_chan_state[x].wait_sof != 0) continue; sc->sc_chan_state[x].allocated = 1; - sc->sc_chan_state[x].tx_size = tx_size; + sc->sc_chan_state[x].tx_p_size = tx_p_size; + sc->sc_chan_state[x].tx_np_size = tx_np_size; - /* keep track of used FIFO */ - sc->sc_tx_cur_size += tx_size; + /* keep track of used TX FIFO, if any */ + sc->sc_tx_cur_p_level += tx_p_size; + sc->sc_tx_cur_np_level += tx_np_size; /* clear interrupts */ dwc_otg_clear_hcint(sc, x); @@ -685,54 +643,38 @@ dwc_otg_host_channel_alloc(struct dwc_otg_td *td) sc->sc_active_rx_ep |= (1 << x); /* set channel */ - td->channel = x; + td->channel[which] = x; return (0); /* allocated */ } + /* wait a bit */ + dwc_otg_enable_sof_irq(sc); return (1); /* busy */ } static void -dwc_otg_host_channel_disable(struct dwc_otg_softc *sc, uint8_t x) -{ - uint32_t hcchar; - if (sc->sc_chan_state[x].wait_sof != 0) - return; - hcchar = DWC_OTG_READ_4(sc, DOTG_HCCHAR(x)); - if (hcchar & (HCCHAR_CHENA | HCCHAR_CHDIS)) { - /* disable channel */ - DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(x), - HCCHAR_CHENA | HCCHAR_CHDIS); - /* don't re-use channel until next SOF is transmitted */ - sc->sc_chan_state[x].wait_sof = 2; - } -} - -static void -dwc_otg_host_channel_free(struct dwc_otg_td *td) +dwc_otg_host_channel_free(struct dwc_otg_td *td, uint8_t which) { struct dwc_otg_softc *sc; uint8_t x; - if (td->channel >= DWC_OTG_MAX_CHANNELS) + if (td->channel[which] >= DWC_OTG_MAX_CHANNELS) return; /* already freed */ /* free channel */ - x = td->channel; - td->channel = DWC_OTG_MAX_CHANNELS; + x = td->channel[which]; + td->channel[which] = DWC_OTG_MAX_CHANNELS; DPRINTF("CH=%d\n", x); /* get pointer to softc */ sc = DWC_OTG_PC2SC(td->pc); - - dwc_otg_host_channel_disable(sc, x); - + sc->sc_chan_state[x].wait_sof = DWC_OTG_SLOT_IDLE_MAX; sc->sc_chan_state[x].allocated = 0; - sc->sc_chan_state[x].suspended = 0; - /* keep track of used FIFO */ - sc->sc_tx_cur_size -= sc->sc_chan_state[x].tx_size; + /* keep track of used TX FIFO, if any */ + sc->sc_tx_cur_p_level -= sc->sc_chan_state[x].tx_p_size; + sc->sc_tx_cur_np_level -= sc->sc_chan_state[x].tx_np_size; /* ack any pending messages */ if (sc->sc_last_rx_status != 0 && @@ -751,30 +693,33 @@ dwc_otg_host_setup_tx(struct dwc_otg_td *td) struct dwc_otg_softc *sc; uint32_t hcint; uint32_t hcchar; - - if (dwc_otg_host_channel_alloc(td)) - goto busy; + uint8_t delta; /* get pointer to softc */ sc = DWC_OTG_PC2SC(td->pc); - hcint = sc->sc_chan_state[td->channel].hcint; + if (td->channel[0] < DWC_OTG_MAX_CHANNELS) { + hcint = sc->sc_chan_state[td->channel[0]].hcint; - DPRINTF("CH=%d ST=%d HCINT=0x%08x HCCHAR=0x%08x HCTSIZ=0x%08x\n", - td->channel, td->state, hcint, - DWC_OTG_READ_4(sc, DOTG_HCCHAR(td->channel)), - DWC_OTG_READ_4(sc, DOTG_HCTSIZ(td->channel))); + DPRINTF("CH=%d ST=%d HCINT=0x%08x HCCHAR=0x%08x HCTSIZ=0x%08x\n", + td->channel[0], td->state, hcint, + DWC_OTG_READ_4(sc, DOTG_HCCHAR(td->channel[0])), + DWC_OTG_READ_4(sc, DOTG_HCTSIZ(td->channel[0]))); + } else { + hcint = 0; + goto check_state; + } if (hcint & (HCINT_RETRY | HCINT_ACK | HCINT_NYET)) { /* give success bits priority over failure bits */ } else if (hcint & HCINT_STALL) { - DPRINTF("CH=%d STALL\n", td->channel); + DPRINTF("CH=%d STALL\n", td->channel[0]); td->error_stall = 1; td->error_any = 1; goto complete; } else if (hcint & HCINT_ERRORS) { - DPRINTF("CH=%d ERROR\n", td->channel); + DPRINTF("CH=%d ERROR\n", td->channel[0]); td->errcnt++; if (td->hcsplt != 0 || td->errcnt >= 3) { td->error_any = 1; @@ -782,34 +727,23 @@ dwc_otg_host_setup_tx(struct dwc_otg_td *td) } } - /* channel must be disabled before we can complete the transfer */ - if (hcint & (HCINT_ERRORS | HCINT_RETRY | HCINT_ACK | HCINT_NYET)) { - - dwc_otg_host_channel_disable(sc, td->channel); - if (!(hcint & HCINT_ERRORS)) td->errcnt = 0; } +check_state: switch (td->state) { case DWC_CHAN_ST_START: - if (!dwc_otg_host_channel_wait(td)) - break; goto send_pkt; case DWC_CHAN_ST_WAIT_ANE: if (hcint & (HCINT_RETRY | HCINT_ERRORS)) { - if (!dwc_otg_host_channel_wait(td)) - break; td->did_nak = 1; td->tt_scheduled = 0; goto send_pkt; - } - if (hcint & (HCINT_ACK | HCINT_NYET)) { - if (!dwc_otg_host_channel_wait(td)) - break; + } else if (hcint & (HCINT_ACK | HCINT_NYET)) { td->offset += td->tx_bytes; td->remainder -= td->tx_bytes; td->toggle = 1; @@ -820,35 +754,22 @@ dwc_otg_host_setup_tx(struct dwc_otg_td *td) case DWC_CHAN_ST_WAIT_S_ANE: if (hcint & (HCINT_RETRY | HCINT_ERRORS)) { - if (!dwc_otg_host_channel_wait(td)) - break; td->did_nak = 1; td->tt_scheduled = 0; goto send_pkt; - } - if (hcint & (HCINT_ACK | HCINT_NYET)) { - if (!dwc_otg_host_channel_wait(td)) - break; + } else if (hcint & (HCINT_ACK | HCINT_NYET)) { goto send_cpkt; } break; case DWC_CHAN_ST_WAIT_C_ANE: if (hcint & HCINT_NYET) { - if (!dwc_otg_host_channel_wait(td)) - break; goto send_cpkt; - } - if (hcint & (HCINT_RETRY | HCINT_ERRORS)) { - if (!dwc_otg_host_channel_wait(td)) - break; + } else if (hcint & (HCINT_RETRY | HCINT_ERRORS)) { td->did_nak = 1; td->tt_scheduled = 0; goto send_pkt; - } - if (hcint & HCINT_ACK) { - if (!dwc_otg_host_channel_wait(td)) - break; + } else if (hcint & HCINT_ACK) { td->offset += td->tx_bytes; td->remainder -= td->tx_bytes; td->toggle = 1; @@ -857,8 +778,6 @@ dwc_otg_host_setup_tx(struct dwc_otg_td *td) break; case DWC_CHAN_ST_WAIT_C_PKT: - if (!dwc_otg_host_channel_wait(td)) - break; goto send_cpkt; default: @@ -867,20 +786,36 @@ dwc_otg_host_setup_tx(struct dwc_otg_td *td) goto busy; send_pkt: + /* free existing channel, if any */ + dwc_otg_host_channel_free(td, 0); + if (sizeof(req) != td->remainder) { td->error_any = 1; goto complete; } if (td->hcsplt != 0) { - /* Wait for our turn, if TT transfer */ - if (td->tt_scheduled == 0 || - (sc->sc_last_frame_num & 7) < td->tt_start_slot) { - /* set return state */ + delta = td->tt_start_slot - sc->sc_last_frame_num - 1; + if (td->tt_scheduled == 0 || delta < DWC_OTG_TT_SLOT_MAX) { + td->state = DWC_CHAN_ST_START; + goto busy; + } + delta = sc->sc_last_frame_num - td->tt_start_slot; + if (delta > 5) { + /* missed it */ + td->tt_scheduled = 0; td->state = DWC_CHAN_ST_START; - goto tt_wait; + goto busy; } + } + /* allocate a new channel */ + if (dwc_otg_host_channel_alloc(td, 0)) { + td->state = DWC_CHAN_ST_START; + goto busy; + } + + if (td->hcsplt != 0) { td->hcsplt &= ~HCSPLT_COMPSPLT; td->state = DWC_CHAN_ST_WAIT_S_ANE; } else { @@ -889,60 +824,73 @@ send_pkt: usbd_copy_out(td->pc, 0, &req, sizeof(req)); - DWC_OTG_WRITE_4(sc, DOTG_HCTSIZ(td->channel), + DWC_OTG_WRITE_4(sc, DOTG_HCTSIZ(td->channel[0]), (sizeof(req) << HCTSIZ_XFERSIZE_SHIFT) | (1 << HCTSIZ_PKTCNT_SHIFT) | (HCTSIZ_PID_SETUP << HCTSIZ_PID_SHIFT)); - DWC_OTG_WRITE_4(sc, DOTG_HCSPLT(td->channel), td->hcsplt); + DWC_OTG_WRITE_4(sc, DOTG_HCSPLT(td->channel[0]), td->hcsplt); hcchar = td->hcchar; - hcchar &= ~HCCHAR_EPDIR_IN; + hcchar &= ~(HCCHAR_EPDIR_IN | HCCHAR_EPTYPE_MASK); + hcchar |= UE_CONTROL << HCCHAR_EPTYPE_SHIFT; /* must enable channel before writing data to FIFO */ - DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(td->channel), hcchar); + DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(td->channel[0]), hcchar); /* transfer data into FIFO */ bus_space_write_region_4(sc->sc_io_tag, sc->sc_io_hdl, - DOTG_DFIFO(td->channel), (uint32_t *)&req, sizeof(req) / 4); + DOTG_DFIFO(td->channel[0]), (uint32_t *)&req, sizeof(req) / 4); /* store number of bytes transmitted */ td->tx_bytes = sizeof(req); - goto busy; send_cpkt: - /* Wait for our turn, if TT transfer */ - if (td->tt_scheduled == 0 || - (sc->sc_last_frame_num & 7) < td->tt_complete_slot) { - /* set return state */ + /* free existing channel, if any */ + dwc_otg_host_channel_free(td, 0); + + delta = td->tt_complete_slot - sc->sc_last_frame_num - 1; + if (td->tt_scheduled == 0 || delta < DWC_OTG_TT_SLOT_MAX) { td->state = DWC_CHAN_ST_WAIT_C_PKT; - goto tt_wait; + goto busy; + } + delta = sc->sc_last_frame_num - td->tt_start_slot; + if (delta > DWC_OTG_TT_SLOT_MAX) { + /* we missed the service interval */ + if (td->ep_type != UE_ISOCHRONOUS) + td->error_any = 1; + goto complete; } + /* allocate a new channel */ + if (dwc_otg_host_channel_alloc(td, 0)) { + td->state = DWC_CHAN_ST_WAIT_C_PKT; + goto busy; + } + /* wait until next slot before trying again */ td->tt_complete_slot++; td->hcsplt |= HCSPLT_COMPSPLT; td->state = DWC_CHAN_ST_WAIT_C_ANE; - DWC_OTG_WRITE_4(sc, DOTG_HCTSIZ(td->channel), + DWC_OTG_WRITE_4(sc, DOTG_HCTSIZ(td->channel[0]), (HCTSIZ_PID_SETUP << HCTSIZ_PID_SHIFT)); - DWC_OTG_WRITE_4(sc, DOTG_HCSPLT(td->channel), td->hcsplt); + DWC_OTG_WRITE_4(sc, DOTG_HCSPLT(td->channel[0]), td->hcsplt); hcchar = td->hcchar; - hcchar &= ~HCCHAR_EPDIR_IN; + hcchar &= ~(HCCHAR_EPDIR_IN | HCCHAR_EPTYPE_MASK); + hcchar |= UE_CONTROL << HCCHAR_EPTYPE_SHIFT; /* must enable channel before writing data to FIFO */ - DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(td->channel), hcchar); - goto busy; + DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(td->channel[0]), hcchar); -tt_wait: - /* free allocated channel */ - dwc_otg_host_channel_free(td); busy: return (1); /* busy */ + complete: + dwc_otg_host_channel_free(td, 0); return (0); /* complete */ } @@ -1100,20 +1048,11 @@ static uint8_t dwc_otg_host_rate_check(struct dwc_otg_td *td) { struct dwc_otg_softc *sc; - uint8_t ep_type; /* get pointer to softc */ sc = DWC_OTG_PC2SC(td->pc); - if (td->channel < DWC_OTG_MAX_CHANNELS && - sc->sc_chan_state[td->channel].suspended) - goto busy; - - ep_type = ((td->hcchar & - HCCHAR_EPTYPE_MASK) >> HCCHAR_EPTYPE_SHIFT); - - if (ep_type == UE_ISOCHRONOUS) { - + if (td->ep_type == UE_ISOCHRONOUS) { /* non TT isochronous traffic */ if ((td->tmr_val != 0) || (sc->sc_last_frame_num & (td->tmr_res - 1))) { @@ -1122,7 +1061,7 @@ dwc_otg_host_rate_check(struct dwc_otg_td *td) td->tmr_val = 1; /* executed */ td->toggle = 0; - } else if (ep_type == UE_INTERRUPT) { + } else if (td->ep_type == UE_INTERRUPT) { if (!td->tt_scheduled) goto busy; td->tt_scheduled = 0; @@ -1144,23 +1083,24 @@ dwc_otg_host_data_rx(struct dwc_otg_td *td) uint32_t hcint; uint32_t hcchar; uint32_t count; - uint8_t ep_type; - - if (dwc_otg_host_channel_alloc(td)) - goto busy; + uint8_t delta; + uint8_t channel; /* get pointer to softc */ sc = DWC_OTG_PC2SC(td->pc); + channel = td->channel[td->tt_channel_tog]; - ep_type = ((td->hcchar & - HCCHAR_EPTYPE_MASK) >> HCCHAR_EPTYPE_SHIFT); + if (channel < DWC_OTG_MAX_CHANNELS) { + hcint = sc->sc_chan_state[channel].hcint; - hcint = sc->sc_chan_state[td->channel].hcint; - - DPRINTF("CH=%d ST=%d HCINT=0x%08x HCCHAR=0x%08x HCTSIZ=0x%08x\n", - td->channel, td->state, hcint, - DWC_OTG_READ_4(sc, DOTG_HCCHAR(td->channel)), - DWC_OTG_READ_4(sc, DOTG_HCTSIZ(td->channel))); + DPRINTF("CH=%d ST=%d HCINT=0x%08x HCCHAR=0x%08x HCTSIZ=0x%08x\n", + channel, td->state, hcint, + DWC_OTG_READ_4(sc, DOTG_HCCHAR(channel)), + DWC_OTG_READ_4(sc, DOTG_HCTSIZ(channel))); + } else { + hcint = 0; + goto check_state; + } /* check interrupt bits */ @@ -1168,37 +1108,26 @@ dwc_otg_host_data_rx(struct dwc_otg_td *td) HCINT_ACK | HCINT_NYET)) { /* give success bits priority over failure bits */ } else if (hcint & HCINT_STALL) { - DPRINTF("CH=%d STALL\n", td->channel); + DPRINTF("CH=%d STALL\n", channel); td->error_stall = 1; td->error_any = 1; goto complete; } else if (hcint & HCINT_ERRORS) { - DPRINTF("CH=%d ERROR\n", td->channel); + DPRINTF("CH=%d ERROR\n", channel); td->errcnt++; if (td->hcsplt != 0 || td->errcnt >= 3) { - if (ep_type != UE_ISOCHRONOUS) { + if (td->ep_type != UE_ISOCHRONOUS) { td->error_any = 1; goto complete; } } } - /* channel must be disabled before we can complete the transfer */ - - if (hcint & (HCINT_ERRORS | HCINT_RETRY | - HCINT_ACK | HCINT_NYET)) { - - dwc_otg_host_channel_disable(sc, td->channel); - - if (!(hcint & HCINT_ERRORS)) - td->errcnt = 0; - } - /* check endpoint status */ if (sc->sc_last_rx_status == 0) goto check_state; - if (GRXSTSRD_CHNUM_GET(sc->sc_last_rx_status) != td->channel) + if (GRXSTSRD_CHNUM_GET(sc->sc_last_rx_status) != channel) goto check_state; switch (sc->sc_last_rx_status & GRXSTSRD_PKTSTS_MASK) { @@ -1220,7 +1149,7 @@ dwc_otg_host_data_rx(struct dwc_otg_td *td) count = GRXSTSRD_BCNT_GET(sc->sc_last_rx_status); /* check for isochronous transfer or high-speed bandwidth endpoint */ - if (ep_type == UE_ISOCHRONOUS || td->max_packet_count > 1) { + if (td->ep_type == UE_ISOCHRONOUS || td->max_packet_count > 1) { if ((sc->sc_last_rx_status & GRXSTSRD_DPID_MASK) != GRXSTSRD_DPID_DATA0) { td->tt_xactpos = HCSPLT_XACTPOS_MIDDLE; } else { @@ -1269,8 +1198,8 @@ dwc_otg_host_data_rx(struct dwc_otg_td *td) td->remainder -= count; td->offset += count; - hcint |= HCINT_SOFTWARE_ONLY | HCINT_ACK; - sc->sc_chan_state[td->channel].hcint = hcint; + hcint |= HCINT_SOFTWARE_ONLY; + sc->sc_chan_state[channel].hcint = hcint; break; default: @@ -1280,10 +1209,14 @@ dwc_otg_host_data_rx(struct dwc_otg_td *td) dwc_otg_common_rx_ack(sc); check_state: + if (hcint & (HCINT_ERRORS | HCINT_RETRY | + HCINT_ACK | HCINT_NYET)) { + if (!(hcint & HCINT_ERRORS)) + td->errcnt = 0; + } + switch (td->state) { case DWC_CHAN_ST_START: - if (!dwc_otg_host_channel_wait(td)) - break; if (td->hcsplt != 0) goto receive_spkt; else @@ -1291,38 +1224,29 @@ check_state: case DWC_CHAN_ST_WAIT_ANE: if (hcint & (HCINT_RETRY | HCINT_ERRORS)) { - if (!dwc_otg_host_channel_wait(td)) - break; - td->did_nak = 1; td->tt_scheduled = 0; if (td->hcsplt != 0) goto receive_spkt; else goto receive_pkt; - } - if (!(hcint & HCINT_SOFTWARE_ONLY)) { - if (hcint & HCINT_NYET) { - if (ep_type == UE_ISOCHRONOUS) { - /* we missed the service interval */ - goto complete; - } - if (!dwc_otg_host_channel_wait(td)) - break; + } else if (hcint & HCINT_NYET) { + if (td->hcsplt != 0) { + /* try again */ goto receive_pkt; + } else { + /* not a valid token for IN endpoints */ + td->error_any = 1; + goto complete; } - break; - } - if (hcint & (HCINT_ACK | HCINT_NYET)) { - if (!dwc_otg_host_channel_wait(td)) - break; - - if (ep_type == UE_ISOCHRONOUS) { + } else if (hcint & HCINT_ACK) { + if (td->ep_type == UE_ISOCHRONOUS) { /* check if we are complete */ if ((td->remainder == 0) || - (td->tt_xactpos == HCSPLT_XACTPOS_BEGIN)) + (td->tt_xactpos == HCSPLT_XACTPOS_BEGIN)) { goto complete; - + } + /* get another packet */ goto receive_pkt; } else { /* check if we are complete */ @@ -1350,23 +1274,17 @@ check_state: * case of interrupt and isochronous transfers: */ if (hcint & (HCINT_RETRY | HCINT_ERRORS)) { - if (!dwc_otg_host_channel_wait(td)) - break; - td->did_nak = 1; td->tt_scheduled = 0; goto receive_spkt; - } - if (hcint & (HCINT_ACK | HCINT_NYET)) { - if (!dwc_otg_host_channel_wait(td)) - break; + } else if (hcint & HCINT_NYET) { + td->tt_scheduled = 0; + goto receive_spkt; + } else if (hcint & HCINT_ACK) goto receive_pkt; - } break; case DWC_CHAN_ST_WAIT_C_PKT: - if (!dwc_otg_host_channel_wait(td)) - break; goto receive_pkt; default: @@ -1375,103 +1293,149 @@ check_state: goto busy; receive_pkt: + /* free existing channel, if any */ + dwc_otg_host_channel_free(td, td->tt_channel_tog); + if (td->hcsplt != 0) { - /* Wait for our turn, if TT transfer */ - if (td->tt_scheduled == 0 || - (sc->sc_last_frame_num & 7) < td->tt_complete_slot) { - /* set return state */ + delta = td->tt_complete_slot - sc->sc_last_frame_num - 1; + if (td->tt_scheduled == 0 || delta < DWC_OTG_TT_SLOT_MAX) { td->state = DWC_CHAN_ST_WAIT_C_PKT; - goto tt_wait; + goto busy; } - /* wait until next slot before trying again */ - td->tt_complete_slot++; - - /* set toggle, if any */ - if (td->set_toggle) { - td->set_toggle = 0; - td->toggle = 1; + delta = sc->sc_last_frame_num - td->tt_start_slot; + if (delta > DWC_OTG_TT_SLOT_MAX) { + /* we missed the service interval */ + if (td->ep_type != UE_ISOCHRONOUS) + td->error_any = 1; + goto complete; } + /* complete split */ td->hcsplt |= HCSPLT_COMPSPLT; - count = HCSPLT_XACTLEN_MAX; } else if (td->tt_xactpos == HCSPLT_XACTPOS_BEGIN && dwc_otg_host_rate_check(td)) { - td->state = DWC_CHAN_ST_START; - dwc_otg_host_channel_free(td); + td->state = DWC_CHAN_ST_WAIT_C_PKT; goto busy; - } else { - count = td->max_packet_size; } + + /* allocate a new channel */ + if (dwc_otg_host_channel_alloc(td, td->tt_channel_tog)) { + td->state = DWC_CHAN_ST_WAIT_C_PKT; + goto busy; + } + + channel = td->channel[td->tt_channel_tog]; + + /* set toggle, if any */ + if (td->set_toggle) { + td->set_toggle = 0; + td->toggle = 1; + } + td->state = DWC_CHAN_ST_WAIT_ANE; /* receive one packet */ - DWC_OTG_WRITE_4(sc, DOTG_HCTSIZ(td->channel), - (count << HCTSIZ_XFERSIZE_SHIFT) | + DWC_OTG_WRITE_4(sc, DOTG_HCTSIZ(channel), + (td->max_packet_size << HCTSIZ_XFERSIZE_SHIFT) | (1 << HCTSIZ_PKTCNT_SHIFT) | (td->toggle ? (HCTSIZ_PID_DATA1 << HCTSIZ_PID_SHIFT) : (HCTSIZ_PID_DATA0 << HCTSIZ_PID_SHIFT))); - DWC_OTG_WRITE_4(sc, DOTG_HCSPLT(td->channel), td->hcsplt); - - /* send ASAP */ - if ((ep_type == UE_ISOCHRONOUS) && !(sc->sc_last_frame_num & 1)) - td->hcchar |= HCCHAR_ODDFRM; - else - td->hcchar &= ~HCCHAR_ODDFRM; + DWC_OTG_WRITE_4(sc, DOTG_HCSPLT(channel), td->hcsplt); hcchar = td->hcchar; hcchar |= HCCHAR_EPDIR_IN; - /* must enable channel before data can be received */ - DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(td->channel), hcchar); + /* check if other channel is allocated */ + if (td->channel[td->tt_channel_tog ^ 1] < DWC_OTG_MAX_CHANNELS) { + /* second - receive after next SOF event */ + if ((sc->sc_last_frame_num & 1) != 0) + hcchar |= HCCHAR_ODDFRM; + else + hcchar &= ~HCCHAR_ODDFRM; + + /* other channel is next */ + td->tt_channel_tog ^= 1; + td->tt_complete_slot++; + + /* must enable channel before data can be received */ + DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(channel), hcchar); + } else { + /* first - receive after second next SOF event */ + if ((sc->sc_last_frame_num & 1) == 0) + hcchar |= HCCHAR_ODDFRM; + else + hcchar &= ~HCCHAR_ODDFRM; + + /* must enable channel before data can be received */ + DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(channel), hcchar); + + if (td->hcsplt != 0) { + if (td->ep_type == UE_ISOCHRONOUS || td->ep_type == UE_INTERRUPT) { + /* allocate a second channel */ + td->tt_channel_tog ^= 1; + goto receive_pkt; + } else { + td->tt_complete_slot++; + } + } + } goto busy; receive_spkt: - /* Wait for our turn, if TT transfer */ - if (td->tt_scheduled == 0) { - if (ep_type == UE_INTERRUPT) { - td->state = DWC_CHAN_ST_START; - dwc_otg_host_channel_free(td); - goto busy; - } - /* set return state */ + /* free existing channel(s), if any */ + dwc_otg_host_channel_free(td, 0); + dwc_otg_host_channel_free(td, 1); + + delta = td->tt_start_slot - sc->sc_last_frame_num - 1; + if (td->tt_scheduled == 0 || delta < DWC_OTG_TT_SLOT_MAX) { td->state = DWC_CHAN_ST_START; - goto tt_wait; + goto busy; } - if ((sc->sc_last_frame_num & 7) < td->tt_start_slot) { - /* set return state */ + delta = sc->sc_last_frame_num - td->tt_start_slot; + if (delta > 5) { + /* missed it */ + td->tt_scheduled = 0; td->state = DWC_CHAN_ST_START; - goto tt_wait; + goto busy; } - /* send ASAP */ - if ((ep_type == UE_ISOCHRONOUS) && !(sc->sc_last_frame_num & 1)) - td->hcchar |= HCCHAR_ODDFRM; - else - td->hcchar &= ~HCCHAR_ODDFRM; + /* allocate a new channel */ + if (dwc_otg_host_channel_alloc(td, 0)) { + td->state = DWC_CHAN_ST_START; + goto busy; + } + + channel = td->channel[0]; td->hcsplt &= ~HCSPLT_COMPSPLT; td->state = DWC_CHAN_ST_WAIT_S_ANE; + /* reset channel toggle */ + td->tt_channel_tog = 0; + /* receive one packet */ - DWC_OTG_WRITE_4(sc, DOTG_HCTSIZ(td->channel), - (td->toggle ? (HCTSIZ_PID_DATA1 << HCTSIZ_PID_SHIFT) : - (HCTSIZ_PID_DATA0 << HCTSIZ_PID_SHIFT))); + DWC_OTG_WRITE_4(sc, DOTG_HCTSIZ(channel), + (HCTSIZ_PID_DATA0 << HCTSIZ_PID_SHIFT)); - DWC_OTG_WRITE_4(sc, DOTG_HCSPLT(td->channel), td->hcsplt); + DWC_OTG_WRITE_4(sc, DOTG_HCSPLT(channel), td->hcsplt); + + /* send after next SOF event */ + if ((sc->sc_last_frame_num & 1) == 0) + td->hcchar |= HCCHAR_ODDFRM; + else + td->hcchar &= ~HCCHAR_ODDFRM; hcchar = td->hcchar; hcchar |= HCCHAR_EPDIR_IN; /* must enable channel before data can be received */ - DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(td->channel), hcchar); - goto busy; - -tt_wait: - /* free allocated channel */ - dwc_otg_host_channel_free(td); + DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(channel), hcchar); busy: return (1); /* busy */ + complete: + dwc_otg_host_channel_free(td, 0); + dwc_otg_host_channel_free(td, 1); return (0); /* complete */ } @@ -1595,34 +1559,35 @@ dwc_otg_host_data_tx(struct dwc_otg_td *td) uint32_t count; uint32_t hcint; uint32_t hcchar; - uint8_t ep_type; - - if (dwc_otg_host_channel_alloc(td)) - goto busy; + uint8_t delta; + uint8_t channel; /* get pointer to softc */ sc = DWC_OTG_PC2SC(td->pc); + channel = td->channel[td->tt_channel_tog]; - ep_type = ((td->hcchar & - HCCHAR_EPTYPE_MASK) >> HCCHAR_EPTYPE_SHIFT); + if (channel < DWC_OTG_MAX_CHANNELS) { + hcint = sc->sc_chan_state[channel].hcint; - hcint = sc->sc_chan_state[td->channel].hcint; - - DPRINTF("CH=%d ST=%d HCINT=0x%08x HCCHAR=0x%08x HCTSIZ=0x%08x\n", - td->channel, td->state, hcint, - DWC_OTG_READ_4(sc, DOTG_HCCHAR(td->channel)), - DWC_OTG_READ_4(sc, DOTG_HCTSIZ(td->channel))); + DPRINTF("CH=%d ST=%d HCINT=0x%08x HCCHAR=0x%08x HCTSIZ=0x%08x\n", + channel, td->state, hcint, + DWC_OTG_READ_4(sc, DOTG_HCCHAR(channel)), + DWC_OTG_READ_4(sc, DOTG_HCTSIZ(channel))); + } else { + hcint = 0; + goto check_state; + } if (hcint & (HCINT_RETRY | HCINT_ACK | HCINT_NYET)) { /* give success bits priority over failure bits */ } else if (hcint & HCINT_STALL) { - DPRINTF("CH=%d STALL\n", td->channel); + DPRINTF("CH=%d STALL\n", channel); td->error_stall = 1; td->error_any = 1; goto complete; } else if (hcint & HCINT_ERRORS) { - DPRINTF("CH=%d ERROR\n", td->channel); + DPRINTF("CH=%d ERROR\n", channel); td->errcnt++; if (td->hcsplt != 0 || td->errcnt >= 3) { td->error_any = 1; @@ -1635,30 +1600,22 @@ dwc_otg_host_data_tx(struct dwc_otg_td *td) if (hcint & (HCINT_ERRORS | HCINT_RETRY | HCINT_ACK | HCINT_NYET)) { - dwc_otg_host_channel_disable(sc, td->channel); - if (!(hcint & HCINT_ERRORS)) td->errcnt = 0; } +check_state: switch (td->state) { case DWC_CHAN_ST_START: - if (!dwc_otg_host_channel_wait(td)) - break; goto send_pkt; case DWC_CHAN_ST_WAIT_ANE: if (hcint & (HCINT_RETRY | HCINT_ERRORS)) { - if (!dwc_otg_host_channel_wait(td)) - break; td->did_nak = 1; td->tt_scheduled = 0; goto send_pkt; } if (hcint & (HCINT_ACK | HCINT_NYET)) { - if (!dwc_otg_host_channel_wait(td)) - break; - td->offset += td->tx_bytes; td->remainder -= td->tx_bytes; td->toggle ^= 1; @@ -1680,35 +1637,24 @@ dwc_otg_host_data_tx(struct dwc_otg_td *td) case DWC_CHAN_ST_WAIT_S_ANE: if (hcint & (HCINT_RETRY | HCINT_ERRORS)) { - if (!dwc_otg_host_channel_wait(td)) - break; td->did_nak = 1; td->tt_scheduled = 0; goto send_pkt; } - if (hcint & (HCINT_ACK | HCINT_NYET)) { - if (!dwc_otg_host_channel_wait(td)) - break; + if (hcint & (HCINT_ACK | HCINT_NYET)) goto send_cpkt; - } break; case DWC_CHAN_ST_WAIT_C_ANE: - if (hcint & HCINT_NYET) { - if (!dwc_otg_host_channel_wait(td)) - break; + if (hcint & HCINT_NYET) goto send_cpkt; - } + if (hcint & (HCINT_RETRY | HCINT_ERRORS)) { - if (!dwc_otg_host_channel_wait(td)) - break; td->did_nak = 1; td->tt_scheduled = 0; goto send_pkt; } if (hcint & HCINT_ACK) { - if (!dwc_otg_host_channel_wait(td)) - break; td->offset += td->tx_bytes; td->remainder -= td->tx_bytes; td->toggle ^= 1; @@ -1726,46 +1672,35 @@ dwc_otg_host_data_tx(struct dwc_otg_td *td) break; case DWC_CHAN_ST_WAIT_C_PKT: - if (!dwc_otg_host_channel_wait(td)) - break; goto send_cpkt; case DWC_CHAN_ST_TX_WAIT_ISOC: /* Check if isochronous OUT traffic is complete */ - if ((hcint & HCINT_ACK) == 0) + if ((hcint & HCINT_HCH_DONE_MASK) == 0) break; td->offset += td->tx_bytes; td->remainder -= td->tx_bytes; - /* Update split token according to specification */ - if (td->hcsplt != 0) { - if (td->tt_xactpos == HCSPLT_XACTPOS_BEGIN) - td->tt_xactpos = HCSPLT_XACTPOS_MIDDLE; - } else if (td->max_packet_count > 1) { - td->tt_xactpos++; - } + if (td->hcsplt != 0 || td->remainder == 0) + goto complete; - dwc_otg_host_channel_disable(sc, td->channel); + /* check for next packet */ + if (td->max_packet_count > 1) + td->tt_xactpos++; - if (td->remainder == 0) - goto complete; + /* free existing channel, if any */ + dwc_otg_host_channel_free(td, td->tt_channel_tog); td->state = DWC_CHAN_ST_TX_PKT_ISOC; /* FALLTHROUGH */ case DWC_CHAN_ST_TX_PKT_ISOC: - if (!dwc_otg_host_channel_wait(td)) + if (dwc_otg_host_channel_alloc(td, 0)) break; - - if (td->hcsplt != 0) { - if ((sc->sc_last_frame_num & 7) < td->tt_start_slot) - goto tt_wait; - /* packets must be 125us apart */ - td->tt_start_slot++; - } + channel = td->channel[0]; goto send_isoc_pkt; default: break; @@ -1773,39 +1708,43 @@ dwc_otg_host_data_tx(struct dwc_otg_td *td) goto busy; send_pkt: + /* free existing channel(s), if any */ + dwc_otg_host_channel_free(td, 0); + dwc_otg_host_channel_free(td, 1); + if (td->hcsplt != 0) { - /* Wait for our turn, if TT transfer */ - if (td->tt_scheduled == 0) { - if (ep_type == UE_INTERRUPT) { - td->state = DWC_CHAN_ST_START; - dwc_otg_host_channel_free(td); - goto busy; - } - /* set return state */ + delta = td->tt_start_slot - sc->sc_last_frame_num - 1; + if (td->tt_scheduled == 0 || delta < DWC_OTG_TT_SLOT_MAX) { td->state = DWC_CHAN_ST_START; - goto tt_wait; + goto busy; } - if ((sc->sc_last_frame_num & 7) < td->tt_start_slot) { - /* set return state */ + delta = sc->sc_last_frame_num - td->tt_start_slot; + if (delta > 5) { + /* missed it */ + td->tt_scheduled = 0; td->state = DWC_CHAN_ST_START; - goto tt_wait; - } - - /* packets must be 125us apart */ - td->tt_start_slot++; - - /* set toggle, if any */ - if (td->set_toggle) { - td->set_toggle = 0; - td->toggle = 1; + goto busy; } } else if (dwc_otg_host_rate_check(td)) { td->state = DWC_CHAN_ST_START; - dwc_otg_host_channel_free(td); goto busy; } - if (ep_type == UE_ISOCHRONOUS) { + /* allocate a new channel */ + if (dwc_otg_host_channel_alloc(td, 0)) { + td->state = DWC_CHAN_ST_START; + goto busy; + } + + channel = td->channel[0]; + + /* set toggle, if any */ + if (td->set_toggle) { + td->set_toggle = 0; + td->toggle = 1; + } + + if (td->ep_type == UE_ISOCHRONOUS) { send_isoc_pkt: /* Isochronous OUT transfers don't have any ACKs */ td->state = DWC_CHAN_ST_TX_WAIT_ISOC; @@ -1813,23 +1752,14 @@ send_isoc_pkt: if (td->hcsplt != 0) { /* get maximum transfer length */ count = td->remainder; - - /* Update split token according to specification */ - if (td->tt_xactpos == HCSPLT_XACTPOS_BEGIN) { - if (count <= HCSPLT_XACTLEN_MAX) - td->tt_xactpos = HCSPLT_XACTPOS_ALL; - else - count = HCSPLT_XACTLEN_MAX; - } else if (td->tt_xactpos == HCSPLT_XACTPOS_MIDDLE) { - if (count <= HCSPLT_XACTLEN_MAX) - td->tt_xactpos = HCSPLT_XACTPOS_LAST; - else - count = HCSPLT_XACTLEN_MAX; + if (count > HCSPLT_XACTLEN_BURST) { + DPRINTF("TT overflow\n"); + td->error = 1; + goto complete; } - /* Update transaction position */ td->hcsplt &= ~HCSPLT_XACTPOS_MASK; - td->hcsplt |= ((uint32_t)td->tt_xactpos << HCSPLT_XACTPOS_SHIFT); + td->hcsplt |= (HCSPLT_XACTPOS_ALL << HCSPLT_XACTPOS_SHIFT); } else { /* send one packet at a time */ count = td->max_packet_size; @@ -1883,24 +1813,24 @@ send_isoc_pkt: } if (td->tt_xactpos == td->npkt) { if (td->npkt == 1) { - DWC_OTG_WRITE_4(sc, DOTG_HCTSIZ(td->channel), + DWC_OTG_WRITE_4(sc, DOTG_HCTSIZ(channel), (count << HCTSIZ_XFERSIZE_SHIFT) | (1 << HCTSIZ_PKTCNT_SHIFT) | (HCTSIZ_PID_DATA0 << HCTSIZ_PID_SHIFT)); } else if (td->npkt == 2) { - DWC_OTG_WRITE_4(sc, DOTG_HCTSIZ(td->channel), + DWC_OTG_WRITE_4(sc, DOTG_HCTSIZ(channel), (count << HCTSIZ_XFERSIZE_SHIFT) | (1 << HCTSIZ_PKTCNT_SHIFT) | (HCTSIZ_PID_DATA1 << HCTSIZ_PID_SHIFT)); } else { - DWC_OTG_WRITE_4(sc, DOTG_HCTSIZ(td->channel), + DWC_OTG_WRITE_4(sc, DOTG_HCTSIZ(channel), (count << HCTSIZ_XFERSIZE_SHIFT) | (1 << HCTSIZ_PKTCNT_SHIFT) | (HCTSIZ_PID_DATA2 << HCTSIZ_PID_SHIFT)); } td->npkt = 0; } else { - DWC_OTG_WRITE_4(sc, DOTG_HCTSIZ(td->channel), + DWC_OTG_WRITE_4(sc, DOTG_HCTSIZ(channel), (count << HCTSIZ_XFERSIZE_SHIFT) | (1 << HCTSIZ_PKTCNT_SHIFT) | (HCTSIZ_PID_MDATA << HCTSIZ_PID_SHIFT)); @@ -1908,26 +1838,26 @@ send_isoc_pkt: } else { /* TODO: HCTSIZ_DOPNG */ - DWC_OTG_WRITE_4(sc, DOTG_HCTSIZ(td->channel), + DWC_OTG_WRITE_4(sc, DOTG_HCTSIZ(channel), (count << HCTSIZ_XFERSIZE_SHIFT) | (1 << HCTSIZ_PKTCNT_SHIFT) | (td->toggle ? (HCTSIZ_PID_DATA1 << HCTSIZ_PID_SHIFT) : (HCTSIZ_PID_DATA0 << HCTSIZ_PID_SHIFT))); } - DWC_OTG_WRITE_4(sc, DOTG_HCSPLT(td->channel), td->hcsplt); - - /* send ASAP */ - if ((ep_type == UE_ISOCHRONOUS) && !(sc->sc_last_frame_num & 1)) - td->hcchar |= HCCHAR_ODDFRM; - else - td->hcchar &= ~HCCHAR_ODDFRM; + DWC_OTG_WRITE_4(sc, DOTG_HCSPLT(channel), td->hcsplt); hcchar = td->hcchar; hcchar &= ~HCCHAR_EPDIR_IN; + /* send after next SOF event */ + if ((sc->sc_last_frame_num & 1) == 0) + hcchar |= HCCHAR_ODDFRM; + else + hcchar &= ~HCCHAR_ODDFRM; + /* must enable before writing data to FIFO */ - DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(td->channel), hcchar); + DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(channel), hcchar); if (count != 0) { @@ -1940,7 +1870,7 @@ send_isoc_pkt: /* transfer data into FIFO */ bus_space_write_region_4(sc->sc_io_tag, sc->sc_io_hdl, - DOTG_DFIFO(td->channel), + DOTG_DFIFO(channel), sc->sc_tx_bounce_buffer, (count + 3) / 4); } @@ -1949,38 +1879,83 @@ send_isoc_pkt: goto busy; send_cpkt: - /* Wait for our turn, if TT transfer */ - if (td->tt_scheduled == 0 || - (sc->sc_last_frame_num & 7) < td->tt_complete_slot) { - /* set return state */ + /* free existing channel, if any */ + dwc_otg_host_channel_free(td, td->tt_channel_tog); + + delta = td->tt_complete_slot - sc->sc_last_frame_num - 1; + if (td->tt_scheduled == 0 || delta < DWC_OTG_TT_SLOT_MAX) { td->state = DWC_CHAN_ST_WAIT_C_PKT; - goto tt_wait; + goto busy; + } + delta = sc->sc_last_frame_num - td->tt_start_slot; + if (delta > DWC_OTG_TT_SLOT_MAX) { + /* we missed the service interval */ + if (td->ep_type != UE_ISOCHRONOUS) + td->error_any = 1; + goto complete; + } + + /* allocate a new channel */ + if (dwc_otg_host_channel_alloc(td, td->tt_channel_tog)) { + td->state = DWC_CHAN_ST_WAIT_C_PKT; + goto busy; } - /* wait until next slot before trying again */ - td->tt_complete_slot++; + + channel = td->channel[td->tt_channel_tog]; td->hcsplt |= HCSPLT_COMPSPLT; td->state = DWC_CHAN_ST_WAIT_C_ANE; - DWC_OTG_WRITE_4(sc, DOTG_HCTSIZ(td->channel), - (td->toggle ? (HCTSIZ_PID_DATA1 << HCTSIZ_PID_SHIFT) : - (HCTSIZ_PID_DATA0 << HCTSIZ_PID_SHIFT))); + DWC_OTG_WRITE_4(sc, DOTG_HCTSIZ(channel), + (HCTSIZ_PID_DATA0 << HCTSIZ_PID_SHIFT)); - DWC_OTG_WRITE_4(sc, DOTG_HCSPLT(td->channel), td->hcsplt); + DWC_OTG_WRITE_4(sc, DOTG_HCSPLT(channel), td->hcsplt); hcchar = td->hcchar; hcchar &= ~HCCHAR_EPDIR_IN; - /* must enable channel before writing data to FIFO */ - DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(td->channel), hcchar); - goto busy; + /* check if other channel is allocated */ + if (td->channel[td->tt_channel_tog ^ 1] < DWC_OTG_MAX_CHANNELS) { + /* second - receive after next SOF event */ + if ((sc->sc_last_frame_num & 1) != 0) + hcchar |= HCCHAR_ODDFRM; + else + hcchar &= ~HCCHAR_ODDFRM; + + /* other channel is next */ + td->tt_channel_tog ^= 1; + /* wait until next slot before trying again */ + td->tt_complete_slot++; + + /* must enable channel before data can be received */ + DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(channel), hcchar); + } else { + /* first - receive after second next SOF event */ + if ((sc->sc_last_frame_num & 1) == 0) + hcchar |= HCCHAR_ODDFRM; + else + hcchar &= ~HCCHAR_ODDFRM; -tt_wait: - /* free allocated channel */ - dwc_otg_host_channel_free(td); + /* must enable channel before data can be received */ + DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(channel), hcchar); + + if (td->hcsplt != 0) { + if (td->ep_type == UE_ISOCHRONOUS || td->ep_type == UE_INTERRUPT) { + /* allocate a second channel */ + td->tt_channel_tog ^= 1; + goto send_cpkt; + } else { + /* wait until next slot before trying again */ + td->tt_complete_slot++; + } + } + } busy: return (1); /* busy */ + complete: + dwc_otg_host_channel_free(td, 0); + dwc_otg_host_channel_free(td, 1); return (0); /* complete */ } @@ -2226,7 +2201,6 @@ dwc_otg_xfer_do_fifo(struct usb_xfer *xfer) { struct dwc_otg_td *td; uint8_t toggle; - uint8_t channel; uint8_t tmr_val; uint8_t tmr_res; @@ -2234,15 +2208,6 @@ dwc_otg_xfer_do_fifo(struct usb_xfer *xfer) td = xfer->td_transfer_cache; - /* - * If we are suspended in host mode and no channel is - * allocated, simply return: - */ - if (xfer->xroot->udev->flags.self_suspended != 0 && - xfer->xroot->udev->flags.usb_mode == USB_MODE_HOST && - td->channel >= DWC_OTG_MAX_CHANNELS) { - return (1); /* not complete */ - } while (1) { if ((td->func) (td)) { /* operation in progress */ @@ -2269,11 +2234,9 @@ dwc_otg_xfer_do_fifo(struct usb_xfer *xfer) tmr_res = td->tmr_res; tmr_val = td->tmr_val; toggle = td->toggle; - channel = td->channel; td = td->obj_next; xfer->td_transfer_cache = td; td->toggle = toggle; /* transfer toggle */ - td->channel = channel; /* transfer channel */ td->tmr_res = tmr_res; td->tmr_val = tmr_val; } @@ -2343,236 +2306,182 @@ dwc_otg_timer_stop(struct dwc_otg_softc *sc) usb_callout_stop(&sc->sc_timer); } -static void +static uint8_t dwc_otg_update_host_transfer_schedule(struct dwc_otg_softc *sc) { TAILQ_HEAD(, usb_xfer) head; struct usb_xfer *xfer; struct usb_xfer *xfer_next; struct dwc_otg_td *td; - uint8_t needsof; uint16_t temp; + uint8_t x; - /* FS/LS TT frames are one behind, so add one here */ - temp = (DWC_OTG_READ_4(sc, DOTG_HFNUM) + 1) & HFNUM_FRNUM_MASK; + temp = DWC_OTG_READ_4(sc, DOTG_HFNUM) & DWC_OTG_FRAME_MASK; if (sc->sc_last_frame_num == temp) - return; + return (0); sc->sc_last_frame_num = temp; - needsof = 0; - TAILQ_INIT(&head); - if (sc->sc_irq_mask & GINTMSK_SOFMSK) { - uint8_t x; - - for (x = 0; x != sc->sc_host_ch_max; x++) { - if (sc->sc_chan_state[x].wait_sof != 0) { - if (--(sc->sc_chan_state[x].wait_sof) != 0) - needsof = 1; - } - } - } - - if ((temp & 7) == 0) { - - /* reset TT info */ - memset(sc->sc_tt_info, 0, sizeof(sc->sc_tt_info)); - - /* - * Plan ahead FULL speed transfers going through the - * transaction translator, according to the USB - * specified priority: - */ - TAILQ_FOREACH_SAFE(xfer, &sc->sc_bus.intr_q.head, wait_entry, xfer_next) { - struct dwc_otg_tt_info *pinfo; - - td = xfer->td_transfer_cache; - if (td == NULL || td->did_nak != 0 || - (td->hcchar & HCCHAR_EPTYPE_MASK) != - (UE_CONTROL << HCCHAR_EPTYPE_SHIFT)) - continue; - - needsof = 1; - - if (td->hcsplt == 0) - continue; + for (x = 0; x != sc->sc_host_ch_max; x++) { + uint32_t hcchar; - /* Reset state if stuck waiting for complete split */ - if (td->state == DWC_CHAN_ST_WAIT_C_PKT) - td->state = DWC_CHAN_ST_START; + if (sc->sc_chan_state[x].wait_sof == 0) + continue; - pinfo = sc->sc_tt_info + td->tt_index; + sc->sc_needsof = 1; + sc->sc_chan_state[x].wait_sof--; + if (sc->sc_chan_state[x].wait_sof != 0) + continue; - td->tt_start_slot = pinfo->slot_index; - pinfo->bytes_used += td->max_packet_size; - while (pinfo->bytes_used >= HCSPLT_XACTLEN_MAX) { - pinfo->bytes_used -= HCSPLT_XACTLEN_MAX; - pinfo->slot_index ++; - } + hcchar = DWC_OTG_READ_4(sc, DOTG_HCCHAR(x)); - td->tt_complete_slot = pinfo->slot_index + 2; - if (td->tt_complete_slot < 8) { - td->tt_scheduled = 1; - TAILQ_REMOVE(&sc->sc_bus.intr_q.head, xfer, wait_entry); - TAILQ_INSERT_TAIL(&head, xfer, wait_entry); - } else { - td->tt_scheduled = 0; - } + /* disable host channel, if any */ + if (hcchar & (HCCHAR_CHENA | HCCHAR_CHDIS)) { + /* disable channel */ + DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(x), + HCCHAR_CHENA | HCCHAR_CHDIS); + /* wait for chip to get its brains in order */ + sc->sc_chan_state[x].wait_sof = 2; } + } + if ((temp & 7) == 0) { TAILQ_FOREACH_SAFE(xfer, &sc->sc_bus.intr_q.head, wait_entry, xfer_next) { - struct dwc_otg_tt_info *pinfo; - td = xfer->td_transfer_cache; - if (td == NULL || - (td->hcchar & HCCHAR_EPTYPE_MASK) != - (UE_ISOCHRONOUS << HCCHAR_EPTYPE_SHIFT)) + if (td == NULL || td->ep_type != UE_ISOCHRONOUS) continue; /* execute more frames */ td->tmr_val = 0; - needsof = 1; + sc->sc_needsof = 1; - if (td->hcsplt == 0) + if (td->hcsplt == 0 || td->tt_scheduled != 0) continue; - /* Reset state if stuck waiting for complete split */ - if (td->state == DWC_CHAN_ST_WAIT_C_PKT) - td->state = DWC_CHAN_ST_START; - - pinfo = sc->sc_tt_info + td->tt_index; - - td->tt_start_slot = pinfo->slot_index; - pinfo->bytes_used += td->remainder; - while (pinfo->bytes_used >= HCSPLT_XACTLEN_MAX) { - pinfo->bytes_used -= HCSPLT_XACTLEN_MAX; - pinfo->slot_index ++; - } - - td->tt_complete_slot = pinfo->slot_index + 2; - if (td->tt_complete_slot < 8) { - td->tt_scheduled = 1; - TAILQ_REMOVE(&sc->sc_bus.intr_q.head, xfer, wait_entry); - TAILQ_INSERT_TAIL(&head, xfer, wait_entry); - } else { - td->tt_scheduled = 0; - } + /* Start ASAP */ + td->tt_start_slot = temp + 0; + td->tt_complete_slot = temp + 2; + td->tt_scheduled = 1; + TAILQ_REMOVE(&sc->sc_bus.intr_q.head, xfer, wait_entry); + TAILQ_INSERT_TAIL(&head, xfer, wait_entry); } TAILQ_FOREACH_SAFE(xfer, &sc->sc_bus.intr_q.head, wait_entry, xfer_next) { - struct dwc_otg_tt_info *pinfo; - td = xfer->td_transfer_cache; - if (td == NULL || - (td->hcchar & HCCHAR_EPTYPE_MASK) != - (UE_INTERRUPT << HCCHAR_EPTYPE_SHIFT)) { + if (td == NULL || td->ep_type != UE_INTERRUPT) + continue; + + if (td->tt_scheduled != 0) { + sc->sc_needsof = 1; continue; } if (dwc_otg_host_rate_check_interrupt(sc, td)) continue; - needsof = 1; - if (td->hcsplt == 0) { + sc->sc_needsof = 1; td->tt_scheduled = 1; continue; } - /* Reset state if stuck waiting for complete split */ - if (td->state == DWC_CHAN_ST_WAIT_C_PKT) - td->state = DWC_CHAN_ST_START; + /* start ASAP */ + td->tt_start_slot = temp + 0; + td->tt_complete_slot = temp + 2; + sc->sc_needsof = 1; + td->tt_scheduled = 1; + TAILQ_REMOVE(&sc->sc_bus.intr_q.head, xfer, wait_entry); + TAILQ_INSERT_TAIL(&head, xfer, wait_entry); + } - pinfo = sc->sc_tt_info + td->tt_index; + TAILQ_FOREACH_SAFE(xfer, &sc->sc_bus.intr_q.head, wait_entry, xfer_next) { + td = xfer->td_transfer_cache; + if (td == NULL || td->did_nak != 0 || td->ep_type != UE_CONTROL) + continue; - td->tt_start_slot = pinfo->slot_index; - pinfo->bytes_used += td->remainder; - while (pinfo->bytes_used >= HCSPLT_XACTLEN_MAX) { - pinfo->bytes_used -= HCSPLT_XACTLEN_MAX; - pinfo->slot_index ++; - } + sc->sc_needsof = 1; - td->tt_complete_slot = pinfo->slot_index + 2; - if (td->tt_complete_slot < 8) { - td->tt_scheduled = 1; - TAILQ_REMOVE(&sc->sc_bus.intr_q.head, xfer, wait_entry); - TAILQ_INSERT_TAIL(&head, xfer, wait_entry); - } else { - td->tt_scheduled = 0; - } + if (td->hcsplt == 0 || td->tt_scheduled != 0) + continue; + + /* start ASAP */ + td->tt_start_slot = temp + 0; + td->tt_complete_slot = temp + 1; + td->tt_scheduled = 1; + TAILQ_REMOVE(&sc->sc_bus.intr_q.head, xfer, wait_entry); + TAILQ_INSERT_TAIL(&head, xfer, wait_entry); } } - if ((temp & 7) < 6) { TAILQ_FOREACH_SAFE(xfer, &sc->sc_bus.intr_q.head, wait_entry, xfer_next) { - struct dwc_otg_tt_info *pinfo; - td = xfer->td_transfer_cache; - if (td == NULL || td->did_nak != 0 || - (td->hcchar & HCCHAR_EPTYPE_MASK) != - (UE_BULK << HCCHAR_EPTYPE_SHIFT)) { + if (td == NULL || td->did_nak != 0 || td->ep_type != UE_BULK) continue; - } - needsof = 1; + sc->sc_needsof = 1; - if (td->hcsplt == 0) + if (td->hcsplt == 0 || td->tt_scheduled != 0) continue; - if ((temp & 7) == 0) { - /* Reset state if stuck waiting for complete split */ - if (td->state == DWC_CHAN_ST_WAIT_C_PKT) - td->state = DWC_CHAN_ST_START; - } else if (td->tt_scheduled != 0) - continue; /* already scheduled */ - - pinfo = sc->sc_tt_info + td->tt_index; - - td->tt_start_slot = pinfo->slot_index; - pinfo->bytes_used += td->remainder; - while (pinfo->bytes_used >= HCSPLT_XACTLEN_MAX) { - pinfo->bytes_used -= HCSPLT_XACTLEN_MAX; - pinfo->slot_index ++; - } - - td->tt_complete_slot = pinfo->slot_index + 2; - if (td->tt_complete_slot < 8) { - td->tt_scheduled = 1; - TAILQ_REMOVE(&sc->sc_bus.intr_q.head, xfer, wait_entry); - TAILQ_INSERT_TAIL(&head, xfer, wait_entry); - } else { - td->tt_scheduled = 0; - } + /* start ASAP */ + td->tt_start_slot = temp + 0; + td->tt_complete_slot = temp + 1; + td->tt_scheduled = 1; + TAILQ_REMOVE(&sc->sc_bus.intr_q.head, xfer, wait_entry); + TAILQ_INSERT_TAIL(&head, xfer, wait_entry); } } - /* TT transfers need to be executed in a specific order */ + /* Put TT transfers in execution order at the end */ + TAILQ_CONCAT(&sc->sc_bus.intr_q.head, &head, wait_entry); + + /* move all TT transfers in front, keeping the current order */ + TAILQ_FOREACH_SAFE(xfer, &sc->sc_bus.intr_q.head, wait_entry, xfer_next) { + td = xfer->td_transfer_cache; + if (td == NULL || td->hcsplt == 0) + continue; + TAILQ_REMOVE(&sc->sc_bus.intr_q.head, xfer, wait_entry); + TAILQ_INSERT_TAIL(&head, xfer, wait_entry); + } TAILQ_CONCAT(&head, &sc->sc_bus.intr_q.head, wait_entry); + TAILQ_CONCAT(&sc->sc_bus.intr_q.head, &head, wait_entry); - /* Put TT transfers first in the queue */ + /* put non-TT BULK transfers last */ + TAILQ_FOREACH_SAFE(xfer, &sc->sc_bus.intr_q.head, wait_entry, xfer_next) { + td = xfer->td_transfer_cache; + if (td == NULL || td->hcsplt != 0 || td->ep_type != UE_BULK) + continue; + TAILQ_REMOVE(&sc->sc_bus.intr_q.head, xfer, wait_entry); + TAILQ_INSERT_TAIL(&head, xfer, wait_entry); + } TAILQ_CONCAT(&sc->sc_bus.intr_q.head, &head, wait_entry); if ((temp & 7) == 0) { + DPRINTFN(12, "SOF interrupt #%d, needsof=%d\n", - (int)temp, (int)needsof); + (int)temp, (int)sc->sc_needsof); /* update SOF IRQ mask */ if (sc->sc_irq_mask & GINTMSK_SOFMSK) { - if (needsof == 0) { + if (sc->sc_needsof == 0) { sc->sc_irq_mask &= ~GINTMSK_SOFMSK; DWC_OTG_WRITE_4(sc, DOTG_GINTMSK, sc->sc_irq_mask); } } else { - if (needsof != 0) { + if (sc->sc_needsof != 0) { sc->sc_irq_mask |= GINTMSK_SOFMSK; DWC_OTG_WRITE_4(sc, DOTG_GINTMSK, sc->sc_irq_mask); } } + + /* clear need SOF flag */ + sc->sc_needsof = 0; } + return (1); } static void @@ -2669,19 +2578,6 @@ repeat: } } - if (sc->sc_flags.status_device_mode == 0) { - /* update host transfer schedule, so that new transfers can be issued */ - dwc_otg_update_host_transfer_schedule(sc); - - /* start re-scheduled transfers */ - TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) { - if (!dwc_otg_xfer_do_fifo(xfer)) { - /* queue has been modified */ - goto repeat; - } - } - } - if (got_rx_status) { /* check if data was consumed */ if (sc->sc_last_rx_status == 0) @@ -2691,6 +2587,12 @@ repeat: sc->sc_irq_mask &= ~GINTMSK_RXFLVLMSK; DWC_OTG_WRITE_4(sc, DOTG_GINTMSK, sc->sc_irq_mask); } + + if (sc->sc_flags.status_device_mode == 0) { + /* update host transfer schedule, so that new transfers can be issued */ + if (dwc_otg_update_host_transfer_schedule(sc)) + goto repeat; + } } static void @@ -2777,7 +2679,7 @@ dwc_otg_interrupt(struct dwc_otg_softc *sc) sc->sc_flags.port_enabled = 1; /* reset FIFOs */ - dwc_otg_init_fifo(sc, DWC_MODE_DEVICE); + (void) dwc_otg_init_fifo(sc, DWC_MODE_DEVICE); /* reset function address */ dwc_otg_set_address(sc, 0); @@ -2952,11 +2854,12 @@ dwc_otg_setup_standard_chain_sub(struct dwc_otg_std_temp *temp) td->set_toggle = 0; td->got_short = 0; td->did_nak = 0; - td->channel = DWC_OTG_MAX_CHANNELS; + td->channel[0] = DWC_OTG_MAX_CHANNELS; + td->channel[1] = DWC_OTG_MAX_CHANNELS; td->state = 0; td->errcnt = 0; td->tt_scheduled = 0; - td->tt_index = temp->tt_index; + td->tt_channel_tog = 0; td->tt_xactpos = HCSPLT_XACTPOS_BEGIN; } @@ -2965,7 +2868,6 @@ dwc_otg_setup_standard_chain(struct usb_xfer *xfer) { struct dwc_otg_std_temp temp; struct dwc_otg_td *td; - struct usb_device *udev; uint32_t x; uint8_t need_sync; uint8_t is_host; @@ -2976,16 +2878,6 @@ dwc_otg_setup_standard_chain(struct usb_xfer *xfer) temp.max_frame_size = xfer->max_frame_size; - udev = xfer->xroot->udev; - if (udev->parent_hs_hub != NULL && udev->speed != USB_SPEED_HIGH) { - if (udev->parent_hs_hub->ddesc.bDeviceProtocol == UDPROTO_HSHUBMTT) - temp.tt_index = udev->device_index; - else - temp.tt_index = udev->parent_hs_hub->device_index; - } else { - temp.tt_index = udev->device_index; - } - td = xfer->td_start[0]; xfer->td_transfer_first = td; xfer->td_transfer_cache = td; @@ -3170,10 +3062,8 @@ dwc_otg_setup_standard_chain(struct usb_xfer *xfer) struct dwc_otg_softc *sc; uint32_t hcchar; uint32_t hcsplt; - uint8_t xfer_type; sc = DWC_OTG_BUS2SC(xfer->xroot->bus); - xfer_type = xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE; /* get first again */ td = xfer->td_transfer_first; @@ -3181,11 +3071,16 @@ dwc_otg_setup_standard_chain(struct usb_xfer *xfer) hcchar = (xfer->address << HCCHAR_DEVADDR_SHIFT) | - (xfer_type << HCCHAR_EPTYPE_SHIFT) | ((xfer->endpointno & UE_ADDR) << HCCHAR_EPNUM_SHIFT) | (xfer->max_packet_size << HCCHAR_MPS_SHIFT) | HCCHAR_CHENA; + /* XXX stability hack - possible HW issue */ + if (td->ep_type == UE_CONTROL) + hcchar |= (UE_BULK << HCCHAR_EPTYPE_SHIFT); + else + hcchar |= (td->ep_type << HCCHAR_EPTYPE_SHIFT); + if (usbd_get_speed(xfer->xroot->udev) == USB_SPEED_LOW) hcchar |= HCCHAR_LSPDDEV; if (UE_GET_DIR(xfer->endpointno) == UE_DIR_IN) @@ -3204,7 +3099,7 @@ dwc_otg_setup_standard_chain(struct usb_xfer *xfer) } else { hcsplt = 0; } - if (xfer_type == UE_INTERRUPT) { + if (td->ep_type == UE_INTERRUPT) { uint32_t ival; ival = xfer->interval / DWC_OTG_HOST_TIMER_RATE; if (ival == 0) @@ -3213,7 +3108,7 @@ dwc_otg_setup_standard_chain(struct usb_xfer *xfer) ival = 127; td->tmr_val = sc->sc_tmr_val + ival; td->tmr_res = ival; - } else if (xfer_type == UE_ISOCHRONOUS) { + } else if (td->ep_type == UE_ISOCHRONOUS) { td->tmr_val = 0; td->tmr_res = 1; } else { @@ -3223,12 +3118,12 @@ dwc_otg_setup_standard_chain(struct usb_xfer *xfer) break; case USB_SPEED_HIGH: hcsplt = 0; - if (xfer_type == UE_ISOCHRONOUS || - xfer_type == UE_INTERRUPT) { + if (td->ep_type == UE_ISOCHRONOUS || + td->ep_type == UE_INTERRUPT) { hcchar |= ((xfer->max_packet_count & 3) << HCCHAR_MC_SHIFT); } - if (xfer_type == UE_INTERRUPT) { + if (td->ep_type == UE_INTERRUPT) { uint32_t ival; ival = xfer->interval / DWC_OTG_HOST_TIMER_RATE; if (ival == 0) @@ -3237,7 +3132,7 @@ dwc_otg_setup_standard_chain(struct usb_xfer *xfer) ival = 127; td->tmr_val = sc->sc_tmr_val + ival; td->tmr_res = ival; - } else if (xfer_type == UE_ISOCHRONOUS) { + } else if (td->ep_type == UE_ISOCHRONOUS) { td->tmr_val = 0; td->tmr_res = 1 << usbd_xfer_get_fps_shift(xfer); } else { @@ -3446,8 +3341,10 @@ dwc_otg_device_done(struct usb_xfer *xfer, usb_error_t error) td = xfer->td_transfer_first; - if (td != NULL) - dwc_otg_host_channel_free(td); + if (td != NULL) { + dwc_otg_host_channel_free(td, 0); + dwc_otg_host_channel_free(td, 1); + } } /* dequeue transfer and start next transfer */ usbd_transfer_done(xfer, error); @@ -3755,8 +3652,10 @@ dwc_otg_init(struct dwc_otg_softc *sc) sc->sc_host_ch_max); /* setup FIFO */ - if (dwc_otg_init_fifo(sc, sc->sc_mode)) + if (dwc_otg_init_fifo(sc, sc->sc_mode)) { + USB_BUS_UNLOCK(&sc->sc_bus); return (EINVAL); + } /* enable interrupts */ sc->sc_irq_mask = DWC_OTG_MSK_GINT_ENABLED; @@ -4445,7 +4344,7 @@ tr_handle_set_port_feature: usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 16); /* reset FIFOs */ - dwc_otg_init_fifo(sc, DWC_MODE_HOST); + (void) dwc_otg_init_fifo(sc, DWC_MODE_HOST); sc->sc_flags.change_reset = 1; } else { @@ -4555,6 +4454,7 @@ dwc_otg_xfer_setup(struct usb_setup_params *parm) uint32_t ntd; uint32_t n; uint8_t ep_no; + uint8_t ep_type; xfer = parm->curr_xfer; @@ -4572,7 +4472,9 @@ dwc_otg_xfer_setup(struct usb_setup_params *parm) /* * compute maximum number of TDs */ - if ((xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE) == UE_CONTROL) { + ep_type = (xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE); + + if (ep_type == UE_CONTROL) { ntd = xfer->nframes + 1 /* STATUS */ + 1 /* SYNC 1 */ + 1 /* SYNC 2 */ + 1 /* SYNC 3 */; @@ -4624,6 +4526,7 @@ dwc_otg_xfer_setup(struct usb_setup_params *parm) td->max_packet_size = xfer->max_packet_size; td->max_packet_count = xfer->max_packet_count; td->ep_no = ep_no; + td->ep_type = ep_type; td->obj_next = last_obj; last_obj = td; @@ -4659,6 +4562,14 @@ dwc_otg_ep_init(struct usb_device *udev, struct usb_endpoint_descriptor *edesc, /* not supported */ return; } + } else { + if (udev->speed == USB_SPEED_HIGH) { + if ((UGETW(edesc->wMaxPacketSize) >> 11) & 3) { + /* high bandwidth endpoint - not tested */ + DPRINTF("High Bandwidth Endpoint - not tested\n"); + return; + } + } } if ((edesc->bmAttributes & UE_XFERTYPE) == UE_ISOCHRONOUS) ep->methods = &dwc_otg_device_isoc_methods; @@ -4697,29 +4608,8 @@ dwc_otg_get_dma_delay(struct usb_device *udev, uint32_t *pus) static void dwc_otg_device_resume(struct usb_device *udev) { - struct dwc_otg_softc *sc = DWC_OTG_BUS2SC(udev->bus); - struct usb_xfer *xfer; - struct dwc_otg_td *td; - DPRINTF("\n"); - /* Enable relevant Host channels before resuming */ - - USB_BUS_LOCK(udev->bus); - - TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) { - - if (xfer->xroot->udev == udev) { - - td = xfer->td_transfer_cache; - if (td != NULL && - td->channel < DWC_OTG_MAX_CHANNELS) - sc->sc_chan_state[td->channel].suspended = 0; - } - } - - USB_BUS_UNLOCK(udev->bus); - /* poll all transfers again to restart resumed ones */ dwc_otg_do_poll(udev->bus); } @@ -4727,28 +4617,7 @@ dwc_otg_device_resume(struct usb_device *udev) static void dwc_otg_device_suspend(struct usb_device *udev) { - struct dwc_otg_softc *sc = DWC_OTG_BUS2SC(udev->bus); - struct usb_xfer *xfer; - struct dwc_otg_td *td; - DPRINTF("\n"); - - /* Disable relevant Host channels before going to suspend */ - - USB_BUS_LOCK(udev->bus); - - TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) { - - if (xfer->xroot->udev == udev) { - - td = xfer->td_transfer_cache; - if (td != NULL && - td->channel < DWC_OTG_MAX_CHANNELS) - sc->sc_chan_state[td->channel].suspended = 1; - } - } - - USB_BUS_UNLOCK(udev->bus); } static const struct usb_bus_methods dwc_otg_bus_methods = diff --git a/sys/dev/usb/controller/dwc_otg.h b/sys/dev/usb/controller/dwc_otg.h index 2ae2eaeb6014..f2a54a6f9d86 100644 --- a/sys/dev/usb/controller/dwc_otg.h +++ b/sys/dev/usb/controller/dwc_otg.h @@ -34,6 +34,8 @@ #define DWC_OTG_MAX_CHANNELS 16 #define DWC_OTG_MAX_ENDPOINTS 16 #define DWC_OTG_HOST_TIMER_RATE 10 /* ms */ +#define DWC_OTG_TT_SLOT_MAX 8 +#define DWC_OTG_SLOT_IDLE_MAX 4 #define DWC_OTG_READ_4(sc, reg) \ bus_space_read_4((sc)->sc_io_tag, (sc)->sc_io_hdl, reg) @@ -62,8 +64,8 @@ struct dwc_otg_td { uint8_t tmr_res; uint8_t tmr_val; uint8_t ep_no; - uint8_t channel; - uint8_t tt_index; /* TT data */ + uint8_t ep_type; + uint8_t channel[2]; uint8_t tt_start_slot; /* TT data */ uint8_t tt_complete_slot; /* TT data */ uint8_t tt_xactpos; /* TT data */ @@ -86,6 +88,7 @@ struct dwc_otg_td { uint8_t got_short:1; uint8_t did_nak:1; uint8_t tt_scheduled:1; + uint8_t tt_channel_tog:1; }; struct dwc_otg_std_temp { @@ -105,7 +108,6 @@ struct dwc_otg_std_temp { uint8_t setup_alt_next; uint8_t did_stall; uint8_t bulk_or_control; - uint8_t tt_index; }; struct dwc_otg_config_desc { @@ -145,17 +147,11 @@ struct dwc_otg_profile { }; struct dwc_otg_chan_state { + uint16_t allocated; + uint16_t wait_sof; uint32_t hcint; - uint32_t tx_size; - uint8_t wait_sof; - uint8_t allocated; - uint8_t suspended; -}; - -struct dwc_otg_tt_info { - uint16_t bytes_used; - uint8_t slot_index; - uint8_t dummy; + uint16_t tx_p_size; /* periodic */ + uint16_t tx_np_size; /* non-periodic */ }; struct dwc_otg_softc { @@ -177,7 +173,8 @@ struct dwc_otg_softc { uint32_t sc_fifo_size; uint32_t sc_tx_max_size; - uint32_t sc_tx_cur_size; + uint32_t sc_tx_cur_p_level; /* periodic */ + uint32_t sc_tx_cur_np_level; /* non-periodic */ uint32_t sc_irq_mask; uint32_t sc_last_rx_status; uint32_t sc_out_ctl[DWC_OTG_MAX_ENDPOINTS]; @@ -186,7 +183,6 @@ struct dwc_otg_softc { uint32_t sc_tmr_val; uint32_t sc_hprt_val; - struct dwc_otg_tt_info sc_tt_info[DWC_OTG_MAX_DEVICES]; uint16_t sc_active_rx_ep; uint16_t sc_last_frame_num; @@ -194,6 +190,7 @@ struct dwc_otg_softc { uint8_t sc_dev_ep_max; uint8_t sc_dev_in_ep_max; uint8_t sc_host_ch_max; + uint8_t sc_needsof; uint8_t sc_rt_addr; /* root HUB address */ uint8_t sc_conf; /* root HUB config */ uint8_t sc_mode; /* mode of operation */ diff --git a/sys/dev/usb/controller/dwc_otg_fdt.c b/sys/dev/usb/controller/dwc_otg_fdt.c index 78bb801edf5b..d7de56799a88 100644 --- a/sys/dev/usb/controller/dwc_otg_fdt.c +++ b/sys/dev/usb/controller/dwc_otg_fdt.c @@ -146,7 +146,7 @@ dwc_otg_attach(device_t dev) device_set_ivars(sc->sc_otg.sc_bus.bdev, &sc->sc_otg.sc_bus); - err = bus_setup_intr(dev, sc->sc_otg.sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, + err = bus_setup_intr(dev, sc->sc_otg.sc_irq_res, INTR_TYPE_TTY | INTR_MPSAFE, NULL, (driver_intr_t *)dwc_otg_interrupt, sc, &sc->sc_otg.sc_intr_hdl); if (err) { sc->sc_otg.sc_intr_hdl = NULL; diff --git a/sys/dev/usb/controller/dwc_otgreg.h b/sys/dev/usb/controller/dwc_otgreg.h index cd2f45de32a6..344d36a28534 100644 --- a/sys/dev/usb/controller/dwc_otgreg.h +++ b/sys/dev/usb/controller/dwc_otgreg.h @@ -540,7 +540,7 @@ #define HCSPLT_XACTPOS_LAST 1 #define HCSPLT_XACTPOS_BEGIN 2 #define HCSPLT_XACTPOS_ALL 3 -#define HCSPLT_XACTLEN_MAX 188 /* bytes */ +#define HCSPLT_XACTLEN_BURST 1023 /* bytes */ #define HCSPLT_HUBADDR_SHIFT 7 #define HCSPLT_HUBADDR_MASK 0x00003f80 #define HCSPLT_PRTADDR_SHIFT 0 @@ -555,6 +555,9 @@ HCINT_XACTERR | HCINT_NAK | HCINT_ACK | HCINT_NYET | \ HCINT_CHHLTD | HCINT_FRMOVRUN | \ HCINT_DATATGLERR) +#define HCINT_HCH_DONE_MASK \ + (HCINT_ACK | HCINT_RETRY | HCINT_NYET | \ + HCINT_ERRORS | HCINT_STALL | HCINT_SOFTWARE_ONLY) #define HCINT_SOFTWARE_ONLY (1<<20) /* BSD only */ #define HCINT_DATATGLERR (1<<10) -- cgit v1.2.3 From aa06c87e50393b31d460bee564dd743b01190fd6 Mon Sep 17 00:00:00 2001 From: "Alexander V. Chernikov" Date: Fri, 9 May 2014 14:24:02 +0000 Subject: Fix ndp(8) -f flag parsing PR: bin/136661 Reminded by: Vinicius Zavam MFC after: 2 weeks --- usr.sbin/ndp/ndp.8 | 25 +++++++++++++++++++++---- usr.sbin/ndp/ndp.c | 23 ++++++++++++++--------- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/usr.sbin/ndp/ndp.8 b/usr.sbin/ndp/ndp.8 index 19da8bb6e164..c2a4c1de3e22 100644 --- a/usr.sbin/ndp/ndp.8 +++ b/usr.sbin/ndp/ndp.8 @@ -29,7 +29,7 @@ .\" .\" $FreeBSD$ .\" -.Dd Jan 10, 2013 +.Dd May 9, 2014 .Dt NDP 8 .Os .\" @@ -136,9 +136,26 @@ seconds. Erase all the NDP entries. .It Fl d Delete specified NDP entry. -.It Fl f -Parse the file specified by -.Ar filename . +.It Fl f Ar filename +Cause the file +.Ar filename +to be read and multiple entries to be set in the +.Tn NDP +table. +Entries +in the file should be of the form +.Pp +.Bd -ragged -offset indent -compact +.Ar hostname ether_addr +.Op Cm temp +.Op Cm proxy +.Ed +.Pp +with argument meanings as given above. +Leading whitespace and empty lines are ignored. +A +.Ql # +character will mark the rest of the line as a comment. .It Fl H Harmonize consistency between the routing table and the default router list; install the top entry of the list into the kernel routing table. diff --git a/usr.sbin/ndp/ndp.c b/usr.sbin/ndp/ndp.c index 3888b057b857..809d758d6499 100644 --- a/usr.sbin/ndp/ndp.c +++ b/usr.sbin/ndp/ndp.c @@ -97,6 +97,7 @@ #include +#include #include #include #include @@ -126,7 +127,7 @@ char host_buf[NI_MAXHOST]; /* getnameinfo() */ char ifix_buf[IFNAMSIZ]; /* if_indextoname() */ int main(int, char **); -int file(char *); +static int file(char *); void getsocket(void); int set(int, char **); void get(char *); @@ -189,7 +190,8 @@ main(int argc, char **argv) break; case 'd': case 'f': - case 'i' : + exit(file(optarg) ? 1 : 0); + case 'i': if (mode) { usage(); /*NOTREACHED*/ @@ -312,17 +314,15 @@ main(int argc, char **argv) /* * Process a file to set standard ndp entries */ -int +static int file(char *name) { FILE *fp; int i, retval; - char line[100], arg[5][50], *args[5]; + char line[100], arg[5][50], *args[5], *p; - if ((fp = fopen(name, "r")) == NULL) { - fprintf(stderr, "ndp: cannot open %s\n", name); - exit(1); - } + if ((fp = fopen(name, "r")) == NULL) + err(1, "cannot open %s", name); args[0] = &arg[0][0]; args[1] = &arg[1][0]; args[2] = &arg[2][0]; @@ -330,10 +330,15 @@ file(char *name) args[4] = &arg[4][0]; retval = 0; while (fgets(line, sizeof(line), fp) != NULL) { + if ((p = strchr(line, '#')) != NULL) + *p = '\0'; + for (p = line; isblank(*p); p++); + if (*p == '\n' || *p == '\0') + continue; i = sscanf(line, "%49s %49s %49s %49s %49s", arg[0], arg[1], arg[2], arg[3], arg[4]); if (i < 2) { - fprintf(stderr, "ndp: bad line: %s\n", line); + warnx("bad line: %s", line); retval = 1; continue; } -- cgit v1.2.3 From 81c36cd940041f96b1323563db01b7ed79316fcd Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Fri, 9 May 2014 14:28:11 +0000 Subject: Fix for NULL pointer. MFC after: 1 week --- sys/dev/usb/usb_pf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/usb/usb_pf.c b/sys/dev/usb/usb_pf.c index 650f666d0f50..468eafbfda10 100644 --- a/sys/dev/usb/usb_pf.c +++ b/sys/dev/usb/usb_pf.c @@ -395,7 +395,7 @@ usbpf_xfertap(struct usb_xfer *xfer, int type) bus = xfer->xroot->bus; /* sanity checks */ - if (bus->ifp == NULL) + if (bus->ifp == NULL || bus->ifp->if_bpf == NULL) return; if (!bpf_peers_present(bus->ifp->if_bpf)) return; -- cgit v1.2.3 From 827ac19dc212c4ee961696f23f2a6961bb30398b Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Fri, 9 May 2014 14:35:07 +0000 Subject: Invert platform check. Suggested by: imp @ MFC after: 2 weeks --- sys/modules/sound/sound/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/modules/sound/sound/Makefile b/sys/modules/sound/sound/Makefile index cf0b53055ece..0db294bce2e3 100644 --- a/sys/modules/sound/sound/Makefile +++ b/sys/modules/sound/sound/Makefile @@ -44,8 +44,8 @@ CLEANFILES+= feeder_eq_gen.h feeder_rate_gen.h snd_fxdiv_gen.h EXPORT_SYMS= YES # XXX evaluate -.if ${MACHINE_CPUARCH} == "sparc64" || ${MACHINE_CPUARCH} == "powerpc" || \ - ${MACHINE_CPUARCH} == "arm" || ${MACHINE_CPUARCH} == "mips" +.if ${MACHINE_CPUARCH} != "i386" && ${MACHINE_CPUARCH} != "amd64" && \ + ${MACHINE_CPUARCH} != "ia64" && ${MACHINE_CPUARCH} != "pc98" # Create an empty opt_isa.h in order to keep kmod.mk from linking in an # existing one from KERNBUILDDIR which possibly has DEV_ISA defined so # sound.ko is always built without isadma support. -- cgit v1.2.3 From 6052df8ef8f767decb426dceca5be4b419f011ca Mon Sep 17 00:00:00 2001 From: "Alexander V. Chernikov" Date: Fri, 9 May 2014 16:20:55 +0000 Subject: Allow systat(1) interactive dispay-specific commands to be specified via command line. Submitted by: vsevolod MFC after: 2 weeks --- usr.bin/systat/ifstat.c | 29 +++++++++++-------- usr.bin/systat/main.c | 74 ++++++++++++++++++++++++++++++++++++++++++++----- usr.bin/systat/systat.1 | 18 ++++++++++++ 3 files changed, 103 insertions(+), 18 deletions(-) diff --git a/usr.bin/systat/ifstat.c b/usr.bin/systat/ifstat.c index 16328906832a..4cfe01c4d616 100644 --- a/usr.bin/systat/ifstat.c +++ b/usr.bin/systat/ifstat.c @@ -77,7 +77,7 @@ struct if_stat { u_long if_in_pps_peak; u_long if_out_pps_peak; u_int if_row; /* Index into ifmib sysctl */ - u_int if_ypos; /* 0 if not being displayed */ + int if_ypos; /* -1 if not being displayed */ u_int display; u_int match; }; @@ -210,13 +210,19 @@ showifstat(void) struct if_stat *ifp = NULL; SLIST_FOREACH(ifp, &curlist, link) { - if (ifp->display == 0 || (ifp->match == 0) || - ifp->if_ypos > LINES - 3 - 1) - continue; - PUTNAME(ifp); - PUTRATE(col2, ifp->if_ypos); - PUTRATE(col3, ifp->if_ypos); - PUTTOTAL(col4, ifp->if_ypos); + if (ifp->if_ypos < LINES - 3 && ifp->if_ypos != -1) + if (ifp->display == 0 || ifp->match == 0) { + wmove(wnd, ifp->if_ypos, 0); + wclrtoeol(wnd); + wmove(wnd, ifp->if_ypos + 1, 0); + wclrtoeol(wnd); + } + else { + PUTNAME(ifp); + PUTRATE(col2, ifp->if_ypos); + PUTRATE(col3, ifp->if_ypos); + PUTTOTAL(col4, ifp->if_ypos); + } } return; @@ -425,6 +431,8 @@ sort_interface_list(void) ifp->if_ypos = y; y += ROW_SPACING; } + else + ifp->if_ypos = -1; } needsort = 0; @@ -476,14 +484,13 @@ cmdifstat(const char *cmd, const char *args) retval = ifcmd(cmd, args); /* ifcmd() returns 1 on success */ if (retval == 1) { - showifstat(); - refresh(); if (needclear) { + showifstat(); + refresh(); werase(wnd); labelifstat(); needclear = 0; } } - return (retval); } diff --git a/usr.bin/systat/main.c b/usr.bin/systat/main.c index 8417811e222e..e80dc6133808 100644 --- a/usr.bin/systat/main.c +++ b/usr.bin/systat/main.c @@ -44,6 +44,7 @@ static const char copyright[] = #include #include #include +#include #include #include @@ -53,6 +54,7 @@ static const char copyright[] = #include #include #include +#include #include #include "systat.h" @@ -77,12 +79,67 @@ int use_kvm = 1; static WINDOW *wload; /* one line window for load average */ +struct cmdentry { + SLIST_ENTRY(cmdentry) link; + char *cmd; /* Command name */ + char *argv; /* Arguments vector for a command */ +}; +SLIST_HEAD(, cmdentry) commands; + +static void +parse_cmd_args (int argc, char **argv) +{ + int in_command = 0; + struct cmdentry *cmd = NULL; + double t; + + while (argc) { + if (argv[0][0] == '-') { + if (in_command) + SLIST_INSERT_HEAD(&commands, cmd, link); + + if (memcmp(argv[0], "--", 3) == 0) { + in_command = 0; /*-- ends a command explicitly*/ + argc --, argv ++; + continue; + } + cmd = calloc(1, sizeof(struct cmdentry)); + if (cmd == NULL) + errx(1, "memory allocating failure"); + cmd->cmd = strdup(&argv[0][1]); + if (cmd->cmd == NULL) + errx(1, "memory allocating failure"); + in_command = 1; + } + else if (!in_command) { + t = strtod(argv[0], NULL) * 1000000.0; + if (t > 0 && t < (double)UINT_MAX) + delay = (unsigned int)t; + } + else if (cmd != NULL) { + cmd->argv = strdup(argv[0]); + if (cmd->argv == NULL) + errx(1, "memory allocating failure"); + in_command = 0; + SLIST_INSERT_HEAD(&commands, cmd, link); + } + else + errx(1, "invalid arguments list"); + + argc--, argv++; + } + if (in_command && cmd != NULL) + SLIST_INSERT_HEAD(&commands, cmd, link); + +} + int main(int argc, char **argv) { char errbuf[_POSIX2_LINE_MAX], dummy; size_t size; double t; + struct cmdentry *cmd = NULL; #ifdef USE_WIDECHAR (void) setlocale(LC_ALL, ""); @@ -90,8 +147,9 @@ main(int argc, char **argv) (void) setlocale(LC_TIME, ""); #endif + SLIST_INIT(&commands); argc--, argv++; - while (argc > 0) { + if (argc > 0) { if (argv[0][0] == '-') { struct cmdtab *p; @@ -101,12 +159,10 @@ main(int argc, char **argv) if (p == (struct cmdtab *)0) errx(1, "%s: unknown request", &argv[0][1]); curcmd = p; - } else { - t = strtod(argv[0], NULL) * 1000000.0; - if (t > 0 && t < (double)UINT_MAX) - delay = (unsigned int)t; + argc--, argv++; } - argc--, argv++; + parse_cmd_args (argc, argv); + } kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf); if (kd != NULL) { @@ -169,8 +225,12 @@ main(int argc, char **argv) curcmd->c_flags |= CF_INIT; labels(); - dellave = 0.0; + if (curcmd->c_cmd != NULL) + SLIST_FOREACH (cmd, &commands, link) + if (!curcmd->c_cmd(cmd->cmd, cmd->argv)) + warnx("command is not understood"); + dellave = 0.0; display(); noecho(); crmode(); diff --git a/usr.bin/systat/systat.1 b/usr.bin/systat/systat.1 index 9c144e7e2325..5fc3257c59b5 100644 --- a/usr.bin/systat/systat.1 +++ b/usr.bin/systat/systat.1 @@ -37,6 +37,7 @@ .Sh SYNOPSIS .Nm .Op Fl display +.Op Ar display-commands .Op Ar refresh-interval .Sh DESCRIPTION The @@ -108,6 +109,23 @@ The .Ar refresh-value specifies the screen refresh time interval in seconds. Time interval can be fractional. +.It Ar display-commands +A list of commands specific for this display. These commands can also +be entered interactively and are described for each display separately +below. If the command of the display requires an argument or arguments, +it is possible to specify them as separate command line argument. To finish +display commands it is possible to use double dash at the end +of the list. For example: +.Pp +.Dl Nm Fl ifstat Fl match Ar bge0,em1 Fl pps +.Pp +This will display statistics of packets per second for network interfaces +named as bge0 and em1. +.Pp +.Dl Nm Fl iostat Fl numeric Fl - Ar 2.1 +.Pp +This will display all IO statistics in a numeric format and the information +will be refreshed each 2.1 seconds. .El .Pp Certain characters cause immediate action by -- cgit v1.2.3 From 897b7965df2d9fc0ccd49a70dcc048d5234482cb Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Fri, 9 May 2014 16:40:41 +0000 Subject: Fix a regression issue: - ACK can be received before data arrives in RX FIFO. Handle this. - Remove obsolete comment. - Some minor code styling. MFC after: 2 weeks --- sys/dev/usb/controller/dwc_otg.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sys/dev/usb/controller/dwc_otg.c b/sys/dev/usb/controller/dwc_otg.c index 3f4d3a00047c..0b203ddd1e64 100644 --- a/sys/dev/usb/controller/dwc_otg.c +++ b/sys/dev/usb/controller/dwc_otg.c @@ -1240,6 +1240,10 @@ check_state: goto complete; } } else if (hcint & HCINT_ACK) { + /* wait for data - ACK arrived first */ + if (!(hcint & HCINT_SOFTWARE_ONLY)) + goto busy; + if (td->ep_type == UE_ISOCHRONOUS) { /* check if we are complete */ if ((td->remainder == 0) || @@ -1595,8 +1599,6 @@ dwc_otg_host_data_tx(struct dwc_otg_td *td) } } - /* channel must be disabled before we can complete the transfer */ - if (hcint & (HCINT_ERRORS | HCINT_RETRY | HCINT_ACK | HCINT_NYET)) { @@ -1646,15 +1648,13 @@ check_state: break; case DWC_CHAN_ST_WAIT_C_ANE: - if (hcint & HCINT_NYET) + if (hcint & HCINT_NYET) { goto send_cpkt; - - if (hcint & (HCINT_RETRY | HCINT_ERRORS)) { + } else if (hcint & (HCINT_RETRY | HCINT_ERRORS)) { td->did_nak = 1; td->tt_scheduled = 0; goto send_pkt; - } - if (hcint & HCINT_ACK) { + } else if (hcint & HCINT_ACK) { td->offset += td->tx_bytes; td->remainder -= td->tx_bytes; td->toggle ^= 1; -- cgit v1.2.3 From dfd03689d774abce8280675623b3a116113b5530 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Fri, 9 May 2014 19:14:34 +0000 Subject: Call idcache_inv_all from the AP core entry code before turning on the MMU. Also, enable instruction and branch caches, which should be safe now that they're properly initialized/invalidated first. --- sys/arm/arm/cpufunc_asm_armv7.S | 4 ++++ sys/arm/arm/locore.S | 21 ++++++++++++--------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/sys/arm/arm/cpufunc_asm_armv7.S b/sys/arm/arm/cpufunc_asm_armv7.S index 45f4593cff57..71e9ca5d8d1b 100644 --- a/sys/arm/arm/cpufunc_asm_armv7.S +++ b/sys/arm/arm/cpufunc_asm_armv7.S @@ -319,6 +319,10 @@ ENTRY(armv7_auxctrl) RET END(armv7_auxctrl) +/* + * Invalidate all I+D+branch cache. Used by startup code, which counts + * on the fact that only r0-r3,ip are modified and no stack space is used. + */ ENTRY(armv7_idcache_inv_all) mov r0, #0 mcr p15, 2, r0, c0, c0, 0 @ set cache level to L1 diff --git a/sys/arm/arm/locore.S b/sys/arm/arm/locore.S index ad4204b82628..3a6c3c5368aa 100644 --- a/sys/arm/arm/locore.S +++ b/sys/arm/arm/locore.S @@ -353,24 +353,24 @@ ASENTRY_NP(mpentry) orr r7, r7, #(I32_bit|F32_bit) msr cpsr_c, r7 - - adr r7, Ltag - bic r7, r7, #0xf0000000 - orr r7, r7, #PHYSADDR - - /* Disable MMU for a while */ + /* Disable MMU. It should be disabled already, but make sure. */ mrc p15, 0, r2, c1, c0, 0 bic r2, r2, #(CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE |\ CPU_CONTROL_WBUF_ENABLE) bic r2, r2, #(CPU_CONTROL_IC_ENABLE) bic r2, r2, #(CPU_CONTROL_BPRD_ENABLE) mcr p15, 0, r2, c1, c0, 0 - nop nop nop + CPWAIT(r0) + +#if defined(ARM_MMU_V6) + bl armv6_idcache_inv_all /* Modifies r0 only */ +#elif defined(ARM_MMU_V7) + bl armv7_idcache_inv_all /* Modifies r0-r3, ip */ +#endif -Ltag: ldr r0, Lstartup_pagetable_secondary bic r0, r0, #0xf0000000 orr r0, r0, #PHYSADDR @@ -389,7 +389,10 @@ Ltag: mrc p15, 0, r0, c1, c0, 0 orr r0, r0, #CPU_CONTROL_V6_EXTPAGE orr r0, r0, #CPU_CONTROL_AF_ENABLE - orr r0, r0, #(CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE) + orr r0, r0, #(CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE |\ + CPU_CONTROL_WBUF_ENABLE) + orr r0, r0, #(CPU_CONTROL_IC_ENABLE) + orr r0, r0, #(CPU_CONTROL_BPRD_ENABLE) mcr p15, 0, r0, c1, c0, 0 nop nop -- cgit v1.2.3 From 22cac7546cddcaeeafe93a44cac5f0b3dd472945 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 9 May 2014 21:11:27 +0000 Subject: Introduce kern.opts.mk to hold all the options for kernel module builds. Include this in the right places. Make src.opts.mk optional so that modules can be built outside of the tree in the ports system. PR: 189520 --- share/mk/src.opts.mk | 4 +--- sys/conf/kern.opts.mk | 24 ++++++++++++++++++++++++ sys/conf/kern.pre.mk | 1 + sys/conf/kmod.mk | 8 +++++++- 4 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 sys/conf/kern.opts.mk diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk index 72d13c058241..17b3fa97d37e 100644 --- a/share/mk/src.opts.mk +++ b/share/mk/src.opts.mk @@ -24,7 +24,7 @@ # # Makefiles should never test WITH_FOO or WITHOUT_FOO directly (although an # exception is made for _WITHOUT_SRCONF which turns off this mechanism -# completely). +# completely inside bsd.*.mk files). # .if !target(____) @@ -84,7 +84,6 @@ __DEFAULT_YES_OPTIONS = \ FDT \ FLOPPY \ FMTREE \ - FORMAT_EXTENSIONS \ FORTH \ FP_LIBC \ FREEBSD_UPDATE \ @@ -105,7 +104,6 @@ __DEFAULT_YES_OPTIONS = \ IPFW \ JAIL \ KDUMP \ - KERNEL_SYMBOLS \ KVM \ LDNS \ LDNS_UTILS \ diff --git a/sys/conf/kern.opts.mk b/sys/conf/kern.opts.mk new file mode 100644 index 000000000000..fe7f5b0106b7 --- /dev/null +++ b/sys/conf/kern.opts.mk @@ -0,0 +1,24 @@ +# $FreeBSD$ + +# Options set in the build system that affect the kernel somehow. + +# +# Define MK_* variables (which are either "yes" or "no") for users +# to set via WITH_*/WITHOUT_* in /etc/src.conf and override in the +# make(1) environment. +# These should be tested with `== "no"' or `!= "no"' in makefiles. +# The NO_* variables should only be set by makefiles for variables +# that haven't been converted over. +# + +# These options are used by the kernel build process (kern.mk and kmod.mk) +# They have to be listed here so we can build modules outside of the +# src tree. + +__DEFAULT_YES_OPTIONS = \ + FORMAT_EXTENTIONS \ + KERNEL_SYMBOLS + +__DEFAULT_NO_OPTIONS = \ + +.include "../../share/mk/bsd.mkopt.mk" diff --git a/sys/conf/kern.pre.mk b/sys/conf/kern.pre.mk index 1b7c49dbd6dc..343be5742699 100644 --- a/sys/conf/kern.pre.mk +++ b/sys/conf/kern.pre.mk @@ -5,6 +5,7 @@ .include .include +.include "kern.opts.mk" # backwards compat option for older systems. MACHINE_CPUARCH?=${MACHINE_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc64/powerpc/} diff --git a/sys/conf/kmod.mk b/sys/conf/kmod.mk index f65d6763b777..ebd6179d8453 100644 --- a/sys/conf/kmod.mk +++ b/sys/conf/kmod.mk @@ -72,9 +72,15 @@ OBJCOPY?= objcopy .error "Do not use KMODDEPS on 5.0+; use MODULE_VERSION/MODULE_DEPEND" .endif -.include +# Note: we're really bsd.kmod.mk, so we have to allow src.opts.mk to be +# optional. Include it if we can so we can get /etc/src.conf changes, +# if we're in the tree. If we can't include it that's OK. kern.opts.mk +# has all the kernel options in it, and should be included after src.opts.mk +# so it picks everything up. +.sinclude .include .include +.include "kern.opts.mk" .SUFFIXES: .out .o .c .cc .cxx .C .y .l .s .S -- cgit v1.2.3 From 5a701e995354911cb7a773586c0b26b08e3ae858 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 10 May 2014 00:42:43 +0000 Subject: Fix typo in FORMAT_EXTENSIONS which breaks universe. --- sys/conf/kern.opts.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/conf/kern.opts.mk b/sys/conf/kern.opts.mk index fe7f5b0106b7..b3ce90eaf223 100644 --- a/sys/conf/kern.opts.mk +++ b/sys/conf/kern.opts.mk @@ -16,7 +16,7 @@ # src tree. __DEFAULT_YES_OPTIONS = \ - FORMAT_EXTENTIONS \ + FORMAT_EXTENSIONS \ KERNEL_SYMBOLS __DEFAULT_NO_OPTIONS = \ -- cgit v1.2.3 From ac75ee9fa3027e2353cf38ae0bd3ed4ad69d1d63 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sat, 10 May 2014 00:53:36 +0000 Subject: Add in support to optionally pin the swi threads. Under enough load, the swi's can actually be preempted and migrated to other currently free cores. When doing RSS experiments, this lead to the per-CPU TCP timers not lining up any more with the RX CPU said flows were ending up on, leading to increased lock contention. Since there was a little pushback on flipping them on by default, I've left the default at "don't pin." The other less obvious problem here is that the default swi is also the same as the destination swi for CPU #0. So if one pins the swi on CPU #0, there's no default floating swi. A nice future project would be to create a separate swi for the "default" floating swi, as well as per-CPU swis that are (optionally) pinned. Tested: * parallel TCP tests (2 x 1g unfortunately for now); CPU: Intel(R) Xeon(R) CPU E5-2650 Note: This is based on some initial investigation into RSS/TCP stack lock contention on FreeBSD-HEAD whilst at Netflix in January 2014. --- sys/kern/kern_timeout.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/sys/kern/kern_timeout.c b/sys/kern/kern_timeout.c index ad6db5bcc44c..ef20ed109c91 100644 --- a/sys/kern/kern_timeout.c +++ b/sys/kern/kern_timeout.c @@ -104,6 +104,14 @@ static int ncallout; SYSCTL_INT(_kern, OID_AUTO, ncallout, CTLFLAG_RDTUN, &ncallout, 0, "Number of entries in callwheel and size of timeout() preallocation"); +static int pin_default_swi = 0; +static int pin_pcpu_swi = 0; + +SYSCTL_INT(_kern, OID_AUTO, pin_default_swi, CTLFLAG_RDTUN, &pin_default_swi, + 0, "Pin the default (non-per-cpu) swi (shared with PCPU 0 swi)"); +SYSCTL_INT(_kern, OID_AUTO, pin_pcpu_swi, CTLFLAG_RDTUN, &pin_pcpu_swi, + 0, "Pin the per-CPU swis (except PCPU 0, which is also default"); + /* * TODO: * allocate more timeout table slots when table overflows. @@ -272,6 +280,12 @@ callout_callwheel_init(void *dummy) callwheelsize = 1 << fls(ncallout); callwheelmask = callwheelsize - 1; + /* + * Fetch whether we're pinning the swi's or not. + */ + TUNABLE_INT_FETCH("kern.pin_default_swi", &pin_default_swi); + TUNABLE_INT_FETCH("kern.pin_pcpu_swi", &pin_pcpu_swi); + /* * Only cpu0 handles timeout(9) and receives a preallocation. * @@ -355,6 +369,7 @@ start_softclock(void *dummy) char name[MAXCOMLEN]; #ifdef SMP int cpu; + struct intr_event *ie; #endif cc = CC_CPU(timeout_cpu); @@ -362,6 +377,13 @@ start_softclock(void *dummy) if (swi_add(&clk_intr_event, name, softclock, cc, SWI_CLOCK, INTR_MPSAFE, &cc->cc_cookie)) panic("died while creating standard software ithreads"); + if (pin_default_swi && + (intr_event_bind(clk_intr_event, timeout_cpu) != 0)) { + printf("%s: timeout clock couldn't be pinned to cpu %d\n", + __func__, + timeout_cpu); + } + #ifdef SMP CPU_FOREACH(cpu) { if (cpu == timeout_cpu) @@ -370,9 +392,16 @@ start_softclock(void *dummy) cc->cc_callout = NULL; /* Only cpu0 handles timeout(9). */ callout_cpu_init(cc); snprintf(name, sizeof(name), "clock (%d)", cpu); - if (swi_add(NULL, name, softclock, cc, SWI_CLOCK, + ie = NULL; + if (swi_add(&ie, name, softclock, cc, SWI_CLOCK, INTR_MPSAFE, &cc->cc_cookie)) panic("died while creating standard software ithreads"); + if (pin_pcpu_swi && (intr_event_bind(ie, cpu) != 0)) { + printf("%s: per-cpu clock couldn't be pinned to " + "cpu %d\n", + __func__, + cpu); + } } #endif } -- cgit v1.2.3 From abebc22f2c8b0076f56247430ae6bc118d468818 Mon Sep 17 00:00:00 2001 From: Warren Block Date: Sat, 10 May 2014 03:24:45 +0000 Subject: Add a man page for the new vt.4 device. Reviewed by: ray, emaste (slightly earlier version) --- share/man/man4/vt.4 | 230 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 share/man/man4/vt.4 diff --git a/share/man/man4/vt.4 b/share/man/man4/vt.4 new file mode 100644 index 000000000000..58ee10535532 --- /dev/null +++ b/share/man/man4/vt.4 @@ -0,0 +1,230 @@ +.\" Copyright (c) 2014 Warren Block +.\" 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 AUTHORS 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 AUTHORS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd May 9, 2014 +.Dt VIRTUAL TERMINALS 4 +.Os +.Sh NAME +.Nm vt +.Nd virtual terminal console driver +.Sh SYNOPSIS +.Cd "options VT_MAXWINDOWS=N" +.Cd "options VT_ALT_TO_ESC_HACK=1" +.Cd "options VT_TWOBUTTON_MOUSE" +.Cd "options VT_FB_DEFAULT_WIDTH=X" +.Cd "options VT_FB_DEFAULT_HEIGHT=Y" +.Cd "options SC_NO_CUTPASTE" +.Cd "options SC_NO_SYSMOUSE" +.Cd "device vt" +.Pp +In +.Xr loader.conf 5 : +.Cd hw.vga.textmode=1 +.Sh DESCRIPTION +The +.Nm +device provides multiple virtual terminals with an extensive feature +set: +.Bl -item -offset indent +.It +Unicode UTF-8 text with double-width characters. +.It +Large font maps in graphics mode, including support for Asian +character sets. +.It +Graphics-mode consoles. +.It +Integration with +KMS +.Pq Kernel Mode Setting +video drivers for switching between the +.Em X Window System +and virtual terminals. +.El +.Ss Virtual Terminals +Multiple virtual terminals are provided on a single computer. +Up to sixteen virtual terminals can be defined. +A single virtual terminal is connected to the screen and keyboard +at a time. +Key combinations are used to select a virtual terminal. +Alt-F1 through Alt-F12 correspond to the first twelve virtual terminals. +If more than twelve virtual terminals are created, Shift-Alt-F1 through +Shift-Alt-F4 are used to switch to the additional terminals. +.Ss Copying and Pasting Text with a Mouse +Copying and pasting text from the screen with a mouse is supported. +Press and hold down mouse button 1, usually the left button, while +moving the mouse to select text. +Selected text is highlighted with reversed foreground and background +colors. +To select more text after releasing mouse button 1, press mouse button +3, usually the right button. +To paste text that has been selected, press mouse button 2, usually the +middle button. +The text is entered as if it were typed at the keyboard. +The +.Dv VT_TWOBUTTON_MOUSE +kernel option can be used with mice that only have two buttons. +Setting this option makes the second mouse button into the +paste button. +See +.Xr moused 8 +for more information. +.Ss Scrolling Back +Output that has scrolled off the screen can be reviewed by pressing the +Scroll Lock key, then scrolling up and down with the arrow keys. +The Page Up and Page Down keys scroll up or down a full screen at a +time. +The Home and End keys jump to the beginning or end of the scrollback +buffer. +When finished reviewing, press the Scroll Lock key again to return to +normal use. +.Sh DRIVER CONFIGURATION +.Ss Kernel Configuration Options +These kernel options control the +.Nm +driver. +.Bl -tag -width MAXCONS +.It Dv VT_MAXWINDOWS=N +Set the number of virtual terminals to be created to +.Fa N . +The value defaults to 12. +.It Dv VT_ALT_TO_ESC_HACK=1 +When the Alt key is held down while pressing another key, send an ESC +sequence instead of the Alt key. +.It Dv VT_TWOBUTTON_MOUSE +If defined, swap the functions of mouse buttons 2 and 3. +In effect, this makes the right-hand mouse button perform a paste. +These options are checked in the order shown. +.It Dv SC_NO_CUTPASTE +Disable mouse support. +.It VT_FB_DEFAULT_WIDTH=X +Set the default width to +.Fa X . +.It VT_FB_DEFAULT_HEIGHT=Y +Set the default height to +.Fa Y . +.El +.Sh BACKWARDS COMPATIBILITY +Several options are provided for compatibility with the previous +console device, +.Xr sc 4 . +These options will be removed in a future +.Fx +version. +.Bl -column -offset indent ".Sy vt VT_TWOBUTTON_MOUSE" ".Sy SC_TWOBUTTON_MOUSE" +.It Sy vt Option Name Ta Sy sc Option Name +.It Dv VT_TWOBUTTON_MOUSE Ta Dv SC_TWOBUTTON_MOUSE +.It Dv VT_MAXWINDOWS Ta Dv MAXCONS +.It none Ta Dv SC_NO_CUTPASTE +.It none Ta Dv SC_NO_SYSMOUSE +.El +.Sh START-UP OPERATION WITH X86 BIOS SYSTEMS +The computer BIOS starts in text mode, and +the +.Fx +.Xr loader 8 +runs, loading the kernel. +If +.Va hw.vga.textmode +is set, the system remains in text mode. +Otherwise, +.Nm +switches to 640x480x16 VGA mode using +.Fn vt_vga . +If a KMS +.Pq Kernel Mode Switching +video driver is available, the display is switched to high resolution +and the KMS driver takes over. +When a KMS driver is not available, +.Fn vt_vga +remains active. +.Sh LOADER TUNABLES +These settings can be entered at the +.Xr loader 8 +prompt or in +.Xr loader.conf 5 . +.Bl -tag -width indent +.It Va hw.vga.textmode +Set to 1 to use virtual terminals in text mode instead of graphics mode. +Features that require graphics mode, like loadable fonts, will be +disabled. +.El +.Sh FILES +.Bl -tag -width /usr/share/syscons/keymaps/* -compact +.It Pa /dev/console +.It Pa /dev/consolectl +.It Pa /dev/ttyv* +virtual terminals +.It Pa /etc/ttys +terminal initialization information +.El +.Sh SEE ALSO +.Xr kbdcontrol 1 , +.Xr login 1 , +.Xr vidcontrol 1 , +.Xr atkbd 4 , +.Xr atkbdc 4 , +.Xr keyboard 4 , +.Xr screen 4 , +.Xr splash 4 , +.Xr syscons 4 , +.Xr ukbd 4 , +.Xr vga 4 , +.Xr kbdmap 5 , +.Xr rc.conf 5 , +.Xr ttys 5 , +.Xr config 8 , +.Xr getty 8 , +.Xr kbdmux 8 , +.Xr kldload 8 , +.Xr moused 8 +.\" WB: to be uncommented when an actual release contains vt(4) +.\" .Sh HISTORY +.\" The +.\" Nm +.\" driver first appeared in +.\" .Fx 9.3 . +.Sh AUTHORS +.An -nosplit +The +.Nm +device driver was developed by +.An Ed Schouten Aq ed@FreeBSD.org , +.An Ed Maste Aq emaste@FreeBSD.org , +and +.An Aleksandr Rybalko Aq ray@FreeBSD.org , +with sponsorship provided by the +.Fx +Foundation. +This manual page was written by +.An Warren Block . +.Sh CAVEATS +Paste buffer size is limited by the system value +.Brq Dv MAX_INPUT , +the number of bytes that can be stored in the terminal +input queue, usually 1024 bytes +(see +.Xr termios 4 ) . -- cgit v1.2.3 From fa5ff59a784cc1c78d654150e0a89c93a42a24c6 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sat, 10 May 2014 05:56:10 +0000 Subject: Fix the required calibration flags for the Centrino 1000 NIC. --- sys/dev/iwn/if_iwn_chip_cfg.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sys/dev/iwn/if_iwn_chip_cfg.h b/sys/dev/iwn/if_iwn_chip_cfg.h index 8d518bb2c09e..67eba898a193 100644 --- a/sys/dev/iwn/if_iwn_chip_cfg.h +++ b/sys/dev/iwn/if_iwn_chip_cfg.h @@ -219,14 +219,16 @@ static const struct iwn_base_params iwn1000_base_params = { .regulatory_bands = iwn5000_regulatory_bands, .enhanced_TX_power = false, .calib_need = - ( IWN_FLG_NEED_PHY_CALIB_DC - | IWN_FLG_NEED_PHY_CALIB_LO + ( IWN_FLG_NEED_PHY_CALIB_LO + | IWN_FLG_NEED_PHY_CALIB_TX_IQ_PERIODIC | IWN_FLG_NEED_PHY_CALIB_TX_IQ - | IWN_FLG_NEED_PHY_CALIB_BASE_BAND ), + | IWN_FLG_NEED_PHY_CALIB_BASE_BAND + ), .support_hostap = false, .no_multi_vaps = true, .additional_gp_drv_bit = IWN_GP_DRIVER_NONE, - .bt_mode = IWN_BT_NONE, + /* XXX 1000 - no BT */ + .bt_mode = IWN_BT_SIMPLE, .plcp_err_threshold = IWN_PLCP_ERR_EXT_LONG_THRESHOLD, }; static const struct iwn_base_params iwn_6000_base_params = { -- cgit v1.2.3 From e2192fdfc691176d1280cadb9f8d22ba1bbe2351 Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Sat, 10 May 2014 07:37:32 +0000 Subject: Optimise host channel disabling: - For non-periodic traffic we only need to wait two SOFs before disabling the channel. - Make sure we release the TX FIFO tracking level after the host channel is disabled. - Make sure the host channel state gets reset/disabled initially. - Two minor code style changes. MFC after: 2 weeks --- sys/dev/usb/controller/dwc_otg.c | 105 +++++++++++++++++++++++++-------------- sys/dev/usb/controller/dwc_otg.h | 1 + 2 files changed, 68 insertions(+), 38 deletions(-) diff --git a/sys/dev/usb/controller/dwc_otg.c b/sys/dev/usb/controller/dwc_otg.c index 0b203ddd1e64..c225bac7fb68 100644 --- a/sys/dev/usb/controller/dwc_otg.c +++ b/sys/dev/usb/controller/dwc_otg.c @@ -141,6 +141,7 @@ static void dwc_otg_do_poll(struct usb_bus *); static void dwc_otg_standard_done(struct usb_xfer *); static void dwc_otg_root_intr(struct dwc_otg_softc *); static void dwc_otg_interrupt_poll(struct dwc_otg_softc *); +static void dwc_otg_host_channel_disable(struct dwc_otg_softc *, uint8_t); /* * Here is a configuration that the chip supports. @@ -210,6 +211,13 @@ dwc_otg_init_fifo(struct dwc_otg_softc *sc, uint8_t mode) return (EINVAL); } + /* disable any leftover host channels */ + for (x = 0; x != sc->sc_host_ch_max; x++) { + if (sc->sc_chan_state[x].wait_sof == 0) + continue; + dwc_otg_host_channel_disable(sc, x); + } + if (mode == DWC_MODE_HOST) { /* reset active endpoints */ @@ -236,6 +244,9 @@ dwc_otg_init_fifo(struct dwc_otg_softc *sc, uint8_t mode) ((fifo_size / 4) << 16) | (tx_start / 4)); + /* reset host channel state */ + memset(sc->sc_chan_state, 0, sizeof(sc->sc_chan_state)); + /* reset FIFO TX levels */ sc->sc_tx_cur_p_level = 0; sc->sc_tx_cur_np_level = 0; @@ -326,6 +337,9 @@ dwc_otg_init_fifo(struct dwc_otg_softc *sc, uint8_t mode) /* reset periodic and non-periodic FIFO TX size */ sc->sc_tx_max_size = fifo_size; + /* reset host channel state */ + memset(sc->sc_chan_state, 0, sizeof(sc->sc_chan_state)); + /* reset FIFO TX levels */ sc->sc_tx_cur_p_level = 0; sc->sc_tx_cur_np_level = 0; @@ -569,7 +583,7 @@ dwc_otg_clear_hcint(struct dwc_otg_softc *sc, uint8_t x) } static uint8_t -dwc_otg_host_channel_alloc(struct dwc_otg_td *td, uint8_t which) +dwc_otg_host_channel_alloc(struct dwc_otg_td *td, uint8_t which, uint8_t is_out) { struct dwc_otg_softc *sc; uint32_t tx_p_size; @@ -587,11 +601,7 @@ dwc_otg_host_channel_alloc(struct dwc_otg_td *td, uint8_t which) sc = DWC_OTG_PC2SC(td->pc); /* compute needed TX FIFO size */ - if (td->ep_type == UE_CONTROL) { - /* RX and TX transactions */ - tx_p_size = 0; - tx_np_size = td->max_packet_size; - } else if ((td->hcchar & HCCHAR_EPDIR) == HCCHAR_EPDIR_OUT) { + if (is_out != 0) { if (td->ep_type == UE_INTERRUPT || td->ep_type == UE_ISOCHRONOUS) { tx_p_size = td->max_packet_size; @@ -669,12 +679,22 @@ dwc_otg_host_channel_free(struct dwc_otg_td *td, uint8_t which) /* get pointer to softc */ sc = DWC_OTG_PC2SC(td->pc); - sc->sc_chan_state[x].wait_sof = DWC_OTG_SLOT_IDLE_MAX; - sc->sc_chan_state[x].allocated = 0; - /* keep track of used TX FIFO, if any */ - sc->sc_tx_cur_p_level -= sc->sc_chan_state[x].tx_p_size; - sc->sc_tx_cur_np_level -= sc->sc_chan_state[x].tx_np_size; + /* + * We need to let programmed host channels run till complete + * else the host channel will stop functioning. Assume that + * after a fixed given amount of time the host channel is no + * longer doing any USB traffic: + */ + if (td->ep_type == UE_ISOCHRONOUS || td->ep_type == UE_INTERRUPT) { + /* double buffered */ + sc->sc_chan_state[x].wait_sof = DWC_OTG_SLOT_IDLE_MAX; + } else { + /* single buffered */ + sc->sc_chan_state[x].wait_sof = DWC_OTG_SLOT_IDLE_MIN; + } + + sc->sc_chan_state[x].allocated = 0; /* ack any pending messages */ if (sc->sc_last_rx_status != 0 && @@ -810,7 +830,7 @@ send_pkt: } /* allocate a new channel */ - if (dwc_otg_host_channel_alloc(td, 0)) { + if (dwc_otg_host_channel_alloc(td, 0, 1)) { td->state = DWC_CHAN_ST_START; goto busy; } @@ -863,7 +883,7 @@ send_cpkt: goto complete; } /* allocate a new channel */ - if (dwc_otg_host_channel_alloc(td, 0)) { + if (dwc_otg_host_channel_alloc(td, 0, 0)) { td->state = DWC_CHAN_ST_WAIT_C_PKT; goto busy; } @@ -1322,7 +1342,7 @@ receive_pkt: } /* allocate a new channel */ - if (dwc_otg_host_channel_alloc(td, td->tt_channel_tog)) { + if (dwc_otg_host_channel_alloc(td, td->tt_channel_tog, 0)) { td->state = DWC_CHAN_ST_WAIT_C_PKT; goto busy; } @@ -1404,7 +1424,7 @@ receive_spkt: } /* allocate a new channel */ - if (dwc_otg_host_channel_alloc(td, 0)) { + if (dwc_otg_host_channel_alloc(td, 0, 0)) { td->state = DWC_CHAN_ST_START; goto busy; } @@ -1616,8 +1636,7 @@ check_state: td->did_nak = 1; td->tt_scheduled = 0; goto send_pkt; - } - if (hcint & (HCINT_ACK | HCINT_NYET)) { + } else if (hcint & (HCINT_ACK | HCINT_NYET)) { td->offset += td->tx_bytes; td->remainder -= td->tx_bytes; td->toggle ^= 1; @@ -1642,8 +1661,7 @@ check_state: td->did_nak = 1; td->tt_scheduled = 0; goto send_pkt; - } - if (hcint & (HCINT_ACK | HCINT_NYET)) + } else if (hcint & (HCINT_ACK | HCINT_NYET)) goto send_cpkt; break; @@ -1698,7 +1716,7 @@ check_state: /* FALLTHROUGH */ case DWC_CHAN_ST_TX_PKT_ISOC: - if (dwc_otg_host_channel_alloc(td, 0)) + if (dwc_otg_host_channel_alloc(td, 0, 1)) break; channel = td->channel[0]; goto send_isoc_pkt; @@ -1731,7 +1749,7 @@ send_pkt: } /* allocate a new channel */ - if (dwc_otg_host_channel_alloc(td, 0)) { + if (dwc_otg_host_channel_alloc(td, 0, 1)) { td->state = DWC_CHAN_ST_START; goto busy; } @@ -1896,7 +1914,7 @@ send_cpkt: } /* allocate a new channel */ - if (dwc_otg_host_channel_alloc(td, td->tt_channel_tog)) { + if (dwc_otg_host_channel_alloc(td, td->tt_channel_tog, 0)) { td->state = DWC_CHAN_ST_WAIT_C_PKT; goto busy; } @@ -2306,6 +2324,31 @@ dwc_otg_timer_stop(struct dwc_otg_softc *sc) usb_callout_stop(&sc->sc_timer); } +static void +dwc_otg_host_channel_disable(struct dwc_otg_softc *sc, uint8_t x) +{ + uint32_t hcchar; + + hcchar = DWC_OTG_READ_4(sc, DOTG_HCCHAR(x)); + + /* disable host channel, if any */ + if (hcchar & (HCCHAR_CHENA | HCCHAR_CHDIS)) { + /* disable channel */ + DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(x), + HCCHAR_CHENA | HCCHAR_CHDIS); + /* wait for chip to get its brains in order */ + sc->sc_chan_state[x].wait_sof = 2; + } + + /* release TX FIFO usage, if any */ + sc->sc_tx_cur_p_level -= sc->sc_chan_state[x].tx_p_size; + sc->sc_tx_cur_np_level -= sc->sc_chan_state[x].tx_np_size; + + /* don't release TX FIFO usage twice */ + sc->sc_chan_state[x].tx_p_size = 0; + sc->sc_chan_state[x].tx_np_size = 0; +} + static uint8_t dwc_otg_update_host_transfer_schedule(struct dwc_otg_softc *sc) { @@ -2326,26 +2369,12 @@ dwc_otg_update_host_transfer_schedule(struct dwc_otg_softc *sc) TAILQ_INIT(&head); for (x = 0; x != sc->sc_host_ch_max; x++) { - uint32_t hcchar; - if (sc->sc_chan_state[x].wait_sof == 0) continue; sc->sc_needsof = 1; - sc->sc_chan_state[x].wait_sof--; - if (sc->sc_chan_state[x].wait_sof != 0) - continue; - - hcchar = DWC_OTG_READ_4(sc, DOTG_HCCHAR(x)); - - /* disable host channel, if any */ - if (hcchar & (HCCHAR_CHENA | HCCHAR_CHDIS)) { - /* disable channel */ - DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(x), - HCCHAR_CHENA | HCCHAR_CHDIS); - /* wait for chip to get its brains in order */ - sc->sc_chan_state[x].wait_sof = 2; - } + if (--(sc->sc_chan_state[x].wait_sof) == 0) + dwc_otg_host_channel_disable(sc, x); } if ((temp & 7) == 0) { diff --git a/sys/dev/usb/controller/dwc_otg.h b/sys/dev/usb/controller/dwc_otg.h index f2a54a6f9d86..406341669788 100644 --- a/sys/dev/usb/controller/dwc_otg.h +++ b/sys/dev/usb/controller/dwc_otg.h @@ -36,6 +36,7 @@ #define DWC_OTG_HOST_TIMER_RATE 10 /* ms */ #define DWC_OTG_TT_SLOT_MAX 8 #define DWC_OTG_SLOT_IDLE_MAX 4 +#define DWC_OTG_SLOT_IDLE_MIN 2 #define DWC_OTG_READ_4(sc, reg) \ bus_space_read_4((sc)->sc_io_tag, (sc)->sc_io_hdl, reg) -- cgit v1.2.3 From 6c19260269557808317e91251b08a4fc7037dc46 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Sat, 10 May 2014 08:48:04 +0000 Subject: Whitespace change. --- sys/netinet/udp_usrreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index 8cae36a6ddc6..52f22df83069 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -1340,7 +1340,7 @@ udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr, * For UDP-Lite, checksum coverage length of zero means * the entire UDPLite packet is covered by the checksum. */ - cscov_partial = (cscov == 0) ? 0 : 1; + cscov_partial = (cscov == 0) ? 0 : 1; } else ui->ui_v = IPVERSION << 4; -- cgit v1.2.3 From dd75f2c5eb990ab1b642591b83c47e7be184ad75 Mon Sep 17 00:00:00 2001 From: Luiz Otavio O Souza Date: Sat, 10 May 2014 12:19:02 +0000 Subject: Add the lm75 i2c digital temperature sensor driver. This driver supports the low and high precision models (9 and 11 bits) and it will auto-detect the both variants. The driver expose the temperature registers (actual temperature, shutdown and hysteresys temperature) and also the configuration register. It was tested on FDT systems: RPi, BBB and on non-FDT systems: AR71xx, with both, hardware i2c controllers (when available) and gpioiic(4). This provides a simple and cheap way for verifying the i2c bus on embedded systems. --- share/man/man4/Makefile | 1 + share/man/man4/lm75.4 | 191 ++++++++++++++++ sys/conf/files | 1 + sys/dev/iicbus/lm75.c | 574 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 767 insertions(+) create mode 100644 share/man/man4/lm75.4 create mode 100644 sys/dev/iicbus/lm75.c diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index b0f8e572ca26..2d81344e86e5 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -228,6 +228,7 @@ MAN= aac.4 \ led.4 \ lge.4 \ ${_linux.4} \ + lm75.4 \ lmc.4 \ lo.4 \ lp.4 \ diff --git a/share/man/man4/lm75.4 b/share/man/man4/lm75.4 new file mode 100644 index 000000000000..361044bc6c1d --- /dev/null +++ b/share/man/man4/lm75.4 @@ -0,0 +1,191 @@ +.\" +.\" Copyright (c) 2014 Luiz Otavio O Souza +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd March 7, 2014 +.Dt LM75 4 +.Os +.Sh NAME +.Nm lm75 +.Nd lm75 i2c digital temperature sensor driver +.Sh SYNOPSIS +.Cd "device iic" +.Cd "device iicbus" +.Cd "device lm75" +.Sh DESCRIPTION +The +.Nm +driver provides access to sensor data and configuration over the +.Xr iicbus 4 . +.Pp +It provides an easy and simple way to check the functionality of an i2c bus +as it provides read and write access to the +.Nm +configuration register. +.Pp +The access to +.Nm +data is made via the +.Xr sysctl 8 +interface: +.Bd -literal +dev.lm75.0.%desc: LM75 temperature sensor +dev.lm75.0.%driver: lm75 +dev.lm75.0.%location: addr=0x49 +dev.lm75.0.%pnpinfo: name=lm750 compat=national,lm75 +dev.lm75.0.%parent: iicbus3 +dev.lm75.0.temperature: 27.1C +dev.lm75.0.thyst: 75.0C +dev.lm75.0.tos: 80.0C +dev.lm75.0.faults: 1 +dev.lm75.0.mode: comparator +dev.lm75.0.polarity: active-low +dev.lm75.0.shutdown: 0 +.Ed +.Bl -tag -width ".Va dev.lm75.%d.temperature" +.It Va dev.lm75.%d.temperature +Is the read-only value of the current temperature read by the sensor. +.It Va dev.lm75.%d.thyst +Sets the hysteresis temperature. +Once the temperature get over the overtemperature shutdown value (tos) +it need to drop bellow the hysteresis temperature to disable the output +(interrupt) pin again. +.It Va dev.lm75.%d.tos +Sets the overtemperature shutdown value. +Once the temperature get over this value the output pin will be enabled. +The way the output (interrupt) pin works, depends on the mode configuration. +.It Va dev.lm75.%d.faults +Is the number of faults that must occur consecutively to activate the +interrupt (output) pin. +It can be set to 1, 2, 4, and 6. +.It Va dev.lm75.%d.mode +Set the operation mode for the sensor interrupt pin. +It can be set to 'comparator' (default) or 'interrupt'. +.It Va dev.lm75.%d.polarity +Set the polarity of the sensor interrupt pin. +It can be set to 'active-low' (default) or 'active-high'. +Please note that the output pin is an open-drain output and it needs a +proper pull-up resistor to work. +.It Va dev.lm75.%d.shutdown +When set to '1' it shutdown the sensor. +The temperature convertion stops but the sensor remains with its i2c bus +active, i.e., it can be woken up by setting this option to '0' again. +.El +.Pp +Please check the +.Nm +datasheet for more details. +.Pp +When used together with +.Xr snmp_lm75 3 +it allows the monitoring of +.Nm +temperature data over SNMP. +.Pp +The +.Nm +driver supports both the low and the high resolution models. +.Pp +The low resolution model (lm75) provides a 9 bit output with the LSB +representing 0.5C. +.Pp +The high resolution model (lm75a) provides an 11 bit output with the LSB +representing 0.125C. +.Pp +The driver tries to auto-detect the +.Nm +model, but the detection of some +.Nm +clones may not work reliably. +.Pp +On a +.Xr device.hints 5 +based system, like +.Li MIPS , +these values are configurable for the +.Nm : +.Bl -tag -width ".Va hint.lm75.%d.addr" +.It Va hint.lm75.%d.at +Is the +.Xr iicbus 4 +you are attaching to. +.It Va hint.lm75.%d.addr +Is the +.Nm +i2c address on the +.Xr iicbus 4 . +.El +.Pp +On a +.Xr FDT 4 +based system, like +.Li ARM , +the DTS part for a +.Nm +device usually looks like: +.Bd -literal +i2c { + + ... + + lm750 { + compatible = "national,lm75"; + i2c-address = <0x49>; + }; +}; +.Ed +.Pp +Where: +.Bl -tag -width ".Va i2c-address" +.It Va compatible +Should always be set to "national,lm75". +.It Va i2c-address +The +.Va i2c-address +property indicates which i2c address the +.Nm +is wired at. +.Nm +temperature sensors can be wired to 8 different address, allowing up to 8 +sensors on the same +.Xr iicbus 4 . +.El +.Sh SEE ALSO +.Xr snmp_lm75 3 , +.Xr fdt 4 , +.Xr iic 4 , +.Xr iicbus 4 , +.Xr sysctl 8 +.Sh HISTORY +The +.Nm +driver first appeared in +.Fx 11.0 . +.Sh AUTHORS +.An -nosplit +The +.Nm +driver and this manual page was written by +.An Luiz Otavio O Souza Aq loos@FreeBSD.org diff --git a/sys/conf/files b/sys/conf/files index d11faa97473e..38afd9d993a6 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1444,6 +1444,7 @@ dev/iicbus/iiconf.c optional iicbus dev/iicbus/iicsmb.c optional iicsmb \ dependency "iicbus_if.h" dev/iicbus/iicoc.c optional iicoc +dev/iicbus/lm75.c optional lm75 dev/iicbus/pcf8563.c optional pcf8563 dev/iicbus/s35390a.c optional s35390a dev/iir/iir.c optional iir diff --git a/sys/dev/iicbus/lm75.c b/sys/dev/iicbus/lm75.c new file mode 100644 index 000000000000..52ab159e964b --- /dev/null +++ b/sys/dev/iicbus/lm75.c @@ -0,0 +1,574 @@ +/*- + * Copyright (c) 2010 Andreas Tobler. + * Copyright (c) 2013-2014 Luiz Otavio O Souza + * 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 "opt_platform.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#ifdef FDT +#include +#include +#include +#endif + +/* LM75 registers. */ +#define LM75_TEMP 0x0 +#define LM75_CONF 0x1 +#define LM75_CONF_FSHIFT 3 +#define LM75_CONF_FAULT 0x18 +#define LM75_CONF_POL 0x04 +#define LM75_CONF_MODE 0x02 +#define LM75_CONF_SHUTD 0x01 +#define LM75_CONF_MASK 0x1f +#define LM75_THYST 0x2 +#define LM75_TOS 0x3 + +/* LM75 constants. */ +#define LM75_TEST_PATTERN 0xa +#define LM75_MIN_TEMP -55 +#define LM75_MAX_TEMP 125 +#define LM75_0500C 0x80 +#define LM75_0250C 0x40 +#define LM75_0125C 0x20 +#define LM75_MSB 0x8000 +#define LM75_NEG_BIT LM75_MSB +#define TZ_ZEROC 2732 + +/* LM75 supported models. */ +#define HWTYPE_LM75 1 +#define HWTYPE_LM75A 2 + +/* Regular bus attachment functions */ +static int lm75_probe(device_t); +static int lm75_attach(device_t); + +struct lm75_softc { + device_t sc_dev; + struct intr_config_hook enum_hook; + int32_t sc_hwtype; + uint32_t sc_addr; + uint32_t sc_conf; +}; + +static int lm75_faults[4] = { 1, 2, 4, 6 }; + +/* Utility functions */ +static int lm75_conf_read(struct lm75_softc *); +static int lm75_conf_write(struct lm75_softc *); +static int lm75_temp_read(struct lm75_softc *, uint8_t, int *); +static int lm75_temp_write(struct lm75_softc *, uint8_t, int); +static void lm75_start(void *); +static int lm75_read(device_t, uint32_t, uint8_t, uint8_t *, size_t); +static int lm75_write(device_t, uint32_t, uint8_t *, size_t); +static int lm75_str_mode(char *); +static int lm75_str_pol(char *); +static int lm75_temp_sysctl(SYSCTL_HANDLER_ARGS); +static int lm75_faults_sysctl(SYSCTL_HANDLER_ARGS); +static int lm75_mode_sysctl(SYSCTL_HANDLER_ARGS); +static int lm75_pol_sysctl(SYSCTL_HANDLER_ARGS); +static int lm75_shutdown_sysctl(SYSCTL_HANDLER_ARGS); + +static device_method_t lm75_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, lm75_probe), + DEVMETHOD(device_attach, lm75_attach), + + DEVMETHOD_END +}; + +static driver_t lm75_driver = { + "lm75", + lm75_methods, + sizeof(struct lm75_softc) +}; + +static devclass_t lm75_devclass; + +DRIVER_MODULE(lm75, iicbus, lm75_driver, lm75_devclass, 0, 0); + +static int +lm75_read(device_t dev, uint32_t addr, uint8_t reg, uint8_t *data, size_t len) +{ + struct iic_msg msg[2] = { + { addr, IIC_M_WR | IIC_M_NOSTOP, 1, ® }, + { addr, IIC_M_RD, len, data }, + }; + + if (iicbus_transfer(dev, msg, 2) != 0) + return (-1); + + return (0); +} + +static int +lm75_write(device_t dev, uint32_t addr, uint8_t *data, size_t len) +{ + struct iic_msg msg[1] = { + { addr, IIC_M_WR, len, data }, + }; + + if (iicbus_transfer(dev, msg, 1) != 0) + return (-1); + + return (0); +} + +static int +lm75_probe(device_t dev) +{ + struct lm75_softc *sc; + + sc = device_get_softc(dev); + sc->sc_hwtype = HWTYPE_LM75; +#ifdef FDT + if (!ofw_bus_is_compatible(dev, "national,lm75")) + return (ENXIO); +#endif + device_set_desc(dev, "LM75 temperature sensor"); + + return (BUS_PROBE_GENERIC); +} + +static int +lm75_attach(device_t dev) +{ + struct lm75_softc *sc; + + sc = device_get_softc(dev); + sc->sc_dev = dev; + sc->sc_addr = iicbus_get_addr(dev); + + sc->enum_hook.ich_func = lm75_start; + sc->enum_hook.ich_arg = dev; + + /* + * We have to wait until interrupts are enabled. Usually I2C read + * and write only works when the interrupts are available. + */ + if (config_intrhook_establish(&sc->enum_hook) != 0) + return (ENOMEM); + + return (0); +} + +static int +lm75_type_detect(struct lm75_softc *sc) +{ + int i, lm75a; + uint8_t buf8; + uint32_t conf; + + /* Save the contents of the configuration register. */ + if (lm75_conf_read(sc) != 0) + return (-1); + conf = sc->sc_conf; + + /* + * Just write some pattern at configuration register so we can later + * verify. The test pattern should be pretty harmless. + */ + sc->sc_conf = LM75_TEST_PATTERN; + if (lm75_conf_write(sc) != 0) + return (-1); + + /* + * Read the configuration register again and check for our test + * pattern. + */ + if (lm75_conf_read(sc) != 0) + return (-1); + if (sc->sc_conf != LM75_TEST_PATTERN) + return (-1); + + /* + * Read from nonexistent registers (0x4 ~ 0x6). + * LM75A always return 0xff for nonexistent registers. + * LM75 will return the last read value - our test pattern written to + * configuration register. + */ + lm75a = 0; + for (i = 4; i <= 6; i++) { + if (lm75_read(sc->sc_dev, sc->sc_addr, i, &buf8, 1) < 0) + return (-1); + if (buf8 != LM75_TEST_PATTERN && buf8 != 0xff) + return (-1); + if (buf8 == 0xff) + lm75a++; + } + if (lm75a == 3) + sc->sc_hwtype = HWTYPE_LM75A; + + /* Restore the configuration register. */ + sc->sc_conf = conf; + if (lm75_conf_write(sc) != 0) + return (-1); + + return (0); +} + +static void +lm75_start(void *xdev) +{ + device_t dev; + struct lm75_softc *sc; + struct sysctl_ctx_list *ctx; + struct sysctl_oid *tree_node; + struct sysctl_oid_list *tree; + + dev = (device_t)xdev; + sc = device_get_softc(dev); + ctx = device_get_sysctl_ctx(dev); + tree_node = device_get_sysctl_tree(dev); + tree = SYSCTL_CHILDREN(tree_node); + + config_intrhook_disestablish(&sc->enum_hook); + + /* + * Detect the kind of chip we are attaching to. + * This may not work for LM75 clones. + */ + if (lm75_type_detect(sc) != 0) { + device_printf(dev, "cannot read from sensor.\n"); + return; + } + if (sc->sc_hwtype == HWTYPE_LM75A) + device_printf(dev, + "LM75A type sensor detected (11bits resolution).\n"); + + /* Temperature. */ + SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "temperature", + CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE, dev, LM75_TEMP, + lm75_temp_sysctl, "IK", "Current temperature"); + SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "thyst", + CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, dev, LM75_THYST, + lm75_temp_sysctl, "IK", "Hysteresis temperature"); + SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "tos", + CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, dev, LM75_TOS, + lm75_temp_sysctl, "IK", "Overtemperature"); + + /* Configuration parameters. */ + SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "faults", + CTLFLAG_RW | CTLTYPE_UINT, dev, 0, + lm75_faults_sysctl, "IU", "LM75 fault queue"); + SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "mode", + CTLFLAG_RW | CTLTYPE_STRING, dev, 0, + lm75_mode_sysctl, "A", "LM75 mode"); + SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "polarity", + CTLFLAG_RW | CTLTYPE_STRING, dev, 0, + lm75_pol_sysctl, "A", "LM75 OS polarity"); + SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "shutdown", + CTLFLAG_RW | CTLTYPE_UINT, dev, 0, + lm75_shutdown_sysctl, "IU", "LM75 shutdown"); +} + +static int +lm75_conf_read(struct lm75_softc *sc) +{ + uint8_t buf8; + + if (lm75_read(sc->sc_dev, sc->sc_addr, LM75_CONF, &buf8, 1) < 0) + return (-1); + + sc->sc_conf = (uint32_t)buf8; + + return (0); +} + +static int +lm75_conf_write(struct lm75_softc *sc) +{ + uint8_t buf8[2]; + + buf8[0] = LM75_CONF; + buf8[1] = (uint8_t)sc->sc_conf & LM75_CONF_MASK; + + if (lm75_write(sc->sc_dev, sc->sc_addr, buf8, 2) < 0) + return (-1); + + return (0); +} + +static int +lm75_temp_read(struct lm75_softc *sc, uint8_t reg, int *temp) +{ + uint8_t buf8[2]; + uint16_t buf; + int t; + + if (lm75_read(sc->sc_dev, sc->sc_addr, reg, buf8, 2) < 0) + return (-1); + + buf = (buf8[0] << 8) | (buf8[1] & 0xff); + + /* + * LM75 has a 9 bit ADC with resolution of 0.5 C per bit. + * LM75A has an 11 bit ADC with resolution of 0.125 C per bit. + * Temperature is stored with two's complement. + */ + if (buf & LM75_NEG_BIT) + buf = ~buf + 1; + *temp = ((int16_t)buf >> 8) * 10; + t = 0; + if (sc->sc_hwtype == HWTYPE_LM75A) { + if (buf & LM75_0125C) + t += 125; + if (buf & LM75_0250C) + t += 250; + } + if (buf & LM75_0500C) + t += 500; + t /= 100; + *temp += t; + if (buf & LM75_NEG_BIT) + *temp = -(*temp); + *temp += TZ_ZEROC; + + return (0); +} + +static int +lm75_temp_write(struct lm75_softc *sc, uint8_t reg, int temp) +{ + uint8_t buf8[3]; + uint16_t buf; + + if (temp > LM75_MAX_TEMP) + temp = LM75_MAX_TEMP; + if (temp < LM75_MIN_TEMP) + temp = LM75_MIN_TEMP; + + buf = (uint16_t)temp; + buf <<= 8; + + buf8[0] = reg; + buf8[1] = buf >> 8; + buf8[2] = buf & 0xff; + + if (lm75_write(sc->sc_dev, sc->sc_addr, buf8, 3) < 0) + return (-1); + + return (0); +} + +static int +lm75_str_mode(char *buf) +{ + int len, rtrn; + + rtrn = -1; + len = strlen(buf); + if (len > 2 && strncasecmp("interrupt", buf, len) == 0) + rtrn = 1; + else if (len > 2 && strncasecmp("comparator", buf, len) == 0) + rtrn = 0; + + return (rtrn); +} + +static int +lm75_str_pol(char *buf) +{ + int len, rtrn; + + rtrn = -1; + len = strlen(buf); + if (len > 1 && strncasecmp("high", buf, len) == 0) + rtrn = 1; + else if (len > 1 && strncasecmp("low", buf, len) == 0) + rtrn = 0; + else if (len > 8 && strncasecmp("active-high", buf, len) == 0) + rtrn = 1; + else if (len > 8 && strncasecmp("active-low", buf, len) == 0) + rtrn = 0; + + return (rtrn); +} + +static int +lm75_temp_sysctl(SYSCTL_HANDLER_ARGS) +{ + device_t dev; + int error, temp; + struct lm75_softc *sc; + uint8_t reg; + + dev = (device_t)arg1; + reg = (uint8_t)arg2; + sc = device_get_softc(dev); + + if (lm75_temp_read(sc, reg, &temp) != 0) + return (EIO); + + error = sysctl_handle_int(oidp, &temp, 0, req); + if (error != 0 || req->newptr == NULL) + return (error); + + if (lm75_temp_write(sc, reg, temp) != 0) + return (EIO); + + return (error); +} + +static int +lm75_faults_sysctl(SYSCTL_HANDLER_ARGS) +{ + device_t dev; + int error, faults, i, newf, tmp; + struct lm75_softc *sc; + + dev = (device_t)arg1; + sc = device_get_softc(dev); + tmp = (sc->sc_conf & LM75_CONF_FAULT) >> LM75_CONF_FSHIFT; + if (tmp > nitems(lm75_faults)) + tmp = nitems(lm75_faults); + faults = lm75_faults[tmp]; + + error = sysctl_handle_int(oidp, &faults, 0, req); + if (error != 0 || req->newptr == NULL) + return (error); + + if (faults != lm75_faults[tmp]) { + newf = 0; + for (i = 0; i < nitems(lm75_faults); i++) + if (faults >= lm75_faults[i]) + newf = i; + sc->sc_conf &= ~LM75_CONF_FAULT; + sc->sc_conf |= newf << LM75_CONF_FSHIFT; + if (lm75_conf_write(sc) != 0) + return (EIO); + } + + return (error); +} + +static int +lm75_mode_sysctl(SYSCTL_HANDLER_ARGS) +{ + char buf[16]; + device_t dev; + int error, mode, newm; + struct lm75_softc *sc; + + dev = (device_t)arg1; + sc = device_get_softc(dev); + if (sc->sc_conf & LM75_CONF_MODE) { + mode = 1; + strlcpy(buf, "interrupt", sizeof(buf)); + } else { + mode = 0; + strlcpy(buf, "comparator", sizeof(buf)); + } + + error = sysctl_handle_string(oidp, buf, sizeof(buf), req); + if (error != 0 || req->newptr == NULL) + return (error); + + newm = lm75_str_mode(buf); + if (newm != -1 && mode != newm) { + sc->sc_conf &= ~LM75_CONF_MODE; + if (newm == 1) + sc->sc_conf |= LM75_CONF_MODE; + if (lm75_conf_write(sc) != 0) + return (EIO); + } + + return (error); +} + +static int +lm75_pol_sysctl(SYSCTL_HANDLER_ARGS) +{ + char buf[16]; + device_t dev; + int error, newp, pol; + struct lm75_softc *sc; + + dev = (device_t)arg1; + sc = device_get_softc(dev); + if (sc->sc_conf & LM75_CONF_POL) { + pol = 1; + strlcpy(buf, "active-high", sizeof(buf)); + } else { + pol = 0; + strlcpy(buf, "active-low", sizeof(buf)); + } + + error = sysctl_handle_string(oidp, buf, sizeof(buf), req); + if (error != 0 || req->newptr == NULL) + return (error); + + newp = lm75_str_pol(buf); + if (newp != -1 && pol != newp) { + sc->sc_conf &= ~LM75_CONF_POL; + if (newp == 1) + sc->sc_conf |= LM75_CONF_POL; + if (lm75_conf_write(sc) != 0) + return (EIO); + } + + return (error); +} + +static int +lm75_shutdown_sysctl(SYSCTL_HANDLER_ARGS) +{ + device_t dev; + int error, shutdown, tmp; + struct lm75_softc *sc; + + dev = (device_t)arg1; + sc = device_get_softc(dev); + tmp = shutdown = (sc->sc_conf & LM75_CONF_SHUTD) ? 1 : 0; + + error = sysctl_handle_int(oidp, &shutdown, 0, req); + if (error != 0 || req->newptr == NULL) + return (error); + + if (shutdown != tmp) { + sc->sc_conf &= ~LM75_CONF_SHUTD; + if (shutdown) + sc->sc_conf |= LM75_CONF_SHUTD; + if (lm75_conf_write(sc) != 0) + return (EIO); + } + + return (error); +} -- cgit v1.2.3 From 9cce5d9339e8bfef1e3dd2d8b303035c866d396b Mon Sep 17 00:00:00 2001 From: Luiz Otavio O Souza Date: Sat, 10 May 2014 12:58:18 +0000 Subject: Remove an old mistake of mine. This has sneak in the code i sent to gonzo at that time, but AFAIK it is only used on routerboards. Enabling GPIO_FUNC_SPI_CS[1|2]_EN will claim the use of gpio pins 0 and 1 respectivelly for use as SPI CS pins. When really needed, this can still be enabled on kernel hints using the function_set and function_clear knobs. --- sys/mips/atheros/ar71xx_gpio.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/sys/mips/atheros/ar71xx_gpio.c b/sys/mips/atheros/ar71xx_gpio.c index 1a2d1e997ed2..9078d961a2da 100644 --- a/sys/mips/atheros/ar71xx_gpio.c +++ b/sys/mips/atheros/ar71xx_gpio.c @@ -352,7 +352,6 @@ ar71xx_gpio_attach(device_t dev) int error = 0; int i, j, maxpin; int mask, pinon; - int old = 0; KASSERT((device_get_unit(dev) == 0), ("ar71xx_gpio: Only one gpio module supported")); @@ -391,19 +390,12 @@ ar71xx_gpio_attach(device_t dev) "function_set", &mask) == 0) { device_printf(dev, "function_set: 0x%x\n", mask); ar71xx_gpio_function_enable(sc, mask); - old = 1; } /* Disable function bits that are required */ if (resource_int_value(device_get_name(dev), device_get_unit(dev), "function_clear", &mask) == 0) { device_printf(dev, "function_clear: 0x%x\n", mask); ar71xx_gpio_function_disable(sc, mask); - old = 1; - } - /* Handle previous behaviour */ - if (old == 0) { - ar71xx_gpio_function_enable(sc, GPIO_FUNC_SPI_CS1_EN); - ar71xx_gpio_function_enable(sc, GPIO_FUNC_SPI_CS2_EN); } /* Configure all pins as input */ @@ -457,8 +449,6 @@ ar71xx_gpio_detach(device_t dev) KASSERT(mtx_initialized(&sc->gpio_mtx), ("gpio mutex not initialized")); - ar71xx_gpio_function_disable(sc, GPIO_FUNC_SPI_CS1_EN); - ar71xx_gpio_function_disable(sc, GPIO_FUNC_SPI_CS2_EN); bus_generic_detach(dev); if (sc->gpio_mem_res) -- cgit v1.2.3 From 3bff5e84a75b2222129f9313c3c6f50a312ee77c Mon Sep 17 00:00:00 2001 From: Warren Block Date: Sat, 10 May 2014 13:10:42 +0000 Subject: Fix document title. Submitted by: pluknet --- share/man/man4/vt.4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/man/man4/vt.4 b/share/man/man4/vt.4 index 58ee10535532..10be5906da53 100644 --- a/share/man/man4/vt.4 +++ b/share/man/man4/vt.4 @@ -25,7 +25,7 @@ .\" $FreeBSD$ .\" .Dd May 9, 2014 -.Dt VIRTUAL TERMINALS 4 +.Dt "VIRTUAL TERMINALS" 4 .Os .Sh NAME .Nm vt -- cgit v1.2.3 From ee454ea929b455e58e49b4a5672de30a5d3c757d Mon Sep 17 00:00:00 2001 From: Luiz Otavio O Souza Date: Sat, 10 May 2014 13:16:04 +0000 Subject: Do not configure all pins as outputs as this can lead to short circuits when the GPIO pin is connected to a push button (or other devices). Instead keep the boot loader settings. Calling ar71xx_gpio_pin_configure() with DEFAULT_CAPS was probably a mistake and was causing all the pins to be set as outputs. --- sys/mips/atheros/ar71xx_gpio.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/sys/mips/atheros/ar71xx_gpio.c b/sys/mips/atheros/ar71xx_gpio.c index 9078d961a2da..d0a52ca0bbe7 100644 --- a/sys/mips/atheros/ar71xx_gpio.c +++ b/sys/mips/atheros/ar71xx_gpio.c @@ -352,6 +352,7 @@ ar71xx_gpio_attach(device_t dev) int error = 0; int i, j, maxpin; int mask, pinon; + uint32_t oe; KASSERT((device_get_unit(dev) == 0), ("ar71xx_gpio: Only one gpio module supported")); @@ -398,8 +399,7 @@ ar71xx_gpio_attach(device_t dev) ar71xx_gpio_function_disable(sc, mask); } - /* Configure all pins as input */ - /* disable interrupts for all pins */ + /* Disable interrupts for all pins. */ GPIO_WRITE(sc, AR71XX_GPIO_INT_MASK, 0); /* Initialise all pins specified in the mask, up to the pin count */ @@ -416,6 +416,8 @@ ar71xx_gpio_attach(device_t dev) continue; sc->gpio_npins++; } + /* Iniatilize the GPIO pins, keep the loader settings. */ + oe = GPIO_READ(sc, AR71XX_GPIO_OE); sc->gpio_pins = malloc(sizeof(*sc->gpio_pins) * sc->gpio_npins, M_DEVBUF, M_WAITOK | M_ZERO); for (i = 0, j = 0; j <= maxpin; j++) { @@ -425,8 +427,10 @@ ar71xx_gpio_attach(device_t dev) "pin %d", j); sc->gpio_pins[i].gp_pin = j; sc->gpio_pins[i].gp_caps = DEFAULT_CAPS; - sc->gpio_pins[i].gp_flags = 0; - ar71xx_gpio_pin_configure(sc, &sc->gpio_pins[i], DEFAULT_CAPS); + if (oe & (1 << j)) + sc->gpio_pins[i].gp_flags = GPIO_PIN_OUTPUT; + else + sc->gpio_pins[i].gp_flags = GPIO_PIN_INPUT; i++; } /* Turn on the hinted pins. */ -- cgit v1.2.3 From 6ed8e454a10bce8dee08d0918791a9f519eba783 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Sat, 10 May 2014 13:18:20 +0000 Subject: UDP-Lite uses SOCK_DGRAM, not SOCK_STREAM. --- share/man/man4/udplite.4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/man/man4/udplite.4 b/share/man/man4/udplite.4 index 37fcf121b4d3..d40aaa9a8af8 100644 --- a/share/man/man4/udplite.4 +++ b/share/man/man4/udplite.4 @@ -35,7 +35,7 @@ .In sys/socket.h .In netinet/udplite.h .Ft int -.Fn socket AF_INET SOCK_STREAM IPPROTO_UDPLITE +.Fn socket AF_INET SOCK_DGRAM IPPROTO_UDPLITE .Sh DESCRIPTION The .Tn UDP-Lite -- cgit v1.2.3 From 7585c684868255c27641b298731bc9ac7b6c30f5 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sat, 10 May 2014 15:21:37 +0000 Subject: Comment out some pointless device open/close around reading device IDs. FreeBSD ZFS port unlike OpenSolaris does not use device IDs, and does not implement respective devid_*() fuctions. It is pointless to open devices just to close them back immediately. MFC after: 2 weeks Sponsored by: iXsystems, Inc. --- cddl/contrib/opensolaris/cmd/zpool/zpool_vdev.c | 2 ++ cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c | 4 ++++ cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c | 4 ++++ 3 files changed, 10 insertions(+) diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool_vdev.c b/cddl/contrib/opensolaris/cmd/zpool/zpool_vdev.c index 5ffd39ac8fe6..374798b5e72d 100644 --- a/cddl/contrib/opensolaris/cmd/zpool/zpool_vdev.c +++ b/cddl/contrib/opensolaris/cmd/zpool/zpool_vdev.c @@ -512,6 +512,7 @@ make_leaf_vdev(const char *arg, uint64_t is_log) verify(nvlist_add_uint64(vdev, ZPOOL_CONFIG_WHOLE_DISK, (uint64_t)wholedisk) == 0); +#ifdef have_devid /* * For a whole disk, defer getting its devid until after labeling it. */ @@ -546,6 +547,7 @@ make_leaf_vdev(const char *arg, uint64_t is_log) (void) close(fd); } +#endif return (vdev); } diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c index e53a8cdf94a6..868961d96d66 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c @@ -94,6 +94,7 @@ typedef struct pool_list { static char * get_devid(const char *path) { +#ifdef have_devid int fd; ddi_devid_t devid; char *minor, *ret; @@ -113,6 +114,9 @@ get_devid(const char *path) (void) close(fd); return (ret); +#else + return (NULL); +#endif } diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c index 8dd24a791f19..02f0b96b8c11 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c @@ -3324,6 +3324,7 @@ devid_to_path(char *devid_str) static char * path_to_devid(const char *path) { +#ifdef have_devid int fd; ddi_devid_t devid; char *minor, *ret; @@ -3343,6 +3344,9 @@ path_to_devid(const char *path) (void) close(fd); return (ret); +#else + return (NULL); +#endif } /* -- cgit v1.2.3 From 3e901731736c7748e740c1de9281150652ee4fce Mon Sep 17 00:00:00 2001 From: Kevin Lo Date: Sat, 10 May 2014 15:34:32 +0000 Subject: Fix -width argument to Bl -tag. --- share/man/man4/udplite.4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/man/man4/udplite.4 b/share/man/man4/udplite.4 index d40aaa9a8af8..5d06b1440984 100644 --- a/share/man/man4/udplite.4 +++ b/share/man/man4/udplite.4 @@ -52,7 +52,7 @@ supports a number of socket options which can be set with .Xr setsockopt 2 and tested with .Xr getsockopt 2 : -.Bl -tag -width ".Dv SCTP_SET_PEER_PRIMARY_ADDR" +.Bl -tag -width ".Dv UDPLITE_SEND_CSCOV" .It Dv UDPLITE_SEND_CSCOV This option sets the sender checksum coverage. A value of zero indicates that the entire packet -- cgit v1.2.3 From 4f412b06fd056bb140d35b5ccbd3a2920176c267 Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Sat, 10 May 2014 15:38:26 +0000 Subject: Simplify code slightly. Passing an array by &array[0] does work, but is silly. --- sys/powerpc/powerpc/platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/powerpc/powerpc/platform.c b/sys/powerpc/powerpc/platform.c index f77869ccd3cc..4698ed21666c 100644 --- a/sys/powerpc/powerpc/platform.c +++ b/sys/powerpc/powerpc/platform.c @@ -116,7 +116,7 @@ mem_regions(struct mem_region **phys, int *physsz, struct mem_region **avail, int i, j, still_merging; if (npregions == 0) { - PLATFORM_MEM_REGIONS(plat_obj, &pregions[0], &npregions, + PLATFORM_MEM_REGIONS(plat_obj, pregions, &npregions, aregions, &naregions); qsort(pregions, npregions, sizeof(*pregions), mr_cmp); qsort(aregions, naregions, sizeof(*aregions), mr_cmp); -- cgit v1.2.3 From 3d95614f9dc2e80b015908156080c924961ca676 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 10 May 2014 16:30:48 +0000 Subject: Print the entry address in addition to the object. The variable is typically optimized out and debuggers cannot find its value. Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/vm/vm_map.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index a6a500d88a31..c9402da06048 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -1949,7 +1949,8 @@ vm_map_protect(vm_map_t map, vm_offset_t start, vm_offset_t end, * charged clipped mapping of the same object later. */ KASSERT(obj->charge == 0, - ("vm_map_protect: object %p overcharged\n", obj)); + ("vm_map_protect: object %p overcharged (entry %p)", + obj, current)); if (!swap_reserve(ptoa(obj->size))) { VM_OBJECT_WUNLOCK(obj); vm_map_unlock(map); -- cgit v1.2.3 From 44bbc3b77d40c8a17efd1c6b0b50a5f13810c3c6 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 10 May 2014 16:36:13 +0000 Subject: When printing the map with the ddb 'show procvm' command, do not dump page queues for the backing objects. The queues are huge and clutter the display, when mostly the map entries and its backing storage is interesting. The page queues can be seen with ddb 'show object' command. Reviewed by: alc Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/vm/vm_map.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index c9402da06048..e8eaf178d4d1 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -4154,7 +4154,7 @@ vm_map_print(vm_map_t map) db_indent += 2; vm_object_print((db_expr_t)(intptr_t) entry->object.vm_object, - 1, 0, (char *)0); + 0, 0, (char *)0); db_indent -= 2; } } -- cgit v1.2.3 From 21f76c672f8d6e6194dc7e4983963f0c25a3d480 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 10 May 2014 16:37:28 +0000 Subject: Document WITHOUT_SYSCALL_COMPAT and WITHOUT_GNU_GREP_COMPAT. --- tools/build/options/WITHOUT_GNU_GREP_COMPAT | 4 ++++ tools/build/options/WITHOUT_SYSCALL_COMPAT | 2 ++ 2 files changed, 6 insertions(+) create mode 100644 tools/build/options/WITHOUT_GNU_GREP_COMPAT create mode 100644 tools/build/options/WITHOUT_SYSCALL_COMPAT diff --git a/tools/build/options/WITHOUT_GNU_GREP_COMPAT b/tools/build/options/WITHOUT_GNU_GREP_COMPAT new file mode 100644 index 000000000000..e3ef593e87d5 --- /dev/null +++ b/tools/build/options/WITHOUT_GNU_GREP_COMPAT @@ -0,0 +1,4 @@ +.\" $FreeBSD$ +Set this option to omit the gnu extentions to grep from being included in +BSD grep. + diff --git a/tools/build/options/WITHOUT_SYSCALL_COMPAT b/tools/build/options/WITHOUT_SYSCALL_COMPAT new file mode 100644 index 000000000000..a20adcb3e5da --- /dev/null +++ b/tools/build/options/WITHOUT_SYSCALL_COMPAT @@ -0,0 +1,2 @@ +.\" $FreeBSD$ +Do not include some compatible syscall wrappers in libc. -- cgit v1.2.3 From 4d9b013a6308e35806ec533f8dd38f716b83e617 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 10 May 2014 16:37:33 +0000 Subject: Remove a few more vestiges of allowing WITHOUT_BMAKE to imply you want to buid with fmake. --- Makefile | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index b0e21c1ca1df..a29e01a15ee8 100644 --- a/Makefile +++ b/Makefile @@ -316,13 +316,6 @@ kernel: buildkernel installkernel upgrade_checks: .if ${HAVE_MAKE} != ${WANT_MAKE} @(cd ${.CURDIR} && ${MAKE} ${WANT_MAKE:S,^f,,}) -.elif ${WANT_MAKE} == "fmake" - @if ! (cd ${.CURDIR}/tools/build/make_check && \ - PATH=${PATH} ${BINMAKE} obj >/dev/null 2>&1 && \ - PATH=${PATH} ${BINMAKE} >/dev/null 2>&1); \ - then \ - (cd ${.CURDIR} && ${MAKE} make); \ - fi .endif # @@ -336,18 +329,18 @@ MMAKEENV= MAKEOBJDIRPREFIX=${MYMAKE:H} \ MMAKE= ${MMAKEENV} ${MAKE} \ -D_UPGRADING -DNO_MAN -DNO_SHARED \ -DNO_CPU_CFLAGS -DNO_WERROR \ - DESTDIR= MK_TESTS=no PROGNAME=${MYMAKE:T} + DESTDIR= PROGNAME=${MYMAKE:T} -make bmake: .PHONY +bmake: .PHONY @echo @echo "--------------------------------------------------------------" - @echo ">>> Building an up-to-date make(1)" + @echo ">>> Building an up-to-date ${.TARGET}(1)" @echo "--------------------------------------------------------------" ${_+_}@cd ${.CURDIR}/usr.bin/${.TARGET}; \ ${MMAKE} obj && \ ${MMAKE} depend && \ ${MMAKE} all && \ - ${MMAKE} install DESTDIR=${MYMAKE:H} BINDIR= NO_MAN=t + ${MMAKE} install DESTDIR=${MYMAKE:H} BINDIR= tinderbox toolchains kernel-toolchains: upgrade_checks -- cgit v1.2.3 From f510ecf0ee19e406ef02614fa0c7fb4acd96b613 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 10 May 2014 16:37:39 +0000 Subject: Optionally allow building the historical FreeBSD make program and install it as fmake. This defaults to no. This should be viewed as the first step towards evental migration of this historic code to ports and removal from the tree. --- share/mk/src.opts.mk | 1 + tools/build/options/WITH_FMAKE | 5 +++++ usr.bin/Makefile | 4 ++++ 3 files changed, 10 insertions(+) create mode 100644 tools/build/options/WITH_FMAKE diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk index 17b3fa97d37e..80ebe76766f1 100644 --- a/share/mk/src.opts.mk +++ b/share/mk/src.opts.mk @@ -165,6 +165,7 @@ __DEFAULT_NO_OPTIONS = \ BSD_GREP \ CLANG_EXTRAS \ EISA \ + FMAKE \ HESIOD \ LLDB \ NAND \ diff --git a/tools/build/options/WITH_FMAKE b/tools/build/options/WITH_FMAKE new file mode 100644 index 000000000000..f777250ce8a4 --- /dev/null +++ b/tools/build/options/WITH_FMAKE @@ -0,0 +1,5 @@ +.\" $FreeBSD$ +Causes the old FreeBSD +.Xr make 1 +program to be built and installed as fmake. + diff --git a/usr.bin/Makefile b/usr.bin/Makefile index 6df995ae8afa..544411b11e9c 100644 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -230,6 +230,10 @@ SUBDIR+= calendar _clang= clang .endif +.if ${MK_FMAKE} != "no" +SUBDIR+= make +.endif + .if ${MK_GPL_DTC} != "yes" SUBDIR+= dtc .endif -- cgit v1.2.3 From 999298523e16939c70c367a7988baeb59ca113d7 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 10 May 2014 16:37:44 +0000 Subject: Support, to the extent we generate proper command lines, compiling with clang 3.3. Useful for test building -current on a -stable system in individual directories. Potentially useful if we ever want to support, say, gcc 4.8 or 4.9's new warnings when building with an external toolchain (but such support not yet committed). Document the bsd.compiler.mk interface. --- share/mk/bsd.compiler.mk | 35 +++++++++++++++++++++++++++-------- share/mk/bsd.sys.mk | 5 ++++- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/share/mk/bsd.compiler.mk b/share/mk/bsd.compiler.mk index bb1229bd9836..a4f3feceb654 100644 --- a/share/mk/bsd.compiler.mk +++ b/share/mk/bsd.compiler.mk @@ -1,27 +1,46 @@ # $FreeBSD$ +# Setup variables for the compiler +# +# COMPILTER_TYPE is the major type of compiler. Currently gcc and clang support +# automatic detetion. Other compiler types can be shoe-horned in, but require explicit +# setting of the compiler type. The compiler type can also be set explicitly if, say, +# you install gcc as clang... +# +# COMPILER_VERSION is a numeric constant equal to major * 10000 + minor * 100 + tiny. It +# too can be overriden on the command line. When testing it, be sure to make sure that you +# are limiting the test to a specific compiler. Testing against 30300 for gcc likely isn't +# what you wanted (since versions of gcc prior to 4.2 likely have no prayer of working). +# +# COMPILER_FEATURES will contain one or more of the following, based on compiler support +# for that feature: c++11 (supports full (or nearly full) C++11 programming environment). +# +# This file may be included multiple times, but only has effect the first time. +# + .if !target(____) ____: +_v!= ${CC} --version .if !defined(COMPILER_TYPE) . if ${CC:T:Mgcc*} COMPILER_TYPE:= gcc . elif ${CC:T:Mclang} COMPILER_TYPE:= clang -. else -_COMPILER_VERSION!= ${CC} --version -. if ${_COMPILER_VERSION:Mgcc} +. elif ${_v:Mgcc} COMPILER_TYPE:= gcc -. elif ${_COMPILER_VERSION:M\(GCC\)} +. elif ${_v:M\(GCC\)} COMPILER_TYPE:= gcc -. elif ${_COMPILER_VERSION:Mclang} +. elif ${_v:Mclang} COMPILER_TYPE:= clang -. else +. else .error Unable to determine compiler type for ${CC}. Consider setting COMPILER_TYPE. -. endif -. undef _COMPILER_VERSION . endif .endif +.if !defined(COMPILER_VERSION) +COMPILER_VERSION!=echo ${_v:M[1-9].[0-9]*} | awk -F. '{print $$1 * 10000 + $$2 * 100 + $$3;}' +.endif +.undef _v .if ${COMPILER_TYPE} == "clang" COMPILER_FEATURES= c++11 diff --git a/share/mk/bsd.sys.mk b/share/mk/bsd.sys.mk index 8b892a9d5133..7150f2f3c0b3 100644 --- a/share/mk/bsd.sys.mk +++ b/share/mk/bsd.sys.mk @@ -64,7 +64,10 @@ CWARNFLAGS+= -Wno-pointer-sign # Clang has more warnings enabled by default, and when using -Wall, so if WARNS # is set to low values, these have to be disabled explicitly. .if ${WARNS} <= 6 -CWARNFLAGS.clang+= -Wno-empty-body -Wno-string-plus-int -Wno-unused-const-variable +CWARNFLAGS.clang+= -Wno-empty-body -Wno-string-plus-int +.if ${COMPILER_TYPE} == "clang" && ${COMPILER_VERSION} > 30300 +CWARNFLAGS.clang+= -Wno-unused-const-variable +.endif .endif # WARNS <= 6 .if ${WARNS} <= 3 CWARNFLAGS.clang+= -Wno-tautological-compare -Wno-unused-value\ -- cgit v1.2.3 From ab72ce6b1bd2665447083bf0f268e6a2e77a845c Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 10 May 2014 16:37:53 +0000 Subject: Migrate NO_WARN to MK_WARN. Support legacy NO_WARN usage. Remove a check for EARLY_BUILD because it isn't necessary (MK_WARN=no will always be defined for that). --- Makefile.inc1 | 10 +++++----- share/mk/bsd.opts.mk | 6 ++++-- share/mk/bsd.sys.mk | 7 +++---- tools/build/options/WITHOUT_WARNS | 5 +++++ 4 files changed, 17 insertions(+), 11 deletions(-) create mode 100644 tools/build/options/WITHOUT_WARNS diff --git a/Makefile.inc1 b/Makefile.inc1 index 549aa2fff001..0781a1c88664 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -248,7 +248,7 @@ BMAKE= MAKEOBJDIRPREFIX=${WORLDTMP} \ SSP_CFLAGS= \ MK_HTML=no MK_INFO=no NO_LINT=yes MK_MAN=no \ -DNO_PIC MK_PROFILE=no -DNO_SHARED \ - -DNO_CPU_CFLAGS -DNO_WARNS MK_CTF=no -DEARLY_BUILD MK_TESTS=no + -DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no -DEARLY_BUILD MK_TESTS=no # build-tools stage TMAKE= MAKEOBJDIRPREFIX=${OBJTREE} \ @@ -258,7 +258,7 @@ TMAKE= MAKEOBJDIRPREFIX=${OBJTREE} \ BOOTSTRAPPING=${OSRELDATE} \ SSP_CFLAGS= \ -DNO_LINT \ - -DNO_CPU_CFLAGS -DNO_WARNS MK_CTF=no -DEARLY_BUILD MK_TESTS=no + -DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no -DEARLY_BUILD MK_TESTS=no # cross-tools stage XMAKE= TOOLS_PREFIX=${WORLDTMP} ${BMAKE} \ @@ -277,7 +277,7 @@ KTMAKE= TOOLS_PREFIX=${WORLDTMP} MAKEOBJDIRPREFIX=${WORLDTMP} \ SSP_CFLAGS= \ MK_HTML=no MK_INFO=no -DNO_LINT MK_MAN=no \ -DNO_PIC MK_PROFILE=no -DNO_SHARED \ - -DNO_CPU_CFLAGS -DNO_WARNS MK_CTF=no -DEARLY_BUILD + -DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no -DEARLY_BUILD # world stage WMAKEENV= ${CROSSENV} \ @@ -609,7 +609,7 @@ build32: WORLDTMP=${WORLDTMP} \ MAKEFLAGS="-m ${.CURDIR}/tools/build/mk ${.MAKEFLAGS}" \ MAKEOBJDIRPREFIX=${OBJTREE}/lib32 ${MAKE} SSP_CFLAGS= DESTDIR= \ - DIRPRFX=${_dir}/ -DNO_LINT -DNO_CPU_CFLAGS -DNO_WARNS MK_CTF=no \ + DIRPRFX=${_dir}/ -DNO_LINT -DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no \ -DEARLY_BUILD build-tools .endfor cd ${.CURDIR}; \ @@ -1846,7 +1846,7 @@ XDEV_CPUTYPE?=${TARGET_CPUTYPE} NOFUN=-DNO_FSCHG MK_HTML=no MK_INFO=no -DNO_LINT \ MK_MAN=no MK_NLS=no MK_PROFILE=no \ - MK_KERBEROS=no MK_RESCUE=no MK_TESTS=no -DNO_WARNS \ + MK_KERBEROS=no MK_RESCUE=no MK_TESTS=no MK_WARNS=no \ TARGET=${XDEV} TARGET_ARCH=${XDEV_ARCH} \ CPUTYPE=${XDEV_CPUTYPE} diff --git a/share/mk/bsd.opts.mk b/share/mk/bsd.opts.mk index 805200b658d7..885d9224c249 100644 --- a/share/mk/bsd.opts.mk +++ b/share/mk/bsd.opts.mk @@ -56,7 +56,8 @@ __DEFAULT_YES_OPTIONS = \ PROFILE \ SSP \ SYMVER \ - TOOLCHAIN + TOOLCHAIN \ + WARNS __DEFAULT_NO_OPTIONS = \ CTF \ @@ -76,7 +77,8 @@ __DEFAULT_NO_OPTIONS = \ DEBUG_FILES \ INSTALLLIB \ MAN \ - PROFILE + PROFILE \ + WARNS .if defined(NO_${var}) # This warning may be premature... #.warning "NO_${var} is defined, but deprecated. Please use MK_${var}=no instead." diff --git a/share/mk/bsd.sys.mk b/share/mk/bsd.sys.mk index 7150f2f3c0b3..3bcd237a9399 100644 --- a/share/mk/bsd.sys.mk +++ b/share/mk/bsd.sys.mk @@ -4,7 +4,7 @@ # sources. # Enable various levels of compiler warning checks. These may be -# overridden (e.g. if using a non-gcc compiler) by defining NO_WARNS. +# overridden (e.g. if using a non-gcc compiler) by defining MK_WARNS=no. # for GCC: http://gcc.gnu.org/onlinedocs/gcc-4.2.1/gcc/Warning-Options.html @@ -134,9 +134,8 @@ CFLAGS+= ${SSP_CFLAGS} .endif # SSP && !IA64 && !ARM && !MIPS # Allow user-specified additional warning flags, plus compiler specific flag overrides. -# Unless we're early in the build, in which case don't (which is lame, this should -# be handled by NO_WARNS which needs to migrate to something else. -.if !defined(NO_WARNS) && !defined(EARLY_BUILD) +# Unless we've overriden this... +.if ${MK_WARNS} != "no" CFLAGS+= ${CWARNFLAGS} ${CWARNFLAGS.${COMPILER_TYPE}} .endif diff --git a/tools/build/options/WITHOUT_WARNS b/tools/build/options/WITHOUT_WARNS new file mode 100644 index 000000000000..185a279bffd9 --- /dev/null +++ b/tools/build/options/WITHOUT_WARNS @@ -0,0 +1,5 @@ +.\" $FreeBSD$ +Set this to not add warning flags to the compiler invocations. +Useful as a temporary workaround when code enters the tree +which triggers warnings in environments that differ from the +original develoepr. -- cgit v1.2.3 From 7273339dc40e5e9e1f0c1fb3c72a29c8528f256d Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 10 May 2014 16:38:03 +0000 Subject: Eliminate EARLY_BUILD flag. It is redundant and means MK_CLANG_FULL=no and MK_LLDB=no, so set those explicitly (now that we can do that). Simplify tests for these variables as well, since we know they will always be defined regardless of the phase of the build. --- Makefile.inc1 | 9 +++++---- lib/clang/Makefile | 11 ++++------- lib/clang/clang.build.mk | 4 ++-- share/mk/bsd.prog.mk | 2 +- share/mk/bsd.sys.mk | 4 ---- usr.bin/clang/clang/Makefile | 4 ++-- 6 files changed, 14 insertions(+), 20 deletions(-) diff --git a/Makefile.inc1 b/Makefile.inc1 index 0781a1c88664..f3fda5769957 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -248,7 +248,8 @@ BMAKE= MAKEOBJDIRPREFIX=${WORLDTMP} \ SSP_CFLAGS= \ MK_HTML=no MK_INFO=no NO_LINT=yes MK_MAN=no \ -DNO_PIC MK_PROFILE=no -DNO_SHARED \ - -DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no -DEARLY_BUILD MK_TESTS=no + -DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no \ + MK_CLANG_FULL=no MK_LLDB=no MK_TESTS=no # build-tools stage TMAKE= MAKEOBJDIRPREFIX=${OBJTREE} \ @@ -258,7 +259,7 @@ TMAKE= MAKEOBJDIRPREFIX=${OBJTREE} \ BOOTSTRAPPING=${OSRELDATE} \ SSP_CFLAGS= \ -DNO_LINT \ - -DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no -DEARLY_BUILD MK_TESTS=no + -DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no MK_CLANG_FULL=no MK_LLDB=no MK_TESTS=no # cross-tools stage XMAKE= TOOLS_PREFIX=${WORLDTMP} ${BMAKE} \ @@ -277,7 +278,7 @@ KTMAKE= TOOLS_PREFIX=${WORLDTMP} MAKEOBJDIRPREFIX=${WORLDTMP} \ SSP_CFLAGS= \ MK_HTML=no MK_INFO=no -DNO_LINT MK_MAN=no \ -DNO_PIC MK_PROFILE=no -DNO_SHARED \ - -DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no -DEARLY_BUILD + -DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no # world stage WMAKEENV= ${CROSSENV} \ @@ -610,7 +611,7 @@ build32: MAKEFLAGS="-m ${.CURDIR}/tools/build/mk ${.MAKEFLAGS}" \ MAKEOBJDIRPREFIX=${OBJTREE}/lib32 ${MAKE} SSP_CFLAGS= DESTDIR= \ DIRPRFX=${_dir}/ -DNO_LINT -DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no \ - -DEARLY_BUILD build-tools + build-tools .endfor cd ${.CURDIR}; \ ${LIB32WMAKE} -f Makefile.inc1 libraries diff --git a/lib/clang/Makefile b/lib/clang/Makefile index ae7ae4a0a44d..328aa7871a92 100644 --- a/lib/clang/Makefile +++ b/lib/clang/Makefile @@ -3,8 +3,7 @@ .include .if !make(install) -.if !defined(EARLY_BUILD) -.if defined(MK_CLANG_FULL) && ${MK_CLANG_FULL} != "no" +.if ${MK_CLANG_FULL} != "no" _libclangstaticanalyzer= \ libclangstaticanalyzercheckers \ libclangstaticanalyzercore \ @@ -12,13 +11,11 @@ _libclangstaticanalyzer= \ _libclangarcmigrate= \ libclangarcmigrate .endif # MK_CLANG_FULL -.if (defined(MK_CLANG_FULL) && ${MK_CLANG_FULL} != "no") || \ - (defined(MK_LLDB) && ${MK_LLDB} != "no") +.if ${MK_CLANG_FULL} != "no" || ${MK_LLDB} != "no" _libclangrewriter= \ libclangrewritecore \ libclangrewritefrontend .endif # (MK_CLANG_FULL || MK_LLDB) -.endif # !EARLY_BUILD SUBDIR= libclanganalysis \ ${_libclangarcmigrate} \ @@ -105,7 +102,7 @@ SUBDIR+=libllvmexecutionengine \ libllvmruntimedyld .endif # MK_CLANG_EXTRAS | LLDB -.if !defined(EARLY_BUILD) && ${MK_LLDB} != "no" +.if ${MK_LLDB} != "no" SUBDIR+=liblldb \ \ liblldbAPI \ @@ -141,7 +138,7 @@ SUBDIR+=liblldb \ liblldbPluginSymbolVendorELF \ liblldbPluginUnwindAssemblyInstEmulation \ liblldbPluginUnwindAssemblyX86 -.endif # !EARLY_BUILD && MK_LLDB +.endif # MK_LLDB .endif # !make(install) diff --git a/lib/clang/clang.build.mk b/lib/clang/clang.build.mk index 057b8aa613b5..3f75a6d99f65 100644 --- a/lib/clang/clang.build.mk +++ b/lib/clang/clang.build.mk @@ -10,11 +10,11 @@ CFLAGS+= -I${LLVM_SRCS}/include -I${CLANG_SRCS}/include \ -DLLVM_ON_UNIX -DLLVM_ON_FREEBSD \ -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS #-DNDEBUG -.if !defined(EARLY_BUILD) && defined(MK_CLANG_FULL) && ${MK_CLANG_FULL} != "no" +.if ${MK_CLANG_FULL} != "no" CFLAGS+= -DCLANG_ENABLE_ARCMT \ -DCLANG_ENABLE_REWRITER \ -DCLANG_ENABLE_STATIC_ANALYZER -.endif # !EARLY_BUILD && MK_CLANG_FULL +.endif # MK_CLANG_FULL # LLVM is not strict aliasing safe as of 12/31/2011 CFLAGS+= -fno-strict-aliasing diff --git a/share/mk/bsd.prog.mk b/share/mk/bsd.prog.mk index 06867eb0e812..a221b53953f1 100644 --- a/share/mk/bsd.prog.mk +++ b/share/mk/bsd.prog.mk @@ -173,7 +173,7 @@ _EXTRADEPEND: .endif .else echo ${PROG}: ${LIBC} ${DPADD} >> ${DEPENDFILE} -.if defined(PROG_CXX) && !defined(EARLY_BUILD) +.if defined(PROG_CXX) .if ${COMPILER_TYPE} == "clang" && empty(CXXFLAGS:M-stdlib=libstdc++) echo ${PROG}: ${LIBCPLUSPLUS} >> ${DEPENDFILE} .else diff --git a/share/mk/bsd.sys.mk b/share/mk/bsd.sys.mk index 3bcd237a9399..41d74461b9ca 100644 --- a/share/mk/bsd.sys.mk +++ b/share/mk/bsd.sys.mk @@ -139,12 +139,8 @@ CFLAGS+= ${SSP_CFLAGS} CFLAGS+= ${CWARNFLAGS} ${CWARNFLAGS.${COMPILER_TYPE}} .endif -# Not sure this is 100% kosher, but I think that EARLY_BUILD must be only -# defined when we're not building programs that use the CFLAGS.foo feature. -.if !defined(EARLY_BUILD) CFLAGS+= ${CFLAGS.${COMPILER_TYPE}} CXXFLAGS+= ${CXXFLAGS.${COMPILER_TYPE}} -.endif # Tell bmake not to mistake standard targets for things to be searched for # or expect to ever be up-to-date. diff --git a/usr.bin/clang/clang/Makefile b/usr.bin/clang/clang/Makefile index 74ef867b441c..345efde9076e 100644 --- a/usr.bin/clang/clang/Makefile +++ b/usr.bin/clang/clang/Makefile @@ -36,7 +36,7 @@ TGHDRS= CC1AsOptions \ DiagnosticSemaKinds \ Options -.if !defined(EARLY_BUILD) && defined(MK_CLANG_FULL) && ${MK_CLANG_FULL} != "no" +.if ${MK_CLANG_FULL} != "no" _clangstaticanalyzer= \ clangstaticanalyzerfrontend \ clangstaticanalyzercheckers \ @@ -46,7 +46,7 @@ _clangarcmigrate= \ _clangrewriter= \ clangrewritefrontend \ clangrewritecore -.endif # !EARLY_BUILD && MK_CLANG_FULL +.endif # MK_CLANG_FULL LIBDEPS=clangfrontendtool \ clangfrontend \ -- cgit v1.2.3 From 22ba0b2f67ac68d6094772a98e961e2aa572383e Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 10 May 2014 16:38:09 +0000 Subject: Simplify clang ifdefs in the kernel a bit. Introduce CFLAGS.${COMPILER_TYPE} to mirror userland. Be explicit about which compiler needs something (not clang isn't necessarily gcc in the future). --- sys/conf/Makefile.arm | 13 +++++-------- sys/conf/kern.mk | 20 +++++++------------- sys/conf/kern.pre.mk | 22 +++++++++------------- sys/conf/kmod.mk | 8 +++----- 4 files changed, 24 insertions(+), 39 deletions(-) diff --git a/sys/conf/Makefile.arm b/sys/conf/Makefile.arm index 562d15227eca..9ea428e91fa8 100644 --- a/sys/conf/Makefile.arm +++ b/sys/conf/Makefile.arm @@ -39,20 +39,17 @@ SYSTEM_DEP:= ${SYSTEM_DEP:$S/conf/ldscript.$M=ldscript.$M} STRIP_FLAGS = -S .endif -.if ${COMPILER_TYPE} != "clang" -CFLAGS += -mno-thumb-interwork -.endif +# We don't support gcc's thump interwork stuff, so disable it +CFLAGS.gcc += -mno-thumb-interwork .if empty(DDB_ENABLED) -.if ${MK_ARM_EABI} == "no" && ${COMPILER_TYPE} == "gcc" -CFLAGS += -mno-apcs-frame +.if ${MK_ARM_EABI} == "no" +CFLAGS.gcc += -mno-apcs-frame .endif .elif ${MK_ARM_EABI} != "no" CFLAGS += -funwind-tables -.if ${COMPILER_TYPE} == "clang" # clang requires us to tell it to emit assembly with unwind information -CFLAGS += -mllvm -arm-enable-ehabi -.endif +CFLAGS.clang += -mllvm -arm-enable-ehabi .endif # hack because genassym.c includes sys/bus.h which includes these. diff --git a/sys/conf/kern.mk b/sys/conf/kern.mk index 1571f8360512..19afc4d49381 100644 --- a/sys/conf/kern.mk +++ b/sys/conf/kern.mk @@ -64,11 +64,8 @@ FORMAT_EXTENSIONS= -fformat-extensions # Setting -mno-sse implies -mno-sse2, -mno-sse3, -mno-ssse3, -mno-sse41 and -mno-sse42 # .if ${MACHINE_CPUARCH} == "i386" -.if ${COMPILER_TYPE} != "clang" -CFLAGS+= -mno-align-long-strings -mpreferred-stack-boundary=2 -.else -CFLAGS+= -mno-aes -mno-avx -.endif +CFLAGS.gcc+= -mno-align-long-strings -mpreferred-stack-boundary=2 +CFLAGS.clang+= -mno-aes -mno-avx CFLAGS+= -mno-mmx -mno-sse -msoft-float INLINE_LIMIT?= 8000 .endif @@ -93,11 +90,8 @@ INLINE_LIMIT?= 15000 # operations which it has a tendency to do. # .if ${MACHINE_CPUARCH} == "sparc64" -.if ${COMPILER_TYPE} == "clang" -CFLAGS+= -mcmodel=large -fno-dwarf2-cfi-asm -.else -CFLAGS+= -mcmodel=medany -msoft-float -.endif +CFLAGS.clang+= -mcmodel=large -fno-dwarf2-cfi-asm +CFLAGS.gcc+= -mcmodel=medany -msoft-float INLINE_LIMIT?= 15000 .endif @@ -116,9 +110,7 @@ INLINE_LIMIT?= 15000 # (-mfpmath= is not supported) # .if ${MACHINE_CPUARCH} == "amd64" -.if ${COMPILER_TYPE} == "clang" -CFLAGS+= -mno-aes -mno-avx -.endif +CFLAGS.clang+= -mno-aes -mno-avx CFLAGS+= -mcmodel=kernel -mno-red-zone -mno-mmx -mno-sse -msoft-float \ -fno-asynchronous-unwind-tables INLINE_LIMIT?= 8000 @@ -173,3 +165,5 @@ CFLAGS+= -fstack-protector .if ${CFLAGS:M-g} != "" && ${CFLAGS:M-gdwarf*} == "" CFLAGS+= -gdwarf-2 .endif + +CFLAGS+= ${CFLAGS.${COMPILER_TYPE}} diff --git a/sys/conf/kern.pre.mk b/sys/conf/kern.pre.mk index 343be5742699..05706fa85be7 100644 --- a/sys/conf/kern.pre.mk +++ b/sys/conf/kern.pre.mk @@ -37,10 +37,10 @@ _MINUS_O= -O2 .endif .endif .if ${MACHINE_CPUARCH} == "amd64" -.if ${COMPILER_TYPE} != "clang" -COPTFLAGS?=-O2 -frename-registers -pipe -.else +.if ${COMPILER_TYPE} == "clang" COPTFLAGS?=-O2 -pipe +.else +COPTFLAGS?=-O2 -frename-registers -pipe .endif .else COPTFLAGS?=${_MINUS_O} -pipe @@ -86,13 +86,11 @@ CFLAGS_PARAM_LARGE_FUNCTION_GROWTH?=1000 .if ${MACHINE_CPUARCH} == "mips" CFLAGS_ARCH_PARAMS?=--param max-inline-insns-single=1000 .endif -.if ${COMPILER_TYPE} != "clang" -CFLAGS+= -fno-common -finline-limit=${INLINE_LIMIT} -CFLAGS+= --param inline-unit-growth=${CFLAGS_PARAM_INLINE_UNIT_GROWTH} -CFLAGS+= --param large-function-growth=${CFLAGS_PARAM_LARGE_FUNCTION_GROWTH} +CFLAGS.gcc+= -fno-common -finline-limit=${INLINE_LIMIT} +CFLAGS.gcc+= --param inline-unit-growth=${CFLAGS_PARAM_INLINE_UNIT_GROWTH} +CFLAGS.gcc+= --param large-function-growth=${CFLAGS_PARAM_LARGE_FUNCTION_GROWTH} .if defined(CFLAGS_ARCH_PARAMS) -CFLAGS+=${CFLAGS_ARCH_PARAMS} -.endif +CFLAGS.gcc+=${CFLAGS_ARCH_PARAMS} .endif WERROR?= -Werror @@ -107,13 +105,11 @@ GCC_MS_EXTENSIONS= -fms-extensions .if defined(PROFLEVEL) && ${PROFLEVEL} >= 1 CFLAGS+= -DGPROF -.if ${COMPILER_TYPE} != "clang" -CFLAGS+= -falign-functions=16 -.endif +CFLAGS.gcc+= -falign-functions=16 .if ${PROFLEVEL} >= 2 CFLAGS+= -DGPROF4 -DGUPROF PROF= -pg -.if ${COMPILER_TYPE} != "clang" +.if ${COMPILER_TYPE} == "gcc" PROF+= -mprofiler-epilogue .endif .else diff --git a/sys/conf/kmod.mk b/sys/conf/kmod.mk index ebd6179d8453..4f85ab4185a3 100644 --- a/sys/conf/kmod.mk +++ b/sys/conf/kmod.mk @@ -116,11 +116,9 @@ CFLAGS+= -I. -I@ # for example. CFLAGS+= -I@/contrib/altq -.if ${COMPILER_TYPE} != "clang" -CFLAGS+= -finline-limit=${INLINE_LIMIT} -CFLAGS+= --param inline-unit-growth=100 -CFLAGS+= --param large-function-growth=1000 -.endif +CFLAGS.gcc+= -finline-limit=${INLINE_LIMIT} +CFLAGS.gcc+= --param inline-unit-growth=100 +CFLAGS.gcc+= --param large-function-growth=1000 # Disallow common variables, and if we end up with commons from # somewhere unexpected, allocate storage for them in the module itself. -- cgit v1.2.3 From 58c2dbbc30fbd7673cbba8d2098bc86f4fa626ef Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 10 May 2014 16:38:18 +0000 Subject: Remove the compatibility hack for FreeBSD 7 systems for MACHINE_CPUARCH. Fewer places to have to hack each time a new one is added. --- sys/conf/kern.pre.mk | 3 --- sys/conf/kmod.mk | 3 --- 2 files changed, 6 deletions(-) diff --git a/sys/conf/kern.pre.mk b/sys/conf/kern.pre.mk index 05706fa85be7..6db81ebfc519 100644 --- a/sys/conf/kern.pre.mk +++ b/sys/conf/kern.pre.mk @@ -7,9 +7,6 @@ .include .include "kern.opts.mk" -# backwards compat option for older systems. -MACHINE_CPUARCH?=${MACHINE_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc64/powerpc/} - # Can be overridden by makeoptions or /etc/make.conf KERNEL_KO?= kernel KERNEL?= kernel diff --git a/sys/conf/kmod.mk b/sys/conf/kmod.mk index 4f85ab4185a3..242c3c680963 100644 --- a/sys/conf/kmod.mk +++ b/sys/conf/kmod.mk @@ -60,9 +60,6 @@ # Unload a module. # -# backwards compat option for older systems. -MACHINE_CPUARCH?=${MACHINE_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc64/powerpc/} - AWK?= awk KMODLOAD?= /sbin/kldload KMODUNLOAD?= /sbin/kldunload -- cgit v1.2.3 From dfd11a44133fe332d2c75a32411a8c75cfe1655c Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 10 May 2014 16:38:27 +0000 Subject: g/c unmaintained, uninstalled bsd.pkg.mk. It tied into the ports system, as it existed 9 years ago, and has been obsolete for a long time. --- share/mk/bsd.pkg.mk | 48 ------------------------------------------------ share/mk/bsd.prog.mk | 4 ---- share/mk/bsd.sys.mk | 6 +----- 3 files changed, 1 insertion(+), 57 deletions(-) delete mode 100644 share/mk/bsd.pkg.mk diff --git a/share/mk/bsd.pkg.mk b/share/mk/bsd.pkg.mk deleted file mode 100644 index 3d1ca42e9355..000000000000 --- a/share/mk/bsd.pkg.mk +++ /dev/null @@ -1,48 +0,0 @@ -# $FreeBSD$ - -WRKDIR=${.OBJDIR} -.if ${.OBJDIR} == ${.CURDIR} -WRKDIR=${.CURDIR}/work -.endif -NO_WRKSUBDIR=YES -NO_CHECKSUM=YES -NO_BUILD=YES - -fetch: -extract: -patch: -configure: -build: - -.if target(____) -clean: do-clean -.if ${CANONICALOBJDIR} != ${.CURDIR} && exists(${CANONICALOBJDIR}/) - @rm -rf ${CANONICALOBJDIR} -.else - @if [ -L ${.CURDIR}/obj ]; then rm -f ${.CURDIR}/obj; fi -.if defined(CLEANFILES) && !empty(CLEANFILES) - rm -f ${CLEANFILES} -.endif -.if defined(CLEANDIRS) && !empty(CLEANDIRS) - rm -rf ${CLEANDIRS} -.endif -.endif -.endif - -.if !target(beforeinstall) -beforeinstall: -.endif -.if !target(afterinstall) -afterinstall: -.endif - -install: install-message check-categories check-conflicts \ - run-depends lib-depends pre-install pre-install-script \ - generate-plist check-already-installed \ - check-umask install-mtree pre-su-install \ - pre-su-install-script \ - beforeinstall realinstall afterinstall \ - add-plist-info post-install post-install-script \ - compress-man run-ldconfig fake-pkg - -.include diff --git a/share/mk/bsd.prog.mk b/share/mk/bsd.prog.mk index a221b53953f1..fd35e0323028 100644 --- a/share/mk/bsd.prog.mk +++ b/share/mk/bsd.prog.mk @@ -276,7 +276,3 @@ ${OBJS}: ${SRCS:M*.h} .include .include - -.if defined(PORTNAME) -.include -.endif diff --git a/share/mk/bsd.sys.mk b/share/mk/bsd.sys.mk index 41d74461b9ca..f019e5ebc593 100644 --- a/share/mk/bsd.sys.mk +++ b/share/mk/bsd.sys.mk @@ -147,15 +147,11 @@ CXXFLAGS+= ${CXXFLAGS.${COMPILER_TYPE}} PHONY_NOTMAIN = afterdepend afterinstall all beforedepend beforeinstall \ beforelinking build build-tools buildfiles buildincludes \ checkdpadd clean cleandepend cleandir cleanobj configure \ - depend dependall distclean distribute exe extract \ + depend dependall distclean distribute exe \ html includes install installfiles installincludes lint \ obj objlink objs objwarn realall realdepend \ realinstall regress subdir-all subdir-depend subdir-install \ tags whereobj -.if defined(PORTNAME) -PHONY_NOTMAIN+= fetch patch -.endif - .PHONY: ${PHONY_NOTMAIN} .NOTMAIN: ${PHONY_NOTMAIN} -- cgit v1.2.3 From be4646cf7f16392345f2896879ad15961c360b48 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 10 May 2014 16:38:32 +0000 Subject: Remove some useless, commented out code. Remove name space polution in the POSIX case by moving more things under !Posix part of an if. --- share/mk/sys.mk | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/share/mk/sys.mk b/share/mk/sys.mk index 2f84319b84c7..f9ea0e23d413 100644 --- a/share/mk/sys.mk +++ b/share/mk/sys.mk @@ -74,10 +74,6 @@ CTFMERGE ?= ctfmerge DTRACE ?= dtrace .if defined(CFLAGS) && (${CFLAGS:M-g} != "") CTFFLAGS += -g -.else -# XXX: What to do here? Is removing the CFLAGS part completely ok here? -# For now comment it out to not compile with -g unconditionally. -#CFLAGS += -g .endif CXX ?= c++ @@ -338,11 +334,7 @@ SHELL= ${__MAKE_SHELL} # Toggle on warnings .WARN: dirsyntax -.endif - -.endif - -.if defined(.PARSEDIR) +.else # is bmake # Tell bmake to expand -V VAR by default .MAKE.EXPAND_VARIABLES= yes @@ -359,7 +351,8 @@ SHELL= ${__MAKE_SHELL} echoFlag=v errFlag=e \ path=${__MAKE_SHELL:U/bin/sh} .endif - -.endif +.endif # bmake .include + +.endif # ! Posix -- cgit v1.2.3 From c115b8184e271efe4b570223da6156cb3b32dc23 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 10 May 2014 16:38:37 +0000 Subject: Remove last two NO_MAN= in the tree. In both of these cases, MAN= is what is needed. --- share/mk/bsd.test.mk | 3 +-- tests/sys/netinet/Makefile | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/share/mk/bsd.test.mk b/share/mk/bsd.test.mk index 2aa7a33d8563..33993035b5fe 100644 --- a/share/mk/bsd.test.mk +++ b/share/mk/bsd.test.mk @@ -51,8 +51,7 @@ SUBDIR+= ${TESTS_SUBDIRS} # it is rare for test cases to have man pages .if !defined(MAN) -NO_MAN=yes -.export NO_MAN +MAN= .endif # tell progs.mk we might want to install things diff --git a/tests/sys/netinet/Makefile b/tests/sys/netinet/Makefile index aff1b421ea07..e271e2fe1c63 100644 --- a/tests/sys/netinet/Makefile +++ b/tests/sys/netinet/Makefile @@ -6,7 +6,7 @@ BINDIR= ${TESTSDIR} ATF_TESTS_SH+= fibs_test PROG= udp_dontroute SRCS= udp_dontroute.c -NO_MAN= +MAN= WARNS?= 6 .include -- cgit v1.2.3 From 93654dca21248e1bef592d868faf27ad1a69e994 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 10 May 2014 16:38:45 +0000 Subject: We haven't done anything with _UPGRADING in ~forever (was present, but not needed, in FreeBSD 6.x, and has been absent in newer versions). This was needed to upgrade from 3.x -> 4.x, once upon a time. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a29e01a15ee8..8db5fe4cbc48 100644 --- a/Makefile +++ b/Makefile @@ -327,7 +327,7 @@ MMAKEENV= MAKEOBJDIRPREFIX=${MYMAKE:H} \ DESTDIR= \ INSTALL="sh ${.CURDIR}/tools/install.sh" MMAKE= ${MMAKEENV} ${MAKE} \ - -D_UPGRADING -DNO_MAN -DNO_SHARED \ + -DNO_MAN -DNO_SHARED \ -DNO_CPU_CFLAGS -DNO_WERROR \ DESTDIR= PROGNAME=${MYMAKE:T} -- cgit v1.2.3 From 7ecf742eebab46b6c2b6c7037e204a2447609a82 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 10 May 2014 16:38:54 +0000 Subject: Move DOCCOMPRESS to MK variable. --- share/mk/bsd.doc.mk | 8 ++++---- share/mk/bsd.opts.mk | 1 + tools/build/options/WITHOUT_DOCCOMPRESS | 4 ++++ tools/build/options/WITHOUT_MANCOMPRESS | 5 +++++ 4 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 tools/build/options/WITHOUT_DOCCOMPRESS create mode 100644 tools/build/options/WITHOUT_MANCOMPRESS diff --git a/share/mk/bsd.doc.mk b/share/mk/bsd.doc.mk index 49b2d9b85fa8..836ace9568c8 100644 --- a/share/mk/bsd.doc.mk +++ b/share/mk/bsd.doc.mk @@ -19,7 +19,7 @@ # # MACROS Macro packages used to build the document. [not set] # -# NO_DOCCOMPRESS If you do not want formatted troff documents to be +# WITHOUT_DOCCOMPRESS If you do not want formatted troff documents to be # compressed when they are installed. [not set] # # PRINTERDEVICE Indicates which output formats will be generated @@ -87,7 +87,7 @@ DCOMPRESS_CMD?= ${COMPRESS_CMD} DFILE.html= ${DOC}.html .endfor .for _dev in ${PRINTERDEVICE:Nhtml} -.if defined(NO_DOCCOMPRESS) +.if ${MK_DOCCOMPRESS} == "no" DFILE.${_dev}= ${DOC}.${_dev} .else DFILE.${_dev}= ${DOC}.${_dev}${DCOMPRESS_EXT} @@ -117,7 +117,7 @@ print: ${DFILE.${_dev}} .endfor print: .for _dev in ${PRINTERDEVICE} -.if defined(NO_DOCCOMPRESS) +.if ${MK_DOCCOMPRESS} == "no" ${LPR} ${DFILE.${_dev}} .else ${DCOMPRESS_CMD} -d ${DFILE.${_dev}} | ${LPR} @@ -164,7 +164,7 @@ CLEANFILES+= _stamp.extra ${DFILE.${_dev}}: _stamp.extra .endif ${DFILE.${_dev}}: ${SRCS} -.if defined(NO_DOCCOMPRESS) +.if ${MK_DOCCOMPRESS} == "no" ${ROFF.${_dev}} ${.ALLSRC:N_stamp.extra} > ${.TARGET} .else ${ROFF.${_dev}} ${.ALLSRC:N_stamp.extra} | ${DCOMPRESS_CMD} > ${.TARGET} diff --git a/share/mk/bsd.opts.mk b/share/mk/bsd.opts.mk index 885d9224c249..327b9970c41d 100644 --- a/share/mk/bsd.opts.mk +++ b/share/mk/bsd.opts.mk @@ -45,6 +45,7 @@ ____: __DEFAULT_YES_OPTIONS = \ ASSERT_DEBUG \ + DOCCOMPRESS \ INFO \ INSTALLLIB \ KERBEROS \ diff --git a/tools/build/options/WITHOUT_DOCCOMPRESS b/tools/build/options/WITHOUT_DOCCOMPRESS new file mode 100644 index 000000000000..7580202cd236 --- /dev/null +++ b/tools/build/options/WITHOUT_DOCCOMPRESS @@ -0,0 +1,4 @@ +.\" $FreeBSD$ +Set to not to install compressed system documentation. +Only the uncompressed version will be installed. + diff --git a/tools/build/options/WITHOUT_MANCOMPRESS b/tools/build/options/WITHOUT_MANCOMPRESS new file mode 100644 index 000000000000..d270d1d703c1 --- /dev/null +++ b/tools/build/options/WITHOUT_MANCOMPRESS @@ -0,0 +1,5 @@ +.\" $FreeBSD$ +Set to not to install compressed man pages. +Only the uncompressed versions will be installed. + + -- cgit v1.2.3 From b8fffe166dee826100722fefefdcf6dd73bd194f Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 10 May 2014 16:39:00 +0000 Subject: Sprinkle a few more .WAITs into the mix after csu, libc, msun and the early built libraries. This should be sufficient for most cases and has eliminated the issues I've seen with high -j builds. Races likely still remain, but this knocks the problem down a notch. --- lib/Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/Makefile b/lib/Makefile index de87cbaa8560..51abfcadcdb0 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -31,8 +31,12 @@ # Except it appears bind needs to be compiled last SUBDIR_ORDERED= ${_csu} \ + .WAIT \ libc \ libc_nonshared \ + .WAIT \ + msun \ + .WAIT \ libbsm \ libauditd \ libutil \ @@ -45,7 +49,6 @@ SUBDIR_ORDERED= ${_csu} \ ${_libiconv_modules} \ libkvm \ ${_libldns} \ - msun \ libmd \ ncurses \ ${_libnetgraph} \ @@ -62,6 +65,7 @@ SUBDIR_ORDERED+= libcom_err .endif SUBDIR= ${SUBDIR_ORDERED} \ + .WAIT \ libalias \ libarchive \ ${_libatm} \ -- cgit v1.2.3 From e8bad5dc64783d1b4c9d243414c440aba43d5491 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 10 May 2014 16:39:08 +0000 Subject: grep -L returns non-zero status if none of the files had the pattern in them. This is often the case, so just ignore the return code. Actual errors that are found will also be detected downstream in the rare cases where the return code is 2 instead of 1. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8db5fe4cbc48..c47ba90a70cb 100644 --- a/Makefile +++ b/Makefile @@ -450,7 +450,7 @@ TARGET!= uname -m .if defined(MAKE_ALL_KERNELS) _THINNER=cat .else -_THINNER=xargs grep -L "^.NO_UNIVERSE" +_THINNER=xargs grep -L "^.NO_UNIVERSE" || true .endif KERNCONFS!= cd ${KERNSRCDIR}/${TARGET}/conf && \ find [A-Z0-9]*[A-Z0-9] -type f -maxdepth 0 \ -- cgit v1.2.3 From 724afafa7249392ff5a6c15f488b0c97ef2b1e0f Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 10 May 2014 16:39:15 +0000 Subject: bitrotted compat cruft removal: o KMODDEPS warning is 15 years stale. Remove it. o MK_CTF will always be defined now, so no need to test to see if it is defined. o no need to define MK_FORMAT_EXTENTIONS if undefined anymore. --- sys/conf/kern.mk | 3 --- sys/conf/kmod.mk | 6 +----- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/sys/conf/kern.mk b/sys/conf/kern.mk index 19afc4d49381..ee9a204c21ed 100644 --- a/sys/conf/kern.mk +++ b/sys/conf/kern.mk @@ -1,8 +1,5 @@ # $FreeBSD$ -# Compat -MK_FORMAT_EXTENSIONS?=no - # # Warning flags for compiling the kernel and components of the kernel: # diff --git a/sys/conf/kmod.mk b/sys/conf/kmod.mk index 242c3c680963..b3f058967097 100644 --- a/sys/conf/kmod.mk +++ b/sys/conf/kmod.mk @@ -65,10 +65,6 @@ KMODLOAD?= /sbin/kldload KMODUNLOAD?= /sbin/kldunload OBJCOPY?= objcopy -.if defined(KMODDEPS) -.error "Do not use KMODDEPS on 5.0+; use MODULE_VERSION/MODULE_DEPEND" -.endif - # Note: we're really bsd.kmod.mk, so we have to allow src.opts.mk to be # optional. Include it if we can so we can get /etc/src.conf changes, # if we're in the tree. If we can't include it that's OK. kern.opts.mk @@ -204,7 +200,7 @@ ${KMOD}.kld: ${OBJS} ${FULLPROG}: ${OBJS} .endif ${LD} ${LDFLAGS} -r -d -o ${.TARGET} ${OBJS} -.if defined(MK_CTF) && ${MK_CTF} != "no" +.if ${MK_CTF} != "no" ${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${OBJS} .endif .if defined(EXPORT_SYMS) -- cgit v1.2.3 From b17de684ba85f679a41a134e1954458c679f58fe Mon Sep 17 00:00:00 2001 From: Eitan Adler Date: Sat, 10 May 2014 16:59:15 +0000 Subject: arcconfig: add one Add a .arcconfig to allow arc to work in its usual way. --- .arcconfig | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .arcconfig diff --git a/.arcconfig b/.arcconfig new file mode 100644 index 000000000000..848a7636d0cc --- /dev/null +++ b/.arcconfig @@ -0,0 +1,3 @@ +{ + "phabricator.uri" : "https://phabric.freebsd.org/" +} -- cgit v1.2.3 From 0973283d6e0c5f59f02b690ec7084ece0d86bd14 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 10 May 2014 17:03:33 +0000 Subject: For the upgrade case in vm_fault_copy_entry(), when the entry does not need COW and is writeable (i.e. becoming writeable due to the mprotect(2) operation), do not create a new backing object for the entry. The caller of the function is vm_map_protect(), the call is made to ensure that wired entry has all pages resident and wired in the top level object and to enable the write. We might need to copy read-only page from some backing objects into the top object or remap the page with the write allowed. This fixes the issue with mishandling of the swap accounting when read-only wired mapping is upgraded to write-enabled after fork. The previous code path did not accounted the new object, but it creation is redundand anyway and the change provides an optimization for the non-common situation. Reported by: markj Suggested and reviewed by: alc (previous version) Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/vm/vm_fault.c | 107 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 67 insertions(+), 40 deletions(-) diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index 3faf28b04073..125a5fc2bdd3 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -1247,38 +1247,48 @@ vm_fault_copy_entry(vm_map_t dst_map, vm_map_t src_map, #endif /* lint */ upgrade = src_entry == dst_entry; + access = prot = dst_entry->protection; src_object = src_entry->object.vm_object; src_pindex = OFF_TO_IDX(src_entry->offset); - /* - * Create the top-level object for the destination entry. (Doesn't - * actually shadow anything - we copy the pages directly.) - */ - dst_object = vm_object_allocate(OBJT_DEFAULT, - OFF_TO_IDX(dst_entry->end - dst_entry->start)); + if (upgrade && (dst_entry->eflags & MAP_ENTRY_NEEDS_COPY) == 0) { + dst_object = src_object; + vm_object_reference(dst_object); + } else { + /* + * Create the top-level object for the destination entry. (Doesn't + * actually shadow anything - we copy the pages directly.) + */ + dst_object = vm_object_allocate(OBJT_DEFAULT, + OFF_TO_IDX(dst_entry->end - dst_entry->start)); #if VM_NRESERVLEVEL > 0 - dst_object->flags |= OBJ_COLORED; - dst_object->pg_color = atop(dst_entry->start); + dst_object->flags |= OBJ_COLORED; + dst_object->pg_color = atop(dst_entry->start); #endif + } VM_OBJECT_WLOCK(dst_object); KASSERT(upgrade || dst_entry->object.vm_object == NULL, ("vm_fault_copy_entry: vm_object not NULL")); - dst_entry->object.vm_object = dst_object; - dst_entry->offset = 0; - dst_object->charge = dst_entry->end - dst_entry->start; + if (src_object != dst_object) { + dst_entry->object.vm_object = dst_object; + dst_entry->offset = 0; + dst_object->charge = dst_entry->end - dst_entry->start; + } if (fork_charge != NULL) { KASSERT(dst_entry->cred == NULL, ("vm_fault_copy_entry: leaked swp charge")); dst_object->cred = curthread->td_ucred; crhold(dst_object->cred); *fork_charge += dst_object->charge; - } else { + } else if (dst_object->cred == NULL) { + KASSERT(dst_entry->cred != NULL, ("no cred for entry %p", + dst_entry)); dst_object->cred = dst_entry->cred; dst_entry->cred = NULL; } - access = prot = dst_entry->protection; + /* * If not an upgrade, then enter the mappings in the pmap as * read and/or execute accesses. Otherwise, enter them as @@ -1304,26 +1314,14 @@ vm_fault_copy_entry(vm_map_t dst_map, vm_map_t src_map, for (vaddr = dst_entry->start, dst_pindex = 0; vaddr < dst_entry->end; vaddr += PAGE_SIZE, dst_pindex++) { - - /* - * Allocate a page in the destination object. - */ - do { - dst_m = vm_page_alloc(dst_object, dst_pindex, - VM_ALLOC_NORMAL); - if (dst_m == NULL) { - VM_OBJECT_WUNLOCK(dst_object); - VM_WAIT; - VM_OBJECT_WLOCK(dst_object); - } - } while (dst_m == NULL); - +again: /* * Find the page in the source object, and copy it in. * Because the source is wired down, the page will be * in memory. */ - VM_OBJECT_RLOCK(src_object); + if (src_object != dst_object) + VM_OBJECT_RLOCK(src_object); object = src_object; pindex = src_pindex + dst_pindex; while ((src_m = vm_page_lookup(object, pindex)) == NULL && @@ -1343,14 +1341,39 @@ vm_fault_copy_entry(vm_map_t dst_map, vm_map_t src_map, VM_OBJECT_RLOCK(backing_object); pindex += OFF_TO_IDX(object->backing_object_offset); - VM_OBJECT_RUNLOCK(object); + if (object != dst_object) + VM_OBJECT_RUNLOCK(object); object = backing_object; } KASSERT(src_m != NULL, ("vm_fault_copy_entry: page missing")); - pmap_copy_page(src_m, dst_m); - VM_OBJECT_RUNLOCK(object); - dst_m->valid = VM_PAGE_BITS_ALL; - dst_m->dirty = VM_PAGE_BITS_ALL; + + if (object != dst_object) { + /* + * Allocate a page in the destination object. + */ + do { + dst_m = vm_page_alloc(dst_object, + (src_object == dst_object ? src_pindex : + 0) + dst_pindex, VM_ALLOC_NORMAL); + if (dst_m == NULL) { + VM_OBJECT_WUNLOCK(dst_object); + VM_OBJECT_RUNLOCK(object); + VM_WAIT; + goto again; + } + } while (dst_m == NULL); + pmap_copy_page(src_m, dst_m); + VM_OBJECT_RUNLOCK(object); + dst_m->valid = VM_PAGE_BITS_ALL; + dst_m->dirty = VM_PAGE_BITS_ALL; + } else { + dst_m = src_m; + if (vm_page_sleep_if_busy(dst_m, "fltupg")) + goto again; + vm_page_xbusy(dst_m); + KASSERT(dst_m->valid == VM_PAGE_BITS_ALL, + ("invalid dst page %p", dst_m)); + } VM_OBJECT_WUNLOCK(dst_object); /* @@ -1366,13 +1389,17 @@ vm_fault_copy_entry(vm_map_t dst_map, vm_map_t src_map, VM_OBJECT_WLOCK(dst_object); if (upgrade) { - vm_page_lock(src_m); - vm_page_unwire(src_m, 0); - vm_page_unlock(src_m); - - vm_page_lock(dst_m); - vm_page_wire(dst_m); - vm_page_unlock(dst_m); + if (src_m != dst_m) { + vm_page_lock(src_m); + vm_page_unwire(src_m, 0); + vm_page_unlock(src_m); + vm_page_lock(dst_m); + vm_page_wire(dst_m); + vm_page_unlock(dst_m); + } else { + KASSERT(dst_m->wire_count > 0, + ("dst_m %p is not wired", dst_m)); + } } else { vm_page_lock(dst_m); vm_page_activate(dst_m); -- cgit v1.2.3 From 6e76445cf757a6f21c6c060d5773a7a64f447c9b Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Sat, 10 May 2014 17:42:21 +0000 Subject: sh: Don't discard getopts state on unknown option or missing argument. When getopts finds an invalid option or a missing option-argument, it should not reset its state and should set OPTIND as normal. This is an old ash bug that was fixed long ago in dash. Our behaviour now matches most other shells. --- bin/sh/options.c | 12 ++++-------- bin/sh/tests/builtins/getopts6.0 | 7 +++++++ bin/sh/tests/builtins/getopts7.0 | 6 ++++++ 3 files changed, 17 insertions(+), 8 deletions(-) create mode 100644 bin/sh/tests/builtins/getopts6.0 create mode 100644 bin/sh/tests/builtins/getopts7.0 diff --git a/bin/sh/options.c b/bin/sh/options.c index caaa88461056..8594c5707a4c 100644 --- a/bin/sh/options.c +++ b/bin/sh/options.c @@ -480,7 +480,7 @@ atend: INTON; } c = '?'; - goto bad; + goto out; } if (*++q == ':') q++; @@ -501,7 +501,7 @@ atend: INTON; c = '?'; } - goto bad; + goto out; } if (p == **optnext) @@ -511,14 +511,10 @@ atend: } else setvarsafe("OPTARG", "", 0); - ind = *optnext - optfirst + 1; - goto out; -bad: - ind = 1; - *optnext = NULL; - p = NULL; out: + if (*optnext != NULL) + ind = *optnext - optfirst + 1; *optptr = p; fmtstr(s, sizeof(s), "%d", ind); err |= setvarsafe("OPTIND", s, VNOFUNC); diff --git a/bin/sh/tests/builtins/getopts6.0 b/bin/sh/tests/builtins/getopts6.0 new file mode 100644 index 000000000000..1d3c39ba953e --- /dev/null +++ b/bin/sh/tests/builtins/getopts6.0 @@ -0,0 +1,7 @@ +# $FreeBSD$ + +set -- -x -y +getopts :x var || echo "First getopts bad: $?" +getopts :x var +r=$? +[ r != 0 ] && [ "$OPTIND" = 3 ] diff --git a/bin/sh/tests/builtins/getopts7.0 b/bin/sh/tests/builtins/getopts7.0 new file mode 100644 index 000000000000..3745555f8c1a --- /dev/null +++ b/bin/sh/tests/builtins/getopts7.0 @@ -0,0 +1,6 @@ +# $FreeBSD$ + +set -- -x +getopts :x: var +r=$? +[ r != 0 ] && [ "$OPTIND" = 2 ] -- cgit v1.2.3 From 9b6224b70f404bd85fe19cd23a231562250f36d0 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 10 May 2014 18:59:09 +0000 Subject: Style. Sponsored by: The FreeBSD Foundation MFC after: 1 week --- lib/libc/gen/sem_new.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/libc/gen/sem_new.c b/lib/libc/gen/sem_new.c index 9a2ab2716dfc..f1960066d0a5 100644 --- a/lib/libc/gen/sem_new.c +++ b/lib/libc/gen/sem_new.c @@ -294,13 +294,13 @@ _sem_unlink(const char *name) return -1; } name++; - strcpy(path, SEM_PREFIX); if (strlcat(path, name, sizeof(path)) >= sizeof(path)) { errno = ENAMETOOLONG; return (-1); } - return unlink(path); + + return (unlink(path)); } int -- cgit v1.2.3 From 8207fd5f81ddd3d649eb5fb99e5dfa02a14d22ab Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Sat, 10 May 2014 19:06:36 +0000 Subject: sh: Add new tests to the Makefile. --- bin/sh/tests/builtins/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bin/sh/tests/builtins/Makefile b/bin/sh/tests/builtins/Makefile index c0b21dc6072d..054a3b8fde7c 100644 --- a/bin/sh/tests/builtins/Makefile +++ b/bin/sh/tests/builtins/Makefile @@ -83,6 +83,8 @@ FILES+= getopts2.0 getopts2.0.stdout FILES+= getopts3.0 FILES+= getopts4.0 FILES+= getopts5.0 +FILES+= getopts6.0 +FILES+= getopts7.0 FILES+= hash1.0 hash1.0.stdout FILES+= hash2.0 hash2.0.stdout FILES+= hash3.0 hash3.0.stdout -- cgit v1.2.3 From ca5e4fe97019c4a616b6b07569c22dba75467dab Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 10 May 2014 19:08:07 +0000 Subject: Invalidate the cache for the named posix semaphore when opened and actual file storing the semaphore object is different from the file created on the first open. Store the file st_dev and st_ino members of the struct stat in the semaphore structure on open, and compare them with the attributes of the opened file to detect unlink and re-creation. This fixes an issue of sem_unlink(3) failing to flush the named entry in the semaphore list for the current or remote process, making sem_unlink(3) not correctly operating if the unlinked semaphore is still opened. Reported by: Joris Giovannangeli PR: standards/189353 Reviewed by: jilles (previous version) Sponsored by: The FreeBSD Foundation MFC after: 1 week --- lib/libc/gen/sem_new.c | 65 ++++++++++++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/lib/libc/gen/sem_new.c b/lib/libc/gen/sem_new.c index f1960066d0a5..ec1a2fde8537 100644 --- a/lib/libc/gen/sem_new.c +++ b/lib/libc/gen/sem_new.c @@ -66,6 +66,8 @@ __weak_reference(_sem_wait, sem_wait); struct sem_nameinfo { int open_count; char *name; + dev_t dev; + ino_t ino; sem_t *sem; LIST_ENTRY(sem_nameinfo) next; }; @@ -151,37 +153,46 @@ _sem_open(const char *name, int flags, ...) return (SEM_FAILED); } name++; - + strcpy(path, SEM_PREFIX); + if (strlcat(path, name, sizeof(path)) >= sizeof(path)) { + errno = ENAMETOOLONG; + return (SEM_FAILED); + } if (flags & ~(O_CREAT|O_EXCL)) { errno = EINVAL; return (SEM_FAILED); } - + if ((flags & O_CREAT) != 0) { + va_start(ap, flags); + mode = va_arg(ap, int); + value = va_arg(ap, int); + va_end(ap); + } + fd = -1; _pthread_once(&once, sem_module_init); _pthread_mutex_lock(&sem_llock); LIST_FOREACH(ni, &sem_list, next) { - if (strcmp(name, ni->name) == 0) { - if ((flags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL)) { - _pthread_mutex_unlock(&sem_llock); - errno = EEXIST; - return (SEM_FAILED); - } else { - ni->open_count++; - sem = ni->sem; - _pthread_mutex_unlock(&sem_llock); - return (sem); + if (ni->name != NULL && strcmp(name, ni->name) == 0) { + fd = _open(path, flags | O_RDWR | O_CLOEXEC | + O_EXLOCK, mode); + if (fd == -1 || _fstat(fd, &sb) == -1) + goto error; + if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | + O_EXCL) || ni->dev != sb.st_dev || + ni->ino != sb.st_ino) { + ni->name = NULL; + ni = NULL; + break; } + ni->open_count++; + sem = ni->sem; + _pthread_mutex_unlock(&sem_llock); + _close(fd); + return (sem); } } - if (flags & O_CREAT) { - va_start(ap, flags); - mode = va_arg(ap, int); - value = va_arg(ap, int); - va_end(ap); - } - len = sizeof(*ni) + strlen(name) + 1; ni = (struct sem_nameinfo *)malloc(len); if (ni == NULL) { @@ -192,17 +203,11 @@ _sem_open(const char *name, int flags, ...) ni->name = (char *)(ni+1); strcpy(ni->name, name); - strcpy(path, SEM_PREFIX); - if (strlcat(path, name, sizeof(path)) >= sizeof(path)) { - errno = ENAMETOOLONG; - goto error; + if (fd == -1) { + fd = _open(path, flags | O_RDWR | O_CLOEXEC | O_EXLOCK, mode); + if (fd == -1 || _fstat(fd, &sb) == -1) + goto error; } - - fd = _open(path, flags|O_RDWR|O_CLOEXEC|O_EXLOCK, mode); - if (fd == -1) - goto error; - if (_fstat(fd, &sb)) - goto error; if (sb.st_size < sizeof(sem_t)) { sem_t tmp; @@ -228,6 +233,8 @@ _sem_open(const char *name, int flags, ...) } ni->open_count = 1; ni->sem = sem; + ni->dev = sb.st_dev; + ni->ino = sb.st_ino; LIST_INSERT_HEAD(&sem_list, ni, next); _close(fd); _pthread_mutex_unlock(&sem_llock); -- cgit v1.2.3 From c8fb3e69d0345eb9bd36a945994e50e4792ad773 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Sat, 10 May 2014 19:18:49 +0000 Subject: sh: In getopts, unset OPTARG where POSIX says we should. --- bin/sh/options.c | 25 ++++++++++++------------- bin/sh/tests/builtins/Makefile | 1 + bin/sh/tests/builtins/getopts8.0 | 8 ++++++++ bin/sh/tests/builtins/getopts8.0.stdout | 5 +++++ 4 files changed, 26 insertions(+), 13 deletions(-) create mode 100644 bin/sh/tests/builtins/getopts8.0 create mode 100644 bin/sh/tests/builtins/getopts8.0.stdout diff --git a/bin/sh/options.c b/bin/sh/options.c index 8594c5707a4c..bf00a4e7d47e 100644 --- a/bin/sh/options.c +++ b/bin/sh/options.c @@ -446,6 +446,7 @@ getopts(char *optstr, char *optvar, char **optfirst, char ***optnext, int ind = 0; int err = 0; char s[10]; + const char *optarg = NULL; if ((p = *optptr) == NULL || *p == '\0') { /* Current word is done, advance */ @@ -471,14 +472,10 @@ atend: if (optstr[0] == ':') { s[0] = c; s[1] = '\0'; - err |= setvarsafe("OPTARG", s, 0); + optarg = s; } - else { + else out2fmt_flush("Illegal option -%c\n", c); - INTOFF; - (void) unsetvar("OPTARG"); - INTON; - } c = '?'; goto out; } @@ -491,14 +488,11 @@ atend: if (optstr[0] == ':') { s[0] = c; s[1] = '\0'; - err |= setvarsafe("OPTARG", s, 0); + optarg = s; c = ':'; } else { out2fmt_flush("No arg for -%c option\n", c); - INTOFF; - (void) unsetvar("OPTARG"); - INTON; c = '?'; } goto out; @@ -506,16 +500,21 @@ atend: if (p == **optnext) (*optnext)++; - setvarsafe("OPTARG", p, 0); + optarg = p; p = NULL; } - else - setvarsafe("OPTARG", "", 0); out: if (*optnext != NULL) ind = *optnext - optfirst + 1; *optptr = p; + if (optarg != NULL) + err |= setvarsafe("OPTARG", optarg, 0); + else { + INTOFF; + err |= unsetvar("OPTARG"); + INTON; + } fmtstr(s, sizeof(s), "%d", ind); err |= setvarsafe("OPTIND", s, VNOFUNC); s[0] = c; diff --git a/bin/sh/tests/builtins/Makefile b/bin/sh/tests/builtins/Makefile index 054a3b8fde7c..7a71318c8227 100644 --- a/bin/sh/tests/builtins/Makefile +++ b/bin/sh/tests/builtins/Makefile @@ -85,6 +85,7 @@ FILES+= getopts4.0 FILES+= getopts5.0 FILES+= getopts6.0 FILES+= getopts7.0 +FILES+= getopts8.0 getopts8.0.stdout FILES+= hash1.0 hash1.0.stdout FILES+= hash2.0 hash2.0.stdout FILES+= hash3.0 hash3.0.stdout diff --git a/bin/sh/tests/builtins/getopts8.0 b/bin/sh/tests/builtins/getopts8.0 new file mode 100644 index 000000000000..da4af6bd0b56 --- /dev/null +++ b/bin/sh/tests/builtins/getopts8.0 @@ -0,0 +1,8 @@ +# $FreeBSD$ + +set -- -yz -wx +opt=wrong1 OPTARG=wrong2 +while getopts :x opt; do + echo "$opt:${OPTARG-unset}" +done +echo "OPTIND=$OPTIND" diff --git a/bin/sh/tests/builtins/getopts8.0.stdout b/bin/sh/tests/builtins/getopts8.0.stdout new file mode 100644 index 000000000000..f10cefcd8c1b --- /dev/null +++ b/bin/sh/tests/builtins/getopts8.0.stdout @@ -0,0 +1,5 @@ +?:y +?:z +?:w +x:unset +OPTIND=3 -- cgit v1.2.3 From d9a9209abe834eb2c643f20258606b385c14d423 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sat, 10 May 2014 19:47:00 +0000 Subject: About 9% of the pmap_protect() calls being performed by vm_map_copy_entry() are unnecessary. Eliminate the unnecessary calls. Reviewed by: kib MFC after: 1 week Sponsored by: EMC / Isilon Storage Division --- sys/vm/vm_map.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index e8eaf178d4d1..0c95707c2674 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -3023,7 +3023,8 @@ vm_map_copy_entry( * If the source entry is marked needs_copy, it is already * write-protected. */ - if ((src_entry->eflags & MAP_ENTRY_NEEDS_COPY) == 0) { + if ((src_entry->eflags & MAP_ENTRY_NEEDS_COPY) == 0 && + (src_entry->protection & VM_PROT_WRITE) != 0) { pmap_protect(src_map->pmap, src_entry->start, src_entry->end, -- cgit v1.2.3 From b8821f8415368f0c761350c82356d234c80dff90 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Sat, 10 May 2014 20:03:03 +0000 Subject: When mapping device memory, use PTE_DEVICE rather than PTE_NOCACHE. On armv4 these are defined as synonyms right now, but it's a bit ambiguous what NOCACHE means (is buffering/write-combining also enabled or not?); this is a first step towards replacing PTE_NOCACHE with a less ambiguous name. --- sys/arm/at91/at91_machdep.c | 12 +++++------ sys/arm/cavium/cns11xx/econa_machdep.c | 8 ++++---- sys/arm/mv/mv_localbus.c | 2 +- sys/arm/mv/mv_machdep.c | 4 ++-- sys/arm/mv/mv_pci.c | 4 ++-- sys/arm/mv/orion/db88f5xxx.c | 12 +++++------ sys/arm/s3c2xx0/s3c24x0_machdep.c | 12 +++++------ sys/arm/xscale/i80321/ep80219_machdep.c | 6 +++--- sys/arm/xscale/i80321/iq31244_machdep.c | 6 +++--- sys/arm/xscale/i8134x/crb_machdep.c | 6 +++--- sys/arm/xscale/ixp425/avila_machdep.c | 36 ++++++++++++++++----------------- sys/arm/xscale/pxa/pxa_machdep.c | 2 +- 12 files changed, 55 insertions(+), 55 deletions(-) diff --git a/sys/arm/at91/at91_machdep.c b/sys/arm/at91/at91_machdep.c index 76310baf5e29..3da9e187c4da 100644 --- a/sys/arm/at91/at91_machdep.c +++ b/sys/arm/at91/at91_machdep.c @@ -126,7 +126,7 @@ const struct arm_devmap_entry at91_devmap[] = { 0xfff00000, 0x00100000, VM_PROT_READ|VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, /* There's a notion that we should do the rest of these lazily. */ /* @@ -150,7 +150,7 @@ const struct arm_devmap_entry at91_devmap[] = { AT91RM92_OHCI_BASE, 0x00100000, VM_PROT_READ|VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, { /* CompactFlash controller. Portion of EBI CS4 1MB */ @@ -158,7 +158,7 @@ const struct arm_devmap_entry at91_devmap[] = { AT91RM92_CF_BASE, 0x00100000, VM_PROT_READ|VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, /* * The next two should be good for the 9260, 9261 and 9G20 since @@ -170,7 +170,7 @@ const struct arm_devmap_entry at91_devmap[] = { AT91SAM9G20_OHCI_BASE, 0x00100000, VM_PROT_READ|VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, { /* EBI CS3 256MB */ @@ -178,7 +178,7 @@ const struct arm_devmap_entry at91_devmap[] = { AT91SAM9G20_NAND_BASE, AT91SAM9G20_NAND_SIZE, VM_PROT_READ|VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, /* * The next should be good for the 9G45. @@ -189,7 +189,7 @@ const struct arm_devmap_entry at91_devmap[] = { AT91SAM9G45_OHCI_BASE, 0x00100000, VM_PROT_READ|VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, { 0, 0, 0, 0, 0, } }; diff --git a/sys/arm/cavium/cns11xx/econa_machdep.c b/sys/arm/cavium/cns11xx/econa_machdep.c index 708109be633c..b2c388f04359 100644 --- a/sys/arm/cavium/cns11xx/econa_machdep.c +++ b/sys/arm/cavium/cns11xx/econa_machdep.c @@ -112,7 +112,7 @@ static const struct arm_devmap_entry econa_devmap[] = { ECONA_SDRAM_BASE, /*physical*/ ECONA_SDRAM_SIZE, /*size*/ VM_PROT_READ|VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, /* * Map the on-board devices VA == PA so that we can access them @@ -127,7 +127,7 @@ static const struct arm_devmap_entry econa_devmap[] = { ECONA_IO_BASE, /*physical*/ ECONA_IO_SIZE, /*size*/ VM_PROT_READ|VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, { /* @@ -137,7 +137,7 @@ static const struct arm_devmap_entry econa_devmap[] = { ECONA_OHCI_PBASE, /*physical*/ ECONA_USB_SIZE, /*size*/ VM_PROT_READ|VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, { /* @@ -147,7 +147,7 @@ static const struct arm_devmap_entry econa_devmap[] = { ECONA_CFI_PBASE, /*physical*/ ECONA_CFI_SIZE, VM_PROT_READ|VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, { 0, diff --git a/sys/arm/mv/mv_localbus.c b/sys/arm/mv/mv_localbus.c index 0882ad4c191d..8d91c41a401d 100644 --- a/sys/arm/mv/mv_localbus.c +++ b/sys/arm/mv/mv_localbus.c @@ -477,7 +477,7 @@ fdt_localbus_devmap(phandle_t dt_node, struct arm_devmap_entry *fdt_devmap, fdt_devmap[j].pd_pa = offset; fdt_devmap[j].pd_size = size; fdt_devmap[j].pd_prot = VM_PROT_READ | VM_PROT_WRITE; - fdt_devmap[j].pd_cache = PTE_NOCACHE; + fdt_devmap[j].pd_cache = PTE_DEVICE; /* Copy data to structure used by localbus driver */ localbus_banks[bank].va = fdt_devmap[j].pd_va; diff --git a/sys/arm/mv/mv_machdep.c b/sys/arm/mv/mv_machdep.c index 7c0e7c108ec8..0c3e18db0057 100644 --- a/sys/arm/mv/mv_machdep.c +++ b/sys/arm/mv/mv_machdep.c @@ -284,7 +284,7 @@ moveon: map->pd_pa = base; map->pd_size = size; map->pd_prot = VM_PROT_READ | VM_PROT_WRITE; - map->pd_cache = PTE_NOCACHE; + map->pd_cache = PTE_DEVICE; return (0); out: @@ -350,7 +350,7 @@ initarm_devmap_init(void) fdt_devmap[i].pd_pa = fdt_immr_pa; fdt_devmap[i].pd_size = fdt_immr_size; fdt_devmap[i].pd_prot = VM_PROT_READ | VM_PROT_WRITE; - fdt_devmap[i].pd_cache = PTE_NOCACHE; + fdt_devmap[i].pd_cache = PTE_DEVICE; i++; /* diff --git a/sys/arm/mv/mv_pci.c b/sys/arm/mv/mv_pci.c index be4ccc9d2fb8..012b31bac04a 100644 --- a/sys/arm/mv/mv_pci.c +++ b/sys/arm/mv/mv_pci.c @@ -235,14 +235,14 @@ mv_pci_devmap(phandle_t node, struct arm_devmap_entry *devmap, vm_offset_t io_va devmap->pd_pa = io_space.base_parent; devmap->pd_size = io_space.len; devmap->pd_prot = VM_PROT_READ | VM_PROT_WRITE; - devmap->pd_cache = PTE_NOCACHE; + devmap->pd_cache = PTE_DEVICE; devmap++; devmap->pd_va = (mem_va ? mem_va : mem_space.base_parent); devmap->pd_pa = mem_space.base_parent; devmap->pd_size = mem_space.len; devmap->pd_prot = VM_PROT_READ | VM_PROT_WRITE; - devmap->pd_cache = PTE_NOCACHE; + devmap->pd_cache = PTE_DEVICE; return (0); } diff --git a/sys/arm/mv/orion/db88f5xxx.c b/sys/arm/mv/orion/db88f5xxx.c index 0762df509855..f59d511f4d09 100644 --- a/sys/arm/mv/orion/db88f5xxx.c +++ b/sys/arm/mv/orion/db88f5xxx.c @@ -84,42 +84,42 @@ const struct pmap_devmap pmap_devmap[] = { MV_PHYS_BASE, MV_SIZE, VM_PROT_READ | VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, { /* PCIE I/O */ MV_PCIE_IO_BASE, MV_PCIE_IO_PHYS_BASE, MV_PCIE_IO_SIZE, VM_PROT_READ | VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, { /* PCIE Memory */ MV_PCIE_MEM_BASE, MV_PCIE_MEM_PHYS_BASE, MV_PCIE_MEM_SIZE, VM_PROT_READ | VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, { /* PCI I/O */ MV_PCI_IO_BASE, MV_PCI_IO_PHYS_BASE, MV_PCI_IO_SIZE, VM_PROT_READ | VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, { /* PCI Memory */ MV_PCI_MEM_BASE, MV_PCI_MEM_PHYS_BASE, MV_PCI_MEM_SIZE, VM_PROT_READ | VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, { /* 7-seg LED */ MV_DEV_CS0_BASE, MV_DEV_CS0_PHYS_BASE, MV_DEV_CS0_SIZE, VM_PROT_READ | VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, { 0, 0, 0, 0, 0, } }; diff --git a/sys/arm/s3c2xx0/s3c24x0_machdep.c b/sys/arm/s3c2xx0/s3c24x0_machdep.c index 73b60ea2da1b..5264e7a805d5 100644 --- a/sys/arm/s3c2xx0/s3c24x0_machdep.c +++ b/sys/arm/s3c2xx0/s3c24x0_machdep.c @@ -130,42 +130,42 @@ static const struct arm_devmap_entry s3c24x0_devmap[] = { _A(S3C24X0_CLKMAN_PA_BASE), _S(S3C24X0_CLKMAN_SIZE), VM_PROT_READ|VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, { _A(S3C24X0_GPIO_BASE), _A(S3C24X0_GPIO_PA_BASE), _S(S3C2410_GPIO_SIZE), VM_PROT_READ|VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, { _A(S3C24X0_INTCTL_BASE), _A(S3C24X0_INTCTL_PA_BASE), _S(S3C24X0_INTCTL_SIZE), VM_PROT_READ|VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, { _A(S3C24X0_TIMER_BASE), _A(S3C24X0_TIMER_PA_BASE), _S(S3C24X0_TIMER_SIZE), VM_PROT_READ|VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, { _A(S3C24X0_UART0_BASE), _A(S3C24X0_UART0_PA_BASE), _S(S3C24X0_UART_PA_BASE(3) - S3C24X0_UART0_PA_BASE), VM_PROT_READ|VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, { _A(S3C24X0_WDT_BASE), _A(S3C24X0_WDT_PA_BASE), _S(S3C24X0_WDT_SIZE), VM_PROT_READ|VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, { 0, diff --git a/sys/arm/xscale/i80321/ep80219_machdep.c b/sys/arm/xscale/i80321/ep80219_machdep.c index 3112fe4a27cc..54fdfbbd1a0b 100644 --- a/sys/arm/xscale/i80321/ep80219_machdep.c +++ b/sys/arm/xscale/i80321/ep80219_machdep.c @@ -130,21 +130,21 @@ static const struct arm_devmap_entry ep80219_devmap[] = { IQ80321_OBIO_BASE, IQ80321_OBIO_SIZE, VM_PROT_READ|VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, { IQ80321_IOW_VBASE, VERDE_OUT_XLATE_IO_WIN0_BASE, VERDE_OUT_XLATE_IO_WIN_SIZE, VM_PROT_READ|VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, { IQ80321_80321_VBASE, VERDE_PMMR_BASE, VERDE_PMMR_SIZE, VM_PROT_READ|VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, { 0, diff --git a/sys/arm/xscale/i80321/iq31244_machdep.c b/sys/arm/xscale/i80321/iq31244_machdep.c index 38827297d179..e1ca22b4f5fa 100644 --- a/sys/arm/xscale/i80321/iq31244_machdep.c +++ b/sys/arm/xscale/i80321/iq31244_machdep.c @@ -128,14 +128,14 @@ static const struct arm_devmap_entry iq80321_devmap[] = { IQ80321_OBIO_BASE, IQ80321_OBIO_SIZE, VM_PROT_READ|VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, { IQ80321_IOW_VBASE, VERDE_OUT_XLATE_IO_WIN0_BASE, VERDE_OUT_XLATE_IO_WIN_SIZE, VM_PROT_READ|VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, { @@ -143,7 +143,7 @@ static const struct arm_devmap_entry iq80321_devmap[] = { VERDE_PMMR_BASE, VERDE_PMMR_SIZE, VM_PROT_READ|VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, { 0, diff --git a/sys/arm/xscale/i8134x/crb_machdep.c b/sys/arm/xscale/i8134x/crb_machdep.c index 98e1ca6c830c..13e62c445715 100644 --- a/sys/arm/xscale/i8134x/crb_machdep.c +++ b/sys/arm/xscale/i8134x/crb_machdep.c @@ -124,7 +124,7 @@ static const struct arm_devmap_entry iq81342_devmap[] = { IOP34X_HWADDR, IOP34X_SIZE, VM_PROT_READ|VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, { /* @@ -135,14 +135,14 @@ static const struct arm_devmap_entry iq81342_devmap[] = { IOP34X_PCIX_OIOBAR &~ (0x100000 - 1), 0x100000, VM_PROT_READ|VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, { IOP34X_PCE1_VADDR, IOP34X_PCE1, IOP34X_PCE1_SIZE, VM_PROT_READ|VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, { 0, diff --git a/sys/arm/xscale/ixp425/avila_machdep.c b/sys/arm/xscale/ixp425/avila_machdep.c index 2ef2adce12c1..2b27a66e90de 100644 --- a/sys/arm/xscale/ixp425/avila_machdep.c +++ b/sys/arm/xscale/ixp425/avila_machdep.c @@ -118,31 +118,31 @@ struct pv_addr minidataclean; static const struct arm_devmap_entry ixp425_devmap[] = { /* Physical/Virtual address for I/O space */ { IXP425_IO_VBASE, IXP425_IO_HWBASE, IXP425_IO_SIZE, - VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, }, + VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, }, /* Expansion Bus */ { IXP425_EXP_VBASE, IXP425_EXP_HWBASE, IXP425_EXP_SIZE, - VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, }, + VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, }, /* CFI Flash on the Expansion Bus */ { IXP425_EXP_BUS_CS0_VBASE, IXP425_EXP_BUS_CS0_HWBASE, - IXP425_EXP_BUS_CS0_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, }, + IXP425_EXP_BUS_CS0_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, }, /* IXP425 PCI Configuration */ { IXP425_PCI_VBASE, IXP425_PCI_HWBASE, IXP425_PCI_SIZE, - VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, }, + VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, }, /* SDRAM Controller */ { IXP425_MCU_VBASE, IXP425_MCU_HWBASE, IXP425_MCU_SIZE, - VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, }, + VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, }, /* PCI Memory Space */ { IXP425_PCI_MEM_VBASE, IXP425_PCI_MEM_HWBASE, IXP425_PCI_MEM_SIZE, - VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, }, + VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, }, /* Q-Mgr Memory Space */ { IXP425_QMGR_VBASE, IXP425_QMGR_HWBASE, IXP425_QMGR_SIZE, - VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, }, + VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, }, { 0 }, }; @@ -151,45 +151,45 @@ static const struct arm_devmap_entry ixp425_devmap[] = { static const struct arm_devmap_entry ixp435_devmap[] = { /* Physical/Virtual address for I/O space */ { IXP425_IO_VBASE, IXP425_IO_HWBASE, IXP425_IO_SIZE, - VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, }, + VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, }, { IXP425_EXP_VBASE, IXP425_EXP_HWBASE, IXP425_EXP_SIZE, - VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, }, + VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, }, /* IXP425 PCI Configuration */ { IXP425_PCI_VBASE, IXP425_PCI_HWBASE, IXP425_PCI_SIZE, - VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, }, + VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, }, /* DDRII Controller NB: mapped same place as IXP425 */ { IXP425_MCU_VBASE, IXP435_MCU_HWBASE, IXP425_MCU_SIZE, - VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, }, + VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, }, /* PCI Memory Space */ { IXP425_PCI_MEM_VBASE, IXP425_PCI_MEM_HWBASE, IXP425_PCI_MEM_SIZE, - VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, }, + VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, }, /* Q-Mgr Memory Space */ { IXP425_QMGR_VBASE, IXP425_QMGR_HWBASE, IXP425_QMGR_SIZE, - VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, }, + VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, }, /* CFI Flash on the Expansion Bus */ { IXP425_EXP_BUS_CS0_VBASE, IXP425_EXP_BUS_CS0_HWBASE, - IXP425_EXP_BUS_CS0_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, }, + IXP425_EXP_BUS_CS0_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, }, /* USB1 Memory Space */ { IXP435_USB1_VBASE, IXP435_USB1_HWBASE, IXP435_USB1_SIZE, - VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, }, + VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, }, /* USB2 Memory Space */ { IXP435_USB2_VBASE, IXP435_USB2_HWBASE, IXP435_USB2_SIZE, - VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, }, + VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, }, /* GPS Memory Space */ { CAMBRIA_GPS_VBASE, CAMBRIA_GPS_HWBASE, CAMBRIA_GPS_SIZE, - VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, }, + VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, }, /* RS485 Memory Space */ { CAMBRIA_RS485_VBASE, CAMBRIA_RS485_HWBASE, CAMBRIA_RS485_SIZE, - VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE, }, + VM_PROT_READ|VM_PROT_WRITE, PTE_DEVICE, }, { 0 } }; diff --git a/sys/arm/xscale/pxa/pxa_machdep.c b/sys/arm/xscale/pxa/pxa_machdep.c index 2e235f0123e2..6bf58d34d715 100644 --- a/sys/arm/xscale/pxa/pxa_machdep.c +++ b/sys/arm/xscale/pxa/pxa_machdep.c @@ -129,7 +129,7 @@ static const struct arm_devmap_entry pxa_devmap[] = { PXA2X0_PERIPH_START, PXA250_PERIPH_END - PXA2X0_PERIPH_START, VM_PROT_READ|VM_PROT_WRITE, - PTE_NOCACHE, + PTE_DEVICE, }, { 0, 0, 0, 0, 0, } }; -- cgit v1.2.3 From 3664cbc0f07d44a679d37c78b46cc58c9f137803 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Sat, 10 May 2014 20:26:49 +0000 Subject: Rename platform_gpio_init to be SoC specific, and make it static as it's only called from this file. --- sys/arm/rockchip/rk30xx_gpio.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/arm/rockchip/rk30xx_gpio.c b/sys/arm/rockchip/rk30xx_gpio.c index 4965735a6afe..3ecedda2cb45 100644 --- a/sys/arm/rockchip/rk30xx_gpio.c +++ b/sys/arm/rockchip/rk30xx_gpio.c @@ -96,7 +96,7 @@ struct gpio_ctrl_entry { }; int rk30_gpios_prop_handle(phandle_t ctrl, pcell_t *gpios, int len); -int platform_gpio_init(void); +static int rk30_gpio_init(void); struct gpio_ctrl_entry gpio_controllers[] = { { "rockchip,rk30xx-gpio", &rk30_gpios_prop_handle }, @@ -509,7 +509,7 @@ rk30_gpio_attach(device_t dev) rk30_gpio_sc = sc; - platform_gpio_init(); + rk30_gpio_init(); return (bus_generic_attach(dev)); @@ -619,8 +619,8 @@ rk30_gpios_prop_handle(phandle_t ctrl, pcell_t *gpios, int len) #define MAX_PINS_PER_NODE 5 #define GPIOS_PROP_CELLS 4 -int -platform_gpio_init(void) +static int +rk30_gpio_init(void) { phandle_t child, parent, root, ctrl; pcell_t gpios[MAX_PINS_PER_NODE * GPIOS_PROP_CELLS]; -- cgit v1.2.3 From 87ef4d1f853d103849dd613691b1f2c5183b78a4 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Sat, 10 May 2014 20:31:05 +0000 Subject: Rename platform_gpio_init to be platform specific, and make it static as it's only used from this file. --- sys/arm/mv/gpio.c | 7 ++++--- sys/arm/mv/mvvar.h | 1 - 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/arm/mv/gpio.c b/sys/arm/mv/gpio.c index 1bdb81b588fd..171e880adfc0 100644 --- a/sys/arm/mv/gpio.c +++ b/sys/arm/mv/gpio.c @@ -74,6 +74,7 @@ static uint32_t gpio_setup[MV_GPIO_MAX_NPINS]; static int mv_gpio_probe(device_t); static int mv_gpio_attach(device_t); static int mv_gpio_intr(void *); +static int mv_gpio_init(void); static void mv_gpio_intr_handler(int pin); static uint32_t mv_gpio_reg_read(uint32_t reg); @@ -201,7 +202,7 @@ mv_gpio_attach(device_t dev) } } - return (platform_gpio_init()); + return (mv_gpio_init()); } static int @@ -604,8 +605,8 @@ mv_handle_gpios_prop(phandle_t ctrl, pcell_t *gpios, int len) #define MAX_PINS_PER_NODE 5 #define GPIOS_PROP_CELLS 4 -int -platform_gpio_init(void) +static int +mv_gpio_init(void) { phandle_t child, parent, root, ctrl; pcell_t gpios[MAX_PINS_PER_NODE * GPIOS_PROP_CELLS]; diff --git a/sys/arm/mv/mvvar.h b/sys/arm/mv/mvvar.h index 0b72dcb7ab5e..a9b2bb0611df 100644 --- a/sys/arm/mv/mvvar.h +++ b/sys/arm/mv/mvvar.h @@ -82,7 +82,6 @@ void mv_gpio_intr_mask(int pin); void mv_gpio_intr_unmask(int pin); void mv_gpio_out(uint32_t pin, uint8_t val, uint8_t enable); uint8_t mv_gpio_in(uint32_t pin); -int platform_gpio_init(void); int soc_decode_win(void); void soc_id(uint32_t *dev, uint32_t *rev); -- cgit v1.2.3 From cb8b0584f4dc35801301e51b61dd07671d845d46 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 10 May 2014 21:27:47 +0000 Subject: Really, I don't want to install src.opts.mk at all. --- share/mk/Makefile | 3 --- 1 file changed, 3 deletions(-) diff --git a/share/mk/Makefile b/share/mk/Makefile index acf7d3963488..4ad624d852a9 100644 --- a/share/mk/Makefile +++ b/share/mk/Makefile @@ -42,9 +42,6 @@ FILES= \ sys.mk \ version_gen.awk -# Installed for the moment, but not may not be in the future. -FILES+= src.opts.mk - NO_OBJ= FILESDIR= ${BINDIR}/mk -- cgit v1.2.3 From b36b897e51ef92ecec742f7d5613081d7bef7973 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Sat, 10 May 2014 21:30:19 +0000 Subject: Rename platform_gpio_init to be SoC specific --- sys/arm/lpc/lpc_gpio.c | 2 +- sys/arm/lpc/lpc_machdep.c | 2 +- sys/arm/lpc/lpcvar.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/arm/lpc/lpc_gpio.c b/sys/arm/lpc/lpc_gpio.c index 9c13d62598be..b2310cb0a2d2 100644 --- a/sys/arm/lpc/lpc_gpio.c +++ b/sys/arm/lpc/lpc_gpio.c @@ -504,7 +504,7 @@ lpc_gpio_get_state(device_t dev, int pin, int *state) } void -platform_gpio_init() +lpc_gpio_init() { bus_space_tag_t bst; bus_space_handle_t bsh; diff --git a/sys/arm/lpc/lpc_machdep.c b/sys/arm/lpc/lpc_machdep.c index 0cdfd038f733..9219c2fe3096 100644 --- a/sys/arm/lpc/lpc_machdep.c +++ b/sys/arm/lpc/lpc_machdep.c @@ -78,7 +78,7 @@ initarm_gpio_init(void) /* * Set initial values of GPIO output ports */ - platform_gpio_init(); + lpc_gpio_init(); } void diff --git a/sys/arm/lpc/lpcvar.h b/sys/arm/lpc/lpcvar.h index a0b3651bb1de..ed05320ca9d5 100644 --- a/sys/arm/lpc/lpcvar.h +++ b/sys/arm/lpc/lpcvar.h @@ -38,7 +38,7 @@ uint32_t lpc_pwr_read(device_t, int); void lpc_pwr_write(device_t, int, uint32_t); /* GPIO */ -void platform_gpio_init(void); +void lpc_gpio_init(void); int lpc_gpio_set_flags(device_t, int, int); int lpc_gpio_set_state(device_t, int, int); int lpc_gpio_get_state(device_t, int, int *); -- cgit v1.2.3 From 76f66be6bfc79104e9f4d0c9ee3ea0c9823ae17a Mon Sep 17 00:00:00 2001 From: "Pedro F. Giffuni" Date: Sat, 10 May 2014 22:27:01 +0000 Subject: prinf: replace use of alloca with variable length array. Use of alloca(3) is discouraged in FreeBSD. Using a VLA is simple and should be more portable. Requested by: jilles --- usr.bin/printf/printf.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/usr.bin/printf/printf.c b/usr.bin/printf/printf.c index ac122f78c1d9..055657fe057a 100644 --- a/usr.bin/printf/printf.c +++ b/usr.bin/printf/printf.c @@ -215,13 +215,11 @@ printf_doformat(char *fmt, int *rval) static const char skip1[] = "#'-+ 0"; int fieldwidth, haveprec, havewidth, mod_ldbl, precision; char convch, nextch; - char *start; + char start[strlen(fmt) + 1]; char **fargv; char *dptr; int l; - start = alloca(strlen(fmt) + 1); - dptr = start; *dptr++ = '%'; *dptr = 0; -- cgit v1.2.3 From 6af0d51bced1cbf3615ff341c20d87a4fac35acc Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Sun, 11 May 2014 00:43:06 +0000 Subject: Make the hardware memory and instruction barrier functions work on armv4 and armv5 as well. --- sys/arm/include/atomic.h | 6 +++--- sys/modules/Makefile | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/sys/arm/include/atomic.h b/sys/arm/include/atomic.h index d16849873480..02be1bdff555 100644 --- a/sys/arm/include/atomic.h +++ b/sys/arm/include/atomic.h @@ -58,9 +58,9 @@ #define dsb() __asm __volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0) : "memory") #define dmb() __asm __volatile("mcr p15, 0, %0, c7, c10, 5" : : "r" (0) : "memory") #else -#define isb() -#define dsb() -#define dmb() +#define isb() __asm __volatile("mcr p15, 0, %0, c7, c5, 4" : : "r" (0) : "memory") +#define dsb() __asm __volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0) : "memory") +#define dmb() dsb() #endif #define mb() dmb() diff --git a/sys/modules/Makefile b/sys/modules/Makefile index 15a516373f44..3d1713f69ee1 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -2,6 +2,8 @@ .include +SUBDIR_PARALLEL= + # Modules that include binary-only blobs of microcode should be selectable by # MK_SOURCELESS_UCODE option (see below). -- cgit v1.2.3 From bdf49e3953150f231b92467c34cade2a318596ba Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Sun, 11 May 2014 01:19:55 +0000 Subject: Make ofwfb actually work again. Apparently the API it was written against still exists but is now silently ignored by the VT core. At least xboxfb needs similar changes. --- sys/dev/vt/hw/ofwfb/ofwfb.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/sys/dev/vt/hw/ofwfb/ofwfb.c b/sys/dev/vt/hw/ofwfb/ofwfb.c index 724572544467..99e2306c350d 100644 --- a/sys/dev/vt/hw/ofwfb/ofwfb.c +++ b/sys/dev/vt/hw/ofwfb/ofwfb.c @@ -58,22 +58,48 @@ struct ofwfb_softc { uint32_t sc_colormap[16]; }; +static vd_probe_t ofwfb_probe; static vd_init_t ofwfb_init; static vd_blank_t ofwfb_blank; static vd_bitbltchr_t ofwfb_bitbltchr; static const struct vt_driver vt_ofwfb_driver = { .vd_name = "ofwfb", + .vd_probe = ofwfb_probe, .vd_init = ofwfb_init, .vd_blank = ofwfb_blank, .vd_bitbltchr = ofwfb_bitbltchr, + .vd_maskbitbltchr = ofwfb_bitbltchr, .vd_priority = VD_PRIORITY_GENERIC+1, }; static struct ofwfb_softc ofwfb_conssoftc; -VT_CONSDEV_DECLARE(vt_ofwfb_driver, PIXEL_WIDTH(1920), PIXEL_HEIGHT(1200), - &ofwfb_conssoftc); -/* XXX: hardcoded max size */ +VT_DRIVER_DECLARE(vt_ofwfb, vt_ofwfb_driver); + +static int +ofwfb_probe(struct vt_device *vd) +{ + phandle_t chosen, node; + ihandle_t stdout; + char type[64]; + + chosen = OF_finddevice("/chosen"); + OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)); + node = OF_instance_to_package(stdout); + if (node == -1) { + /* + * The "/chosen/stdout" does not exist try + * using "screen" directly. + */ + node = OF_finddevice("screen"); + } + OF_getprop(node, "device_type", type, sizeof(type)); + if (strcmp(type, "display") != 0) + return (CN_DEAD); + + /* Looks OK... */ + return (CN_INTERNAL); +} static void ofwfb_blank(struct vt_device *vd, term_color_t color) @@ -218,7 +244,7 @@ ofwfb_initialize(struct vt_device *vd) static int ofwfb_init(struct vt_device *vd) { - struct ofwfb_softc *sc = vd->vd_softc; + struct ofwfb_softc *sc; char type[64]; phandle_t chosen; ihandle_t stdout; @@ -234,6 +260,9 @@ ofwfb_init(struct vt_device *vd) int space; #endif + /* Initialize softc */ + vd->vd_softc = sc = &ofwfb_conssoftc; + chosen = OF_finddevice("/chosen"); OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)); node = OF_instance_to_package(stdout); -- cgit v1.2.3 From 8be8ad916f178c4bf1487a6807450ccf77f2430f Mon Sep 17 00:00:00 2001 From: Eitan Adler Date: Sun, 11 May 2014 01:44:11 +0000 Subject: libedit: add H_SAVE_FP which saves history to a file pointer. H_SAVE_FP is similar to H_SAVE but operates on a FILE* instead of a filename. This is useful when operating in capability mode. Reviewed by: christos@NetBSD.org, pfg --- lib/libedit/editline.3 | 3 +++ lib/libedit/hist.h | 1 + lib/libedit/histedit.h | 1 + lib/libedit/history.c | 39 ++++++++++++++++++++++++++++++--------- 4 files changed, 35 insertions(+), 9 deletions(-) diff --git a/lib/libedit/editline.3 b/lib/libedit/editline.3 index 33f7666f4283..df7cd8791803 100644 --- a/lib/libedit/editline.3 +++ b/lib/libedit/editline.3 @@ -682,6 +682,9 @@ Load the history list stored in .It Dv H_SAVE , Fa "const char *file" Save the history list to .Fa file . +.It Dv H_SAVE_FP , Fa "FILE*" +Save the history list to the opened +.Fa FILE* . .It Dv H_SETUNIQUE , Fa "int unique" Set flag that adjacent identical event strings should not be entered into the history. diff --git a/lib/libedit/hist.h b/lib/libedit/hist.h index 4f2824aff200..4ddedcc59b3d 100644 --- a/lib/libedit/hist.h +++ b/lib/libedit/hist.h @@ -65,6 +65,7 @@ typedef struct el_history_t { #define HIST_SET(el, num) HIST_FUN(el, H_SET, num) #define HIST_LOAD(el, fname) HIST_FUN(el, H_LOAD fname) #define HIST_SAVE(el, fname) HIST_FUN(el, H_SAVE fname) +#define HIST_SAVE_FP(el, fp) HIST_FUN(el, H_SAVE_FP fp) protected int hist_init(EditLine *); protected void hist_end(EditLine *); diff --git a/lib/libedit/histedit.h b/lib/libedit/histedit.h index 8a6caf96c035..9059ea20e52e 100644 --- a/lib/libedit/histedit.h +++ b/lib/libedit/histedit.h @@ -208,6 +208,7 @@ int history(History *, HistEvent *, int, ...); #define H_NEXT_EVDATA 23 /* , const int, histdata_t *); */ #define H_DELDATA 24 /* , int, histdata_t *);*/ #define H_REPLACE 25 /* , const char *, histdata_t); */ +#define H_SAVE_FP 26 /* , FILE*); */ /* diff --git a/lib/libedit/history.c b/lib/libedit/history.c index 8f30a05a9973..cd8697724f1d 100644 --- a/lib/libedit/history.c +++ b/lib/libedit/history.c @@ -103,6 +103,7 @@ private int history_getunique(History *, HistEvent *); private int history_set_fun(History *, History *); private int history_load(History *, const char *); private int history_save(History *, const char *); +private int history_save_fp(History *, FILE*); private int history_prev_event(History *, HistEvent *, int); private int history_next_event(History *, HistEvent *, int); private int history_next_string(History *, HistEvent *, const char *); @@ -773,22 +774,16 @@ done: return (i); } - -/* history_save(): - * History save function +/* history_save_fp(): + * History save with open FILE* */ -private int -history_save(History *h, const char *fname) +private int history_save_fp(History *h, FILE* fp) { - FILE *fp; HistEvent ev; int i = -1, retval; size_t len, max_size; char *ptr; - if ((fp = fopen(fname, "w")) == NULL) - return (-1); - if (fchmod(fileno(fp), S_IRUSR|S_IWUSR) == -1) goto done; if (fputs(hist_cookie, fp) == EOF) @@ -815,6 +810,26 @@ history_save(History *h, const char *fname) } oomem: h_free((ptr_t)ptr); +done: + return (i); + +} + + +/* history_save(): + * History save function + */ +private int +history_save(History *h, const char *fname) +{ + FILE *fp; + int i; + + if ((fp = fopen(fname, "w")) == NULL) + return (-1); + + i = history_save_fp(h, fp); + done: (void) fclose(fp); return (i); @@ -1001,6 +1016,12 @@ history(History *h, HistEvent *ev, int fun, ...) he_seterrev(ev, _HE_HIST_WRITE); break; + case H_SAVE_FP: + retval = history_save_fp(h, va_arg(va, FILE*)); + if (retval == -1) + he_seterrev(ev, _HE_HIST_WRITE); + break; + case H_PREV_EVENT: retval = history_prev_event(h, ev, va_arg(va, int)); break; -- cgit v1.2.3 From 015ac42e4b27b11ce31d22fbde10ec4a9b25d56a Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Sun, 11 May 2014 01:58:56 +0000 Subject: Make ofwfb not be painfully slow. This reduces the time for a verbose boot on my G4 iBook by more than half. Still 10% slower than syscons, but that's much better than a factor of 2. The slowness had to do with pathological write performance on 8-bit framebuffers, which are almost universally used on Open Firmware systems. Writing 1 byte at a time, potentially nonconsecutively, resulted in many extra PCI write cycles. This patch, in the common case where it's writing one or several characters in an 8x8 font, gangs the writes together into a set of 32-bit writes. This is a port of r143830 to vt(4). The EFI framebuffer is also extremely slow, probably for the same reason, and the same patch will likely help there. --- sys/dev/vt/hw/ofwfb/ofwfb.c | 88 ++++++++++++++++++++++++++++++++------------- 1 file changed, 63 insertions(+), 25 deletions(-) diff --git a/sys/dev/vt/hw/ofwfb/ofwfb.c b/sys/dev/vt/hw/ofwfb/ofwfb.c index 99e2306c350d..156675bab0e7 100644 --- a/sys/dev/vt/hw/ofwfb/ofwfb.c +++ b/sys/dev/vt/hw/ofwfb/ofwfb.c @@ -136,6 +136,10 @@ ofwfb_bitbltchr(struct vt_device *vd, const uint8_t *src, const uint8_t *mask, uint32_t fgc, bgc; int c; uint8_t b, m; + union { + uint32_t l; + uint8_t c[4]; + } ch1, ch2; fgc = sc->sc_colormap[fg]; bgc = sc->sc_colormap[bg]; @@ -147,36 +151,70 @@ ofwfb_bitbltchr(struct vt_device *vd, const uint8_t *src, const uint8_t *mask, return; line = (sc->sc_stride * top) + left * sc->sc_depth/8; - for (; height > 0; height--) { - for (c = 0; c < width; c++) { - if (c % 8 == 0) + if (mask == NULL && sc->sc_depth == 8 && (width % 8 == 0)) { + for (; height > 0; height--) { + for (c = 0; c < width; c += 8) { b = *src++; - else - b <<= 1; - if (mask != NULL) { + + /* + * Assume that there is more background than + * foreground in characters and init accordingly + */ + ch1.l = ch2.l = (bg << 24) | (bg << 16) | + (bg << 8) | bg; + + /* + * Calculate 2 x 4-chars at a time, and then + * write these out. + */ + if (b & 0x80) ch1.c[0] = fg; + if (b & 0x40) ch1.c[1] = fg; + if (b & 0x20) ch1.c[2] = fg; + if (b & 0x10) ch1.c[3] = fg; + + if (b & 0x08) ch2.c[0] = fg; + if (b & 0x04) ch2.c[1] = fg; + if (b & 0x02) ch2.c[2] = fg; + if (b & 0x01) ch2.c[3] = fg; + + *(uint32_t *)(sc->sc_addr + line + c) = ch1.l; + *(uint32_t *)(sc->sc_addr + line + c + 4) = + ch2.l; + } + line += sc->sc_stride; + } + } else { + for (; height > 0; height--) { + for (c = 0; c < width; c++) { if (c % 8 == 0) - m = *mask++; + b = *src++; else - m <<= 1; - /* Skip pixel write, if mask has no bit set. */ - if ((m & 0x80) == 0) - continue; - } - switch(sc->sc_depth) { - case 8: - *(uint8_t *)(sc->sc_addr + line + c) = - b & 0x80 ? fg : bg; - break; - case 32: - *(uint32_t *)(sc->sc_addr + line + 4*c) = - (b & 0x80) ? fgc : bgc; - break; - default: - /* panic? */ - break; + b <<= 1; + if (mask != NULL) { + if (c % 8 == 0) + m = *mask++; + else + m <<= 1; + /* Skip pixel write, if mask not set. */ + if ((m & 0x80) == 0) + continue; + } + switch(sc->sc_depth) { + case 8: + *(uint8_t *)(sc->sc_addr + line + c) = + b & 0x80 ? fg : bg; + break; + case 32: + *(uint32_t *)(sc->sc_addr + line + 4*c) + = (b & 0x80) ? fgc : bgc; + break; + default: + /* panic? */ + break; + } } + line += sc->sc_stride; } - line += sc->sc_stride; } } -- cgit v1.2.3 From b245fc98c8118dccca23ae13662c0f7553b0f5d3 Mon Sep 17 00:00:00 2001 From: Eitan Adler Date: Sun, 11 May 2014 02:00:48 +0000 Subject: look(1): add compability with other implementations. On other implementations 'look -a' uses an alternate dictionary. Since we don't have one, just ignore it. --- usr.bin/look/look.1 | 4 ++++ usr.bin/look/look.c | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/usr.bin/look/look.1 b/usr.bin/look/look.1 index e9498bbc35f5..471898fa9c46 100644 --- a/usr.bin/look/look.1 +++ b/usr.bin/look/look.1 @@ -103,6 +103,10 @@ in comparisons when the option was specified. This was incorrect and the current man page matches the historic implementation. +.Pp +The +.Fl a +flag is ignored for compability. .Sh SEE ALSO .Xr grep 1 , .Xr sort 1 diff --git a/usr.bin/look/look.c b/usr.bin/look/look.c index e77a21652d1c..5f830d0857e7 100644 --- a/usr.bin/look/look.c +++ b/usr.bin/look/look.c @@ -102,8 +102,11 @@ main(int argc, char *argv[]) file = _path_words; termchar = L'\0'; - while ((ch = getopt(argc, argv, "dft:")) != -1) + while ((ch = getopt(argc, argv, "adft:")) != -1) switch(ch) { + case 'a': + /* COMPATIBILITY */ + break; case 'd': dflag = 1; break; -- cgit v1.2.3 From 2f4de2978326070a514a57e2a13900396bc30471 Mon Sep 17 00:00:00 2001 From: Eitan Adler Date: Sun, 11 May 2014 02:04:40 +0000 Subject: mesg: remove advertising clause The University of California board of trustees has given permission to remove the advertising clause of all software attributed to it. --- usr.bin/mesg/mesg.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/usr.bin/mesg/mesg.c b/usr.bin/mesg/mesg.c index 270c1c546b5c..796a047730c9 100644 --- a/usr.bin/mesg/mesg.c +++ b/usr.bin/mesg/mesg.c @@ -15,11 +15,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * -- cgit v1.2.3 From 0ee4b22d75b498fd026fbfba3af3c7f51e83a56a Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Sun, 11 May 2014 02:16:08 +0000 Subject: Port over mmap routine from syscons. This lets X11 work on PowerPC with vt. The last obstacle to switching PowerPC entirely to vt is that the Playstation 3 framebuffer driver needs to be ported over. This only applies for powerpc64, however. --- sys/dev/vt/hw/ofwfb/ofwfb.c | 63 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 12 deletions(-) diff --git a/sys/dev/vt/hw/ofwfb/ofwfb.c b/sys/dev/vt/hw/ofwfb/ofwfb.c index 156675bab0e7..d91feff957cf 100644 --- a/sys/dev/vt/hw/ofwfb/ofwfb.c +++ b/sys/dev/vt/hw/ofwfb/ofwfb.c @@ -49,6 +49,10 @@ __FBSDID("$FreeBSD$"); struct ofwfb_softc { phandle_t sc_node; + struct ofw_pci_register sc_pciaddrs[8]; + int sc_num_pciaddrs; + + intptr_t sc_addr; int sc_depth; int sc_stride; @@ -62,6 +66,7 @@ static vd_probe_t ofwfb_probe; static vd_init_t ofwfb_init; static vd_blank_t ofwfb_blank; static vd_bitbltchr_t ofwfb_bitbltchr; +static vd_fb_mmap_t ofwfb_mmap; static const struct vt_driver vt_ofwfb_driver = { .vd_name = "ofwfb", @@ -70,6 +75,7 @@ static const struct vt_driver vt_ofwfb_driver = { .vd_blank = ofwfb_blank, .vd_bitbltchr = ofwfb_bitbltchr, .vd_maskbitbltchr = ofwfb_bitbltchr, + .vd_fb_mmap = ofwfb_mmap, .vd_priority = VD_PRIORITY_GENERIC+1, }; @@ -288,8 +294,6 @@ ofwfb_init(struct vt_device *vd) ihandle_t stdout; phandle_t node; uint32_t depth, height, width; - struct ofw_pci_register pciaddrs[8]; - int n_pciaddrs; uint32_t fb_phys; int i, len; #ifdef __sparc64__ @@ -343,15 +347,15 @@ ofwfb_init(struct vt_device *vd) * child of the PCI device: in that case, try the parent for * the assigned-addresses property. */ - len = OF_getprop(node, "assigned-addresses", pciaddrs, - sizeof(pciaddrs)); + len = OF_getprop(node, "assigned-addresses", sc->sc_pciaddrs, + sizeof(sc->sc_pciaddrs)); if (len == -1) { len = OF_getprop(OF_parent(node), "assigned-addresses", - pciaddrs, sizeof(pciaddrs)); + sc->sc_pciaddrs, sizeof(sc->sc_pciaddrs)); } if (len == -1) len = 0; - n_pciaddrs = len / sizeof(struct ofw_pci_register); + sc->sc_num_pciaddrs = len / sizeof(struct ofw_pci_register); /* * Grab the physical address of the framebuffer, and then map it @@ -381,13 +385,13 @@ ofwfb_init(struct vt_device *vd) * Linux does the same thing. */ - fb_phys = n_pciaddrs; - for (i = 0; i < n_pciaddrs; i++) { + fb_phys = sc->sc_num_pciaddrs; + for (i = 0; i < sc->sc_num_pciaddrs; i++) { /* If it is too small, not the framebuffer */ - if (pciaddrs[i].size_lo < sc->sc_stride*height) + if (sc->sc_pciaddrs[i].size_lo < sc->sc_stride*height) continue; /* If it is not memory, it isn't either */ - if (!(pciaddrs[i].phys_hi & + if (!(sc->sc_pciaddrs[i].phys_hi & OFW_PCI_PHYS_HI_SPACE_MEM32)) continue; @@ -395,11 +399,12 @@ ofwfb_init(struct vt_device *vd) fb_phys = i; /* If it is prefetchable, it certainly is */ - if (pciaddrs[i].phys_hi & OFW_PCI_PHYS_HI_PREFETCHABLE) + if (sc->sc_pciaddrs[i].phys_hi & + OFW_PCI_PHYS_HI_PREFETCHABLE) break; } - if (fb_phys == n_pciaddrs) /* No candidates found */ + if (fb_phys == sc->sc_num_pciaddrs) /* No candidates found */ return (CN_DEAD); #if defined(__powerpc__) @@ -416,3 +421,37 @@ ofwfb_init(struct vt_device *vd) return (CN_INTERNAL); } +static int +ofwfb_mmap(struct vt_device *vd, vm_ooffset_t offset, vm_paddr_t *paddr, + int prot, vm_memattr_t *memattr) +{ + struct ofwfb_softc *sc = vd->vd_softc; + int i; + + /* + * Make sure the requested address lies within the PCI device's + * assigned addrs + */ + for (i = 0; i < sc->sc_num_pciaddrs; i++) + if (offset >= sc->sc_pciaddrs[i].phys_lo && + offset < (sc->sc_pciaddrs[i].phys_lo + sc->sc_pciaddrs[i].size_lo)) + { + /* + * If this is a prefetchable BAR, we can (and should) + * enable write-combining. + */ + if (sc->sc_pciaddrs[i].phys_hi & + OFW_PCI_PHYS_HI_PREFETCHABLE) + *memattr = VM_MEMATTR_WRITE_COMBINING; + + *paddr = offset; + return (0); + } + + /* + * Hack for Radeon... + */ + *paddr = offset; + return (0); +} + -- cgit v1.2.3 From 010afa35cac5249ed5db7087373f68c4fc9f2fe6 Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Sun, 11 May 2014 02:18:17 +0000 Subject: Use vt(4) by default on 32-bit PowerPC now that it is fully functional and fast. 64-bit PowerPC will follow along once the PS3 framebuffer driver is adapted. --- sys/powerpc/conf/GENERIC | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sys/powerpc/conf/GENERIC b/sys/powerpc/conf/GENERIC index 4400b53415f8..15139e93fe96 100644 --- a/sys/powerpc/conf/GENERIC +++ b/sys/powerpc/conf/GENERIC @@ -121,12 +121,9 @@ device sa # Sequential Access (tape etc) device cd # CD device pass # Passthrough device (direct ATA/SCSI access) -# syscons is the default console driver, resembling an SCO console -device sc +# vt is the default console driver, resembling an SCO console +device vt # Generic console driver (pulls in OF FB) device kbdmux -options SC_OFWFB # OFW frame buffer -options SC_DFLT_FONT # compile font in -makeoptions SC_DFLT_FONT=cp437 # Serial (COM) ports device scc -- cgit v1.2.3 From ffd328487af38543406eee26fd01628e60af346d Mon Sep 17 00:00:00 2001 From: Peter Grehan Date: Sun, 11 May 2014 04:18:51 +0000 Subject: Enable SMP for Exynos-based platforms (i.e. Chromebook) Reviewed by: br --- sys/arm/conf/EXYNOS5250.common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/arm/conf/EXYNOS5250.common b/sys/arm/conf/EXYNOS5250.common index 474cb6bed6f3..fa8c9c79ee32 100644 --- a/sys/arm/conf/EXYNOS5250.common +++ b/sys/arm/conf/EXYNOS5250.common @@ -83,7 +83,7 @@ device sdhci # generic sdhci options ROOTDEVNAME=\"ufs:/dev/da0\" -#options SMP +options SMP # Pseudo devices -- cgit v1.2.3 From b07d0cbce33ccea111ae09f818fcfa756d49b1db Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Sun, 11 May 2014 04:24:57 +0000 Subject: Add cpu_l2cache_drain_writebuf(), use it to implement generic_bs_barrier(). On modern ARM SoCs the L2 cache controller sits between the CPU and the AXI bus, and most on-chip memory-mapped devices are on the AXI bus. We map the device registers using the 'Device' memory attribute, which means the memory is not cached, but writes to it are buffered. Ensuring that a write has made it all the way to a device may require that the L2 controller take some action. There is currently only one implementation of the new function, for the PL310 cache controller. It invokes a function that the controller manual calls "cache sync" but it actually has nothing to do with cache at all, it triggers a drain of all pending store buffer writes and it blocks until they complete. The sheeva and xscale L2 controllers (which predate the concept of Device memory) don't seem to have a corresponding function. It appears that the standard armv5 drain_writebuf function includes draining all the way through the L2 controller. --- sys/arm/arm/bus_space_generic.c | 14 +++++++++++++- sys/arm/arm/cpufunc.c | 11 +++++++++++ sys/arm/arm/pl310.c | 13 +++++++++++++ sys/arm/include/cpufunc.h | 2 ++ 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/sys/arm/arm/bus_space_generic.c b/sys/arm/arm/bus_space_generic.c index 8d272c406029..35052ecf9904 100644 --- a/sys/arm/arm/bus_space_generic.c +++ b/sys/arm/arm/bus_space_generic.c @@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include /* Prototypes for all the bus_space structure functions */ @@ -110,5 +111,16 @@ generic_bs_barrier(void *t, bus_space_handle_t bsh, bus_size_t offset, bus_size_t len, int flags) { - /* Nothing to do. */ + /* + * dsb() will drain the L1 write buffer and establish a memory access + * barrier point on platforms where that has meaning. On a write we + * also need to drain the L2 write buffer, because most on-chip memory + * mapped devices are downstream of the L2 cache. Note that this needs + * to be done even for memory mapped as Device type, because while + * Device memory is not cached, writes to it are still buffered. + */ + dsb(); + if (flags & BUS_SPACE_BARRIER_WRITE) { + cpu_l2cache_drain_writebuf(); + } } diff --git a/sys/arm/arm/cpufunc.c b/sys/arm/arm/cpufunc.c index 3d29d713a663..ea631c9ef89f 100644 --- a/sys/arm/arm/cpufunc.c +++ b/sys/arm/arm/cpufunc.c @@ -150,6 +150,7 @@ struct cpu_functions arm9_cpufuncs = { (void *)cpufunc_nullop, /* l2cache_wbinv_range */ (void *)cpufunc_nullop, /* l2cache_inv_range */ (void *)cpufunc_nullop, /* l2cache_wb_range */ + (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ /* Other functions */ @@ -214,6 +215,7 @@ struct cpu_functions armv5_ec_cpufuncs = { (void *)cpufunc_nullop, /* l2cache_wbinv_range */ (void *)cpufunc_nullop, /* l2cache_inv_range */ (void *)cpufunc_nullop, /* l2cache_wb_range */ + (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ /* Other functions */ @@ -276,6 +278,7 @@ struct cpu_functions sheeva_cpufuncs = { sheeva_l2cache_wbinv_range, /* l2cache_wbinv_range */ sheeva_l2cache_inv_range, /* l2cache_inv_range */ sheeva_l2cache_wb_range, /* l2cache_wb_range */ + (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ /* Other functions */ @@ -338,6 +341,7 @@ struct cpu_functions arm10_cpufuncs = { (void *)cpufunc_nullop, /* l2cache_wbinv_range */ (void *)cpufunc_nullop, /* l2cache_inv_range */ (void *)cpufunc_nullop, /* l2cache_wb_range */ + (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ /* Other functions */ @@ -401,6 +405,7 @@ struct cpu_functions pj4bv7_cpufuncs = { (void *)cpufunc_nullop, /* l2cache_wbinv_range */ (void *)cpufunc_nullop, /* l2cache_inv_range */ (void *)cpufunc_nullop, /* l2cache_wb_range */ + (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ /* Other functions */ @@ -466,6 +471,7 @@ struct cpu_functions xscale_cpufuncs = { (void *)cpufunc_nullop, /* l2cache_wbinv_range */ (void *)cpufunc_nullop, /* l2cache_inv_range */ (void *)cpufunc_nullop, /* l2cache_wb_range */ + (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ /* Other functions */ @@ -530,6 +536,7 @@ struct cpu_functions xscalec3_cpufuncs = { xscalec3_l2cache_purge_rng, /* l2cache_wbinv_range */ xscalec3_l2cache_flush_rng, /* l2cache_inv_range */ xscalec3_l2cache_clean_rng, /* l2cache_wb_range */ + (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ /* Other functions */ @@ -593,6 +600,7 @@ struct cpu_functions fa526_cpufuncs = { (void *)cpufunc_nullop, /* l2cache_wbinv_range */ (void *)cpufunc_nullop, /* l2cache_inv_range */ (void *)cpufunc_nullop, /* l2cache_wb_range */ + (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ /* Other functions */ @@ -656,6 +664,7 @@ struct cpu_functions arm1136_cpufuncs = { (void *)cpufunc_nullop, /* l2cache_wbinv_range */ (void *)cpufunc_nullop, /* l2cache_inv_range */ (void *)cpufunc_nullop, /* l2cache_wb_range */ + (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ /* Other functions */ @@ -718,6 +727,7 @@ struct cpu_functions arm1176_cpufuncs = { (void *)cpufunc_nullop, /* l2cache_wbinv_range */ (void *)cpufunc_nullop, /* l2cache_inv_range */ (void *)cpufunc_nullop, /* l2cache_wb_range */ + (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ /* Other functions */ @@ -789,6 +799,7 @@ struct cpu_functions cortexa_cpufuncs = { (void *)cpufunc_nullop, /* l2cache_wbinv_range */ (void *)cpufunc_nullop, /* l2cache_inv_range */ (void *)cpufunc_nullop, /* l2cache_wb_range */ + (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ /* Other functions */ diff --git a/sys/arm/arm/pl310.c b/sys/arm/arm/pl310.c index 83e690711b41..cf19d6c4be10 100644 --- a/sys/arm/arm/pl310.c +++ b/sys/arm/arm/pl310.c @@ -349,6 +349,18 @@ pl310_inv_range(vm_paddr_t start, vm_size_t size) PL310_UNLOCK(pl310_softc); } +static void +pl310_drain_writebuf(void) +{ + + if ((pl310_softc == NULL) || !pl310_softc->sc_enabled) + return; + + PL310_LOCK(pl310_softc); + pl310_cache_sync(); + PL310_UNLOCK(pl310_softc); +} + static void pl310_set_way_sizes(struct pl310_softc *sc) { @@ -484,6 +496,7 @@ pl310_attach(device_t dev) cpufuncs.cf_l2cache_wbinv_range = pl310_wbinv_range; cpufuncs.cf_l2cache_inv_range = pl310_inv_range; cpufuncs.cf_l2cache_wb_range = pl310_wb_range; + cpufuncs.cf_l2cache_drain_writebuf = pl310_drain_writebuf; return (0); } diff --git a/sys/arm/include/cpufunc.h b/sys/arm/include/cpufunc.h index c2a96a81507e..16887b0fcec5 100644 --- a/sys/arm/include/cpufunc.h +++ b/sys/arm/include/cpufunc.h @@ -151,6 +151,7 @@ struct cpu_functions { void (*cf_l2cache_wbinv_range) (vm_offset_t, vm_size_t); void (*cf_l2cache_inv_range) (vm_offset_t, vm_size_t); void (*cf_l2cache_wb_range) (vm_offset_t, vm_size_t); + void (*cf_l2cache_drain_writebuf) (void); /* Other functions */ @@ -252,6 +253,7 @@ void tlb_broadcast(int); #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() #define cpu_flush_prefetchbuf() cpufuncs.cf_flush_prefetchbuf() #define cpu_drain_writebuf() cpufuncs.cf_drain_writebuf() -- cgit v1.2.3 From 49588d0fac18743f84c0fb31fc00e21f466b24c4 Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Sun, 11 May 2014 05:49:35 +0000 Subject: Move the PS3 framebuffer console to use vt instead of syscons and adjust GENERIC64 for PowerPC to use vt with it. Much to my chagrin, PS3 support seems to have bitrotted somewhat since the last time I tried it. ehci panics on attach and interrupt handling seems to be faulty. This should be fixed soon... --- sys/conf/files.powerpc | 4 +- sys/powerpc/conf/GENERIC64 | 7 +- sys/powerpc/ps3/ps3_syscons.c | 669 +++--------------------------------------- 3 files changed, 51 insertions(+), 629 deletions(-) diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc index 95fa6ecb9f51..8aed60a3d568 100644 --- a/sys/conf/files.powerpc +++ b/sys/conf/files.powerpc @@ -222,8 +222,8 @@ powerpc/ps3/ps3bus.c optional ps3 powerpc/ps3/ps3cdrom.c optional ps3 scbus powerpc/ps3/ps3disk.c optional ps3 powerpc/ps3/ps3pic.c optional ps3 -powerpc/ps3/ps3_syscons.c optional ps3 sc -powerpc/ps3/ps3-hvcall.S optional ps3 sc +powerpc/ps3/ps3_syscons.c optional ps3 vt +powerpc/ps3/ps3-hvcall.S optional ps3 powerpc/pseries/phyp-hvcall.S optional pseries powerpc64 powerpc/pseries/mmu_phyp.c optional pseries powerpc64 powerpc/pseries/phyp_console.c optional pseries powerpc64 uart diff --git a/sys/powerpc/conf/GENERIC64 b/sys/powerpc/conf/GENERIC64 index 60bd04e1013c..0003822eaf9e 100644 --- a/sys/powerpc/conf/GENERIC64 +++ b/sys/powerpc/conf/GENERIC64 @@ -119,12 +119,9 @@ device sa # Sequential Access (tape etc) device cd # CD device pass # Passthrough device (direct ATA/SCSI access) -# syscons is the default console driver, resembling an SCO console -device sc +# vt is the default console driver, resembling an SCO console +device vt # Core console driver device kbdmux -options SC_OFWFB # OFW frame buffer -options SC_DFLT_FONT # compile font in -makeoptions SC_DFLT_FONT=cp437 # Serial (COM) ports device scc diff --git a/sys/powerpc/ps3/ps3_syscons.c b/sys/powerpc/ps3/ps3_syscons.c index 2b6e18201393..032653bdc8b8 100644 --- a/sys/powerpc/ps3/ps3_syscons.c +++ b/sys/powerpc/ps3/ps3_syscons.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2003 Peter Grehan + * Copyright (c) 2011-2014 Nathan Whitehorn * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,31 +29,22 @@ __FBSDID("$FreeBSD$"); #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 "ps3-hvcall.h" @@ -65,62 +56,12 @@ __FBSDID("$FreeBSD$"); #define L1GPU_DISPLAY_SYNC_VSYNC 2 #define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP 0x0102 -extern u_char dflt_font_16[]; -extern u_char dflt_font_14[]; -extern u_char dflt_font_8[]; - -static int ps3fb_configure(int flags); +static vd_init_t ps3fb_init; +static vd_probe_t ps3fb_probe; void ps3fb_remap(void); -static vi_probe_t ps3fb_probe; -static vi_init_t ps3fb_init; -static vi_get_info_t ps3fb_get_info; -static vi_query_mode_t ps3fb_query_mode; -static vi_set_mode_t ps3fb_set_mode; -static vi_save_font_t ps3fb_save_font; -static vi_load_font_t ps3fb_load_font; -static vi_show_font_t ps3fb_show_font; -static vi_save_palette_t ps3fb_save_palette; -static vi_load_palette_t ps3fb_load_palette; -static vi_set_border_t ps3fb_set_border; -static vi_save_state_t ps3fb_save_state; -static vi_load_state_t ps3fb_load_state; -static vi_set_win_org_t ps3fb_set_win_org; -static vi_read_hw_cursor_t ps3fb_read_hw_cursor; -static vi_set_hw_cursor_t ps3fb_set_hw_cursor; -static vi_set_hw_cursor_shape_t ps3fb_set_hw_cursor_shape; -static vi_blank_display_t ps3fb_blank_display; -static vi_mmap_t ps3fb_mmap; -static vi_ioctl_t ps3fb_ioctl; -static vi_clear_t ps3fb_clear; -static vi_fill_rect_t ps3fb_fill_rect; -static vi_bitblt_t ps3fb_bitblt; -static vi_diag_t ps3fb_diag; -static vi_save_cursor_palette_t ps3fb_save_cursor_palette; -static vi_load_cursor_palette_t ps3fb_load_cursor_palette; -static vi_copy_t ps3fb_copy; -static vi_putp_t ps3fb_putp; -static vi_putc_t ps3fb_putc; -static vi_puts_t ps3fb_puts; -static vi_putm_t ps3fb_putm; - struct ps3fb_softc { - video_adapter_t sc_va; - struct cdev *sc_si; - int sc_console; - - intptr_t sc_addr; - int sc_height; - int sc_width; - int sc_stride; - int sc_ncol; - int sc_nrow; - - int sc_xmargin; - int sc_ymargin; - - u_char *sc_font; - int sc_font_height; + struct fb_info fb_info; uint64_t sc_fbhandle; uint64_t sc_fbcontext; @@ -130,106 +71,22 @@ struct ps3fb_softc { uint64_t sc_reports_size; }; -static video_switch_t ps3fbvidsw = { - .probe = ps3fb_probe, - .init = ps3fb_init, - .get_info = ps3fb_get_info, - .query_mode = ps3fb_query_mode, - .set_mode = ps3fb_set_mode, - .save_font = ps3fb_save_font, - .load_font = ps3fb_load_font, - .show_font = ps3fb_show_font, - .save_palette = ps3fb_save_palette, - .load_palette = ps3fb_load_palette, - .set_border = ps3fb_set_border, - .save_state = ps3fb_save_state, - .load_state = ps3fb_load_state, - .set_win_org = ps3fb_set_win_org, - .read_hw_cursor = ps3fb_read_hw_cursor, - .set_hw_cursor = ps3fb_set_hw_cursor, - .set_hw_cursor_shape = ps3fb_set_hw_cursor_shape, - .blank_display = ps3fb_blank_display, - .mmap = ps3fb_mmap, - .ioctl = ps3fb_ioctl, - .clear = ps3fb_clear, - .fill_rect = ps3fb_fill_rect, - .bitblt = ps3fb_bitblt, - .diag = ps3fb_diag, - .save_cursor_palette = ps3fb_save_cursor_palette, - .load_cursor_palette = ps3fb_load_cursor_palette, - .copy = ps3fb_copy, - .putp = ps3fb_putp, - .putc = ps3fb_putc, - .puts = ps3fb_puts, - .putm = ps3fb_putm, -}; - -VIDEO_DRIVER(ps3fb, ps3fbvidsw, ps3fb_configure); - -extern sc_rndr_sw_t txtrndrsw; -RENDERER(ps3fb, 0, txtrndrsw, gfb_set); - -RENDERER_MODULE(ps3fb, gfb_set); - -/* - * Define the iso6429-1983 colormap - */ -static struct { - uint8_t red; - uint8_t green; - uint8_t blue; -} ps3fb_cmap[16] = { /* # R G B Color */ - /* - - - - ----- */ - { 0x00, 0x00, 0x00 }, /* 0 0 0 0 Black */ - { 0x00, 0x00, 0xaa }, /* 1 0 0 2/3 Blue */ - { 0x00, 0xaa, 0x00 }, /* 2 0 2/3 0 Green */ - { 0x00, 0xaa, 0xaa }, /* 3 0 2/3 2/3 Cyan */ - { 0xaa, 0x00, 0x00 }, /* 4 2/3 0 0 Red */ - { 0xaa, 0x00, 0xaa }, /* 5 2/3 0 2/3 Magenta */ - { 0xaa, 0x55, 0x00 }, /* 6 2/3 1/3 0 Brown */ - { 0xaa, 0xaa, 0xaa }, /* 7 2/3 2/3 2/3 White */ - { 0x55, 0x55, 0x55 }, /* 8 1/3 1/3 1/3 Gray */ - { 0x55, 0x55, 0xff }, /* 9 1/3 1/3 1 Bright Blue */ - { 0x55, 0xff, 0x55 }, /* 10 1/3 1 1/3 Bright Green */ - { 0x55, 0xff, 0xff }, /* 11 1/3 1 1 Bright Cyan */ - { 0xff, 0x55, 0x55 }, /* 12 1 1/3 1/3 Bright Red */ - { 0xff, 0x55, 0xff }, /* 13 1 1/3 1 Bright Magenta */ - { 0xff, 0xff, 0x80 }, /* 14 1 1 1/3 Bright Yellow */ - { 0xff, 0xff, 0xff } /* 15 1 1 1 Bright White */ +static struct vt_driver vt_ps3fb_driver = { + .vd_name = "ps3fb", + .vd_probe = ps3fb_probe, + .vd_init = ps3fb_init, + .vd_blank = vt_fb_blank, + .vd_bitbltchr = vt_fb_bitbltchr, + .vd_maskbitbltchr = vt_fb_maskbitbltchr, + /* Better than VGA, but still generic driver. */ + .vd_priority = VD_PRIORITY_GENERIC + 1, }; -#define TODO printf("%s: unimplemented\n", __func__) - -static u_int16_t ps3fb_static_window[ROW*COL]; - +VT_DRIVER_DECLARE(vt_ps3fb, vt_ps3fb_driver); static struct ps3fb_softc ps3fb_softc; -static __inline int -ps3fb_background(uint8_t attr) -{ - return (attr >> 4); -} - -static __inline int -ps3fb_foreground(uint8_t attr) -{ - return (attr & 0x0f); -} - -static u_int -ps3fb_pix32(int attr) -{ - u_int retval; - - retval = (ps3fb_cmap[attr].red << 16) | - (ps3fb_cmap[attr].green << 8) | - ps3fb_cmap[attr].blue; - - return (retval); -} - static int -ps3fb_configure(int flags) +ps3fb_probe(struct vt_device *vd) { struct ps3fb_softc *sc; int disable; @@ -237,17 +94,12 @@ ps3fb_configure(int flags) #if 0 phandle_t root; #endif - static int done = 0; disable = 0; TUNABLE_INT_FETCH("hw.syscons.disable", &disable); if (disable != 0) return (0); - if (done != 0) - return (0); - done = 1; - sc = &ps3fb_softc; #if 0 @@ -260,24 +112,10 @@ ps3fb_configure(int flags) #else TUNABLE_STR_FETCH("hw.platform", compatible, sizeof(compatible)); if (strcmp(compatible, "ps3") != 0) - return (0); + return (CN_DEAD); #endif - sc->sc_console = 1; - - /* XXX: get from HV repository */ - sc->sc_height = 480; - sc->sc_width = 720; - sc->sc_stride = sc->sc_width*4; - - /* - * The loader puts the FB at 0x10000000, so use that for now. - */ - - sc->sc_addr = 0x10000000; - ps3fb_init(0, &sc->sc_va, 0); - - return (0); + return (CN_INTERNAL); } void @@ -299,474 +137,61 @@ ps3fb_remap(void) 0,L1GPU_DISPLAY_SYNC_VSYNC,0,0); lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC, 1,L1GPU_DISPLAY_SYNC_VSYNC,0,0); - lv1_gpu_memory_allocate(PS3FB_SIZE, 0, 0, 0, 0, &sc->sc_fbhandle, &fb_paddr); - lv1_gpu_context_allocate(sc->sc_fbhandle, 0, &sc->sc_fbcontext, &sc->sc_dma_control, - &sc->sc_driver_info, &sc->sc_reports, &sc->sc_reports_size); + lv1_gpu_memory_allocate(PS3FB_SIZE, 0, 0, 0, 0, &sc->sc_fbhandle, + &fb_paddr); + lv1_gpu_context_allocate(sc->sc_fbhandle, 0, &sc->sc_fbcontext, + &sc->sc_dma_control, &sc->sc_driver_info, &sc->sc_reports, + &sc->sc_reports_size); lv1_gpu_context_attribute(sc->sc_fbcontext, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 0, 0, 0, 0); lv1_gpu_context_attribute(sc->sc_fbcontext, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 1, 0, 0, 0); + sc->fb_info.fb_pbase = fb_paddr; for (va = 0; va < PS3FB_SIZE; va += PAGE_SIZE) pmap_kenter_attr(0x10000000 + va, fb_paddr + va, VM_MEMATTR_WRITE_COMBINING); } static int -ps3fb_probe(int unit, video_adapter_t **adp, void *arg, int flags) -{ - TODO; - return (0); -} - -static int -ps3fb_init(int unit, video_adapter_t *adp, int flags) +ps3fb_init(struct vt_device *vd) { struct ps3fb_softc *sc; - video_info_t *vi; - int cxborder, cyborder; - int font_height; - - sc = (struct ps3fb_softc *)adp; - vi = &adp->va_info; - - vid_init_struct(adp, "ps3fb", -1, unit); - - /* The default font size can be overridden by loader */ - font_height = 16; - TUNABLE_INT_FETCH("hw.syscons.fsize", &font_height); - if (font_height == 8) { - sc->sc_font = dflt_font_8; - sc->sc_font_height = 8; - } else if (font_height == 14) { - sc->sc_font = dflt_font_14; - sc->sc_font_height = 14; - } else { - /* default is 8x16 */ - sc->sc_font = dflt_font_16; - sc->sc_font_height = 16; - } - - /* The user can set a border in chars - default is 1 char width */ - cxborder = 8; - cyborder = 2; - TUNABLE_INT_FETCH("hw.syscons.xborder", &cxborder); - TUNABLE_INT_FETCH("hw.syscons.yborder", &cyborder); - - vi->vi_cheight = sc->sc_font_height; - vi->vi_width = sc->sc_width/8 - 2*cxborder; - vi->vi_height = sc->sc_height/sc->sc_font_height - 2*cyborder; - vi->vi_cwidth = 8; - - /* - * Clamp width/height to syscons maximums - */ - if (vi->vi_width > COL) - vi->vi_width = COL; - if (vi->vi_height > ROW) - vi->vi_height = ROW; - sc->sc_xmargin = (sc->sc_width - (vi->vi_width * vi->vi_cwidth)) / 2; - sc->sc_ymargin = (sc->sc_height - (vi->vi_height * vi->vi_cheight))/2; + /* Init softc */ + vd->vd_softc = sc = &ps3fb_softc; - /* - * Avoid huge amounts of conditional code in syscons by - * defining a dummy h/w text display buffer. - */ - adp->va_window = (vm_offset_t) ps3fb_static_window; + /* XXX: get from HV repository */ + sc->fb_info.fb_depth = 32; + sc->fb_info.fb_height = 480; + sc->fb_info.fb_width = 720; + sc->fb_info.fb_stride = sc->fb_info.fb_width*4; + sc->fb_info.fb_size = sc->fb_info.fb_height * sc->fb_info.fb_stride; + sc->fb_info.fb_bpp = sc->fb_info.fb_stride / sc->fb_info.fb_width * 8; /* - * Enable future font-loading and flag color support, as well as - * adding V_ADP_MODECHANGE so that we ps3fb_set_mode() gets called - * when the X server shuts down. This enables us to get the console - * back when X disappears. + * The loader puts the FB at 0x10000000, so use that for now. */ - adp->va_flags |= V_ADP_FONT | V_ADP_COLOR | V_ADP_MODECHANGE; - - ps3fb_set_mode(&sc->sc_va, 0); - vid_register(&sc->sc_va); - - return (0); -} -static int -ps3fb_get_info(video_adapter_t *adp, int mode, video_info_t *info) -{ - bcopy(&adp->va_info, info, sizeof(*info)); - return (0); -} + sc->fb_info.fb_vbase = 0x10000000; -static int -ps3fb_query_mode(video_adapter_t *adp, video_info_t *info) -{ - TODO; - return (0); -} - -static int -ps3fb_set_mode(video_adapter_t *adp, int mode) -{ - struct ps3fb_softc *sc; - - sc = (struct ps3fb_softc *)adp; - - /* XXX: no real mode setting at the moment */ - - ps3fb_blank_display(&sc->sc_va, V_DISPLAY_ON); + /* 32-bit VGA palette */ + vt_generate_vga_palette(sc->fb_info.fb_cmap, COLOR_FORMAT_RGB, + 255, 16, 255, 8, 255, 0); + /* Set correct graphics context */ lv1_gpu_context_attribute(sc->sc_fbcontext, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 0, 0, 0, 0); lv1_gpu_context_attribute(sc->sc_fbcontext, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 1, 0, 0, 0); - return (0); -} - -static int -ps3fb_save_font(video_adapter_t *adp, int page, int size, int width, - u_char *data, int c, int count) -{ - TODO; - return (0); -} - -static int -ps3fb_load_font(video_adapter_t *adp, int page, int size, int width, - u_char *data, int c, int count) -{ - struct ps3fb_softc *sc; - - sc = (struct ps3fb_softc *)adp; - - /* - * syscons code has already determined that current width/height - * are unchanged for this new font - */ - sc->sc_font = data; - return (0); -} - -static int -ps3fb_show_font(video_adapter_t *adp, int page) -{ - - return (0); -} - -static int -ps3fb_save_palette(video_adapter_t *adp, u_char *palette) -{ - /* TODO; */ - return (0); -} - -static int -ps3fb_load_palette(video_adapter_t *adp, u_char *palette) -{ - /* TODO; */ - return (0); -} - -static int -ps3fb_set_border(video_adapter_t *adp, int border) -{ - /* XXX Be lazy for now and blank entire screen */ - return (ps3fb_blank_display(adp, border)); -} - -static int -ps3fb_save_state(video_adapter_t *adp, void *p, size_t size) -{ - TODO; - return (0); -} - -static int -ps3fb_load_state(video_adapter_t *adp, void *p) -{ - TODO; - return (0); -} - -static int -ps3fb_set_win_org(video_adapter_t *adp, off_t offset) -{ - TODO; - return (0); -} - -static int -ps3fb_read_hw_cursor(video_adapter_t *adp, int *col, int *row) -{ - *col = 0; - *row = 0; - - return (0); -} - -static int -ps3fb_set_hw_cursor(video_adapter_t *adp, int col, int row) -{ - - return (0); -} - -static int -ps3fb_set_hw_cursor_shape(video_adapter_t *adp, int base, int height, - int celsize, int blink) -{ - return (0); -} - -static int -ps3fb_blank_display(video_adapter_t *adp, int mode) -{ - struct ps3fb_softc *sc; - int i; - uint32_t *addr; - - sc = (struct ps3fb_softc *)adp; - addr = (uint32_t *) sc->sc_addr; - - for (i = 0; i < (sc->sc_stride/4)*sc->sc_height; i++) - *(addr + i) = ps3fb_pix32(ps3fb_background(SC_NORM_ATTR)); - - return (0); -} - -static int -ps3fb_mmap(video_adapter_t *adp, vm_ooffset_t offset, vm_paddr_t *paddr, - int prot, vm_memattr_t *memattr) -{ - struct ps3fb_softc *sc; - - sc = (struct ps3fb_softc *)adp; - - /* - * This might be a legacy VGA mem request: if so, just point it at the - * framebuffer, since it shouldn't be touched - */ - if (offset < sc->sc_stride*sc->sc_height) { - *paddr = sc->sc_addr + offset; - return (0); - } - - return (EINVAL); -} - -static int -ps3fb_ioctl(video_adapter_t *adp, u_long cmd, caddr_t data) -{ - - return (0); -} - -static int -ps3fb_clear(video_adapter_t *adp) -{ - TODO; - return (0); -} - -static int -ps3fb_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy) -{ - TODO; - return (0); -} - -static int -ps3fb_bitblt(video_adapter_t *adp, ...) -{ - TODO; - return (0); -} - -static int -ps3fb_diag(video_adapter_t *adp, int level) -{ - TODO; - return (0); -} + fb_probe(&sc->fb_info); + vt_fb_init(vd); -static int -ps3fb_save_cursor_palette(video_adapter_t *adp, u_char *palette) -{ - TODO; - return (0); -} - -static int -ps3fb_load_cursor_palette(video_adapter_t *adp, u_char *palette) -{ - TODO; - return (0); -} - -static int -ps3fb_copy(video_adapter_t *adp, vm_offset_t src, vm_offset_t dst, int n) -{ - TODO; - return (0); -} - -static int -ps3fb_putp(video_adapter_t *adp, vm_offset_t off, uint32_t p, uint32_t a, - int size, int bpp, int bit_ltor, int byte_ltor) -{ - TODO; - return (0); -} - -static int -ps3fb_putc(video_adapter_t *adp, vm_offset_t off, uint8_t c, uint8_t a) -{ - struct ps3fb_softc *sc; - int row; - int col; - int i, j, k; - uint32_t *addr; - u_char *p; - - sc = (struct ps3fb_softc *)adp; - row = (off / adp->va_info.vi_width) * adp->va_info.vi_cheight; - col = (off % adp->va_info.vi_width) * adp->va_info.vi_cwidth; - p = sc->sc_font + c*sc->sc_font_height; - addr = (uint32_t *)sc->sc_addr - + (row + sc->sc_ymargin)*(sc->sc_stride/4) - + col + sc->sc_xmargin; - - for (i = 0; i < sc->sc_font_height; i++) { - for (j = 0, k = 7; j < 8; j++, k--) { - if ((p[i] & (1 << k)) == 0) - *(addr + j) = ps3fb_pix32(ps3fb_background(a)); - else - *(addr + j) = ps3fb_pix32(ps3fb_foreground(a)); - } - addr += (sc->sc_stride/4); - } - - return (0); -} - -static int -ps3fb_puts(video_adapter_t *adp, vm_offset_t off, u_int16_t *s, int len) -{ - int i; - - for (i = 0; i < len; i++) { - ps3fb_putc(adp, off + i, s[i] & 0xff, (s[i] & 0xff00) >> 8); - } - return (0); -} - -static int -ps3fb_putm(video_adapter_t *adp, int x, int y, uint8_t *pixel_image, - uint32_t pixel_mask, int size, int width) -{ - struct ps3fb_softc *sc; - int i, j, k; - uint32_t fg, bg; - uint32_t *addr; - - sc = (struct ps3fb_softc *)adp; - addr = (uint32_t *)sc->sc_addr - + (y + sc->sc_ymargin)*(sc->sc_stride/4) - + x + sc->sc_xmargin; - - fg = ps3fb_pix32(ps3fb_foreground(SC_NORM_ATTR)); - bg = ps3fb_pix32(ps3fb_background(SC_NORM_ATTR)); - - for (i = 0; i < size && i+y < sc->sc_height - 2*sc->sc_ymargin; i++) { - for (j = 0, k = width; j < 8; j++, k--) { - if (x + j >= sc->sc_width - 2*sc->sc_xmargin) - continue; - - if (pixel_image[i] & (1 << k)) - *(addr + j) = (*(addr + j) == fg) ? bg : fg; - } - addr += (sc->sc_stride/4); - } - - return (0); -} - -/* - * Define the syscons nexus device attachment - */ -static void -ps3fb_scidentify(driver_t *driver, device_t parent) -{ - device_t child; - - /* - * Add with a priority guaranteed to make it last on - * the device list - */ - if (strcmp(installed_platform(), "ps3") == 0) - child = BUS_ADD_CHILD(parent, INT_MAX, SC_DRIVER_NAME, 0); -} - -static int -ps3fb_scprobe(device_t dev) -{ - int error; - - if (strcmp(installed_platform(), "ps3") != 0) - return (ENXIO); - - device_set_desc(dev, "System console"); - - error = sc_probe_unit(device_get_unit(dev), - device_get_flags(dev) | SC_AUTODETECT_KBD); - if (error != 0) - return (error); - - /* This is a fake device, so make sure we added it ourselves */ - return (BUS_PROBE_NOWILDCARD); -} - -static int -ps3fb_scattach(device_t dev) -{ - return (sc_attach_unit(device_get_unit(dev), - device_get_flags(dev) | SC_AUTODETECT_KBD)); -} - -static device_method_t ps3fb_sc_methods[] = { - DEVMETHOD(device_identify, ps3fb_scidentify), - DEVMETHOD(device_probe, ps3fb_scprobe), - DEVMETHOD(device_attach, ps3fb_scattach), - { 0, 0 } -}; - -static driver_t ps3fb_sc_driver = { - SC_DRIVER_NAME, - ps3fb_sc_methods, - sizeof(sc_softc_t), -}; - -static devclass_t sc_devclass; - -DRIVER_MODULE(ps3fb, nexus, ps3fb_sc_driver, sc_devclass, 0, 0); - -/* - * Define a stub keyboard driver in case one hasn't been - * compiled into the kernel - */ -#include -#include - -static int dummy_kbd_configure(int flags); - -keyboard_switch_t ps3dummysw; - -static int -dummy_kbd_configure(int flags) -{ + /* Clear the screen. */ + vt_fb_blank(vd, TC_BLACK); - return (0); + return (CN_INTERNAL); } -KEYBOARD_DRIVER(ps3dummy, ps3dummysw, dummy_kbd_configure); -- cgit v1.2.3 From 4541f27356219bd72f2f74dac9dc15593c7e20bf Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Sun, 11 May 2014 08:17:46 +0000 Subject: Optimise host mode data roundtrip time. When BULK data is submitted to the main processing queue, clear the NAK counter for any associated BULK or CONTROL transfers and poll the endpoint(s) for 1 millisecond at 125us rate interval, before going into slow, 10ms, NAK polling mode again. This has the effect that typical ping-ping protocols respond quicker when initiated from the USB host. MFC after: 2 weeks --- sys/dev/usb/controller/dwc_otg.c | 94 +++++++++++++++++++++++++++++----------- sys/dev/usb/controller/dwc_otg.h | 3 +- 2 files changed, 71 insertions(+), 26 deletions(-) diff --git a/sys/dev/usb/controller/dwc_otg.c b/sys/dev/usb/controller/dwc_otg.c index c225bac7fb68..5d003a7eb72e 100644 --- a/sys/dev/usb/controller/dwc_otg.c +++ b/sys/dev/usb/controller/dwc_otg.c @@ -760,7 +760,7 @@ check_state: case DWC_CHAN_ST_WAIT_ANE: if (hcint & (HCINT_RETRY | HCINT_ERRORS)) { - td->did_nak = 1; + td->did_nak++; td->tt_scheduled = 0; goto send_pkt; } else if (hcint & (HCINT_ACK | HCINT_NYET)) { @@ -774,7 +774,7 @@ check_state: case DWC_CHAN_ST_WAIT_S_ANE: if (hcint & (HCINT_RETRY | HCINT_ERRORS)) { - td->did_nak = 1; + td->did_nak++; td->tt_scheduled = 0; goto send_pkt; } else if (hcint & (HCINT_ACK | HCINT_NYET)) { @@ -786,7 +786,7 @@ check_state: if (hcint & HCINT_NYET) { goto send_cpkt; } else if (hcint & (HCINT_RETRY | HCINT_ERRORS)) { - td->did_nak = 1; + td->did_nak++; td->tt_scheduled = 0; goto send_pkt; } else if (hcint & HCINT_ACK) { @@ -1085,7 +1085,7 @@ dwc_otg_host_rate_check(struct dwc_otg_td *td) if (!td->tt_scheduled) goto busy; td->tt_scheduled = 0; - } else if (td->did_nak != 0) { + } else if (td->did_nak >= DWC_OTG_NAK_MAX) { goto busy; } else if (td->set_toggle) { td->set_toggle = 0; @@ -1244,7 +1244,7 @@ check_state: case DWC_CHAN_ST_WAIT_ANE: if (hcint & (HCINT_RETRY | HCINT_ERRORS)) { - td->did_nak = 1; + td->did_nak++; td->tt_scheduled = 0; if (td->hcsplt != 0) goto receive_spkt; @@ -1284,6 +1284,7 @@ check_state: */ } td->tt_scheduled = 0; + td->did_nak = 0; if (td->hcsplt != 0) goto receive_spkt; else @@ -1298,14 +1299,16 @@ check_state: * case of interrupt and isochronous transfers: */ if (hcint & (HCINT_RETRY | HCINT_ERRORS)) { - td->did_nak = 1; + td->did_nak++; td->tt_scheduled = 0; goto receive_spkt; } else if (hcint & HCINT_NYET) { td->tt_scheduled = 0; goto receive_spkt; - } else if (hcint & HCINT_ACK) + } else if (hcint & HCINT_ACK) { + td->did_nak = 0; goto receive_pkt; + } break; case DWC_CHAN_ST_WAIT_C_PKT: @@ -1633,13 +1636,14 @@ check_state: case DWC_CHAN_ST_WAIT_ANE: if (hcint & (HCINT_RETRY | HCINT_ERRORS)) { - td->did_nak = 1; + td->did_nak++; td->tt_scheduled = 0; goto send_pkt; } else if (hcint & (HCINT_ACK | HCINT_NYET)) { td->offset += td->tx_bytes; td->remainder -= td->tx_bytes; td->toggle ^= 1; + td->did_nak = 0; td->tt_scheduled = 0; /* check remainder */ @@ -1658,24 +1662,27 @@ check_state: case DWC_CHAN_ST_WAIT_S_ANE: if (hcint & (HCINT_RETRY | HCINT_ERRORS)) { - td->did_nak = 1; + td->did_nak++; td->tt_scheduled = 0; goto send_pkt; - } else if (hcint & (HCINT_ACK | HCINT_NYET)) + } else if (hcint & (HCINT_ACK | HCINT_NYET)) { + td->did_nak = 0; goto send_cpkt; + } break; case DWC_CHAN_ST_WAIT_C_ANE: if (hcint & HCINT_NYET) { goto send_cpkt; } else if (hcint & (HCINT_RETRY | HCINT_ERRORS)) { - td->did_nak = 1; + td->did_nak++; td->tt_scheduled = 0; goto send_pkt; } else if (hcint & HCINT_ACK) { td->offset += td->tx_bytes; td->remainder -= td->tx_bytes; td->toggle ^= 1; + td->did_nak = 0; td->tt_scheduled = 0; /* check remainder */ @@ -2283,8 +2290,10 @@ dwc_otg_timer(void *_sc) TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) { td = xfer->td_transfer_cache; - if (td != NULL) + if (td != NULL) { + /* reset NAK counter */ td->did_nak = 0; + } } /* enable SOF interrupt, which will poll jobs */ @@ -2429,8 +2438,11 @@ dwc_otg_update_host_transfer_schedule(struct dwc_otg_softc *sc) TAILQ_FOREACH_SAFE(xfer, &sc->sc_bus.intr_q.head, wait_entry, xfer_next) { td = xfer->td_transfer_cache; - if (td == NULL || td->did_nak != 0 || td->ep_type != UE_CONTROL) + if (td == NULL || + td->ep_type != UE_CONTROL || + td->did_nak >= DWC_OTG_NAK_MAX) { continue; + } sc->sc_needsof = 1; @@ -2448,8 +2460,11 @@ dwc_otg_update_host_transfer_schedule(struct dwc_otg_softc *sc) if ((temp & 7) < 6) { TAILQ_FOREACH_SAFE(xfer, &sc->sc_bus.intr_q.head, wait_entry, xfer_next) { td = xfer->td_transfer_cache; - if (td == NULL || td->did_nak != 0 || td->ep_type != UE_BULK) + if (td == NULL || + td->ep_type != UE_BULK || + td->did_nak >= DWC_OTG_NAK_MAX) { continue; + } sc->sc_needsof = 1; @@ -3206,24 +3221,53 @@ static void dwc_otg_start_standard_chain(struct usb_xfer *xfer) { struct dwc_otg_softc *sc = DWC_OTG_BUS2SC(xfer->xroot->bus); + struct usb_xfer_root *xroot; + struct dwc_otg_td *td; DPRINTFN(9, "\n"); - /* poll one time - will turn on interrupts */ - if (dwc_otg_xfer_do_fifo(xfer)) { + /* + * Poll one time in device mode, which will turn on the + * endpoint interrupts. Else wait for SOF interrupt in host + * mode. + */ + if (sc->sc_flags.status_device_mode != 0 && + dwc_otg_xfer_do_fifo(xfer) == 0) + goto done; - /* put transfer on interrupt queue */ - usbd_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer); + /* put transfer on interrupt queue */ + usbd_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer); - /* start timeout, if any */ - if (xfer->timeout != 0) { - usbd_transfer_timeout_ms(xfer, - &dwc_otg_timeout, xfer->timeout); - } + /* start timeout, if any */ + if (xfer->timeout != 0) { + usbd_transfer_timeout_ms(xfer, + &dwc_otg_timeout, xfer->timeout); + } + + if (sc->sc_flags.status_device_mode != 0) + goto done; - /* enable SOF interrupt, if any */ - dwc_otg_enable_sof_irq(sc); + /* enable SOF interrupt, if any */ + dwc_otg_enable_sof_irq(sc); + + td = xfer->td_transfer_cache; + if (td->ep_type != UE_BULK) + goto done; + + xroot = xfer->xroot; + + /* + * Optimise the ping-pong effect by waking up other BULK + * transfers belonging to the same device group: + */ + TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) { + td = xfer->td_transfer_cache; + if (td == NULL || td->ep_type != UE_BULK || xfer->xroot != xroot) + continue; + /* reset NAK counter */ + td->did_nak = 0; } +done:; } static void diff --git a/sys/dev/usb/controller/dwc_otg.h b/sys/dev/usb/controller/dwc_otg.h index 406341669788..7c46b75494e0 100644 --- a/sys/dev/usb/controller/dwc_otg.h +++ b/sys/dev/usb/controller/dwc_otg.h @@ -37,6 +37,7 @@ #define DWC_OTG_TT_SLOT_MAX 8 #define DWC_OTG_SLOT_IDLE_MAX 4 #define DWC_OTG_SLOT_IDLE_MIN 2 +#define DWC_OTG_NAK_MAX 8 /* 1 ms */ #define DWC_OTG_READ_4(sc, reg) \ bus_space_read_4((sc)->sc_io_tag, (sc)->sc_io_hdl, reg) @@ -64,6 +65,7 @@ struct dwc_otg_td { uint8_t errcnt; uint8_t tmr_res; uint8_t tmr_val; + uint8_t did_nak; /* NAK counter */ uint8_t ep_no; uint8_t ep_type; uint8_t channel[2]; @@ -87,7 +89,6 @@ struct dwc_otg_td { uint8_t toggle:1; uint8_t set_toggle:1; uint8_t got_short:1; - uint8_t did_nak:1; uint8_t tt_scheduled:1; uint8_t tt_channel_tog:1; }; -- cgit v1.2.3 From 3b4afe73d0a29b344e75de5f599a8cd9dff377d8 Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Sun, 11 May 2014 10:06:27 +0000 Subject: Typo fixes and some language/punctuation improvements. --- share/man/man4/lm75.4 | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/share/man/man4/lm75.4 b/share/man/man4/lm75.4 index 361044bc6c1d..8e794dc6b99c 100644 --- a/share/man/man4/lm75.4 +++ b/share/man/man4/lm75.4 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 7, 2014 +.Dd May 11, 2014 .Dt LM75 4 .Os .Sh NAME @@ -69,28 +69,28 @@ dev.lm75.0.shutdown: 0 Is the read-only value of the current temperature read by the sensor. .It Va dev.lm75.%d.thyst Sets the hysteresis temperature. -Once the temperature get over the overtemperature shutdown value (tos) -it need to drop bellow the hysteresis temperature to disable the output +Once the temperature gets over the overtemperature shutdown value (tos) +it needs to drop below the hysteresis temperature to disable the output (interrupt) pin again. .It Va dev.lm75.%d.tos Sets the overtemperature shutdown value. -Once the temperature get over this value the output pin will be enabled. +Once the temperature gets over this value the output pin will be enabled. The way the output (interrupt) pin works, depends on the mode configuration. .It Va dev.lm75.%d.faults Is the number of faults that must occur consecutively to activate the interrupt (output) pin. It can be set to 1, 2, 4, and 6. .It Va dev.lm75.%d.mode -Set the operation mode for the sensor interrupt pin. +Sets the operation mode for the sensor interrupt pin. It can be set to 'comparator' (default) or 'interrupt'. .It Va dev.lm75.%d.polarity -Set the polarity of the sensor interrupt pin. +Sets the polarity of the sensor interrupt pin. It can be set to 'active-low' (default) or 'active-high'. Please note that the output pin is an open-drain output and it needs a proper pull-up resistor to work. .It Va dev.lm75.%d.shutdown -When set to '1' it shutdown the sensor. -The temperature convertion stops but the sensor remains with its i2c bus +When set to '1' it shuts down the sensor. +The temperature conversion stops but the sensor remains with its i2c bus active, i.e., it can be woken up by setting this option to '0' again. .El .Pp @@ -124,7 +124,7 @@ On a .Xr device.hints 5 based system, like .Li MIPS , -these values are configurable for the +these values are configurable for .Nm : .Bl -tag -width ".Va hint.lm75.%d.addr" .It Va hint.lm75.%d.at @@ -168,7 +168,7 @@ property indicates which i2c address the .Nm is wired at. .Nm -temperature sensors can be wired to 8 different address, allowing up to 8 +temperature sensors can be wired to 8 different addresses, allowing up to 8 sensors on the same .Xr iicbus 4 . .El @@ -187,5 +187,5 @@ driver first appeared in .An -nosplit The .Nm -driver and this manual page was written by -.An Luiz Otavio O Souza Aq loos@FreeBSD.org +driver and this manual page were written by +.An Luiz Otavio O Souza Aq loos@FreeBSD.org . -- cgit v1.2.3 From 760f4dec67f4cef8b2721022cbd167799668d38b Mon Sep 17 00:00:00 2001 From: Colin Percival Date: Sun, 11 May 2014 10:32:58 +0000 Subject: In cf_get_method, when we don't already know what clock speed the CPU is running at, guess the nearest value instead of looking for a value within 25 MHz of the observed frequency. Prior to this change, if a system booted with Intel Turbo Boost enabled, the dev.cpu.0.freq sysctl is nonfunctional, since the ACPI-reported frequency for Turbo Boost states does not match the actual clock frequency (and thus no levels are within 25 MHz of the observed frequency) and the current performance level is read before a new level is set. MFC after: 3 days Relnotes: Bug fix in power management on CPUs with Intel Turbo Boost --- sys/kern/kern_cpu.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sys/kern/kern_cpu.c b/sys/kern/kern_cpu.c index b4ba635ed129..7206c388f76a 100644 --- a/sys/kern/kern_cpu.c +++ b/sys/kern/kern_cpu.c @@ -418,7 +418,7 @@ cf_get_method(device_t dev, struct cf_level *level) struct cf_setting *curr_set, set; struct pcpu *pc; device_t *devs; - int count, error, i, n, numdevs; + int bdiff, count, diff, error, i, n, numdevs; uint64_t rate; sc = device_get_softc(dev); @@ -494,14 +494,15 @@ cf_get_method(device_t dev, struct cf_level *level) } cpu_est_clockrate(pc->pc_cpuid, &rate); rate /= 1000000; + bdiff = 1 << 30; for (i = 0; i < count; i++) { - if (CPUFREQ_CMP(rate, levels[i].total_set.freq)) { + diff = abs(levels[i].total_set.freq - rate); + if (diff < bdiff) { + bdiff = diff; sc->curr_level = levels[i]; - CF_DEBUG("get estimated freq %d\n", curr_set->freq); - goto out; } } - error = ENXIO; + CF_DEBUG("get estimated freq %d\n", curr_set->freq); out: if (error == 0) -- cgit v1.2.3 From 204fa412be63514ff5835028e2643e77cf488ce3 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Sun, 11 May 2014 12:55:31 +0000 Subject: Revert accidental commit of SUBDIR_PARALLEL for sys/modules. (It hasn't been tested sufficiently). --- sys/modules/Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/modules/Makefile b/sys/modules/Makefile index 3d1713f69ee1..15a516373f44 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -2,8 +2,6 @@ .include -SUBDIR_PARALLEL= - # Modules that include binary-only blobs of microcode should be selectable by # MK_SOURCELESS_UCODE option (see below). -- cgit v1.2.3 From 448f5f73dcc7efe69df16b6a875b0cf0c6f41ae3 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Sun, 11 May 2014 13:48:21 +0000 Subject: include: Remove checks for __BSD_VISIBLE where redundant with __XSI_VISIBLE or __POSIX_VISIBLE. Whenever sets __BSD_VISIBLE to non-zero, it also sets __POSIX_VISIBLE and __XSI_VISIBLE to the newest version supported. No functional change is intended. --- include/dirent.h | 2 +- include/grp.h | 6 +++--- include/setjmp.h | 4 ++-- include/signal.h | 2 +- include/stdio.h | 8 ++++---- include/string.h | 6 +++--- include/termios.h | 2 +- include/unistd.h | 6 +++--- include/wchar.h | 2 +- sys/sys/stat.h | 4 ++-- 10 files changed, 21 insertions(+), 21 deletions(-) diff --git a/include/dirent.h b/include/dirent.h index f43210c7ddb6..c77d844e399b 100644 --- a/include/dirent.h +++ b/include/dirent.h @@ -40,7 +40,7 @@ #include #include -#if __BSD_VISIBLE || __XSI_VISIBLE +#if __XSI_VISIBLE /* * XXX this is probably illegal in the __XSI_VISIBLE case, but brings us closer * to the specification. diff --git a/include/grp.h b/include/grp.h index e7f65ecad636..b10fd0f8ad36 100644 --- a/include/grp.h +++ b/include/grp.h @@ -61,7 +61,7 @@ struct group { }; __BEGIN_DECLS -#if __BSD_VISIBLE || __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE +#if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE void endgrent(void); struct group *getgrent(void); #endif @@ -74,11 +74,11 @@ int pwcache_groupdb(int (*)(int), void (*)(void), struct group * (*)(const char *), struct group * (*)(gid_t)); #endif -#if __BSD_VISIBLE || __XSI_VISIBLE +#if __XSI_VISIBLE /* XXX IEEE Std 1003.1, 2003 specifies `void setgrent(void)' */ int setgrent(void); #endif -#if __BSD_VISIBLE || __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE +#if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE int getgrgid_r(gid_t, struct group *, char *, size_t, struct group **); int getgrnam_r(const char *, struct group *, char *, size_t, diff --git a/include/setjmp.h b/include/setjmp.h index bf03f6fbb43a..598e07a77bc4 100644 --- a/include/setjmp.h +++ b/include/setjmp.h @@ -44,7 +44,7 @@ #include __BEGIN_DECLS -#if __BSD_VISIBLE || __XSI_VISIBLE >= 600 +#if __XSI_VISIBLE >= 600 void _longjmp(jmp_buf, int) __dead2; int _setjmp(jmp_buf) __returns_twice; #endif @@ -53,7 +53,7 @@ void longjmp(jmp_buf, int) __dead2; void longjmperror(void); #endif int setjmp(jmp_buf) __returns_twice; -#if __BSD_VISIBLE || __POSIX_VISIBLE || __XSI_VISIBLE +#if __POSIX_VISIBLE || __XSI_VISIBLE void siglongjmp(sigjmp_buf, int) __dead2; int sigsetjmp(sigjmp_buf, int) __returns_twice; #endif diff --git a/include/signal.h b/include/signal.h index e7447dfd053d..dca19aaa8613 100644 --- a/include/signal.h +++ b/include/signal.h @@ -108,7 +108,7 @@ int xsi_sigpause(int); int siginterrupt(int, int); #endif -#if __POSIX_VISIBLE >= 200809 || __BSD_VISIBLE +#if __POSIX_VISIBLE >= 200809 void psignal(unsigned int, const char *); #endif diff --git a/include/stdio.h b/include/stdio.h index 19b1e20f66be..cebc1241359d 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -47,7 +47,7 @@ typedef __size_t size_t; #define _SIZE_T_DECLARED #endif -#if __BSD_VISIBLE || __POSIX_VISIBLE >= 200809 +#if __POSIX_VISIBLE >= 200809 #ifndef _OFF_T_DECLARED #define _OFF_T_DECLARED typedef __off_t off_t; @@ -58,7 +58,7 @@ typedef __ssize_t ssize_t; #endif #endif -#if __BSD_VISIBLE || __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE +#if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE #ifndef _VA_LIST_DECLARED typedef __va_list va_list; #define _VA_LIST_DECLARED @@ -342,7 +342,7 @@ int putw(int, FILE *); char *tempnam(const char *, const char *); #endif -#if __BSD_VISIBLE || __POSIX_VISIBLE >= 200809 +#if __POSIX_VISIBLE >= 200809 FILE *fmemopen(void * __restrict, size_t, const char * __restrict); ssize_t getdelim(char ** __restrict, size_t * __restrict, int, FILE * __restrict); @@ -387,7 +387,7 @@ ssize_t getline(char ** __restrict, size_t * __restrict, FILE * __restrict); int (dprintf)(int, const char * __restrict, ...); #endif -#endif /* __BSD_VISIBLE || __POSIX_VISIBLE >= 200809 */ +#endif /* __POSIX_VISIBLE >= 200809 */ /* * Routines that are purely local. diff --git a/include/string.h b/include/string.h index ceffcf6aeaac..af8b0d46c86c 100644 --- a/include/string.h +++ b/include/string.h @@ -65,7 +65,7 @@ void *memmem(const void *, size_t, const void *, size_t) __pure; #endif void *memmove(void *, const void *, size_t); void *memset(void *, int, size_t); -#if __POSIX_VISIBLE >= 200809 || __BSD_VISIBLE +#if __POSIX_VISIBLE >= 200809 char *stpcpy(char * __restrict, const char * __restrict); char *stpncpy(char * __restrict, const char * __restrict, size_t); #endif @@ -99,7 +99,7 @@ void strmode(int, char *); char *strncat(char * __restrict, const char * __restrict, size_t); int strncmp(const char *, const char *, size_t) __pure; char *strncpy(char * __restrict, const char * __restrict, size_t); -#if __POSIX_VISIBLE >= 200809 || __BSD_VISIBLE +#if __POSIX_VISIBLE >= 200809 char *strndup(const char *, size_t) __malloc_like; size_t strnlen(const char *, size_t) __pure; #endif @@ -111,7 +111,7 @@ char *strrchr(const char *, int) __pure; #if __BSD_VISIBLE char *strsep(char **, const char *); #endif -#if __POSIX_VISIBLE >= 200809 || __BSD_VISIBLE +#if __POSIX_VISIBLE >= 200809 char *strsignal(int); #endif size_t strspn(const char *, const char *) __pure; diff --git a/include/termios.h b/include/termios.h index e41da9fea12a..ed8e328d7fd9 100644 --- a/include/termios.h +++ b/include/termios.h @@ -81,7 +81,7 @@ int tcflow(int, int); int tcflush(int, int); int tcsendbreak(int, int); -#if __POSIX_VISIBLE >= 200112 || __BSD_VISIBLE +#if __POSIX_VISIBLE >= 200112 pid_t tcgetsid(int); #endif #if __BSD_VISIBLE diff --git a/include/unistd.h b/include/unistd.h index 5868ba2ed94f..f1913b693458 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -426,7 +426,7 @@ int truncate(const char *, off_t); #endif #endif /* __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE */ -#if __POSIX_VISIBLE >= 200809 || __BSD_VISIBLE +#if __POSIX_VISIBLE >= 200809 int faccessat(int, const char *, int, int); int fchownat(int, const char *, uid_t, gid_t, int); int fexecve(int, char *const [], char *const []); @@ -434,14 +434,14 @@ int linkat(int, const char *, int, const char *, int); ssize_t readlinkat(int, const char * __restrict, char * __restrict, size_t); int symlinkat(const char *, int, const char *); int unlinkat(int, const char *, int); -#endif /* __POSIX_VISIBLE >= 200809 || __BSD_VISIBLE */ +#endif /* __POSIX_VISIBLE >= 200809 */ /* * symlink() was originally in POSIX.1a, which was withdrawn after * being overtaken by events (1003.1-2001). It was in XPG4.2, and of * course has been in BSD since 4.2. */ -#if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE >= 402 || __BSD_VISIBLE +#if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE >= 402 int symlink(const char * __restrict, const char * __restrict); #endif diff --git a/include/wchar.h b/include/wchar.h index 8233bdff1014..84a4a976e6bd 100644 --- a/include/wchar.h +++ b/include/wchar.h @@ -204,7 +204,7 @@ int wcwidth(wchar_t); #define wcwidth(_c) __wcwidth(_c) #endif -#if __POSIX_VISIBLE >= 200809 || __BSD_VISIBLE +#if __POSIX_VISIBLE >= 200809 size_t mbsnrtowcs(wchar_t * __restrict, const char ** __restrict, size_t, size_t, mbstate_t * __restrict); FILE *open_wmemstream(wchar_t **, size_t *); diff --git a/sys/sys/stat.h b/sys/sys/stat.h index 0f3284f9791d..13dea2dc72b9 100644 --- a/sys/sys/stat.h +++ b/sys/sys/stat.h @@ -339,12 +339,12 @@ int mknod(const char *, mode_t, dev_t); #endif int stat(const char * __restrict, struct stat * __restrict); mode_t umask(mode_t); -#if __BSD_VISIBLE || __POSIX_VISIBLE >= 200809 +#if __POSIX_VISIBLE >= 200809 int fstatat(int, const char *, struct stat *, int); int mkdirat(int, const char *, mode_t); int mkfifoat(int, const char *, mode_t); #endif -#if __BSD_VISIBLE || __XSI_VISIBLE >= 700 +#if __XSI_VISIBLE >= 700 int mknodat(int, const char *, mode_t, dev_t); #endif __END_DECLS -- cgit v1.2.3 From 76902266ae6bd08d20532316b9c031e1f34ee232 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Sun, 11 May 2014 16:34:17 +0000 Subject: include: Don't expose L_cuserid in strict C standard compliance mode. L_cuserid is supposed to be exposed only for old POSIX, or in the default (expose everything) environment. --- include/stdio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/stdio.h b/include/stdio.h index cebc1241359d..512e60e9ac1a 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -290,7 +290,7 @@ int vsscanf(const char * __restrict, const char * __restrict, __va_list) /* * Functions defined in all versions of POSIX 1003.1. */ -#if __BSD_VISIBLE || __POSIX_VISIBLE <= 199506 +#if __BSD_VISIBLE || (__POSIX_VISIBLE && __POSIX_VISIBLE <= 199506) #define L_cuserid 17 /* size for cuserid(3); MAXLOGNAME, legacy */ #endif -- cgit v1.2.3 From 0d1381bb569d8b1d52217e9a92a8278dca1f4c15 Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Sun, 11 May 2014 16:49:31 +0000 Subject: Fix interrupt allocation after changes to nexus. This makes PS3 boot multiuser again (this commit comes from the PS3 itself). Some problems still exist with SMP, apparently, as I had to boot a non-SMP kernel to get here. --- sys/powerpc/ps3/ps3bus.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/sys/powerpc/ps3/ps3bus.c b/sys/powerpc/ps3/ps3bus.c index 65e11534f509..d7659e44f5d4 100644 --- a/sys/powerpc/ps3/ps3bus.c +++ b/sys/powerpc/ps3/ps3bus.c @@ -127,6 +127,7 @@ static device_method_t ps3bus_methods[] = { struct ps3bus_softc { struct rman sc_mem_rman; + struct rman sc_intr_rman; struct mem_region *regions; int rcount; }; @@ -328,7 +329,11 @@ ps3bus_attach(device_t self) sc = device_get_softc(self); sc->sc_mem_rman.rm_type = RMAN_ARRAY; sc->sc_mem_rman.rm_descr = "PS3Bus Memory Mapped I/O"; + sc->sc_intr_rman.rm_type = RMAN_ARRAY; + sc->sc_intr_rman.rm_descr = "PS3Bus Interrupts"; rman_init(&sc->sc_mem_rman); + rman_init(&sc->sc_intr_rman); + rman_manage_region(&sc->sc_intr_rman, 0, ~0); /* Get memory regions for DMA */ mem_regions(&sc->regions, &sc->rcount, &sc->regions, &sc->rcount); @@ -562,8 +567,13 @@ ps3bus_alloc_resource(device_t bus, device_t child, int type, int *rid, rm = &sc->sc_mem_rman; break; case SYS_RES_IRQ: - return (resource_list_alloc(&dinfo->resources, bus, child, - type, rid, start, end, count, flags)); + rle = resource_list_find(&dinfo->resources, SYS_RES_IRQ, + *rid); + rm = &sc->sc_intr_rman; + adjstart = rle->start; + adjcount = ulmax(count, rle->count); + adjend = ulmax(rle->end, rle->start + adjcount - 1); + break; default: device_printf(bus, "unknown resource request from %s\n", device_get_nameunit(child)); -- cgit v1.2.3 From 30238f4963dbdd5884065eebe514cbd46e247af4 Mon Sep 17 00:00:00 2001 From: "Pedro F. Giffuni" Date: Sun, 11 May 2014 17:28:57 +0000 Subject: printf: fix regression after illumos merges. The "bltin/bltin.h" wrappers do not support exit() and attempting to call it will exit sh completely. Note that errx() is acceptable but will always return with status 2. Reported by: jilles (and the testing framework) Fix by: jilles Pointyhat: pfg --- usr.bin/printf/printf.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/usr.bin/printf/printf.c b/usr.bin/printf/printf.c index 055657fe057a..7a7e055ae4fe 100644 --- a/usr.bin/printf/printf.c +++ b/usr.bin/printf/printf.c @@ -101,6 +101,8 @@ static void usage(void); static const char digits[] = "0123456789"; +static char end_fmt[1]; + static int myargc; static char **myargv; static char **gargv; @@ -171,11 +173,11 @@ main(int argc, char *argv[]) fmt += 2; } else { fmt = printf_doformat(fmt, &rval); - if (fmt == NULL) { + if (fmt == NULL || fmt == end_fmt) { #ifdef SHELL INTON; #endif - return (1); + return (fmt == NULL ? 1 : rval); } end = 0; } @@ -372,7 +374,7 @@ printf_doformat(char *fmt, int *rval) fputs(p, stdout); free(p); if (getout) - exit(*rval); + return (end_fmt); break; } case 'c': { -- cgit v1.2.3 From dd006a1b14951f2fbe871f162e359773cc699d17 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sun, 11 May 2014 17:41:29 +0000 Subject: With the new-and-improved vm_fault_copy_entry() (r265843), we can always avoid soft page faults when adding write access to user wired entries in vm_map_protect(). Previously, we only avoided the soft page fault when the underlying pages were copy-on-write. In other words, we avoided the pages faults that might sleep on page allocation, but not the trivial page faults to update the physical map. Reviewed by: kib MFC after: 1 week Sponsored by: EMC / Isilon Storage Division --- sys/vm/vm_map.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index 0c95707c2674..3f46bcdba9a1 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -1978,10 +1978,17 @@ vm_map_protect(vm_map_t map, vm_offset_t start, vm_offset_t end, else current->protection = new_prot; - if ((current->eflags & (MAP_ENTRY_COW | MAP_ENTRY_USER_WIRED)) - == (MAP_ENTRY_COW | MAP_ENTRY_USER_WIRED) && + /* + * For user wired map entries, the normal lazy evaluation of + * write access upgrades through soft page faults is + * undesirable. Instead, immediately copy any pages that are + * copy-on-write and enable write access in the physical map. + */ + if ((current->eflags & MAP_ENTRY_USER_WIRED) != 0 && (current->protection & VM_PROT_WRITE) != 0 && (old_prot & VM_PROT_WRITE) == 0) { + KASSERT(old_prot != VM_PROT_NONE, + ("vm_map_protect: inaccessible wired map entry")); vm_fault_copy_entry(map, map, current, current, NULL); } -- cgit v1.2.3 From c8f780e3d618efb8f42814b3a20e344f4e771371 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 11 May 2014 18:07:07 +0000 Subject: Fix locking. The dst_object must remain locked on the retry of the loop iteration. Reported and tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 6 days --- sys/vm/vm_fault.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index 125a5fc2bdd3..ff6bca077178 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -1359,6 +1359,7 @@ again: VM_OBJECT_WUNLOCK(dst_object); VM_OBJECT_RUNLOCK(object); VM_WAIT; + VM_OBJECT_WLOCK(dst_object); goto again; } } while (dst_m == NULL); -- cgit v1.2.3 From e2fc1af45ed774470562952b97e52e9f57651bbd Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Sun, 11 May 2014 18:22:05 +0000 Subject: OF_peer() in IEEE 1275 returns 0 if no peer exists, not -1. --- sys/dev/ofw/ofwbus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/ofw/ofwbus.c b/sys/dev/ofw/ofwbus.c index d06917d22fa6..aa7566b52977 100644 --- a/sys/dev/ofw/ofwbus.c +++ b/sys/dev/ofw/ofwbus.c @@ -187,7 +187,7 @@ ofwbus_identify(driver_t *driver, device_t parent) { /* Check if Open Firmware has been instantiated */ - if (OF_peer(0) == -1) + if (OF_peer(0) == 0) return; if (device_find_child(parent, "ofwbus", -1) == NULL) -- cgit v1.2.3 From 68bcb7db193e4bc81430063148253d30a791023e Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Sun, 11 May 2014 18:24:26 +0000 Subject: Vendor import of llvm RELEASE_34/dot1-final tag r208032 (effectively, 3.4.1 release): https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_34/dot1-final@208032 --- CMakeLists.txt | 4 +- Makefile.config.in | 4 + Makefile.rules | 11 +- autoconf/configure.ac | 19 ++- configure | 78 ++++++---- include/llvm/Config/config.h.in | 21 +-- include/llvm/IR/IntrinsicsX86.td | 50 +++---- include/llvm/MC/MCAsmInfo.h | 29 +++- lib/Analysis/BasicAliasAnalysis.cpp | 166 ++++++++++++++++----- lib/Analysis/IVUsers.cpp | 23 ++- lib/Analysis/ScalarEvolution.cpp | 2 +- lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 7 +- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 5 +- lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp | 1 + lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp | 7 +- lib/MC/MCAsmInfo.cpp | 6 +- lib/MC/MCAsmInfoCOFF.cpp | 2 +- lib/MC/MCAsmInfoDarwin.cpp | 3 +- lib/MC/MCDwarf.cpp | 16 +- lib/MC/MCParser/AsmParser.cpp | 4 + lib/Target/AArch64/AArch64ISelLowering.cpp | 10 +- lib/Target/AArch64/AArch64InstrInfo.td | 1 + lib/Target/AArch64/AArch64TargetObjectFile.cpp | 7 + lib/Target/AArch64/AArch64TargetObjectFile.h | 8 +- lib/Target/ARM/A15SDOptimizer.cpp | 12 +- lib/Target/ARM/ARMBaseInstrInfo.cpp | 2 + lib/Target/ARM/ARMExpandPseudoInsts.cpp | 4 + lib/Target/ARM/ARMISelDAGToDAG.cpp | 75 ++++++++-- lib/Target/ARM/ARMInstrNEON.td | 8 +- lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp | 26 ++++ lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.h | 4 + .../PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp | 2 +- lib/Target/PowerPC/PPCAsmPrinter.cpp | 7 - lib/Target/PowerPC/PPCCTRLoops.cpp | 17 ++- lib/Target/PowerPC/PPCFastISel.cpp | 8 +- lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 4 +- lib/Target/PowerPC/PPCISelLowering.cpp | 11 +- lib/Target/PowerPC/PPCInstrInfo.cpp | 12 +- lib/Target/PowerPC/PPCInstrInfo.td | 25 +++- lib/Target/PowerPC/PPCRegisterInfo.td | 12 ++ lib/Target/PowerPC/PPCSubtarget.h | 16 -- lib/Target/PowerPC/PPCTargetMachine.cpp | 39 ++++- lib/Target/R600/AMDGPUISelLowering.cpp | 2 + lib/Target/R600/AMDGPUInstructions.td | 7 + lib/Target/R600/MCTargetDesc/AMDGPUMCAsmInfo.cpp | 2 - lib/Target/R600/R600ControlFlowFinalizer.cpp | 1 + lib/Target/R600/R600InstrInfo.cpp | 8 +- lib/Target/R600/R600Instructions.td | 6 +- lib/Target/R600/SIFixSGPRCopies.cpp | 2 +- lib/Target/R600/SIInsertWaits.cpp | 6 + lib/Target/R600/SIInstrInfo.td | 64 +++++--- lib/Target/R600/SIInstructions.td | 108 ++++++++++++-- lib/Target/R600/SIIntrinsics.td | 16 ++ lib/Target/R600/SILowerControlFlow.cpp | 42 ++++-- lib/Target/X86/AsmParser/X86AsmParser.cpp | 65 +++++--- .../X86/Disassembler/X86DisassemblerDecoder.c | 7 +- lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp | 11 ++ lib/Target/X86/X86AsmPrinter.cpp | 8 +- lib/Target/X86/X86ISelLowering.cpp | 36 ++++- lib/Target/X86/X86InstrCompiler.td | 5 +- .../InstCombine/InstCombineVectorOps.cpp | 12 +- lib/Transforms/Scalar/LoopRerollPass.cpp | 22 +-- lib/Transforms/Scalar/LoopStrengthReduce.cpp | 12 ++ lib/Transforms/Utils/LCSSA.cpp | 2 + lib/Transforms/Vectorize/LoopVectorize.cpp | 13 +- test/Analysis/BasicAA/noalias-bugs.ll | 33 ++++ test/Analysis/BasicAA/phi-aa.ll | 47 ++++++ .../Analysis/ScalarEvolution/zext-signed-addrec.ll | 81 ++++++++++ test/CodeGen/AArch64/atomic-ops.ll | 81 ++++++++++ test/CodeGen/AArch64/init-array.ll | 1 + test/CodeGen/AArch64/variadic.ll | 23 ++- test/CodeGen/ARM/a15-SD-dep.ll | 59 ++++++++ test/CodeGen/ARM/vld3.ll | 13 ++ test/CodeGen/ARM/vld4.ll | 13 ++ test/CodeGen/ARM/vst3.ll | 12 ++ test/CodeGen/ARM/vst4.ll | 12 ++ test/CodeGen/PowerPC/anon_aggr.ll | 4 +- test/CodeGen/PowerPC/byval-agg-info.ll | 17 +++ test/CodeGen/PowerPC/cc.ll | 70 +++++++++ test/CodeGen/PowerPC/ctrloop-udivti3.ll | 31 ++++ test/CodeGen/PowerPC/fast-isel-conversion-p5.ll | 153 +++++++++++++++++++ test/CodeGen/PowerPC/spill-nor0.ll | 23 +++ test/CodeGen/PowerPC/weak_def_can_be_hidden.ll | 38 +++++ test/CodeGen/R600/bfe_uint.ll | 2 + test/CodeGen/R600/fabs.ll | 14 +- test/CodeGen/R600/fneg-fabs.ll | 55 +++++++ test/CodeGen/R600/fneg.ll | 14 +- test/CodeGen/R600/lds-oqap-crash.ll | 28 ++++ test/CodeGen/R600/llvm.AMDGPU.kill.ll | 18 +++ test/CodeGen/R600/llvm.SI.load.dword.ll | 40 +++++ test/CodeGen/R600/llvm.SI.sendmsg.ll | 21 +++ test/CodeGen/R600/load.ll | 19 ++- test/CodeGen/R600/trunc.ll | 10 ++ test/CodeGen/R600/vtx-fetch-branch.ll | 29 ++++ test/CodeGen/R600/zero_extend.ll | 10 ++ test/CodeGen/X86/2009-06-05-VZextByteShort.ll | 2 +- test/CodeGen/X86/bswap-vector.ll | 19 +++ test/CodeGen/X86/fma4-intrinsics-x86_64.ll | 2 +- test/CodeGen/X86/fp-fast.ll | 2 +- test/CodeGen/X86/inline-asm-modifier-q.ll | 12 ++ test/CodeGen/X86/isint.ll | 26 +++- test/CodeGen/X86/pr10420.ll | 48 +++++- test/CodeGen/X86/stores-merging.ll | 23 +++ test/CodeGen/X86/vaargs.ll | 67 +++++++++ test/CodeGen/X86/vastart-defs-eflags.ll | 23 +++ test/CodeGen/X86/vec_shift4.ll | 2 +- test/CodeGen/X86/vshift-4.ll | 2 +- test/CodeGen/X86/weak_def_can_be_hidden.ll | 15 +- test/MC/Disassembler/X86/x86-64.txt | 24 +++ test/MC/X86/intel-syntax.s | 9 ++ test/Transforms/InstCombine/vec_extract_var_elt.ll | 8 + test/Transforms/LoopReroll/basic.ll | 10 +- test/Transforms/LoopReroll/nonconst_lb.ll | 152 +++++++++++++++++++ test/Transforms/LoopReroll/reduction.ll | 4 +- test/Transforms/LoopStrengthReduce/X86/pr17473.ll | 67 +++++++++ test/Transforms/LoopStrengthReduce/pr18165.ll | 88 +++++++++++ .../LoopVectorize/multi-use-reduction-bug.ll | 42 ++++++ tools/llvm-shlib/Makefile | 2 + utils/release/test-release.sh | 35 ++++- 119 files changed, 2510 insertions(+), 370 deletions(-) create mode 100644 test/Analysis/BasicAA/noalias-bugs.ll create mode 100644 test/Analysis/ScalarEvolution/zext-signed-addrec.ll create mode 100644 test/CodeGen/PowerPC/byval-agg-info.ll create mode 100644 test/CodeGen/PowerPC/cc.ll create mode 100644 test/CodeGen/PowerPC/ctrloop-udivti3.ll create mode 100644 test/CodeGen/PowerPC/fast-isel-conversion-p5.ll create mode 100644 test/CodeGen/PowerPC/spill-nor0.ll create mode 100644 test/CodeGen/PowerPC/weak_def_can_be_hidden.ll create mode 100644 test/CodeGen/R600/fneg-fabs.ll create mode 100644 test/CodeGen/R600/lds-oqap-crash.ll create mode 100644 test/CodeGen/R600/llvm.AMDGPU.kill.ll create mode 100644 test/CodeGen/R600/llvm.SI.load.dword.ll create mode 100644 test/CodeGen/R600/llvm.SI.sendmsg.ll create mode 100644 test/CodeGen/R600/vtx-fetch-branch.ll create mode 100644 test/CodeGen/X86/bswap-vector.ll create mode 100644 test/CodeGen/X86/inline-asm-modifier-q.ll create mode 100644 test/CodeGen/X86/stores-merging.ll create mode 100644 test/CodeGen/X86/vaargs.ll create mode 100644 test/CodeGen/X86/vastart-defs-eflags.ll create mode 100644 test/Transforms/LoopReroll/nonconst_lb.ll create mode 100644 test/Transforms/LoopStrengthReduce/X86/pr17473.ll create mode 100644 test/Transforms/LoopStrengthReduce/pr18165.ll create mode 100644 test/Transforms/LoopVectorize/multi-use-reduction-bug.ll diff --git a/CMakeLists.txt b/CMakeLists.txt index a68e7e163c52..bd0f846f04b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,9 +12,10 @@ set(CMAKE_MODULE_PATH set(LLVM_VERSION_MAJOR 3) set(LLVM_VERSION_MINOR 4) +set(LLVM_VERSION_PATCH 1) if (NOT PACKAGE_VERSION) - set(PACKAGE_VERSION "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}svn") + set(PACKAGE_VERSION "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}") endif() option(LLVM_INSTALL_TOOLCHAIN_ONLY "Only include toolchain files in the 'install' target." OFF) @@ -42,6 +43,7 @@ set(CPACK_PACKAGE_INSTALL_DIRECTORY "LLVM") set(CPACK_PACKAGE_VENDOR "LLVM") set(CPACK_PACKAGE_VERSION_MAJOR ${LLVM_VERSION_MAJOR}) set(CPACK_PACKAGE_VERSION_MINOR ${LLVM_VERSION_MINOR}) +set(CPACK_PACKAGE_VERSION_PATCH ${LLVM_VERSION_PATCH}) set(CPACK_PACKAGE_VERSION ${PACKAGE_VERSION}) set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.TXT") if(WIN32 AND NOT UNIX) diff --git a/Makefile.config.in b/Makefile.config.in index dcca45f36cd8..00c6d965170a 100644 --- a/Makefile.config.in +++ b/Makefile.config.in @@ -15,6 +15,10 @@ # Define LLVM specific info and directories based on the autoconf variables LLVMPackageName := @PACKAGE_TARNAME@ LLVMVersion := @PACKAGE_VERSION@ +LLVM_VERSION_MAJOR := @LLVM_VERSION_MAJOR@ +LLVM_VERSION_MINOR := @LLVM_VERSION_MINOR@ +LLVM_VERSION_PATCH := @LLVM_VERSION_PATCH@ +LLVM_VERSION_SUFFIX := @LLVM_VERSION_SUFFIX@ LLVM_CONFIGTIME := @LLVM_CONFIGTIME@ ########################################################################### diff --git a/Makefile.rules b/Makefile.rules index 68f6cf8ec5d1..210abdafc8e3 100644 --- a/Makefile.rules +++ b/Makefile.rules @@ -757,7 +757,7 @@ else Ranlib = ranlib endif -AliasTool = ln -s +AliasTool = ln -sf #---------------------------------------------------------- # Get the list of source files and compute object file @@ -1121,15 +1121,19 @@ ifdef LIBRARYNAME # Make sure there isn't any extraneous whitespace on the LIBRARYNAME option LIBRARYNAME := $(strip $(LIBRARYNAME)) +LIBRARYALIASNAME := $(strip $(LIBRARYALIASNAME)) ifdef LOADABLE_MODULE BaseLibName.A := $(LIBRARYNAME).a BaseLibName.SO := $(LIBRARYNAME)$(SHLIBEXT) +BaseAliasName.SO := $(LIBRARYALIASNAME)$(SHLIBEXT) else BaseLibName.A := lib$(LIBRARYNAME).a BaseLibName.SO := $(SharedPrefix)$(LIBRARYNAME)$(SHLIBEXT) +BaseAliasName.SO := $(SharedPrefix)$(LIBRARYALIASNAME)$(SHLIBEXT) endif LibName.A := $(LibDir)/$(BaseLibName.A) LibName.SO := $(SharedLibDir)/$(BaseLibName.SO) +AliasName.SO := $(SharedLibDir)/$(BaseAliasName.SO) LibName.O := $(LibDir)/$(LIBRARYNAME).o #--------------------------------------------------------- @@ -1183,12 +1187,17 @@ else DestSharedLibDir := $(DESTDIR)$(PROJ_libdir) endif DestSharedLib := $(DestSharedLibDir)/$(BaseLibName.SO) +DestSharedAlias := $(DestSharedLibDir)/$(BaseAliasName.SO) install-local:: $(DestSharedLib) $(DestSharedLib): $(LibName.SO) $(DestSharedLibDir) $(Echo) Installing $(BuildMode) Shared Library $(DestSharedLib) $(Verb) $(INSTALL) $(LibName.SO) $(DestSharedLib) +ifdef SHARED_ALIAS + $(Echo) Creating alias from $(DestSharedLib) to $(DestSharedAlias) + $(Verb) $(AliasTool) $(DestSharedLib) $(DestSharedAlias) +endif uninstall-local:: $(Echo) Uninstalling $(BuildMode) Shared Library $(DestSharedLib) diff --git a/autoconf/configure.ac b/autoconf/configure.ac index a9d491548f11..7b4bae7e71a5 100644 --- a/autoconf/configure.ac +++ b/autoconf/configure.ac @@ -31,9 +31,22 @@ dnl=== dnl===-----------------------------------------------------------------------=== dnl Initialize autoconf and define the package name, version number and dnl address for reporting bugs. -AC_INIT([LLVM],[3.4],[http://llvm.org/bugs/]) -AC_DEFINE([LLVM_VERSION_MAJOR], [3], [Major version of the LLVM API]) -AC_DEFINE([LLVM_VERSION_MINOR], [4], [Minor version of the LLVM API]) + +AC_INIT([LLVM],[3.4.1],[http://llvm.org/bugs/]) + +LLVM_VERSION_MAJOR=3 +LLVM_VERSION_MINOR=4 +LLVM_VERSION_PATCH=1 +LLVM_VERSION_SUFFIX= + +AC_DEFINE_UNQUOTED([LLVM_VERSION_MAJOR], $LLVM_VERSION_MAJOR, [Major version of the LLVM API]) +AC_DEFINE_UNQUOTED([LLVM_VERSION_MINOR], $LLVM_VERSION_MINOR, [Minor version of the LLVM API]) +AC_DEFINE_UNQUOTED([LLVM_VERSION_PATCH], $LLVM_VERSION_PATCH, [Patch version of the LLVM API]) + +AC_SUBST([LLVM_VERSION_MAJOR]) +AC_SUBST([LLVM_VERSION_MINOR]) +AC_SUBST([LLVM_VERSION_PATCH]) +AC_SUBST([LLVM_VERSION_SUFFIX]) dnl Provide a copyright substitution and ensure the copyright notice is included dnl in the output of --version option of the generated configure script. diff --git a/configure b/configure index 72e9b1330443..cbda923cc700 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.60 for LLVM 3.4. +# Generated by GNU Autoconf 2.60 for LLVM 3.4.1. # # Report bugs to . # @@ -561,8 +561,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='LLVM' PACKAGE_TARNAME='llvm' -PACKAGE_VERSION='3.4' -PACKAGE_STRING='LLVM 3.4' +PACKAGE_VERSION='3.4.1' +PACKAGE_STRING='LLVM 3.4.1' PACKAGE_BUGREPORT='http://llvm.org/bugs/' ac_unique_file="lib/IR/Module.cpp" @@ -639,6 +639,10 @@ LIBS build_alias host_alias target_alias +LLVM_VERSION_MAJOR +LLVM_VERSION_MINOR +LLVM_VERSION_PATCH +LLVM_VERSION_SUFFIX LLVM_COPYRIGHT CC CFLAGS @@ -1330,7 +1334,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures LLVM 3.4 to adapt to many kinds of systems. +\`configure' configures LLVM 3.4.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1396,7 +1400,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of LLVM 3.4:";; + short | recursive ) echo "Configuration of LLVM 3.4.1:";; esac cat <<\_ACEOF @@ -1564,7 +1568,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -LLVM configure 3.4 +LLVM configure 3.4.1 generated by GNU Autoconf 2.60 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -1580,7 +1584,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by LLVM $as_me 3.4, which was +It was created by LLVM $as_me 3.4.1, which was generated by GNU Autoconf 2.60. Invocation command line was $ $0 $@ @@ -1934,16 +1938,32 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu -cat >>confdefs.h <<\_ACEOF -#define LLVM_VERSION_MAJOR 3 +LLVM_VERSION_MAJOR=3 +LLVM_VERSION_MINOR=4 +LLVM_VERSION_PATCH=1 +LLVM_VERSION_SUFFIX= + + +cat >>confdefs.h <<_ACEOF +#define LLVM_VERSION_MAJOR $LLVM_VERSION_MAJOR _ACEOF -cat >>confdefs.h <<\_ACEOF -#define LLVM_VERSION_MINOR 4 +cat >>confdefs.h <<_ACEOF +#define LLVM_VERSION_MINOR $LLVM_VERSION_MINOR +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define LLVM_VERSION_PATCH $LLVM_VERSION_PATCH _ACEOF + + + + + LLVM_COPYRIGHT="Copyright (c) 2003-2013 University of Illinois at Urbana-Champaign." @@ -8825,7 +8845,9 @@ if test "${enable_ltdl_install+set}" = set; then fi - if test x"${enable_ltdl_install-no}" != xno; then + + +if test x"${enable_ltdl_install-no}" != xno; then INSTALL_LTDL_TRUE= INSTALL_LTDL_FALSE='#' else @@ -8833,7 +8855,9 @@ else INSTALL_LTDL_FALSE= fi - if test x"${enable_ltdl_convenience-no}" != xno; then + + +if test x"${enable_ltdl_convenience-no}" != xno; then CONVENIENCE_LTDL_TRUE= CONVENIENCE_LTDL_FALSE='#' else @@ -10582,7 +10606,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <&1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by LLVM $as_me 3.4, which was +This file was extended by LLVM $as_me 3.4.1, which was generated by GNU Autoconf 2.60. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -22798,7 +22822,7 @@ Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -LLVM config.status 3.4 +LLVM config.status 3.4.1 configured by $0, generated by GNU Autoconf 2.60, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" @@ -23036,6 +23060,10 @@ LIBS!$LIBS$ac_delim build_alias!$build_alias$ac_delim host_alias!$host_alias$ac_delim target_alias!$target_alias$ac_delim +LLVM_VERSION_MAJOR!$LLVM_VERSION_MAJOR$ac_delim +LLVM_VERSION_MINOR!$LLVM_VERSION_MINOR$ac_delim +LLVM_VERSION_PATCH!$LLVM_VERSION_PATCH$ac_delim +LLVM_VERSION_SUFFIX!$LLVM_VERSION_SUFFIX$ac_delim LLVM_COPYRIGHT!$LLVM_COPYRIGHT$ac_delim CC!$CC$ac_delim CFLAGS!$CFLAGS$ac_delim @@ -23092,10 +23120,6 @@ DISABLE_ASSERTIONS!$DISABLE_ASSERTIONS$ac_delim ENABLE_WERROR!$ENABLE_WERROR$ac_delim ENABLE_EXPENSIVE_CHECKS!$ENABLE_EXPENSIVE_CHECKS$ac_delim EXPENSIVE_CHECKS!$EXPENSIVE_CHECKS$ac_delim -DEBUG_RUNTIME!$DEBUG_RUNTIME$ac_delim -DEBUG_SYMBOLS!$DEBUG_SYMBOLS$ac_delim -KEEP_SYMBOLS!$KEEP_SYMBOLS$ac_delim -JIT!$JIT$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then @@ -23137,6 +23161,10 @@ _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF +DEBUG_RUNTIME!$DEBUG_RUNTIME$ac_delim +DEBUG_SYMBOLS!$DEBUG_SYMBOLS$ac_delim +KEEP_SYMBOLS!$KEEP_SYMBOLS$ac_delim +JIT!$JIT$ac_delim TARGET_HAS_JIT!$TARGET_HAS_JIT$ac_delim ENABLE_DOCS!$ENABLE_DOCS$ac_delim ENABLE_DOXYGEN!$ENABLE_DOXYGEN$ac_delim @@ -23230,10 +23258,6 @@ LLVM_ETCDIR!$LLVM_ETCDIR$ac_delim LLVM_INCLUDEDIR!$LLVM_INCLUDEDIR$ac_delim LLVM_INFODIR!$LLVM_INFODIR$ac_delim LLVM_MANDIR!$LLVM_MANDIR$ac_delim -LLVM_CONFIGTIME!$LLVM_CONFIGTIME$ac_delim -BINDINGS_TO_BUILD!$BINDINGS_TO_BUILD$ac_delim -ALL_BINDINGS!$ALL_BINDINGS$ac_delim -OCAML_LIBDIR!$OCAML_LIBDIR$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then @@ -23275,6 +23299,10 @@ _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF +LLVM_CONFIGTIME!$LLVM_CONFIGTIME$ac_delim +BINDINGS_TO_BUILD!$BINDINGS_TO_BUILD$ac_delim +ALL_BINDINGS!$ALL_BINDINGS$ac_delim +OCAML_LIBDIR!$OCAML_LIBDIR$ac_delim ENABLE_VISIBILITY_INLINES_HIDDEN!$ENABLE_VISIBILITY_INLINES_HIDDEN$ac_delim RPATH!$RPATH$ac_delim RDYNAMIC!$RDYNAMIC$ac_delim @@ -23283,7 +23311,7 @@ LIBOBJS!$LIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 6; then + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 10; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in index dcec8f8cd1ea..2317823349ee 100644 --- a/include/llvm/Config/config.h.in +++ b/include/llvm/Config/config.h.in @@ -3,9 +3,6 @@ #ifndef CONFIG_H #define CONFIG_H -/* Define if building universal (internal helper macro) */ -#undef AC_APPLE_UNIVERSAL_BUILD - /* Bug report URL. */ #undef BUG_REPORT_URL @@ -641,6 +638,9 @@ /* Minor version of the LLVM API */ #undef LLVM_VERSION_MINOR +/* Patch version of the LLVM API */ +#undef LLVM_VERSION_PATCH + /* Define if the OS needs help to load dependent libraries for dlopen(). */ #undef LTDL_DLOPEN_DEPLIBS @@ -673,9 +673,6 @@ /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME -/* Define to the home page for this package. */ -#undef PACKAGE_URL - /* Define to the version of this package. */ #undef PACKAGE_VERSION @@ -700,18 +697,6 @@ /* Type of 1st arg on ELM Callback */ #undef WIN32_ELMCB_PCSTR -/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most - significant byte first (like Motorola and SPARC, unlike Intel). */ -#if defined AC_APPLE_UNIVERSAL_BUILD -# if defined __BIG_ENDIAN__ -# define WORDS_BIGENDIAN 1 -# endif -#else -# ifndef WORDS_BIGENDIAN -# undef WORDS_BIGENDIAN -# endif -#endif - /* Define to empty if `const' does not conform to ANSI C. */ #undef const diff --git a/include/llvm/IR/IntrinsicsX86.td b/include/llvm/IR/IntrinsicsX86.td index 4c5718f8c8b5..46c32ae2fd00 100644 --- a/include/llvm/IR/IntrinsicsX86.td +++ b/include/llvm/IR/IntrinsicsX86.td @@ -1758,68 +1758,68 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_avx2_gather_d_pd : GCCBuiltin<"__builtin_ia32_gatherd_pd">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v2f64_ty, llvm_i8_ty], - [IntrReadMem]>; + [IntrReadArgMem]>; def int_x86_avx2_gather_d_pd_256 : GCCBuiltin<"__builtin_ia32_gatherd_pd256">, Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4f64_ty, llvm_i8_ty], - [IntrReadMem]>; + [IntrReadArgMem]>; def int_x86_avx2_gather_q_pd : GCCBuiltin<"__builtin_ia32_gatherq_pd">, Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v2f64_ty, llvm_i8_ty], - [IntrReadMem]>; + [IntrReadArgMem]>; def int_x86_avx2_gather_q_pd_256 : GCCBuiltin<"__builtin_ia32_gatherq_pd256">, Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4f64_ty, llvm_i8_ty], - [IntrReadMem]>; + [IntrReadArgMem]>; def int_x86_avx2_gather_d_ps : GCCBuiltin<"__builtin_ia32_gatherd_ps">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4f32_ty, llvm_i8_ty], - [IntrReadMem]>; + [IntrReadArgMem]>; def int_x86_avx2_gather_d_ps_256 : GCCBuiltin<"__builtin_ia32_gatherd_ps256">, Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_v8f32_ty, llvm_i8_ty], - [IntrReadMem]>; + [IntrReadArgMem]>; def int_x86_avx2_gather_q_ps : GCCBuiltin<"__builtin_ia32_gatherq_ps">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v4f32_ty, llvm_i8_ty], - [IntrReadMem]>; + [IntrReadArgMem]>; def int_x86_avx2_gather_q_ps_256 : GCCBuiltin<"__builtin_ia32_gatherq_ps256">, Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4f32_ty, llvm_i8_ty], - [IntrReadMem]>; + [IntrReadArgMem]>; def int_x86_avx2_gather_d_q : GCCBuiltin<"__builtin_ia32_gatherd_q">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v2i64_ty, llvm_i8_ty], - [IntrReadMem]>; + [IntrReadArgMem]>; def int_x86_avx2_gather_d_q_256 : GCCBuiltin<"__builtin_ia32_gatherd_q256">, Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4i64_ty, llvm_i8_ty], - [IntrReadMem]>; + [IntrReadArgMem]>; def int_x86_avx2_gather_q_q : GCCBuiltin<"__builtin_ia32_gatherq_q">, Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i8_ty], - [IntrReadMem]>; + [IntrReadArgMem]>; def int_x86_avx2_gather_q_q_256 : GCCBuiltin<"__builtin_ia32_gatherq_q256">, Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i64_ty, llvm_i8_ty], - [IntrReadMem]>; + [IntrReadArgMem]>; def int_x86_avx2_gather_d_d : GCCBuiltin<"__builtin_ia32_gatherd_d">, Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4i32_ty, llvm_i8_ty], - [IntrReadMem]>; + [IntrReadArgMem]>; def int_x86_avx2_gather_d_d_256 : GCCBuiltin<"__builtin_ia32_gatherd_d256">, Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_v8i32_ty, llvm_i8_ty], - [IntrReadMem]>; + [IntrReadArgMem]>; def int_x86_avx2_gather_q_d : GCCBuiltin<"__builtin_ia32_gatherq_d">, Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v4i32_ty, llvm_i8_ty], - [IntrReadMem]>; + [IntrReadArgMem]>; def int_x86_avx2_gather_q_d_256 : GCCBuiltin<"__builtin_ia32_gatherq_d256">, Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i32_ty, llvm_i8_ty], - [IntrReadMem]>; + [IntrReadArgMem]>; } // Misc. @@ -2909,28 +2909,28 @@ let TargetPrefix = "x86" in { def int_x86_avx512_gather_dpd_mask_512 : GCCBuiltin<"__builtin_ia32_mask_gatherdpd512">, Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_i8_ty, llvm_v8i32_ty, llvm_ptr_ty, llvm_i32_ty], - [IntrReadMem]>; + [IntrReadArgMem]>; def int_x86_avx512_gather_dps_mask_512 : GCCBuiltin<"__builtin_ia32_mask_gatherdps512">, Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_i16_ty, llvm_v16i32_ty, llvm_ptr_ty, llvm_i32_ty], - [IntrReadMem]>; + [IntrReadArgMem]>; def int_x86_avx512_gather_qpd_mask_512 : GCCBuiltin<"__builtin_ia32_mask_gatherqpd512">, Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_i8_ty, llvm_v8i64_ty, llvm_ptr_ty, llvm_i32_ty], - [IntrReadMem]>; + [IntrReadArgMem]>; def int_x86_avx512_gather_qps_mask_512 : GCCBuiltin<"__builtin_ia32_mask_gatherqps512">, Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_i8_ty, llvm_v8i64_ty, llvm_ptr_ty, llvm_i32_ty], - [IntrReadMem]>; + [IntrReadArgMem]>; def int_x86_avx512_gather_dpd_512 : GCCBuiltin<"__builtin_ia32_gatherdpd512">, Intrinsic<[llvm_v8f64_ty], [llvm_v8i32_ty, llvm_ptr_ty, llvm_i32_ty], - [IntrReadMem]>; + [IntrReadArgMem]>; def int_x86_avx512_gather_dps_512 : GCCBuiltin<"__builtin_ia32_gatherdps512">, Intrinsic<[llvm_v16f32_ty], [llvm_v16i32_ty, llvm_ptr_ty, llvm_i32_ty], - [IntrReadMem]>; + [IntrReadArgMem]>; def int_x86_avx512_gather_qpd_512 : GCCBuiltin<"__builtin_ia32_gatherqpd512">, Intrinsic<[llvm_v8f64_ty], [llvm_v8i64_ty, llvm_ptr_ty, llvm_i32_ty], @@ -2938,12 +2938,12 @@ let TargetPrefix = "x86" in { def int_x86_avx512_gather_qps_512 : GCCBuiltin<"__builtin_ia32_gatherqps512">, Intrinsic<[llvm_v8f32_ty], [llvm_v8i64_ty, llvm_ptr_ty, llvm_i32_ty], - [IntrReadMem]>; + [IntrReadArgMem]>; def int_x86_avx512_gather_dpq_mask_512 : GCCBuiltin<"__builtin_ia32_mask_gatherdpq512">, Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_i8_ty, llvm_v8i32_ty, llvm_ptr_ty, llvm_i32_ty], - [IntrReadMem]>; + [IntrReadArgMem]>; def int_x86_avx512_gather_dpi_mask_512 : GCCBuiltin<"__builtin_ia32_mask_gatherdpi512">, Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_i16_ty, llvm_v16i32_ty, llvm_ptr_ty, llvm_i32_ty], @@ -2955,7 +2955,7 @@ let TargetPrefix = "x86" in { def int_x86_avx512_gather_qpi_mask_512 : GCCBuiltin<"__builtin_ia32_mask_gatherqpi512">, Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_i8_ty, llvm_v8i64_ty, llvm_ptr_ty, llvm_i32_ty], - [IntrReadMem]>; + [IntrReadArgMem]>; def int_x86_avx512_gather_dpq_512 : GCCBuiltin<"__builtin_ia32_gatherdpq512">, Intrinsic<[llvm_v8i64_ty], [llvm_v8i32_ty, llvm_ptr_ty, diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index 7a9939462147..9845623d4716 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -266,13 +266,16 @@ namespace llvm { /// global as being a weak undefined symbol. const char *WeakRefDirective; // Defaults to NULL. - /// WeakDefDirective - This directive, if non-null, is used to declare a - /// global as being a weak defined symbol. - const char *WeakDefDirective; // Defaults to NULL. + /// True if we have a directive to declare a global as being a weak + /// defined symbol. + bool HasWeakDefDirective; // Defaults to false. - /// LinkOnceDirective - This directive, if non-null is used to declare a - /// global as being a weak defined symbol. This is used on cygwin/mingw. - const char *LinkOnceDirective; // Defaults to NULL. + /// True if we have a directive to declare a global as being a weak + /// defined symbol that can be hidden (unexported). + bool HasWeakDefCanBeHiddenDirective; // Defaults to false. + + /// True if we have a .linkonce directive. This is used on cygwin/mingw. + bool HasLinkOnceDirective; // Defaults to false. /// HiddenVisibilityAttr - This attribute, if not MCSA_Invalid, is used to /// declare a symbol as having hidden visibility. @@ -303,6 +306,10 @@ namespace llvm { /// uses relocations for references to other .debug_* sections. bool DwarfUsesRelocationsAcrossSections; + /// DwarfFDESymbolsUseAbsDiff - true if DWARF FDE symbol reference + /// relocations should be replaced by an absolute difference. + bool DwarfFDESymbolsUseAbsDiff; + /// DwarfRegNumForCFI - True if dwarf register numbers are printed /// instead of symbolic register names in .cfi_* directives. bool DwarfRegNumForCFI; // Defaults to false; @@ -497,8 +504,11 @@ namespace llvm { bool hasIdentDirective() const { return HasIdentDirective; } bool hasNoDeadStrip() const { return HasNoDeadStrip; } const char *getWeakRefDirective() const { return WeakRefDirective; } - const char *getWeakDefDirective() const { return WeakDefDirective; } - const char *getLinkOnceDirective() const { return LinkOnceDirective; } + bool hasWeakDefDirective() const { return HasWeakDefDirective; } + bool hasWeakDefCanBeHiddenDirective() const { + return HasWeakDefCanBeHiddenDirective; + } + bool hasLinkOnceDirective() const { return HasLinkOnceDirective; } MCSymbolAttr getHiddenVisibilityAttr() const { return HiddenVisibilityAttr;} MCSymbolAttr getHiddenDeclarationVisibilityAttr() const { @@ -528,6 +538,9 @@ namespace llvm { bool doesDwarfUseRelocationsAcrossSections() const { return DwarfUsesRelocationsAcrossSections; } + bool doDwarfFDESymbolsUseAbsDiff() const { + return DwarfFDESymbolsUseAbsDiff; + } bool useDwarfRegNumForCFI() const { return DwarfRegNumForCFI; } diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp index b2c20110e90e..d0e186c5f23f 100644 --- a/lib/Analysis/BasicAliasAnalysis.cpp +++ b/lib/Analysis/BasicAliasAnalysis.cpp @@ -18,7 +18,10 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/CaptureTracking.h" +#include "llvm/Analysis/CFG.h" +#include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/InstructionSimplify.h" +#include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/Constants.h" @@ -38,6 +41,12 @@ #include using namespace llvm; +/// Cutoff after which to stop analysing a set of phi nodes potentially involved +/// in a cycle. Because we are analysing 'through' phi nodes we need to be +/// careful with value equivalence. We use reachability to make sure a value +/// cannot be involved in a cycle. +const unsigned MaxNumPhiBBsValueReachabilityCheck = 20; + //===----------------------------------------------------------------------===// // Useful predicates //===----------------------------------------------------------------------===// @@ -403,42 +412,6 @@ DecomposeGEPExpression(const Value *V, int64_t &BaseOffs, return V; } -/// GetIndexDifference - Dest and Src are the variable indices from two -/// decomposed GetElementPtr instructions GEP1 and GEP2 which have common base -/// pointers. Subtract the GEP2 indices from GEP1 to find the symbolic -/// difference between the two pointers. -static void GetIndexDifference(SmallVectorImpl &Dest, - const SmallVectorImpl &Src) { - if (Src.empty()) return; - - for (unsigned i = 0, e = Src.size(); i != e; ++i) { - const Value *V = Src[i].V; - ExtensionKind Extension = Src[i].Extension; - int64_t Scale = Src[i].Scale; - - // Find V in Dest. This is N^2, but pointer indices almost never have more - // than a few variable indexes. - for (unsigned j = 0, e = Dest.size(); j != e; ++j) { - if (Dest[j].V != V || Dest[j].Extension != Extension) continue; - - // If we found it, subtract off Scale V's from the entry in Dest. If it - // goes to zero, remove the entry. - if (Dest[j].Scale != Scale) - Dest[j].Scale -= Scale; - else - Dest.erase(Dest.begin()+j); - Scale = 0; - break; - } - - // If we didn't consume this entry, add it to the end of the Dest list. - if (Scale) { - VariableGEPIndex Entry = { V, Extension, -Scale }; - Dest.push_back(Entry); - } - } -} - //===----------------------------------------------------------------------===// // BasicAliasAnalysis Pass //===----------------------------------------------------------------------===// @@ -492,6 +465,7 @@ namespace { // SmallDenseMap if it ever grows larger. // FIXME: This should really be shrink_to_inline_capacity_and_clear(). AliasCache.shrink_and_clear(); + VisitedPhiBBs.clear(); return Alias; } @@ -532,9 +506,39 @@ namespace { typedef SmallDenseMap AliasCacheTy; AliasCacheTy AliasCache; + /// \brief Track phi nodes we have visited. When interpret "Value" pointer + /// equality as value equality we need to make sure that the "Value" is not + /// part of a cycle. Otherwise, two uses could come from different + /// "iterations" of a cycle and see different values for the same "Value" + /// pointer. + /// The following example shows the problem: + /// %p = phi(%alloca1, %addr2) + /// %l = load %ptr + /// %addr1 = gep, %alloca2, 0, %l + /// %addr2 = gep %alloca2, 0, (%l + 1) + /// alias(%p, %addr1) -> MayAlias ! + /// store %l, ... + SmallPtrSet VisitedPhiBBs; + // Visited - Track instructions visited by pointsToConstantMemory. SmallPtrSet Visited; + /// \brief Check whether two Values can be considered equivalent. + /// + /// In addition to pointer equivalence of \p V1 and \p V2 this checks + /// whether they can not be part of a cycle in the value graph by looking at + /// all visited phi nodes an making sure that the phis cannot reach the + /// value. We have to do this because we are looking through phi nodes (That + /// is we say noalias(V, phi(VA, VB)) if noalias(V, VA) and noalias(V, VB). + bool isValueEqualInPotentialCycles(const Value *V1, const Value *V2); + + /// \brief Dest and Src are the variable indices from two decomposed + /// GetElementPtr instructions GEP1 and GEP2 which have common base + /// pointers. Subtract the GEP2 indices from GEP1 to find the symbolic + /// difference between the two pointers. + void GetIndexDifference(SmallVectorImpl &Dest, + const SmallVectorImpl &Src); + // aliasGEP - Provide a bunch of ad-hoc rules to disambiguate a GEP // instruction against another. AliasResult aliasGEP(const GEPOperator *V1, uint64_t V1Size, @@ -1005,7 +1009,15 @@ BasicAliasAnalysis::aliasGEP(const GEPOperator *GEP1, uint64_t V1Size, return NoAlias; } } else { - if (V1Size != UnknownSize) { + // We have the situation where: + // + + + // | BaseOffset | + // ---------------->| + // |-->V1Size |-------> V2Size + // GEP1 V2 + // We need to know that V2Size is not unknown, otherwise we might have + // stripped a gep with negative index ('gep , -1, ...). + if (V1Size != UnknownSize && V2Size != UnknownSize) { if (-(uint64_t)GEP1BaseOffset < V1Size) return PartialAlias; return NoAlias; @@ -1094,6 +1106,10 @@ BasicAliasAnalysis::aliasPHI(const PHINode *PN, uint64_t PNSize, const MDNode *PNTBAAInfo, const Value *V2, uint64_t V2Size, const MDNode *V2TBAAInfo) { + // Track phi nodes we have visited. We use this information when we determine + // value equivalence. + VisitedPhiBBs.insert(PN->getParent()); + // If the values are PHIs in the same block, we can do a more precise // as well as efficient check: just check for aliases between the values // on corresponding edges. @@ -1187,7 +1203,13 @@ BasicAliasAnalysis::aliasCheck(const Value *V1, uint64_t V1Size, V2 = V2->stripPointerCasts(); // Are we checking for alias of the same value? - if (V1 == V2) return MustAlias; + // Because we look 'through' phi nodes we could look at "Value" pointers from + // different iterations. We must therefore make sure that this is not the + // case. The function isValueEqualInPotentialCycles ensures that this cannot + // happen by looking at the visited phi nodes and making sure they cannot + // reach the value. + if (isValueEqualInPotentialCycles(V1, V2)) + return MustAlias; if (!V1->getType()->isPointerTy() || !V2->getType()->isPointerTy()) return NoAlias; // Scalars cannot alias each other @@ -1307,3 +1329,71 @@ BasicAliasAnalysis::aliasCheck(const Value *V1, uint64_t V1Size, Location(V2, V2Size, V2TBAAInfo)); return AliasCache[Locs] = Result; } + +bool BasicAliasAnalysis::isValueEqualInPotentialCycles(const Value *V, + const Value *V2) { + if (V != V2) + return false; + + const Instruction *Inst = dyn_cast(V); + if (!Inst) + return true; + + if (VisitedPhiBBs.size() > MaxNumPhiBBsValueReachabilityCheck) + return false; + + // Use dominance or loop info if available. + DominatorTree *DT = getAnalysisIfAvailable(); + LoopInfo *LI = getAnalysisIfAvailable(); + + // Make sure that the visited phis cannot reach the Value. This ensures that + // the Values cannot come from different iterations of a potential cycle the + // phi nodes could be involved in. + for (SmallPtrSet::iterator PI = VisitedPhiBBs.begin(), + PE = VisitedPhiBBs.end(); + PI != PE; ++PI) + if (isPotentiallyReachable((*PI)->begin(), Inst, DT, LI)) + return false; + + return true; +} + +/// GetIndexDifference - Dest and Src are the variable indices from two +/// decomposed GetElementPtr instructions GEP1 and GEP2 which have common base +/// pointers. Subtract the GEP2 indices from GEP1 to find the symbolic +/// difference between the two pointers. +void BasicAliasAnalysis::GetIndexDifference( + SmallVectorImpl &Dest, + const SmallVectorImpl &Src) { + if (Src.empty()) + return; + + for (unsigned i = 0, e = Src.size(); i != e; ++i) { + const Value *V = Src[i].V; + ExtensionKind Extension = Src[i].Extension; + int64_t Scale = Src[i].Scale; + + // Find V in Dest. This is N^2, but pointer indices almost never have more + // than a few variable indexes. + for (unsigned j = 0, e = Dest.size(); j != e; ++j) { + if (!isValueEqualInPotentialCycles(Dest[j].V, V) || + Dest[j].Extension != Extension) + continue; + + // If we found it, subtract off Scale V's from the entry in Dest. If it + // goes to zero, remove the entry. + if (Dest[j].Scale != Scale) + Dest[j].Scale -= Scale; + else + Dest.erase(Dest.begin() + j); + Scale = 0; + break; + } + + // If we didn't consume this entry, add it to the end of the Dest list. + if (Scale) { + VariableGEPIndex Entry = { V, Extension, -Scale }; + Dest.push_back(Entry); + } + } +} diff --git a/lib/Analysis/IVUsers.cpp b/lib/Analysis/IVUsers.cpp index b33e2cb9999e..5a06cdce3085 100644 --- a/lib/Analysis/IVUsers.cpp +++ b/lib/Analysis/IVUsers.cpp @@ -187,15 +187,34 @@ bool IVUsers::AddUsersImpl(Instruction *I, if (AddUserToIVUsers) { // Okay, we found a user that we cannot reduce. - IVUses.push_back(new IVStrideUse(this, User, I)); - IVStrideUse &NewUse = IVUses.back(); + IVStrideUse &NewUse = AddUser(User, I); // Autodetect the post-inc loop set, populating NewUse.PostIncLoops. // The regular return value here is discarded; instead of recording // it, we just recompute it when we need it. + const SCEV *OriginalISE = ISE; ISE = TransformForPostIncUse(NormalizeAutodetect, ISE, User, I, NewUse.PostIncLoops, *SE, *DT); + + // PostIncNormalization effectively simplifies the expression under + // pre-increment assumptions. Those assumptions (no wrapping) might not + // hold for the post-inc value. Catch such cases by making sure the + // transformation is invertible. + if (OriginalISE != ISE) { + const SCEV *DenormalizedISE = + TransformForPostIncUse(Denormalize, ISE, User, I, + NewUse.PostIncLoops, *SE, *DT); + + // If we normalized the expression, but denormalization doesn't give the + // original one, discard this user. + if (OriginalISE != DenormalizedISE) { + DEBUG(dbgs() << " DISCARDING (NORMALIZATION ISN'T INVERTIBLE): " + << *ISE << '\n'); + IVUses.pop_back(); + return false; + } + } DEBUG(if (SE->getSCEV(I) != ISE) dbgs() << " NORMALIZED TO: " << *ISE << '\n'); } diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index 0a02f4e9d747..d9b696e0798f 100644 --- a/lib/Analysis/ScalarEvolution.cpp +++ b/lib/Analysis/ScalarEvolution.cpp @@ -6218,7 +6218,7 @@ bool ScalarEvolution::isImpliedCond(ICmpInst::Predicate Pred, // LHS' type is checked for above. if (getTypeSizeInBits(LHS->getType()) > getTypeSizeInBits(FoundLHS->getType())) { - if (CmpInst::isSigned(Pred)) { + if (CmpInst::isSigned(FoundPred)) { FoundLHS = getSignExtendExpr(FoundLHS, LHS->getType()); FoundRHS = getSignExtendExpr(FoundRHS, LHS->getType()); } else { diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 308b0e091ac5..8be4dcba3689 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -222,13 +222,14 @@ void AsmPrinter::EmitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const { case GlobalValue::WeakAnyLinkage: case GlobalValue::WeakODRLinkage: case GlobalValue::LinkerPrivateWeakLinkage: - if (MAI->getWeakDefDirective() != 0) { + if (MAI->hasWeakDefDirective()) { // .globl _foo OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global); bool CanBeHidden = false; - if (Linkage == GlobalValue::LinkOnceODRLinkage) { + if (Linkage == GlobalValue::LinkOnceODRLinkage && + MAI->hasWeakDefCanBeHiddenDirective()) { if (GV->hasUnnamedAddr()) { CanBeHidden = true; } else { @@ -243,7 +244,7 @@ void AsmPrinter::EmitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const { OutStreamer.EmitSymbolAttribute(GVSym, MCSA_WeakDefinition); else OutStreamer.EmitSymbolAttribute(GVSym, MCSA_WeakDefAutoPrivate); - } else if (MAI->getLinkOnceDirective() != 0) { + } else if (MAI->hasLinkOnceDirective()) { // .globl _foo OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global); //NOTE: linkonce is handled by the section the symbol was assigned to. diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 43f72c5ef9b4..69cf8d9a909a 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -8547,7 +8547,10 @@ struct MemOpLink { // base ptr. struct ConsecutiveMemoryChainSorter { bool operator()(MemOpLink LHS, MemOpLink RHS) { - return LHS.OffsetFromBase < RHS.OffsetFromBase; + return + LHS.OffsetFromBase < RHS.OffsetFromBase || + (LHS.OffsetFromBase == RHS.OffsetFromBase && + LHS.SequenceNum > RHS.SequenceNum); } }; diff --git a/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp b/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp index 2c3cdccb56e8..3fb2d9bdf55e 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp @@ -210,6 +210,7 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) { case ISD::SRL: case ISD::ROTL: case ISD::ROTR: + case ISD::BSWAP: case ISD::CTLZ: case ISD::CTTZ: case ISD::CTLZ_ZERO_UNDEF: diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp index 054e3dd840b5..c1893c9231f0 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp @@ -219,8 +219,11 @@ void ScheduleDAGSDNodes::ClusterNeighboringLoads(SDNode *Node) { DenseMap O2SMap; // Map from offset to SDNode. bool Cluster = false; SDNode *Base = Node; + // This algorithm requires a reasonably low use count before finding a match + // to avoid uselessly blowing up compile time in large blocks. + unsigned UseCount = 0; for (SDNode::use_iterator I = Chain->use_begin(), E = Chain->use_end(); - I != E; ++I) { + I != E && UseCount < 100; ++I, ++UseCount) { SDNode *User = *I; if (User == Node || !Visited.insert(User)) continue; @@ -237,6 +240,8 @@ void ScheduleDAGSDNodes::ClusterNeighboringLoads(SDNode *Node) { if (Offset2 < Offset1) Base = User; Cluster = true; + // Reset UseCount to allow more matches. + UseCount = 0; } if (!Cluster) diff --git a/lib/MC/MCAsmInfo.cpp b/lib/MC/MCAsmInfo.cpp index 28f1c951641c..daf19e927c7a 100644 --- a/lib/MC/MCAsmInfo.cpp +++ b/lib/MC/MCAsmInfo.cpp @@ -76,8 +76,9 @@ MCAsmInfo::MCAsmInfo() { HasIdentDirective = false; HasNoDeadStrip = false; WeakRefDirective = 0; - WeakDefDirective = 0; - LinkOnceDirective = 0; + HasWeakDefDirective = false; + HasWeakDefCanBeHiddenDirective = false; + HasLinkOnceDirective = false; HiddenVisibilityAttr = MCSA_Hidden; HiddenDeclarationVisibilityAttr = MCSA_Hidden; ProtectedVisibilityAttr = MCSA_Protected; @@ -85,6 +86,7 @@ MCAsmInfo::MCAsmInfo() { SupportsDebugInformation = false; ExceptionsType = ExceptionHandling::None; DwarfUsesRelocationsAcrossSections = true; + DwarfFDESymbolsUseAbsDiff = false; DwarfRegNumForCFI = false; HasMicrosoftFastStdCallMangling = false; NeedsDwarfSectionOffsetDirective = false; diff --git a/lib/MC/MCAsmInfoCOFF.cpp b/lib/MC/MCAsmInfoCOFF.cpp index 9d9f98e72b96..1cac71f1eda1 100644 --- a/lib/MC/MCAsmInfoCOFF.cpp +++ b/lib/MC/MCAsmInfoCOFF.cpp @@ -27,7 +27,7 @@ MCAsmInfoCOFF::MCAsmInfoCOFF() { HasSingleParameterDotFile = false; PrivateGlobalPrefix = "L"; // Prefix for private global symbols WeakRefDirective = "\t.weak\t"; - LinkOnceDirective = "\t.linkonce discard\n"; + HasLinkOnceDirective = true; // Doesn't support visibility: HiddenVisibilityAttr = HiddenDeclarationVisibilityAttr = MCSA_Invalid; diff --git a/lib/MC/MCAsmInfoDarwin.cpp b/lib/MC/MCAsmInfoDarwin.cpp index 704c8161f880..351ec56352a6 100644 --- a/lib/MC/MCAsmInfoDarwin.cpp +++ b/lib/MC/MCAsmInfoDarwin.cpp @@ -36,7 +36,8 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() { InlineAsmEnd = " InlineAsm End"; // Directives: - WeakDefDirective = "\t.weak_definition "; + HasWeakDefDirective = true; + HasWeakDefCanBeHiddenDirective = true; WeakRefDirective = "\t.weak_reference "; ZeroDirective = "\t.space\t"; // ".space N" emits N zeros. HasMachoZeroFillDirective = true; // Uses .zerofill diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp index 1e5c2e34c488..9fd13ab3af61 100644 --- a/lib/MC/MCDwarf.cpp +++ b/lib/MC/MCDwarf.cpp @@ -836,8 +836,9 @@ static unsigned getSizeForEncoding(MCStreamer &streamer, } } -static void EmitSymbol(MCStreamer &streamer, const MCSymbol &symbol, - unsigned symbolEncoding, const char *comment = 0) { +static void EmitFDESymbol(MCStreamer &streamer, const MCSymbol &symbol, + unsigned symbolEncoding, bool isEH, + const char *comment = 0) { MCContext &context = streamer.getContext(); const MCAsmInfo *asmInfo = context.getAsmInfo(); const MCExpr *v = asmInfo->getExprForFDESymbol(&symbol, @@ -845,7 +846,10 @@ static void EmitSymbol(MCStreamer &streamer, const MCSymbol &symbol, streamer); unsigned size = getSizeForEncoding(streamer, symbolEncoding); if (streamer.isVerboseAsm() && comment) streamer.AddComment(comment); - streamer.EmitAbsValue(v, size); + if (asmInfo->doDwarfFDESymbolsUseAbsDiff() && isEH) + streamer.EmitAbsValue(v, size); + else + streamer.EmitValue(v, size); } static void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol, @@ -1344,7 +1348,7 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCStreamer &streamer, unsigned PCEncoding = IsEH ? MOFI->getFDEEncoding(UsingCFI) : (unsigned)dwarf::DW_EH_PE_absptr; unsigned PCSize = getSizeForEncoding(streamer, PCEncoding); - EmitSymbol(streamer, *frame.Begin, PCEncoding, "FDE initial location"); + EmitFDESymbol(streamer, *frame.Begin, PCEncoding, IsEH, "FDE initial location"); // PC Range const MCExpr *Range = MakeStartMinusEndExpr(streamer, *frame.Begin, @@ -1364,8 +1368,8 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCStreamer &streamer, // Augmentation Data if (frame.Lsda) - EmitSymbol(streamer, *frame.Lsda, frame.LsdaEncoding, - "Language Specific Data Area"); + EmitFDESymbol(streamer, *frame.Lsda, frame.LsdaEncoding, true, + "Language Specific Data Area"); } // Call Frame Instructions diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index a91bd93105b6..6f7729639e42 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -4292,6 +4292,10 @@ bool AsmParser::parseMSInlineAsm( break; } case AOK_DotOperator: + // Insert the dot if the user omitted it. + OS.flush(); + if (AsmStringIR.at(AsmStringIR.size() - 1) != '.') + OS << '.'; OS << (*I).Val; break; } diff --git a/lib/Target/AArch64/AArch64ISelLowering.cpp b/lib/Target/AArch64/AArch64ISelLowering.cpp index 4fdb667b9539..cf7aec3b4538 100644 --- a/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -31,12 +31,8 @@ using namespace llvm; static TargetLoweringObjectFile *createTLOF(AArch64TargetMachine &TM) { const AArch64Subtarget *Subtarget = &TM.getSubtarget(); - - if (Subtarget->isTargetLinux()) - return new AArch64LinuxTargetObjectFile(); - if (Subtarget->isTargetELF()) - return new TargetLoweringObjectFileELF(); - llvm_unreachable("unknown subtarget type"); + assert (Subtarget->isTargetELF() && "unknown subtarget type"); + return new AArch64ElfTargetObjectFile(); } AArch64TargetLowering::AArch64TargetLowering(AArch64TargetMachine &TM) @@ -2782,7 +2778,7 @@ AArch64TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const { SDValue AArch64TargetLowering::LowerVACOPY(SDValue Op, SelectionDAG &DAG) const { const Value *DestSV = cast(Op.getOperand(3))->getValue(); - const Value *SrcSV = cast(Op.getOperand(3))->getValue(); + const Value *SrcSV = cast(Op.getOperand(4))->getValue(); // We have to make sure we copy the entire structure: 8+8+8+4+4 = 32 bytes // rather than just 8. diff --git a/lib/Target/AArch64/AArch64InstrInfo.td b/lib/Target/AArch64/AArch64InstrInfo.td index 23d81fc478e8..8e5a4d30396c 100644 --- a/lib/Target/AArch64/AArch64InstrInfo.td +++ b/lib/Target/AArch64/AArch64InstrInfo.td @@ -2587,6 +2587,7 @@ class A64I_SRexs_impl size, bits<3> opcode, string asm, dag outs, pat, itin> { let mayStore = 1; let PostEncoderMethod = "fixLoadStoreExclusive<1,0>"; + let Constraints = "@earlyclobber $Rs"; } multiclass A64I_SRex opcode, string prefix> { diff --git a/lib/Target/AArch64/AArch64TargetObjectFile.cpp b/lib/Target/AArch64/AArch64TargetObjectFile.cpp index b4452f514590..f8f21198a4f9 100644 --- a/lib/Target/AArch64/AArch64TargetObjectFile.cpp +++ b/lib/Target/AArch64/AArch64TargetObjectFile.cpp @@ -22,3 +22,10 @@ AArch64LinuxTargetObjectFile::Initialize(MCContext &Ctx, TargetLoweringObjectFileELF::Initialize(Ctx, TM); InitializeELF(TM.Options.UseInitArray); } + +void +AArch64ElfTargetObjectFile::Initialize(MCContext &Ctx, + const TargetMachine &TM) { + TargetLoweringObjectFileELF::Initialize(Ctx, TM); + InitializeELF(TM.Options.UseInitArray); +} diff --git a/lib/Target/AArch64/AArch64TargetObjectFile.h b/lib/Target/AArch64/AArch64TargetObjectFile.h index bf0565a79ec8..f782285d1c02 100644 --- a/lib/Target/AArch64/AArch64TargetObjectFile.h +++ b/lib/Target/AArch64/AArch64TargetObjectFile.h @@ -20,8 +20,12 @@ namespace llvm { - /// AArch64LinuxTargetObjectFile - This implementation is used for linux - /// AArch64. + /// AArch64ElfTargetObjectFile - This implementation is used for ELF + /// AArch64 targets. + class AArch64ElfTargetObjectFile : public TargetLoweringObjectFileELF { + virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); + }; + class AArch64LinuxTargetObjectFile : public TargetLoweringObjectFileELF { virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); }; diff --git a/lib/Target/ARM/A15SDOptimizer.cpp b/lib/Target/ARM/A15SDOptimizer.cpp index ff585b41a2aa..3e805a2b68bc 100644 --- a/lib/Target/ARM/A15SDOptimizer.cpp +++ b/lib/Target/ARM/A15SDOptimizer.cpp @@ -418,7 +418,8 @@ SmallVector A15SDOptimizer::getReadDPRs(MachineInstr *MI) { if (!MO.isReg() || !MO.isUse()) continue; if (!usesRegClass(MO, &ARM::DPRRegClass) && - !usesRegClass(MO, &ARM::QPRRegClass)) + !usesRegClass(MO, &ARM::QPRRegClass) && + !usesRegClass(MO, &ARM::DPairRegClass)) // Treat DPair as QPR continue; Defs.push_back(MO.getReg()); @@ -538,7 +539,10 @@ A15SDOptimizer::optimizeAllLanesPattern(MachineInstr *MI, unsigned Reg) { InsertPt++; unsigned Out; - if (MRI->getRegClass(Reg)->hasSuperClassEq(&ARM::QPRRegClass)) { + // DPair has the same length as QPR and also has two DPRs as subreg. + // Treat DPair as QPR. + if (MRI->getRegClass(Reg)->hasSuperClassEq(&ARM::QPRRegClass) || + MRI->getRegClass(Reg)->hasSuperClassEq(&ARM::DPairRegClass)) { unsigned DSub0 = createExtractSubreg(MBB, InsertPt, DL, Reg, ARM::dsub_0, &ARM::DPRRegClass); unsigned DSub1 = createExtractSubreg(MBB, InsertPt, DL, Reg, @@ -571,7 +575,9 @@ A15SDOptimizer::optimizeAllLanesPattern(MachineInstr *MI, unsigned Reg) { default: llvm_unreachable("Unknown preferred lane!"); } - bool UsesQPR = usesRegClass(MI->getOperand(0), &ARM::QPRRegClass); + // Treat DPair as QPR + bool UsesQPR = usesRegClass(MI->getOperand(0), &ARM::QPRRegClass) || + usesRegClass(MI->getOperand(0), &ARM::DPairRegClass); Out = createImplicitDef(MBB, InsertPt, DL); Out = createInsertSubreg(MBB, InsertPt, DL, Out, PrefLane, Reg); diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index f835a4e5b5fe..658af8380d8d 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -3684,6 +3684,7 @@ ARMBaseInstrInfo::getOperandLatency(const InstrItineraryData *ItinData, case ARM::VLD3d16Pseudo: case ARM::VLD3d32Pseudo: case ARM::VLD1d64TPseudo: + case ARM::VLD1d64TPseudoWB_fixed: case ARM::VLD3d8Pseudo_UPD: case ARM::VLD3d16Pseudo_UPD: case ARM::VLD3d32Pseudo_UPD: @@ -3700,6 +3701,7 @@ ARMBaseInstrInfo::getOperandLatency(const InstrItineraryData *ItinData, case ARM::VLD4d16Pseudo: case ARM::VLD4d32Pseudo: case ARM::VLD1d64QPseudo: + case ARM::VLD1d64QPseudoWB_fixed: case ARM::VLD4d8Pseudo_UPD: case ARM::VLD4d16Pseudo_UPD: case ARM::VLD4d32Pseudo_UPD: diff --git a/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/lib/Target/ARM/ARMExpandPseudoInsts.cpp index e6f7f86c5587..3e62b649e0dc 100644 --- a/lib/Target/ARM/ARMExpandPseudoInsts.cpp +++ b/lib/Target/ARM/ARMExpandPseudoInsts.cpp @@ -136,7 +136,9 @@ static const NEONLdStTableEntry NEONLdStTable[] = { { ARM::VLD1LNq8Pseudo_UPD, ARM::VLD1LNd8_UPD, true, true, true, EvenDblSpc, 1, 8 ,true}, { ARM::VLD1d64QPseudo, ARM::VLD1d64Q, true, false, false, SingleSpc, 4, 1 ,false}, +{ ARM::VLD1d64QPseudoWB_fixed, ARM::VLD1d64Qwb_fixed, true, true, false, SingleSpc, 4, 1 ,false}, { ARM::VLD1d64TPseudo, ARM::VLD1d64T, true, false, false, SingleSpc, 3, 1 ,false}, +{ ARM::VLD1d64TPseudoWB_fixed, ARM::VLD1d64Twb_fixed, true, true, false, SingleSpc, 3, 1 ,false}, { ARM::VLD2LNd16Pseudo, ARM::VLD2LNd16, true, false, false, SingleSpc, 2, 4 ,true}, { ARM::VLD2LNd16Pseudo_UPD, ARM::VLD2LNd16_UPD, true, true, true, SingleSpc, 2, 4 ,true}, @@ -1071,6 +1073,7 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB, case ARM::VLD3d16Pseudo: case ARM::VLD3d32Pseudo: case ARM::VLD1d64TPseudo: + case ARM::VLD1d64TPseudoWB_fixed: case ARM::VLD3d8Pseudo_UPD: case ARM::VLD3d16Pseudo_UPD: case ARM::VLD3d32Pseudo_UPD: @@ -1087,6 +1090,7 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB, case ARM::VLD4d16Pseudo: case ARM::VLD4d32Pseudo: case ARM::VLD1d64QPseudo: + case ARM::VLD1d64QPseudoWB_fixed: case ARM::VLD4d8Pseudo_UPD: case ARM::VLD4d16Pseudo_UPD: case ARM::VLD4d32Pseudo_UPD: diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index 87d15226947a..6d9b18877f72 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -1673,9 +1673,61 @@ SDValue ARMDAGToDAGISel::GetVLDSTAlign(SDValue Align, unsigned NumVecs, return CurDAG->getTargetConstant(Alignment, MVT::i32); } +static bool isVLDfixed(unsigned Opc) +{ + switch (Opc) { + default: return false; + case ARM::VLD1d8wb_fixed : return true; + case ARM::VLD1d16wb_fixed : return true; + case ARM::VLD1d64Qwb_fixed : return true; + case ARM::VLD1d32wb_fixed : return true; + case ARM::VLD1d64wb_fixed : return true; + case ARM::VLD1d64TPseudoWB_fixed : return true; + case ARM::VLD1d64QPseudoWB_fixed : return true; + case ARM::VLD1q8wb_fixed : return true; + case ARM::VLD1q16wb_fixed : return true; + case ARM::VLD1q32wb_fixed : return true; + case ARM::VLD1q64wb_fixed : return true; + case ARM::VLD2d8wb_fixed : return true; + case ARM::VLD2d16wb_fixed : return true; + case ARM::VLD2d32wb_fixed : return true; + case ARM::VLD2q8PseudoWB_fixed : return true; + case ARM::VLD2q16PseudoWB_fixed : return true; + case ARM::VLD2q32PseudoWB_fixed : return true; + case ARM::VLD2DUPd8wb_fixed : return true; + case ARM::VLD2DUPd16wb_fixed : return true; + case ARM::VLD2DUPd32wb_fixed : return true; + } +} + +static bool isVSTfixed(unsigned Opc) +{ + switch (Opc) { + default: return false; + case ARM::VST1d8wb_fixed : return true; + case ARM::VST1d16wb_fixed : return true; + case ARM::VST1d32wb_fixed : return true; + case ARM::VST1d64wb_fixed : return true; + case ARM::VST1q8wb_fixed : return true; + case ARM::VST1q16wb_fixed : return true; + case ARM::VST1q32wb_fixed : return true; + case ARM::VST1q64wb_fixed : return true; + case ARM::VST1d64TPseudoWB_fixed : return true; + case ARM::VST1d64QPseudoWB_fixed : return true; + case ARM::VST2d8wb_fixed : return true; + case ARM::VST2d16wb_fixed : return true; + case ARM::VST2d32wb_fixed : return true; + case ARM::VST2q8PseudoWB_fixed : return true; + case ARM::VST2q16PseudoWB_fixed : return true; + case ARM::VST2q32PseudoWB_fixed : return true; + } +} + // Get the register stride update opcode of a VLD/VST instruction that // is otherwise equivalent to the given fixed stride updating instruction. static unsigned getVLDSTRegisterUpdateOpcode(unsigned Opc) { + assert((isVLDfixed(Opc) || isVSTfixed(Opc)) + && "Incorrect fixed stride updating instruction."); switch (Opc) { default: break; case ARM::VLD1d8wb_fixed: return ARM::VLD1d8wb_register; @@ -1686,6 +1738,10 @@ static unsigned getVLDSTRegisterUpdateOpcode(unsigned Opc) { case ARM::VLD1q16wb_fixed: return ARM::VLD1q16wb_register; case ARM::VLD1q32wb_fixed: return ARM::VLD1q32wb_register; case ARM::VLD1q64wb_fixed: return ARM::VLD1q64wb_register; + case ARM::VLD1d64Twb_fixed: return ARM::VLD1d64Twb_register; + case ARM::VLD1d64Qwb_fixed: return ARM::VLD1d64Qwb_register; + case ARM::VLD1d64TPseudoWB_fixed: return ARM::VLD1d64TPseudoWB_register; + case ARM::VLD1d64QPseudoWB_fixed: return ARM::VLD1d64QPseudoWB_register; case ARM::VST1d8wb_fixed: return ARM::VST1d8wb_register; case ARM::VST1d16wb_fixed: return ARM::VST1d16wb_register; @@ -1785,11 +1841,11 @@ SDNode *ARMDAGToDAGISel::SelectVLD(SDNode *N, bool isUpdating, unsigned NumVecs, SDValue Inc = N->getOperand(AddrOpIdx + 1); // FIXME: VLD1/VLD2 fixed increment doesn't need Reg0. Remove the reg0 // case entirely when the rest are updated to that form, too. - if ((NumVecs == 1 || NumVecs == 2) && !isa(Inc.getNode())) + if ((NumVecs <= 2) && !isa(Inc.getNode())) Opc = getVLDSTRegisterUpdateOpcode(Opc); - // We use a VLD1 for v1i64 even if the pseudo says vld2/3/4, so + // FIXME: We use a VLD1 for v1i64 even if the pseudo says vld2/3/4, so // check for that explicitly too. Horribly hacky, but temporary. - if ((NumVecs != 1 && NumVecs != 2 && Opc != ARM::VLD1q64wb_fixed) || + if ((NumVecs > 2 && !isVLDfixed(Opc)) || !isa(Inc.getNode())) Ops.push_back(isa(Inc.getNode()) ? Reg0 : Inc); } @@ -1937,11 +1993,12 @@ SDNode *ARMDAGToDAGISel::SelectVST(SDNode *N, bool isUpdating, unsigned NumVecs, // case entirely when the rest are updated to that form, too. if (NumVecs <= 2 && !isa(Inc.getNode())) Opc = getVLDSTRegisterUpdateOpcode(Opc); - // We use a VST1 for v1i64 even if the pseudo says vld2/3/4, so + // FIXME: We use a VST1 for v1i64 even if the pseudo says vld2/3/4, so // check for that explicitly too. Horribly hacky, but temporary. - if ((NumVecs > 2 && Opc != ARM::VST1q64wb_fixed) || - !isa(Inc.getNode())) - Ops.push_back(isa(Inc.getNode()) ? Reg0 : Inc); + if (!isa(Inc.getNode())) + Ops.push_back(Inc); + else if (NumVecs > 2 && !isVSTfixed(Opc)) + Ops.push_back(Reg0); } Ops.push_back(SrcReg); Ops.push_back(Pred); @@ -2834,7 +2891,7 @@ SDNode *ARMDAGToDAGISel::Select(SDNode *N) { static const uint16_t DOpcodes[] = { ARM::VLD3d8Pseudo_UPD, ARM::VLD3d16Pseudo_UPD, ARM::VLD3d32Pseudo_UPD, - ARM::VLD1q64wb_fixed}; + ARM::VLD1d64TPseudoWB_fixed}; static const uint16_t QOpcodes0[] = { ARM::VLD3q8Pseudo_UPD, ARM::VLD3q16Pseudo_UPD, ARM::VLD3q32Pseudo_UPD }; @@ -2848,7 +2905,7 @@ SDNode *ARMDAGToDAGISel::Select(SDNode *N) { static const uint16_t DOpcodes[] = { ARM::VLD4d8Pseudo_UPD, ARM::VLD4d16Pseudo_UPD, ARM::VLD4d32Pseudo_UPD, - ARM::VLD1q64wb_fixed}; + ARM::VLD1d64QPseudoWB_fixed}; static const uint16_t QOpcodes0[] = { ARM::VLD4q8Pseudo_UPD, ARM::VLD4q16Pseudo_UPD, ARM::VLD4q32Pseudo_UPD }; diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td index 43bd4c21dc39..0b05c08ed948 100644 --- a/lib/Target/ARM/ARMInstrNEON.td +++ b/lib/Target/ARM/ARMInstrNEON.td @@ -730,6 +730,8 @@ defm VLD1d32Twb : VLD1D3WB<{1,0,0,?}, "32">; defm VLD1d64Twb : VLD1D3WB<{1,1,0,?}, "64">; def VLD1d64TPseudo : VLDQQPseudo; +def VLD1d64TPseudoWB_fixed : VLDQQWBfixedPseudo; +def VLD1d64TPseudoWB_register : VLDQQWBregisterPseudo; // ...with 4 registers class VLD1D4 op7_4, string Dt> @@ -769,6 +771,8 @@ defm VLD1d32Qwb : VLD1D4WB<{1,0,?,?}, "32">; defm VLD1d64Qwb : VLD1D4WB<{1,1,?,?}, "64">; def VLD1d64QPseudo : VLDQQPseudo; +def VLD1d64QPseudoWB_fixed : VLDQQWBfixedPseudo; +def VLD1d64QPseudoWB_register : VLDQQWBregisterPseudo; // VLD2 : Vector Load (multiple 2-element structures) class VLD2 op11_8, bits<4> op7_4, string Dt, RegisterOperand VdTy, @@ -1671,7 +1675,7 @@ defm VST1d32Twb : VST1D3WB<{1,0,0,?}, "32">; defm VST1d64Twb : VST1D3WB<{1,1,0,?}, "64">; def VST1d64TPseudo : VSTQQPseudo; -def VST1d64TPseudoWB_fixed : VSTQQWBPseudo; +def VST1d64TPseudoWB_fixed : VSTQQWBfixedPseudo; def VST1d64TPseudoWB_register : VSTQQWBPseudo; // ...with 4 registers @@ -1714,7 +1718,7 @@ defm VST1d32Qwb : VST1D4WB<{1,0,?,?}, "32">; defm VST1d64Qwb : VST1D4WB<{1,1,?,?}, "64">; def VST1d64QPseudo : VSTQQPseudo; -def VST1d64QPseudoWB_fixed : VSTQQWBPseudo; +def VST1d64QPseudoWB_fixed : VSTQQWBfixedPseudo; def VST1d64QPseudoWB_register : VSTQQWBPseudo; // VST2 : Vector Store (multiple 2-element structures) diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp index f3dddce30120..1d9c06406a4b 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp @@ -12,10 +12,14 @@ //===----------------------------------------------------------------------===// #include "PPCMCAsmInfo.h" +#include "llvm/ADT/Triple.h" + using namespace llvm; void PPCMCAsmInfoDarwin::anchor() { } +/// This version of the constructor is here to maintain ABI compatibility with +/// LLVM 3.4.0 PPCMCAsmInfoDarwin::PPCMCAsmInfoDarwin(bool is64Bit) { if (is64Bit) { PointerSize = CalleeSaveStackSlotSize = 8; @@ -32,6 +36,28 @@ PPCMCAsmInfoDarwin::PPCMCAsmInfoDarwin(bool is64Bit) { SupportsDebugInformation= true; // Debug information. } +PPCMCAsmInfoDarwin::PPCMCAsmInfoDarwin(bool is64Bit, const Triple& T) { + if (is64Bit) { + PointerSize = CalleeSaveStackSlotSize = 8; + } + IsLittleEndian = false; + + CommentString = ";"; + ExceptionsType = ExceptionHandling::DwarfCFI; + + if (!is64Bit) + Data64bitsDirective = 0; // We can't emit a 64-bit unit in PPC32 mode. + + AssemblerDialect = 1; // New-Style mnemonics. + SupportsDebugInformation= true; // Debug information. + + // old assembler lacks some directives + // FIXME: this should really be a check on the assembler characteristics + // rather than OS version + if (T.isMacOSX() && T.isMacOSXVersionLT(10, 6)) + HasWeakDefCanBeHiddenDirective = false; +} + void PPCLinuxMCAsmInfo::anchor() { } PPCLinuxMCAsmInfo::PPCLinuxMCAsmInfo(bool is64Bit) { diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.h b/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.h index 1530e774cfc7..633970ccc289 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.h +++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.h @@ -18,11 +18,15 @@ #include "llvm/MC/MCAsmInfoELF.h" namespace llvm { +class Triple; class PPCMCAsmInfoDarwin : public MCAsmInfoDarwin { virtual void anchor(); public: + /// This version of the constructor is here to maintain ABI compatibility + /// with LLVM 3.4.0. explicit PPCMCAsmInfoDarwin(bool is64Bit); + explicit PPCMCAsmInfoDarwin(bool is64Bit, const Triple&); }; class PPCLinuxMCAsmInfo : public MCAsmInfoELF { diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp index f18d095c6d02..6a5051840181 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp @@ -72,7 +72,7 @@ static MCAsmInfo *createPPCMCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) { MCAsmInfo *MAI; if (TheTriple.isOSDarwin()) - MAI = new PPCMCAsmInfoDarwin(isPPC64); + MAI = new PPCMCAsmInfoDarwin(isPPC64, TheTriple); else MAI = new PPCLinuxMCAsmInfo(isPPC64); diff --git a/lib/Target/PowerPC/PPCAsmPrinter.cpp b/lib/Target/PowerPC/PPCAsmPrinter.cpp index ada34ed9e18a..2d92a112d5ef 100644 --- a/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -701,13 +701,6 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { return; } break; - case PPC::SYNC: - // In Book E sync is called msync, handle this special case here... - if (Subtarget.isBookE()) { - OutStreamer.EmitRawText(StringRef("\tmsync")); - return; - } - break; case PPC::LD: case PPC::STD: case PPC::LWA_32: diff --git a/lib/Target/PowerPC/PPCCTRLoops.cpp b/lib/Target/PowerPC/PPCCTRLoops.cpp index 4224ae2d273c..e419b9b40d8e 100644 --- a/lib/Target/PowerPC/PPCCTRLoops.cpp +++ b/lib/Target/PowerPC/PPCCTRLoops.cpp @@ -186,6 +186,13 @@ bool PPCCTRLoops::runOnFunction(Function &F) { return MadeChange; } +static bool isLargeIntegerTy(bool Is32Bit, Type *Ty) { + if (IntegerType *ITy = dyn_cast(Ty)) + return ITy->getBitWidth() > (Is32Bit ? 32 : 64); + + return false; +} + bool PPCCTRLoops::mightUseCTR(const Triple &TT, BasicBlock *BB) { for (BasicBlock::iterator J = BB->begin(), JE = BB->end(); J != JE; ++J) { @@ -352,13 +359,11 @@ bool PPCCTRLoops::mightUseCTR(const Triple &TT, BasicBlock *BB) { CastInst *CI = cast(J); if (CI->getSrcTy()->getScalarType()->isPPC_FP128Ty() || CI->getDestTy()->getScalarType()->isPPC_FP128Ty() || - (TT.isArch32Bit() && - (CI->getSrcTy()->getScalarType()->isIntegerTy(64) || - CI->getDestTy()->getScalarType()->isIntegerTy(64)) - )) + isLargeIntegerTy(TT.isArch32Bit(), CI->getSrcTy()->getScalarType()) || + isLargeIntegerTy(TT.isArch32Bit(), CI->getDestTy()->getScalarType())) return true; - } else if (TT.isArch32Bit() && - J->getType()->getScalarType()->isIntegerTy(64) && + } else if (isLargeIntegerTy(TT.isArch32Bit(), + J->getType()->getScalarType()) && (J->getOpcode() == Instruction::UDiv || J->getOpcode() == Instruction::SDiv || J->getOpcode() == Instruction::URem || diff --git a/lib/Target/PowerPC/PPCFastISel.cpp b/lib/Target/PowerPC/PPCFastISel.cpp index 09117e7ded49..4e3b0b83244a 100644 --- a/lib/Target/PowerPC/PPCFastISel.cpp +++ b/lib/Target/PowerPC/PPCFastISel.cpp @@ -892,11 +892,13 @@ unsigned PPCFastISel::PPCMoveToFPReg(MVT SrcVT, unsigned SrcReg, unsigned LoadOpc = PPC::LFD; if (SrcVT == MVT::i32) { - Addr.Offset = 4; - if (!IsSigned) + if (!IsSigned) { LoadOpc = PPC::LFIWZX; - else if (PPCSubTarget.hasLFIWAX()) + Addr.Offset = 4; + } else if (PPCSubTarget.hasLFIWAX()) { LoadOpc = PPC::LFIWAX; + Addr.Offset = 4; + } } const TargetRegisterClass *RC = &PPC::F8RCRegClass; diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index 6ba6af6446e5..d25762a5bbca 100644 --- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -261,11 +261,11 @@ SDNode *PPCDAGToDAGISel::getGlobalBaseReg() { DebugLoc dl; if (PPCLowering.getPointerTy() == MVT::i32) { - GlobalBaseReg = RegInfo->createVirtualRegister(&PPC::GPRCRegClass); + GlobalBaseReg = RegInfo->createVirtualRegister(&PPC::GPRC_NOR0RegClass); BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MovePCtoLR)); BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MFLR), GlobalBaseReg); } else { - GlobalBaseReg = RegInfo->createVirtualRegister(&PPC::G8RCRegClass); + GlobalBaseReg = RegInfo->createVirtualRegister(&PPC::G8RC_NOX0RegClass); BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MovePCtoLR8)); BuildMI(FirstMBB, MBBI, dl, TII.get(PPC::MFLR8), GlobalBaseReg); } diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index 8da5f0563c6a..25a7ca7f59a7 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -2333,7 +2333,7 @@ PPCTargetLowering::LowerFormalArguments_64SVR4( EVT ObjType = (ObjSize == 1 ? MVT::i8 : (ObjSize == 2 ? MVT::i16 : MVT::i32)); Store = DAG.getTruncStore(Val.getValue(1), dl, Val, FIN, - MachinePointerInfo(FuncArg, CurArgOffset), + MachinePointerInfo(FuncArg), ObjType, false, false, 0); } else { // For sizes that don't fit a truncating store (3, 5, 6, 7), @@ -2345,7 +2345,7 @@ PPCTargetLowering::LowerFormalArguments_64SVR4( int FI = MFI->CreateFixedObject(PtrByteSize, ArgOffset, true); SDValue FIN = DAG.getFrameIndex(FI, PtrVT); Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, - MachinePointerInfo(FuncArg, ArgOffset), + MachinePointerInfo(FuncArg), false, false, 0); } @@ -2369,7 +2369,7 @@ PPCTargetLowering::LowerFormalArguments_64SVR4( SDValue FIN = DAG.getFrameIndex(FI, PtrVT); SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT); SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, - MachinePointerInfo(FuncArg, ArgOffset), + MachinePointerInfo(FuncArg, j), false, false, 0); MemOps.push_back(Store); ++GPR_idx; @@ -2665,8 +2665,7 @@ PPCTargetLowering::LowerFormalArguments_Darwin( SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT); EVT ObjType = ObjSize == 1 ? MVT::i8 : MVT::i16; SDValue Store = DAG.getTruncStore(Val.getValue(1), dl, Val, FIN, - MachinePointerInfo(FuncArg, - CurArgOffset), + MachinePointerInfo(FuncArg), ObjType, false, false, 0); MemOps.push_back(Store); ++GPR_idx; @@ -2690,7 +2689,7 @@ PPCTargetLowering::LowerFormalArguments_Darwin( SDValue FIN = DAG.getFrameIndex(FI, PtrVT); SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT); SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, - MachinePointerInfo(FuncArg, ArgOffset), + MachinePointerInfo(FuncArg, j), false, false, 0); MemOps.push_back(Store); ++GPR_idx; diff --git a/lib/Target/PowerPC/PPCInstrInfo.cpp b/lib/Target/PowerPC/PPCInstrInfo.cpp index 315ad04ebe3e..80bc27a95765 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -570,12 +570,14 @@ PPCInstrInfo::StoreRegToStackSlot(MachineFunction &MF, // update isStoreToStackSlot. DebugLoc DL; - if (PPC::GPRCRegClass.hasSubClassEq(RC)) { + if (PPC::GPRCRegClass.hasSubClassEq(RC) || + PPC::GPRC_NOR0RegClass.hasSubClassEq(RC)) { NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STW)) .addReg(SrcReg, getKillRegState(isKill)), FrameIdx)); - } else if (PPC::G8RCRegClass.hasSubClassEq(RC)) { + } else if (PPC::G8RCRegClass.hasSubClassEq(RC) || + PPC::G8RC_NOX0RegClass.hasSubClassEq(RC)) { NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STD)) .addReg(SrcReg, getKillRegState(isKill)), @@ -695,10 +697,12 @@ PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL, // Note: If additional load instructions are added here, // update isLoadFromStackSlot. - if (PPC::GPRCRegClass.hasSubClassEq(RC)) { + if (PPC::GPRCRegClass.hasSubClassEq(RC) || + PPC::GPRC_NOR0RegClass.hasSubClassEq(RC)) { NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LWZ), DestReg), FrameIdx)); - } else if (PPC::G8RCRegClass.hasSubClassEq(RC)) { + } else if (PPC::G8RCRegClass.hasSubClassEq(RC) || + PPC::G8RC_NOX0RegClass.hasSubClassEq(RC)) { NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LD), DestReg), FrameIdx)); } else if (PPC::F8RCRegClass.hasSubClassEq(RC)) { diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td index 2bd3aadc798d..fc29c69642bf 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.td +++ b/lib/Target/PowerPC/PPCInstrInfo.td @@ -580,6 +580,7 @@ def iaddroff : ComplexPattern; def In32BitMode : Predicate<"!PPCSubTarget.isPPC64()">; def In64BitMode : Predicate<"PPCSubTarget.isPPC64()">; def IsBookE : Predicate<"PPCSubTarget.isBookE()">; +def IsNotBookE : Predicate<"!PPCSubTarget.isBookE()">; //===----------------------------------------------------------------------===// // PowerPC Multiclass Definitions. @@ -1541,8 +1542,17 @@ def STMW : DForm_1<47, (outs), (ins gprc:$rS, memri:$dst), "stmw $rS, $dst", LdStLMW, []>; def SYNC : XForm_24_sync<31, 598, (outs), (ins i32imm:$L), - "sync $L", LdStSync, []>; -def : Pat<(int_ppc_sync), (SYNC 0)>; + "sync $L", LdStSync, []>, Requires<[IsNotBookE]>; + +let isCodeGenOnly = 1 in { + def MSYNC : XForm_24_sync<31, 598, (outs), (ins), + "msync", LdStSync, []>, Requires<[IsBookE]> { + let L = 0; + } +} + +def : Pat<(int_ppc_sync), (SYNC 0)>, Requires<[IsNotBookE]>; +def : Pat<(int_ppc_sync), (MSYNC)>, Requires<[IsBookE]>; //===----------------------------------------------------------------------===// // PPC32 Arithmetic Instructions. @@ -2284,7 +2294,8 @@ def : Pat<(f64 (extloadf32 xaddr:$src)), def : Pat<(f64 (fextend f32:$src)), (COPY_TO_REGCLASS $src, F8RC)>; -def : Pat<(atomic_fence (imm), (imm)), (SYNC 0)>; +def : Pat<(atomic_fence (imm), (imm)), (SYNC 0)>, Requires<[IsNotBookE]>; +def : Pat<(atomic_fence (imm), (imm)), (MSYNC)>, Requires<[IsBookE]>; // Additional FNMSUB patterns: -a*c + b == -(a*c - b) def : Pat<(fma (fneg f64:$A), f64:$C, f64:$B), @@ -2373,10 +2384,10 @@ class PPCAsmPseudo def : InstAlias<"sc", (SC 0)>; -def : InstAlias<"sync", (SYNC 0)>; -def : InstAlias<"msync", (SYNC 0)>; -def : InstAlias<"lwsync", (SYNC 1)>; -def : InstAlias<"ptesync", (SYNC 2)>; +def : InstAlias<"sync", (SYNC 0)>, Requires<[IsNotBookE]>; +def : InstAlias<"msync", (SYNC 0)>, Requires<[IsNotBookE]>; +def : InstAlias<"lwsync", (SYNC 1)>, Requires<[IsNotBookE]>; +def : InstAlias<"ptesync", (SYNC 2)>, Requires<[IsNotBookE]>; def : InstAlias<"wait", (WAIT 0)>; def : InstAlias<"waitrsv", (WAIT 1)>; diff --git a/lib/Target/PowerPC/PPCRegisterInfo.td b/lib/Target/PowerPC/PPCRegisterInfo.td index d566e2c3e52d..43663ce013e9 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.td +++ b/lib/Target/PowerPC/PPCRegisterInfo.td @@ -144,6 +144,13 @@ def CR6 : CR<6, "cr6", [CR6LT, CR6GT, CR6EQ, CR6UN]>, DwarfRegNum<[74, 74]>; def CR7 : CR<7, "cr7", [CR7LT, CR7GT, CR7EQ, CR7UN]>, DwarfRegNum<[75, 75]>; } +// The full condition-code register. This is not modeled fully, but defined +// here primarily, for compatibility with gcc, to allow the inline asm "cc" +// clobber specification to work. +def CC : PPCReg<"cc">, DwarfRegAlias { + let Aliases = [CR0, CR1, CR2, CR3, CR4, CR5, CR6, CR7]; +} + // Link register def LR : SPR<8, "lr">, DwarfRegNum<[-2, 65]>; //let Aliases = [LR] in @@ -234,3 +241,8 @@ def VRSAVERC : RegisterClass<"PPC", [i32], 32, (add VRSAVE)>; def CARRYRC : RegisterClass<"PPC", [i32], 32, (add CARRY)> { let CopyCost = -1; } + +def CCRC : RegisterClass<"PPC", [i32], 32, (add CC)> { + let isAllocatable = 0; +} + diff --git a/lib/Target/PowerPC/PPCSubtarget.h b/lib/Target/PowerPC/PPCSubtarget.h index c863a6ecc777..ec8c82ad521c 100644 --- a/lib/Target/PowerPC/PPCSubtarget.h +++ b/lib/Target/PowerPC/PPCSubtarget.h @@ -126,22 +126,6 @@ public: /// selection. const InstrItineraryData &getInstrItineraryData() const { return InstrItins; } - /// getDataLayoutString - Return the pointer size and type alignment - /// properties of this subtarget. - const char *getDataLayoutString() const { - // Note, the alignment values for f64 and i64 on ppc64 in Darwin - // documentation are wrong; these are correct (i.e. "what gcc does"). - if (isPPC64() && isSVR4ABI()) { - if (TargetTriple.getOS() == llvm::Triple::FreeBSD) - return "E-p:64:64-f64:64:64-i64:64:64-v128:128:128-n32:64"; - else - return "E-p:64:64-f64:64:64-i64:64:64-f128:128:128-v128:128:128-n32:64"; - } - - return isPPC64() ? "E-p:64:64-f64:64:64-i64:64:64-f128:64:128-n32:64" - : "E-p:32:32-f64:64:64-i64:64:64-f128:64:128-n32"; - } - /// \brief Reset the features for the PowerPC target. virtual void resetSubtargetFeatures(const MachineFunction *MF); private: diff --git a/lib/Target/PowerPC/PPCTargetMachine.cpp b/lib/Target/PowerPC/PPCTargetMachine.cpp index 9acefe53ce4a..d6767d51f2cc 100644 --- a/lib/Target/PowerPC/PPCTargetMachine.cpp +++ b/lib/Target/PowerPC/PPCTargetMachine.cpp @@ -33,6 +33,43 @@ extern "C" void LLVMInitializePowerPCTarget() { RegisterTargetMachine C(ThePPC64LETarget); } +/// Return the datalayout string of a subtarget. +static std::string getDataLayoutString(const PPCSubtarget &ST) { + const Triple &T = ST.getTargetTriple(); + + // PPC is big endian + std::string Ret = "E"; + + // PPC64 has 64 bit pointers, PPC32 has 32 bit pointers. + if (ST.isPPC64()) + Ret += "-p:64:64"; + else + Ret += "-p:32:32"; + + // Note, the alignment values for f64 and i64 on ppc64 in Darwin + // documentation are wrong; these are correct (i.e. "what gcc does"). + if (ST.isPPC64() || ST.isSVR4ABI()) + Ret += "-f64:64:64-i64:64:64"; + else + Ret += "-f64:32:64"; + + // Set support for 128 floats depending on the ABI. + if (!ST.isPPC64() && ST.isSVR4ABI()) + Ret += "-f128:64:128"; + + // Some ABIs support 128 bit vectors. + if (ST.isPPC64() && ST.isSVR4ABI()) + Ret += "-v128:128:128"; + + // PPC64 has 32 and 64 bit register, PPC32 has only 32 bit ones. + if (ST.isPPC64()) + Ret += "-n32:64"; + else + Ret += "-n32"; + + return Ret; +} + PPCTargetMachine::PPCTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, @@ -41,7 +78,7 @@ PPCTargetMachine::PPCTargetMachine(const Target &T, StringRef TT, bool is64Bit) : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), Subtarget(TT, CPU, FS, is64Bit), - DL(Subtarget.getDataLayoutString()), InstrInfo(*this), + DL(getDataLayoutString(Subtarget)), InstrInfo(*this), FrameLowering(Subtarget), JITInfo(*this, is64Bit), TLInfo(*this), TSInfo(*this), InstrItins(Subtarget.getInstrItineraryData()) { diff --git a/lib/Target/R600/AMDGPUISelLowering.cpp b/lib/Target/R600/AMDGPUISelLowering.cpp index c4d75ffa0d06..1029f306d632 100644 --- a/lib/Target/R600/AMDGPUISelLowering.cpp +++ b/lib/Target/R600/AMDGPUISelLowering.cpp @@ -133,6 +133,8 @@ AMDGPUTargetLowering::AMDGPUTargetLowering(TargetMachine &TM) : setLoadExtAction(ISD::SEXTLOAD, MVT::v4i16, Expand); setLoadExtAction(ISD::ZEXTLOAD, MVT::v4i16, Expand); + setOperationAction(ISD::BR_CC, MVT::i1, Expand); + setOperationAction(ISD::FNEG, MVT::v2f32, Expand); setOperationAction(ISD::FNEG, MVT::v4f32, Expand); diff --git a/lib/Target/R600/AMDGPUInstructions.td b/lib/Target/R600/AMDGPUInstructions.td index 3c5375d84ecf..7acd67313eea 100644 --- a/lib/Target/R600/AMDGPUInstructions.td +++ b/lib/Target/R600/AMDGPUInstructions.td @@ -388,6 +388,11 @@ class SHA256MaPattern : Pat < // Bitfield extract patterns +/* + +XXX: The BFE pattern is not working correctly because the XForm is not being +applied. + def legalshift32 : ImmLeaf =0 && Imm < 32;}]>; def bfemask : PatLeaf <(imm), [{return isMask_32(N->getZExtValue());}], SDNodeXFormgetTargetConstant(CountTrailingOnes_32(N->getZExtValue()), MVT::i32);}]>>; @@ -397,6 +402,8 @@ class BFEPattern : Pat < (BFE $x, $y, $z) >; +*/ + // rotr pattern class ROTRPattern : Pat < (rotr i32:$src0, i32:$src1), diff --git a/lib/Target/R600/MCTargetDesc/AMDGPUMCAsmInfo.cpp b/lib/Target/R600/MCTargetDesc/AMDGPUMCAsmInfo.cpp index 4a8e1b0b2d86..9b26af7bc736 100644 --- a/lib/Target/R600/MCTargetDesc/AMDGPUMCAsmInfo.cpp +++ b/lib/Target/R600/MCTargetDesc/AMDGPUMCAsmInfo.cpp @@ -13,7 +13,6 @@ using namespace llvm; AMDGPUMCAsmInfo::AMDGPUMCAsmInfo(StringRef &TT) : MCAsmInfo() { HasSingleParameterDotFile = false; - WeakDefDirective = 0; //===------------------------------------------------------------------===// HasSubsectionsViaSymbols = true; HasMachoZeroFillDirective = false; @@ -58,7 +57,6 @@ AMDGPUMCAsmInfo::AMDGPUMCAsmInfo(StringRef &TT) : MCAsmInfo() { HasDotTypeDotSizeDirective = false; HasNoDeadStrip = true; WeakRefDirective = ".weakref\t"; - LinkOnceDirective = 0; //===--- Dwarf Emission Directives -----------------------------------===// HasLEB128 = true; SupportsDebugInformation = true; diff --git a/lib/Target/R600/R600ControlFlowFinalizer.cpp b/lib/Target/R600/R600ControlFlowFinalizer.cpp index ac3d8f63d57f..2a8276b2214f 100644 --- a/lib/Target/R600/R600ControlFlowFinalizer.cpp +++ b/lib/Target/R600/R600ControlFlowFinalizer.cpp @@ -356,6 +356,7 @@ public: DEBUG(dbgs() << CfCount << ":"; I->dump();); FetchClauses.push_back(MakeFetchClause(MBB, I)); CfCount++; + LastAlu.back() = 0; continue; } diff --git a/lib/Target/R600/R600InstrInfo.cpp b/lib/Target/R600/R600InstrInfo.cpp index c0827fc1ca40..2eca6cf43271 100644 --- a/lib/Target/R600/R600InstrInfo.cpp +++ b/lib/Target/R600/R600InstrInfo.cpp @@ -716,7 +716,13 @@ R600InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, return false; } - // Get the last instruction in the block. + // Remove successive JUMP + while (I != MBB.begin() && llvm::prior(I)->getOpcode() == AMDGPU::JUMP) { + MachineBasicBlock::iterator PriorI = llvm::prior(I); + if (AllowModify) + I->removeFromParent(); + I = PriorI; + } MachineInstr *LastInst = I; // If there is only one terminator instruction, process it. diff --git a/lib/Target/R600/R600Instructions.td b/lib/Target/R600/R600Instructions.td index 0346e24ab771..74c65daa065c 100644 --- a/lib/Target/R600/R600Instructions.td +++ b/lib/Target/R600/R600Instructions.td @@ -1516,7 +1516,9 @@ let Predicates = [isEGorCayman] in { i32:$src2))], VecALU >; - def : BFEPattern ; +// XXX: This pattern is broken, disabling for now. See comment in +// AMDGPUInstructions.td for more info. +// def : BFEPattern ; def BFI_INT_eg : R600_3OP <0x06, "BFI_INT", [], VecALU>; defm : BFIPatterns ; @@ -1636,7 +1638,6 @@ class R600_LDS_1A lds_op, string name, list pattern> : R600_LDS < let src2 = 0; let src2_rel = 0; - let Defs = [OQAP]; let usesCustomInserter = 1; let LDS_1A = 1; let DisableEncoding = "$dst"; @@ -1672,7 +1673,6 @@ class R600_LDS_1A1D_RET lds_op, string name, list pattern> : let BaseOp = name; let usesCustomInserter = 1; let DisableEncoding = "$dst"; - let Defs = [OQAP]; } class R600_LDS_1A2D lds_op, string name, list pattern> : diff --git a/lib/Target/R600/SIFixSGPRCopies.cpp b/lib/Target/R600/SIFixSGPRCopies.cpp index 3370c7955bc7..f0065ea13c5b 100644 --- a/lib/Target/R600/SIFixSGPRCopies.cpp +++ b/lib/Target/R600/SIFixSGPRCopies.cpp @@ -187,7 +187,7 @@ bool SIFixSGPRCopies::isVGPRToSGPRCopy(const MachineInstr &Copy, DstRC == &AMDGPU::M0RegRegClass) return false; - SrcRC = inferRegClassFromDef(TRI, MRI, SrcReg, SrcSubReg); + SrcRC = TRI->getSubRegClass(MRI.getRegClass(SrcReg), SrcSubReg); return TRI->isSGPRClass(DstRC) && TRI->hasVGPRs(SrcRC); } diff --git a/lib/Target/R600/SIInsertWaits.cpp b/lib/Target/R600/SIInsertWaits.cpp index 7ef662eb65b1..695ec407fdbe 100644 --- a/lib/Target/R600/SIInsertWaits.cpp +++ b/lib/Target/R600/SIInsertWaits.cpp @@ -314,6 +314,12 @@ Counters SIInsertWaits::handleOperands(MachineInstr &MI) { Counters Result = ZeroCounts; + // S_SENDMSG implicitly waits for all outstanding LGKM transfers to finish, + // but we also want to wait for any other outstanding transfers before + // signalling other hardware blocks + if (MI.getOpcode() == AMDGPU::S_SENDMSG) + return LastIssued; + // For each register affected by this // instruction increase the result sequence for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { diff --git a/lib/Target/R600/SIInstrInfo.td b/lib/Target/R600/SIInstrInfo.td index 4cd0daa55c5f..b7879c6eface 100644 --- a/lib/Target/R600/SIInstrInfo.td +++ b/lib/Target/R600/SIInstrInfo.td @@ -290,10 +290,10 @@ multiclass VOP2_64 op, string opName, list pattern, : VOP2_Helper ; multiclass VOP2b_32 op, string opName, list pattern, - string revOp = opName> { + RegisterClass src0_rc, string revOp = opName> { def _e32 : VOP2 < - op, (outs VReg_32:$dst), (ins VSrc_32:$src0, VReg_32:$src1), + op, (outs VReg_32:$dst), (ins src0_rc:$src0, VReg_32:$src1), opName#"_e32 $dst, $src0, $src1", pattern >, VOP , VOP2_REV; @@ -425,26 +425,48 @@ class MTBUF_Store_Helper op, string asm, RegisterClass regClass> : MTBU multiclass MUBUF_Load_Helper op, string asm, RegisterClass regClass> { - let glc = 0, lds = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */, - mayLoad = 1 in { - - let offen = 1, idxen = 0, addr64 = 0, offset = 0 in { - def _OFFEN : MUBUF ; - } - - let offen = 0, idxen = 1, addr64 = 0 in { - def _IDXEN : MUBUF ; - } + let lds = 0, mayLoad = 1 in { + + let addr64 = 0 in { + + let offen = 0, idxen = 0 in { + def _OFFSET : MUBUF ; + } + + let offen = 1, idxen = 0, offset = 0 in { + def _OFFEN : MUBUF ; + } + + let offen = 0, idxen = 1 in { + def _IDXEN : MUBUF ; + } + + let offen = 1, idxen = 1 in { + def _BOTHEN : MUBUF ; + } + } - let offen = 0, idxen = 0, addr64 = 1 in { - def _ADDR64 : MUBUF ; - } + let offen = 0, idxen = 0, addr64 = 1, glc = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */ in { + def _ADDR64 : MUBUF ; + } } } diff --git a/lib/Target/R600/SIInstructions.td b/lib/Target/R600/SIInstructions.td index 76f05eb49655..2ca6a95978b3 100644 --- a/lib/Target/R600/SIInstructions.td +++ b/lib/Target/R600/SIInstructions.td @@ -22,6 +22,8 @@ def InterpSlot : Operand { let PrintMethod = "printInterpSlot"; } +def SendMsgImm : Operand; + def isSI : Predicate<"Subtarget.getGeneration() " ">= AMDGPUSubtarget::SOUTHERN_ISLANDS">; @@ -826,17 +828,25 @@ def S_BARRIER : SOPP <0x0000000a, (ins), "S_BARRIER", def S_WAITCNT : SOPP <0x0000000c, (ins WAIT_FLAG:$simm16), "S_WAITCNT $simm16", [] >; -} // End hasSideEffects //def S_SETHALT : SOPP_ <0x0000000d, "S_SETHALT", []>; //def S_SLEEP : SOPP_ <0x0000000e, "S_SLEEP", []>; //def S_SETPRIO : SOPP_ <0x0000000f, "S_SETPRIO", []>; -//def S_SENDMSG : SOPP_ <0x00000010, "S_SENDMSG", []>; + +let Uses = [EXEC] in { + def S_SENDMSG : SOPP <0x00000010, (ins SendMsgImm:$simm16, M0Reg:$m0), "S_SENDMSG $simm16", + [(int_SI_sendmsg imm:$simm16, M0Reg:$m0)] + > { + let DisableEncoding = "$m0"; + } +} // End Uses = [EXEC] + //def S_SENDMSGHALT : SOPP_ <0x00000011, "S_SENDMSGHALT", []>; //def S_TRAP : SOPP_ <0x00000012, "S_TRAP", []>; //def S_ICACHE_INV : SOPP_ <0x00000013, "S_ICACHE_INV", []>; //def S_INCPERFLEVEL : SOPP_ <0x00000014, "S_INCPERFLEVEL", []>; //def S_DECPERFLEVEL : SOPP_ <0x00000015, "S_DECPERFLEVEL", []>; //def S_TTRACEDATA : SOPP_ <0x00000016, "S_TTRACEDATA", []>; +} // End hasSideEffects def V_CNDMASK_B32_e32 : VOP2 <0x00000000, (outs VReg_32:$dst), (ins VSrc_32:$src0, VReg_32:$src1, VCCReg:$vcc), @@ -979,14 +989,16 @@ defm V_MBCNT_HI_U32_B32 : VOP2_32 <0x00000024, "V_MBCNT_HI_U32_B32", []>; let isCommutable = 1, Defs = [VCC] in { // Carry-out goes to VCC // No patterns so that the scalar instructions are always selected. // The scalar versions will be replaced with vector when needed later. -defm V_ADD_I32 : VOP2b_32 <0x00000025, "V_ADD_I32", []>; -defm V_SUB_I32 : VOP2b_32 <0x00000026, "V_SUB_I32", []>; -defm V_SUBREV_I32 : VOP2b_32 <0x00000027, "V_SUBREV_I32", [], "V_SUB_I32">; +defm V_ADD_I32 : VOP2b_32 <0x00000025, "V_ADD_I32", [], VSrc_32>; +defm V_SUB_I32 : VOP2b_32 <0x00000026, "V_SUB_I32", [], VSrc_32>; +defm V_SUBREV_I32 : VOP2b_32 <0x00000027, "V_SUBREV_I32", [], VSrc_32, + "V_SUB_I32">; let Uses = [VCC] in { // Carry-in comes from VCC -defm V_ADDC_U32 : VOP2b_32 <0x00000028, "V_ADDC_U32", []>; -defm V_SUBB_U32 : VOP2b_32 <0x00000029, "V_SUBB_U32", []>; -defm V_SUBBREV_U32 : VOP2b_32 <0x0000002a, "V_SUBBREV_U32", [], "V_SUBB_U32">; +defm V_ADDC_U32 : VOP2b_32 <0x00000028, "V_ADDC_U32", [], VReg_32>; +defm V_SUBB_U32 : VOP2b_32 <0x00000029, "V_SUBB_U32", [], VReg_32>; +defm V_SUBBREV_U32 : VOP2b_32 <0x0000002a, "V_SUBBREV_U32", [], VReg_32, + "V_SUBB_U32">; } // End Uses = [VCC] } // End isCommutable = 1, Defs = [VCC] @@ -1403,7 +1415,7 @@ def : Pat < /* int_SI_vs_load_input */ def : Pat< (SIload_input i128:$tlst, IMM12bit:$attr_offset, i32:$buf_idx_vgpr), - (BUFFER_LOAD_FORMAT_XYZW_IDXEN $tlst, $buf_idx_vgpr, imm:$attr_offset) + (BUFFER_LOAD_FORMAT_XYZW_IDXEN $tlst, $buf_idx_vgpr, imm:$attr_offset, 0, 0, 0, 0) >; /* int_SI_export */ @@ -1658,16 +1670,30 @@ def : Pat < 0 /* ABS */, 1 /* CLAMP */, 0 /* OMOD */, 0 /* NEG */) >; +/********** ================================ **********/ +/********** Floating point absolute/negative **********/ +/********** ================================ **********/ + +// Manipulate the sign bit directly, as e.g. using the source negation modifier +// in V_ADD_F32_e64 $src, 0, [...] does not result in -0.0 for $src == +0.0, +// breaking the piglit *s-floatBitsToInt-neg* tests + +// TODO: Look into not implementing isFNegFree/isFAbsFree for SI, and possibly +// removing these patterns + +def : Pat < + (fneg (fabs f32:$src)), + (V_OR_B32_e32 $src, (V_MOV_B32_e32 0x80000000)) /* Set sign bit */ +>; + def : Pat < (fabs f32:$src), - (V_ADD_F32_e64 $src, (i32 0 /* SRC1 */), - 1 /* ABS */, 0 /* CLAMP */, 0 /* OMOD */, 0 /* NEG */) + (V_AND_B32_e32 $src, (V_MOV_B32_e32 0x7fffffff)) /* Clear sign bit */ >; def : Pat < (fneg f32:$src), - (V_ADD_F32_e64 $src, (i32 0 /* SRC1 */), - 0 /* ABS */, 0 /* CLAMP */, 0 /* OMOD */, 1 /* NEG */) + (V_XOR_B32_e32 $src, (V_MOV_B32_e32 0x80000000)) /* Toggle sign bit */ >; /********** ================== **********/ @@ -1794,6 +1820,11 @@ def : Pat < (V_CNDMASK_B32_e64 (i32 0), (i32 -1), $src0) >; +def : Pat < + (i32 (zext i1:$src0)), + (V_CNDMASK_B32_e64 (i32 0), (i32 1), $src0) +>; + // 1. Offset as 8bit DWORD immediate def : Pat < (SIload_constant i128:$sbase, IMM8bitDWORD:$offset), @@ -1809,7 +1840,7 @@ def : Pat < // 3. Offset in an 32Bit VGPR def : Pat < (SIload_constant i128:$sbase, i32:$voff), - (BUFFER_LOAD_DWORD_OFFEN $sbase, $voff) + (BUFFER_LOAD_DWORD_OFFEN $sbase, $voff, 0, 0, 0, 0) >; // The multiplication scales from [0,1] to the unsigned integer range @@ -1970,6 +2001,50 @@ defm : MUBUFStore_Pattern ; defm : MUBUFStore_Pattern ; defm : MUBUFStore_Pattern ; +// BUFFER_LOAD_DWORD*, addr64=0 +multiclass MUBUF_Load_Dword { + + def : Pat < + (vt (int_SI_buffer_load_dword i128:$rsrc, i32:$vaddr, i32:$soffset, + imm:$offset, 0, 0, imm:$glc, imm:$slc, + imm:$tfe)), + (offset $rsrc, $vaddr, (as_i16imm $offset), $soffset, (as_i1imm $glc), + (as_i1imm $slc), (as_i1imm $tfe)) + >; + + def : Pat < + (vt (int_SI_buffer_load_dword i128:$rsrc, i32:$vaddr, i32:$soffset, + imm, 1, 0, imm:$glc, imm:$slc, + imm:$tfe)), + (offen $rsrc, $vaddr, $soffset, (as_i1imm $glc), (as_i1imm $slc), + (as_i1imm $tfe)) + >; + + def : Pat < + (vt (int_SI_buffer_load_dword i128:$rsrc, i32:$vaddr, i32:$soffset, + imm:$offset, 0, 1, imm:$glc, imm:$slc, + imm:$tfe)), + (idxen $rsrc, $vaddr, (as_i16imm $offset), $soffset, (as_i1imm $glc), + (as_i1imm $slc), (as_i1imm $tfe)) + >; + + def : Pat < + (vt (int_SI_buffer_load_dword i128:$rsrc, v2i32:$vaddr, i32:$soffset, + imm, 1, 1, imm:$glc, imm:$slc, + imm:$tfe)), + (bothen $rsrc, $vaddr, $soffset, (as_i1imm $glc), (as_i1imm $slc), + (as_i1imm $tfe)) + >; +} + +defm : MUBUF_Load_Dword ; +defm : MUBUF_Load_Dword ; +defm : MUBUF_Load_Dword ; + //===----------------------------------------------------------------------===// // MTBUF Patterns //===----------------------------------------------------------------------===// @@ -2057,6 +2132,11 @@ def : Pat < (EXTRACT_SUBREG $a, sub0) >; +def : Pat < + (i1 (trunc i32:$a)), + (V_CMP_EQ_I32_e64 (V_AND_B32_e32 (i32 1), $a), 1) +>; + // V_ADD_I32_e32/S_ADD_I32 produces carry in VCC/SCC. For the vector // case, the sgpr-copies pass will fix this to use the vector version. def : Pat < diff --git a/lib/Target/R600/SIIntrinsics.td b/lib/Target/R600/SIIntrinsics.td index 7fcc96452114..00e32c03a99e 100644 --- a/lib/Target/R600/SIIntrinsics.td +++ b/lib/Target/R600/SIIntrinsics.td @@ -38,6 +38,22 @@ let TargetPrefix = "SI", isTarget = 1 in { llvm_i32_ty], // tfe(imm) []>; + // Fully-flexible BUFFER_LOAD_DWORD_* except for the ADDR64 bit, which is not exposed + def int_SI_buffer_load_dword : Intrinsic < + [llvm_anyint_ty], // vdata(VGPR), overloaded for types i32, v2i32, v4i32 + [llvm_anyint_ty, // rsrc(SGPR) + llvm_anyint_ty, // vaddr(VGPR) + llvm_i32_ty, // soffset(SGPR) + llvm_i32_ty, // inst_offset(imm) + llvm_i32_ty, // offen(imm) + llvm_i32_ty, // idxen(imm) + llvm_i32_ty, // glc(imm) + llvm_i32_ty, // slc(imm) + llvm_i32_ty], // tfe(imm) + [IntrReadArgMem]>; + + def int_SI_sendmsg : Intrinsic <[], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + class Sample : Intrinsic <[llvm_v4f32_ty], [llvm_anyvector_ty, llvm_v32i8_ty, llvm_anyint_ty, llvm_i32_ty], [IntrNoMem]>; def int_SI_sample : Sample; diff --git a/lib/Target/R600/SILowerControlFlow.cpp b/lib/Target/R600/SILowerControlFlow.cpp index 958763dffc22..ef867d36692d 100644 --- a/lib/Target/R600/SILowerControlFlow.cpp +++ b/lib/Target/R600/SILowerControlFlow.cpp @@ -109,6 +109,23 @@ FunctionPass *llvm::createSILowerControlFlowPass(TargetMachine &tm) { return new SILowerControlFlowPass(tm); } +static bool isDS(unsigned Opcode) { + switch(Opcode) { + default: return false; + case AMDGPU::DS_ADD_U32_RTN: + case AMDGPU::DS_SUB_U32_RTN: + case AMDGPU::DS_WRITE_B32: + case AMDGPU::DS_WRITE_B8: + case AMDGPU::DS_WRITE_B16: + case AMDGPU::DS_READ_B32: + case AMDGPU::DS_READ_I8: + case AMDGPU::DS_READ_U8: + case AMDGPU::DS_READ_I16: + case AMDGPU::DS_READ_U16: + return true; + } +} + bool SILowerControlFlowPass::shouldSkip(MachineBasicBlock *From, MachineBasicBlock *To) { @@ -145,7 +162,9 @@ void SILowerControlFlowPass::SkipIfDead(MachineInstr &MI) { MachineBasicBlock &MBB = *MI.getParent(); DebugLoc DL = MI.getDebugLoc(); - if (!shouldSkip(&MBB, &MBB.getParent()->back())) + if (MBB.getParent()->getInfo()->ShaderType != + ShaderType::PIXEL || + !shouldSkip(&MBB, &MBB.getParent()->back())) return; MachineBasicBlock::iterator Insert = &MI; @@ -296,9 +315,11 @@ void SILowerControlFlowPass::Kill(MachineInstr &MI) { MachineBasicBlock &MBB = *MI.getParent(); DebugLoc DL = MI.getDebugLoc(); - // Kill is only allowed in pixel shaders + // Kill is only allowed in pixel / geometry shaders assert(MBB.getParent()->getInfo()->ShaderType == - ShaderType::PIXEL); + ShaderType::PIXEL || + MBB.getParent()->getInfo()->ShaderType == + ShaderType::GEOMETRY); // Clear this pixel from the exec mask if the operand is negative BuildMI(MBB, &MI, DL, TII->get(AMDGPU::V_CMPX_LE_F32_e32), AMDGPU::VCC) @@ -431,6 +452,11 @@ bool SILowerControlFlowPass::runOnMachineFunction(MachineFunction &MF) { Next = llvm::next(I); MachineInstr &MI = *I; + if (isDS(MI.getOpcode())) { + NeedM0 = true; + NeedWQM = true; + } + switch (MI.getOpcode()) { default: break; case AMDGPU::SI_IF: @@ -491,14 +517,6 @@ bool SILowerControlFlowPass::runOnMachineFunction(MachineFunction &MF) { IndirectDst(MI); break; - case AMDGPU::DS_READ_B32: - NeedWQM = true; - // Fall through - case AMDGPU::DS_WRITE_B32: - case AMDGPU::DS_ADD_U32_RTN: - NeedM0 = true; - break; - case AMDGPU::V_INTERP_P1_F32: case AMDGPU::V_INTERP_P2_F32: case AMDGPU::V_INTERP_MOV_F32: @@ -517,7 +535,7 @@ bool SILowerControlFlowPass::runOnMachineFunction(MachineFunction &MF) { AMDGPU::M0).addImm(0xffffffff); } - if (NeedWQM && MFI->ShaderType != ShaderType::COMPUTE) { + if (NeedWQM && MFI->ShaderType == ShaderType::PIXEL) { MachineBasicBlock &MBB = MF.front(); BuildMI(MBB, MBB.getFirstNonPHI(), DebugLoc(), TII->get(AMDGPU::S_WQM_B64), AMDGPU::EXEC).addReg(AMDGPU::EXEC); diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index bc8f367e9255..22b79b3b2844 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -1181,16 +1181,23 @@ X86AsmParser::CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp, unsigned Scale, SMLoc Start, SMLoc End, unsigned Size, StringRef Identifier, InlineAsmIdentifierInfo &Info){ - if (isa(Disp)) { - // If this is not a VarDecl then assume it is a FuncDecl or some other label - // reference. We need an 'r' constraint here, so we need to create register - // operand to ensure proper matching. Just pick a GPR based on the size of - // a pointer. - if (!Info.IsVarDecl) { - unsigned RegNo = is64BitMode() ? X86::RBX : X86::EBX; - return X86Operand::CreateReg(RegNo, Start, End, /*AddressOf=*/true, - SMLoc(), Identifier, Info.OpDecl); - } + // If this is not a VarDecl then assume it is a FuncDecl or some other label + // reference. We need an 'r' constraint here, so we need to create register + // operand to ensure proper matching. Just pick a GPR based on the size of + // a pointer. + if (isa(Disp) && !Info.IsVarDecl) { + unsigned RegNo = is64BitMode() ? X86::RBX : X86::EBX; + return X86Operand::CreateReg(RegNo, Start, End, /*AddressOf=*/true, + SMLoc(), Identifier, Info.OpDecl); + } + + // We either have a direct symbol reference, or an offset from a symbol. The + // parser always puts the symbol on the LHS, so look there for size + // calculation purposes. + const MCBinaryExpr *BinOp = dyn_cast(Disp); + bool IsSymRef = + isa(BinOp ? BinOp->getLHS() : Disp); + if (IsSymRef) { if (!Size) { Size = Info.Type * 8; // Size is in terms of bits in this context. if (Size) @@ -1312,10 +1319,15 @@ bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) { if (getParser().parsePrimaryExpr(Val, End)) return Error(Tok.getLoc(), "Unexpected identifier!"); } else { - InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo(); - if (ParseIntelIdentifier(Val, Identifier, Info, - /*Unevaluated=*/false, End)) - return true; + // This is a dot operator, not an adjacent identifier. + if (Identifier.find('.') != StringRef::npos) { + return false; + } else { + InlineAsmIdentifierInfo &Info = SM.getIdentifierInfo(); + if (ParseIntelIdentifier(Val, Identifier, Info, + /*Unevaluated=*/false, End)) + return true; + } } SM.onIdentifierExpr(Val, Identifier); UpdateLocLex = false; @@ -1366,7 +1378,7 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start, if (ParseIntelExpression(SM, End)) return 0; - const MCExpr *Disp; + const MCExpr *Disp = 0; if (const MCExpr *Sym = SM.getSym()) { // A symbolic displacement. Disp = Sym; @@ -1374,13 +1386,20 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start, RewriteIntelBracExpression(InstInfo->AsmRewrites, SM.getSymName(), ImmDisp, SM.getImm(), BracLoc, StartInBrac, End); - } else { - // An immediate displacement only. - Disp = MCConstantExpr::Create(SM.getImm(), getContext()); } - // Parse the dot operator (e.g., [ebx].foo.bar). - if (Tok.getString().startswith(".")) { + if (SM.getImm() || !Disp) { + const MCExpr *Imm = MCConstantExpr::Create(SM.getImm(), getContext()); + if (Disp) + Disp = MCBinaryExpr::CreateAdd(Disp, Imm, getContext()); + else + Disp = Imm; // An immediate displacement only. + } + + // Parse struct field access. Intel requires a dot, but MSVC doesn't. MSVC + // will in fact do global lookup the field name inside all global typedefs, + // but we don't emulate that. + if (Tok.getString().find('.') != StringRef::npos) { const MCExpr *NewDisp; if (ParseIntelDotOperator(Disp, NewDisp)) return 0; @@ -1532,8 +1551,10 @@ bool X86AsmParser::ParseIntelDotOperator(const MCExpr *Disp, else return Error(Tok.getLoc(), "Non-constant offsets are not supported!"); - // Drop the '.'. - StringRef DotDispStr = Tok.getString().drop_front(1); + // Drop the optional '.'. + StringRef DotDispStr = Tok.getString(); + if (DotDispStr.startswith(".")) + DotDispStr = DotDispStr.drop_front(1); // .Imm gets lexed as a real. if (Tok.is(AsmToken::Real)) { diff --git a/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c b/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c index c81a85755f82..16ee0d357b77 100644 --- a/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c +++ b/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c @@ -1065,6 +1065,7 @@ static int readSIB(struct InternalInstruction* insn) { switch (base) { case 0x5: + case 0xd: switch (modFromModRM(insn->modRM)) { case 0x0: insn->eaDisplacement = EA_DISP_32; @@ -1072,13 +1073,11 @@ static int readSIB(struct InternalInstruction* insn) { break; case 0x1: insn->eaDisplacement = EA_DISP_8; - insn->sibBase = (insn->addressSize == 4 ? - SIB_BASE_EBP : SIB_BASE_RBP); + insn->sibBase = (SIBBase)(sibBaseBase + base); break; case 0x2: insn->eaDisplacement = EA_DISP_32; - insn->sibBase = (insn->addressSize == 4 ? - SIB_BASE_EBP : SIB_BASE_RBP); + insn->sibBase = (SIBBase)(sibBaseBase + base); break; case 0x3: debug("Cannot have Mod = 0b11 and a SIB byte"); diff --git a/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp b/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp index 3861e1ce290a..8d2b5954ef20 100644 --- a/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp +++ b/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp @@ -65,6 +65,17 @@ X86MCAsmInfoDarwin::X86MCAsmInfoDarwin(const Triple &T) { // Exceptions handling ExceptionsType = ExceptionHandling::DwarfCFI; + + // FIXME: this should not depend on the target OS version, but on the ld64 + // version in use. From at least >= ld64-97.17 (Xcode 3.2.6) the abs-ified + // FDE relocs may be used. + DwarfFDESymbolsUseAbsDiff = T.isMacOSX() && !T.isMacOSXVersionLT(10, 6); + + // old assembler lacks some directives + // FIXME: this should really be a check on the assembler characteristics + // rather than OS version + if (T.isMacOSX() && T.isMacOSXVersionLT(10, 6)) + HasWeakDefCanBeHiddenDirective = false; } X86_64MCAsmInfoDarwin::X86_64MCAsmInfoDarwin(const Triple &Triple) diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp index 12584411509d..1f5f91844f80 100644 --- a/lib/Target/X86/X86AsmPrinter.cpp +++ b/lib/Target/X86/X86AsmPrinter.cpp @@ -393,9 +393,11 @@ bool X86AsmPrinter::printAsmMRegister(const MachineOperand &MO, char Mode, case 'k': // Print SImode register Reg = getX86SubSuperRegister(Reg, MVT::i32); break; - case 'q': // Print DImode register - // FIXME: gcc will actually print e instead of r for 32-bit. - Reg = getX86SubSuperRegister(Reg, MVT::i64); + case 'q': + // Print 64-bit register names if 64-bit integer registers are available. + // Otherwise, print 32-bit register names. + MVT::SimpleValueType Ty = Subtarget->is64Bit() ? MVT::i64 : MVT::i32; + Reg = getX86SubSuperRegister(Reg, Ty); break; } diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 76eeb64650ba..716c146811a1 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -15226,9 +15226,15 @@ X86TargetLowering::EmitVAStartSaveXMMRegsWithCustomInserter( MBB->addSuccessor(EndMBB); } + // Make sure the last operand is EFLAGS, which gets clobbered by the branch + // that was just emitted, but clearly shouldn't be "saved". + assert((MI->getNumOperands() <= 3 || + !MI->getOperand(MI->getNumOperands() - 1).isReg() || + MI->getOperand(MI->getNumOperands() - 1).getReg() == X86::EFLAGS) + && "Expected last argument to be EFLAGS"); unsigned MOVOpc = Subtarget->hasFp256() ? X86::VMOVAPSmr : X86::MOVAPSmr; // In the XMM save block, save all the XMM argument registers. - for (int i = 3, e = MI->getNumOperands(); i != e; ++i) { + for (int i = 3, e = MI->getNumOperands() - 1; i != e; ++i) { int64_t Offset = (i - 3) * 16 + VarArgsFPOffset; MachineMemOperand *MMO = F->getMachineMemOperand( @@ -17577,12 +17583,30 @@ static SDValue CMPEQCombine(SDNode *N, SelectionDAG &DAG, // FIXME: need symbolic constants for these magic numbers. // See X86ATTInstPrinter.cpp:printSSECC(). unsigned x86cc = (cc0 == X86::COND_E) ? 0 : 4; - SDValue OnesOrZeroesF = DAG.getNode(NTOperator, DL, MVT::f32, CMP00, CMP01, + SDValue OnesOrZeroesF = DAG.getNode(NTOperator, DL, CMP00.getValueType(), + CMP00, CMP01, DAG.getConstant(x86cc, MVT::i8)); - SDValue OnesOrZeroesI = DAG.getNode(ISD::BITCAST, DL, MVT::i32, - OnesOrZeroesF); - SDValue ANDed = DAG.getNode(ISD::AND, DL, MVT::i32, OnesOrZeroesI, - DAG.getConstant(1, MVT::i32)); + + MVT IntVT = is64BitFP ? MVT::i64 : MVT::i32; + + if (is64BitFP && !Subtarget->is64Bit()) { + // On a 32-bit target, we cannot bitcast the 64-bit float to a + // 64-bit integer, since that's not a legal type. Since + // OnesOrZeroesF is all ones of all zeroes, we don't need all the + // bits, but can do this little dance to extract the lowest 32 bits + // and work with those going forward. + SDValue Vector64 = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, MVT::v2f64, + OnesOrZeroesF); + SDValue Vector32 = DAG.getNode(ISD::BITCAST, DL, MVT::v4f32, + Vector64); + OnesOrZeroesF = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, + Vector32, DAG.getIntPtrConstant(0)); + IntVT = MVT::i32; + } + + SDValue OnesOrZeroesI = DAG.getNode(ISD::BITCAST, DL, IntVT, OnesOrZeroesF); + SDValue ANDed = DAG.getNode(ISD::AND, DL, IntVT, OnesOrZeroesI, + DAG.getConstant(1, IntVT)); SDValue OneBitOfTruth = DAG.getNode(ISD::TRUNCATE, DL, MVT::i8, ANDed); return OneBitOfTruth; } diff --git a/lib/Target/X86/X86InstrCompiler.td b/lib/Target/X86/X86InstrCompiler.td index 7d10b67bfe6d..5c8840823b16 100644 --- a/lib/Target/X86/X86InstrCompiler.td +++ b/lib/Target/X86/X86InstrCompiler.td @@ -72,7 +72,7 @@ def ADJCALLSTACKUP64 : I<0, Pseudo, (outs), (ins i32imm:$amt1, i32imm:$amt2), // x86-64 va_start lowering magic. -let usesCustomInserter = 1 in { +let usesCustomInserter = 1, Defs = [EFLAGS] in { def VASTART_SAVE_XMM_REGS : I<0, Pseudo, (outs), (ins GR8:$al, @@ -81,7 +81,8 @@ def VASTART_SAVE_XMM_REGS : I<0, Pseudo, "#VASTART_SAVE_XMM_REGS $al, $regsavefi, $offset", [(X86vastart_save_xmm_regs GR8:$al, imm:$regsavefi, - imm:$offset)]>; + imm:$offset), + (implicit EFLAGS)]>; // The VAARG_64 pseudo-instruction takes the address of the va_list, // and places the address of the next argument into a register. diff --git a/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/lib/Transforms/InstCombine/InstCombineVectorOps.cpp index 1e724106991a..30290ee7a799 100644 --- a/lib/Transforms/InstCombine/InstCombineVectorOps.cpp +++ b/lib/Transforms/InstCombine/InstCombineVectorOps.cpp @@ -25,11 +25,13 @@ static bool CheapToScalarize(Value *V, bool isConstant) { if (isConstant) return true; // If all elts are the same, we can extract it and use any of the values. - Constant *Op0 = C->getAggregateElement(0U); - for (unsigned i = 1, e = V->getType()->getVectorNumElements(); i != e; ++i) - if (C->getAggregateElement(i) != Op0) - return false; - return true; + if (Constant *Op0 = C->getAggregateElement(0U)) { + for (unsigned i = 1, e = V->getType()->getVectorNumElements(); i != e; + ++i) + if (C->getAggregateElement(i) != Op0) + return false; + return true; + } } Instruction *I = dyn_cast(V); if (!I) return false; diff --git a/lib/Transforms/Scalar/LoopRerollPass.cpp b/lib/Transforms/Scalar/LoopRerollPass.cpp index 335af81b957a..643bc78f6e58 100644 --- a/lib/Transforms/Scalar/LoopRerollPass.cpp +++ b/lib/Transforms/Scalar/LoopRerollPass.cpp @@ -1088,9 +1088,8 @@ bool LoopReroll::reroll(Instruction *IV, Loop *L, BasicBlock *Header, L, SCEV::FlagAnyWrap)); { // Limit the lifetime of SCEVExpander. SCEVExpander Expander(*SE, "reroll"); - PHINode *NewIV = - cast(Expander.expandCodeFor(H, IV->getType(), - Header->begin())); + Value *NewIV = Expander.expandCodeFor(H, IV->getType(), Header->begin()); + for (DenseSet::iterator J = BaseUseSet.begin(), JE = BaseUseSet.end(); J != JE; ++J) (*J)->replaceUsesOfWith(IV, NewIV); @@ -1101,20 +1100,23 @@ bool LoopReroll::reroll(Instruction *IV, Loop *L, BasicBlock *Header, if (Inc == 1) ICSCEV = SE->getMulExpr(ICSCEV, SE->getConstant(ICSCEV->getType(), Scale)); - Value *IC; - if (isa(ICSCEV)) { - IC = Expander.expandCodeFor(ICSCEV, NewIV->getType(), BI); + // Iteration count SCEV minus 1 + const SCEV *ICMinus1SCEV = + SE->getMinusSCEV(ICSCEV, SE->getConstant(ICSCEV->getType(), 1)); + + Value *ICMinus1; // Iteration count minus 1 + if (isa(ICMinus1SCEV)) { + ICMinus1 = Expander.expandCodeFor(ICMinus1SCEV, NewIV->getType(), BI); } else { BasicBlock *Preheader = L->getLoopPreheader(); if (!Preheader) Preheader = InsertPreheaderForLoop(L, this); - IC = Expander.expandCodeFor(ICSCEV, NewIV->getType(), - Preheader->getTerminator()); + ICMinus1 = Expander.expandCodeFor(ICMinus1SCEV, NewIV->getType(), + Preheader->getTerminator()); } - Value *NewIVNext = NewIV->getIncomingValueForBlock(Header); - Value *Cond = new ICmpInst(BI, CmpInst::ICMP_EQ, NewIVNext, IC, + Value *Cond = new ICmpInst(BI, CmpInst::ICMP_EQ, NewIV, ICMinus1, "exitcond"); BI->setCondition(Cond); diff --git a/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/lib/Transforms/Scalar/LoopStrengthReduce.cpp index eff5268c448a..6133962e42d7 100644 --- a/lib/Transforms/Scalar/LoopStrengthReduce.cpp +++ b/lib/Transforms/Scalar/LoopStrengthReduce.cpp @@ -3390,6 +3390,10 @@ void LSRInstance::GenerateICmpZeroScales(LSRUse &LU, unsigned LUIdx, int64_t NewBaseOffset = (uint64_t)Base.BaseOffset * Factor; if (NewBaseOffset / Factor != Base.BaseOffset) continue; + // If the offset will be truncated at this use, check that it is in bounds. + if (!IntTy->isPointerTy() && + !ConstantInt::isValueValidForType(IntTy, NewBaseOffset)) + continue; // Check that multiplying with the use offset doesn't overflow. int64_t Offset = LU.MinOffset; @@ -3398,6 +3402,10 @@ void LSRInstance::GenerateICmpZeroScales(LSRUse &LU, unsigned LUIdx, Offset = (uint64_t)Offset * Factor; if (Offset / Factor != LU.MinOffset) continue; + // If the offset will be truncated at this use, check that it is in bounds. + if (!IntTy->isPointerTy() && + !ConstantInt::isValueValidForType(IntTy, Offset)) + continue; Formula F = Base; F.BaseOffset = NewBaseOffset; @@ -3432,6 +3440,10 @@ void LSRInstance::GenerateICmpZeroScales(LSRUse &LU, unsigned LUIdx, F.UnfoldedOffset = (uint64_t)F.UnfoldedOffset * Factor; if (F.UnfoldedOffset / Factor != Base.UnfoldedOffset) continue; + // If the offset will be truncated, check that it is in bounds. + if (!IntTy->isPointerTy() && + !ConstantInt::isValueValidForType(IntTy, F.UnfoldedOffset)) + continue; } // If we make it here and it's legal, add it. diff --git a/lib/Transforms/Utils/LCSSA.cpp b/lib/Transforms/Utils/LCSSA.cpp index f15e8d59276b..97e7e5d95783 100644 --- a/lib/Transforms/Utils/LCSSA.cpp +++ b/lib/Transforms/Utils/LCSSA.cpp @@ -32,6 +32,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/IR/Constants.h" @@ -70,6 +71,7 @@ namespace { AU.addRequired(); AU.addRequired(); AU.addPreservedID(LoopSimplifyID); + AU.addPreserved(); AU.addPreserved(); } private: diff --git a/lib/Transforms/Vectorize/LoopVectorize.cpp b/lib/Transforms/Vectorize/LoopVectorize.cpp index 5e758713ed19..f9f6b18940d3 100644 --- a/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -4191,13 +4191,22 @@ bool LoopVectorizationLegality::AddReductionVar(PHINode *Phi, continue; } - // Process instructions only once (termination). + // Process instructions only once (termination). Each reduction cycle + // value must only be used once, except by phi nodes and min/max + // reductions which are represented as a cmp followed by a select. + ReductionInstDesc IgnoredVal(false, 0); if (VisitedInsts.insert(Usr)) { if (isa(Usr)) PHIs.push_back(Usr); else NonPHIs.push_back(Usr); - } + } else if (!isa(Usr) && + ((!isa(Usr) && + !isa(Usr) && + !isa(Usr)) || + !isMinMaxSelectCmpPattern(Usr, IgnoredVal).IsReduction)) + return false; + // Remember that we completed the cycle. if (Usr == Phi) FoundStartPHI = true; diff --git a/test/Analysis/BasicAA/noalias-bugs.ll b/test/Analysis/BasicAA/noalias-bugs.ll new file mode 100644 index 000000000000..c02a302c1950 --- /dev/null +++ b/test/Analysis/BasicAA/noalias-bugs.ll @@ -0,0 +1,33 @@ +; RUN: opt -S -basicaa -dse < %s | FileCheck %s + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target triple = "x86_64-unknown-linux-gnu" + +; We incorrectly returned noalias in the example below for "ptr.64" and +; "either_ptr.64". +; PR18460 + +%nested = type { %nested.i64 } +%nested.i64 = type { i64 } + +define i64 @testcase(%nested * noalias %p1, %nested * noalias %p2, + i32 %a, i32 %b) { + %ptr = getelementptr inbounds %nested* %p1, i64 -1, i32 0 + %ptr.64 = getelementptr inbounds %nested.i64* %ptr, i64 0, i32 0 + %ptr2= getelementptr inbounds %nested* %p2, i64 0, i32 0 + %cmp = icmp ult i32 %a, %b + %either_ptr = select i1 %cmp, %nested.i64* %ptr2, %nested.i64* %ptr + %either_ptr.64 = getelementptr inbounds %nested.i64* %either_ptr, i64 0, i32 0 + +; Because either_ptr.64 and ptr.64 can alias (we used to return noalias) +; elimination of the first store is not valid. + +; CHECK: store i64 2 +; CHECK: load +; CHECK; store i64 1 + + store i64 2, i64* %ptr.64, align 8 + %r = load i64* %either_ptr.64, align 8 + store i64 1, i64* %ptr.64, align 8 + ret i64 %r +} diff --git a/test/Analysis/BasicAA/phi-aa.ll b/test/Analysis/BasicAA/phi-aa.ll index 6aa26c185e0f..74279e1c4c93 100644 --- a/test/Analysis/BasicAA/phi-aa.ll +++ b/test/Analysis/BasicAA/phi-aa.ll @@ -1,10 +1,14 @@ ; RUN: opt < %s -basicaa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + ; rdar://7282591 @X = common global i32 0 @Y = common global i32 0 @Z = common global i32 0 +; CHECK-LABEL: foo ; CHECK: NoAlias: i32* %P, i32* @Z define void @foo(i32 %cond) nounwind { @@ -29,3 +33,46 @@ bb2: return: ret void } + +; Pointers can vary in between iterations of loops. +; PR18068 + +; CHECK-LABEL: pr18068 +; CHECK: MayAlias: i32* %0, i32* %arrayidx5 + +define i32 @pr18068(i32* %jj7, i32* %j) { +entry: + %oa5 = alloca [100 x i32], align 16 + br label %codeRepl + +codeRepl: + %0 = phi i32* [ %arrayidx13, %for.body ], [ %j, %entry ] + %targetBlock = call i1 @cond(i32* %jj7) + br i1 %targetBlock, label %for.body, label %bye + +for.body: + %1 = load i32* %jj7, align 4 + %idxprom4 = zext i32 %1 to i64 + %arrayidx5 = getelementptr inbounds [100 x i32]* %oa5, i64 0, i64 %idxprom4 + %2 = load i32* %arrayidx5, align 4 + %sub6 = sub i32 %2, 6 + store i32 %sub6, i32* %arrayidx5, align 4 + ; %0 and %arrayidx5 can alias! It is not safe to DSE the above store. + %3 = load i32* %0, align 4 + store i32 %3, i32* %arrayidx5, align 4 + %sub11 = add i32 %1, -1 + %idxprom12 = zext i32 %sub11 to i64 + %arrayidx13 = getelementptr inbounds [100 x i32]* %oa5, i64 0, i64 %idxprom12 + call void @inc(i32* %jj7) + br label %codeRepl + +bye: + %.reload = load i32* %jj7, align 4 + ret i32 %.reload +} + +declare i1 @cond(i32*) + +declare void @inc(i32*) + + diff --git a/test/Analysis/ScalarEvolution/zext-signed-addrec.ll b/test/Analysis/ScalarEvolution/zext-signed-addrec.ll new file mode 100644 index 000000000000..27aed3b0da1b --- /dev/null +++ b/test/Analysis/ScalarEvolution/zext-signed-addrec.ll @@ -0,0 +1,81 @@ +; RUN: opt -loop-reduce -S < %s | FileCheck %s +; PR18000 + +target datalayout = "e-i64:64-f80:128-s:64-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@a = global i32 0, align 4 +@b = common global i32 0, align 4 +@e = common global i8 0, align 1 +@d = common global i32 0, align 4 +@c = common global i32 0, align 4 +@.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 + +; Function Attrs: nounwind optsize uwtable +; CHECK-LABEL: foo +define i32 @foo() { +entry: + %.pr = load i32* @b, align 4 + %cmp10 = icmp slt i32 %.pr, 1 + br i1 %cmp10, label %for.cond1.preheader.lr.ph, label %entry.for.end9_crit_edge + +entry.for.end9_crit_edge: ; preds = %entry + %.pre = load i32* @c, align 4 + br label %for.end9 + +for.cond1.preheader.lr.ph: ; preds = %entry + %0 = load i32* @a, align 4 + %tobool = icmp eq i32 %0, 0 + br i1 %tobool, label %for.cond1.preheader.for.cond1.preheader.split_crit_edge, label %return.loopexit.split + +for.cond1.preheader.for.cond1.preheader.split_crit_edge: ; preds = %for.cond1.preheader.lr.ph, %for.inc8 + %1 = phi i32 [ %inc, %for.inc8 ], [ %.pr, %for.cond1.preheader.lr.ph ] + br label %if.end + +; CHECK-LABEL: if.end +if.end: ; preds = %if.end, %for.cond1.preheader.for.cond1.preheader.split_crit_edge + +; CHECK: %lsr.iv = phi i32 [ %lsr.iv.next, %if.end ], [ 258, %for.cond1.preheader.for.cond1.preheader.split_crit_edge ] + %indvars.iv = phi i32 [ 1, %for.cond1.preheader.for.cond1.preheader.split_crit_edge ], [ %indvars.iv.next, %if.end ] + + %2 = phi i8 [ 1, %for.cond1.preheader.for.cond1.preheader.split_crit_edge ], [ %dec, %if.end ] + %conv7 = mul i32 %indvars.iv, 258 + %shl = and i32 %conv7, 510 + store i32 %shl, i32* @c, align 4 + +; CHECK: %lsr.iv.next = add i32 %lsr.iv, -258 + %dec = add i8 %2, -1 + + %cmp2 = icmp sgt i8 %dec, -1 + %indvars.iv.next = add i32 %indvars.iv, -1 + br i1 %cmp2, label %if.end, label %for.inc8 + +for.inc8: ; preds = %if.end + store i32 0, i32* @d, align 4 + %inc = add nsw i32 %1, 1 + store i32 %inc, i32* @b, align 4 + %cmp = icmp slt i32 %1, 0 + br i1 %cmp, label %for.cond1.preheader.for.cond1.preheader.split_crit_edge, label %for.cond.for.end9_crit_edge + +for.cond.for.end9_crit_edge: ; preds = %for.inc8 + store i8 %dec, i8* @e, align 1 + br label %for.end9 + +for.end9: ; preds = %entry.for.end9_crit_edge, %for.cond.for.end9_crit_edge + %3 = phi i32 [ %.pre, %entry.for.end9_crit_edge ], [ %shl, %for.cond.for.end9_crit_edge ] + %call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32 %3) #2 + br label %return + +return.loopexit.split: ; preds = %for.cond1.preheader.lr.ph + store i8 1, i8* @e, align 1 + store i32 0, i32* @d, align 4 + br label %return + +return: ; preds = %return.loopexit.split, %for.end9 + %retval.0 = phi i32 [ 0, %for.end9 ], [ 1, %return.loopexit.split ] + ret i32 %retval.0 +} + +; Function Attrs: nounwind optsize +declare i32 @printf(i8* nocapture readonly, ...) + diff --git a/test/CodeGen/AArch64/atomic-ops.ll b/test/CodeGen/AArch64/atomic-ops.ll index de84ff46ec3b..5857faf80a16 100644 --- a/test/CodeGen/AArch64/atomic-ops.ll +++ b/test/CodeGen/AArch64/atomic-ops.ll @@ -1,4 +1,5 @@ ; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s +; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs < %s | FileCheck --check-prefix=CHECK-REG %s @var8 = global i8 0 @var16 = global i16 0 @@ -17,6 +18,8 @@ define i8 @test_atomic_load_add_i8(i8 %offset) nounwind { ; w0 below is a reasonable guess but could change: it certainly comes into the ; function there. ; CHECK-NEXT: add [[NEW:w[0-9]+]], w[[OLD]], w0 +; CHECK-REG: add w[[NEW:[0-9]+]], w{{[0-9]+}}, w0 +; CHECK-REG-NOT: stlxrb w[[NEW]], w[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stlxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -37,6 +40,8 @@ define i16 @test_atomic_load_add_i16(i16 %offset) nounwind { ; w0 below is a reasonable guess but could change: it certainly comes into the ; function there. ; CHECK-NEXT: add [[NEW:w[0-9]+]], w[[OLD]], w0 +; CHECK-REG: add w[[NEW:[0-9]+]], w{{[0-9]+}}, w0 +; CHECK-REG-NOT: stxrh w[[NEW]], w[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -57,6 +62,8 @@ define i32 @test_atomic_load_add_i32(i32 %offset) nounwind { ; w0 below is a reasonable guess but could change: it certainly comes into the ; function there. ; CHECK-NEXT: add [[NEW:w[0-9]+]], w[[OLD]], w0 +; CHECK-REG: add w[[NEW:[0-9]+]], w{{[0-9]+}}, w0 +; CHECK-REG-NOT: stlxr w[[NEW]], w[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -77,6 +84,8 @@ define i64 @test_atomic_load_add_i64(i64 %offset) nounwind { ; x0 below is a reasonable guess but could change: it certainly comes into the ; function there. ; CHECK-NEXT: add [[NEW:x[0-9]+]], x[[OLD]], x0 +; CHECK-REG: add x[[NEW:[0-9]+]], x{{[0-9]+}}, x0 +; CHECK-REG-NOT: stxr w[[NEW]], x[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -97,6 +106,8 @@ define i8 @test_atomic_load_sub_i8(i8 %offset) nounwind { ; w0 below is a reasonable guess but could change: it certainly comes into the ; function there. ; CHECK-NEXT: sub [[NEW:w[0-9]+]], w[[OLD]], w0 +; CHECK-REG: sub w[[NEW:[0-9]+]], w{{[0-9]+}}, w0 +; CHECK-REG-NOT: stxrb w[[NEW]], w[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -117,6 +128,8 @@ define i16 @test_atomic_load_sub_i16(i16 %offset) nounwind { ; w0 below is a reasonable guess but could change: it certainly comes into the ; function there. ; CHECK-NEXT: sub [[NEW:w[0-9]+]], w[[OLD]], w0 +; CHECK-REG: sub w[[NEW:[0-9]+]], w{{[0-9]+}}, w0 +; CHECK-REG-NOT: stlxrh w[[NEW]], w[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stlxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -137,6 +150,8 @@ define i32 @test_atomic_load_sub_i32(i32 %offset) nounwind { ; w0 below is a reasonable guess but could change: it certainly comes into the ; function there. ; CHECK-NEXT: sub [[NEW:w[0-9]+]], w[[OLD]], w0 +; CHECK-REG: sub w[[NEW:[0-9]+]], w{{[0-9]+}}, w0 +; CHECK-REG-NOT: stxr w[[NEW]], w[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -157,6 +172,8 @@ define i64 @test_atomic_load_sub_i64(i64 %offset) nounwind { ; x0 below is a reasonable guess but could change: it certainly comes into the ; function there. ; CHECK-NEXT: sub [[NEW:x[0-9]+]], x[[OLD]], x0 +; CHECK-REG: sub x[[NEW:[0-9]+]], x{{[0-9]+}}, x0 +; CHECK-REG-NOT: stlxr w[[NEW]], x[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -177,6 +194,8 @@ define i8 @test_atomic_load_and_i8(i8 %offset) nounwind { ; w0 below is a reasonable guess but could change: it certainly comes into the ; function there. ; CHECK-NEXT: and [[NEW:w[0-9]+]], w[[OLD]], w0 +; CHECK-REG: and w[[NEW:[0-9]+]], w{{[0-9]+}}, w0 +; CHECK-REG-NOT: stlxrb w[[NEW]], w[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stlxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -197,6 +216,8 @@ define i16 @test_atomic_load_and_i16(i16 %offset) nounwind { ; w0 below is a reasonable guess but could change: it certainly comes into the ; function there. ; CHECK-NEXT: and [[NEW:w[0-9]+]], w[[OLD]], w0 +; CHECK-REG: and w[[NEW:[0-9]+]], w{{[0-9]+}}, w0 +; CHECK-REG-NOT: stxrh w[[NEW]], w[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -217,6 +238,8 @@ define i32 @test_atomic_load_and_i32(i32 %offset) nounwind { ; w0 below is a reasonable guess but could change: it certainly comes into the ; function there. ; CHECK-NEXT: and [[NEW:w[0-9]+]], w[[OLD]], w0 +; CHECK-REG: and w[[NEW:[0-9]+]], w{{[0-9]+}}, w0 +; CHECK-REG-NOT: stlxr w[[NEW]], w[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -237,6 +260,8 @@ define i64 @test_atomic_load_and_i64(i64 %offset) nounwind { ; x0 below is a reasonable guess but could change: it certainly comes into the ; function there. ; CHECK-NEXT: and [[NEW:x[0-9]+]], x[[OLD]], x0 +; CHECK-REG: and x[[NEW:[0-9]+]], x{{[0-9]+}}, x0 +; CHECK-REG-NOT: stxr w[[NEW]], x[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -257,6 +282,8 @@ define i8 @test_atomic_load_or_i8(i8 %offset) nounwind { ; w0 below is a reasonable guess but could change: it certainly comes into the ; function there. ; CHECK-NEXT: orr [[NEW:w[0-9]+]], w[[OLD]], w0 +; CHECK-REG: orr w[[NEW:[0-9]+]], w{{[0-9]+}}, w0 +; CHECK-REG-NOT: stlxrb w[[NEW]], w[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stlxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -277,6 +304,8 @@ define i16 @test_atomic_load_or_i16(i16 %offset) nounwind { ; w0 below is a reasonable guess but could change: it certainly comes into the ; function there. ; CHECK-NEXT: orr [[NEW:w[0-9]+]], w[[OLD]], w0 +; CHECK-REG: orr w[[NEW:[0-9]+]], w{{[0-9]+}}, w0 +; CHECK-REG-NOT: stxrh w[[NEW]], w[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -297,6 +326,8 @@ define i32 @test_atomic_load_or_i32(i32 %offset) nounwind { ; w0 below is a reasonable guess but could change: it certainly comes into the ; function there. ; CHECK-NEXT: orr [[NEW:w[0-9]+]], w[[OLD]], w0 +; CHECK-REG: orr w[[NEW:[0-9]+]], w{{[0-9]+}}, w0 +; CHECK-REG-NOT: stxr w[[NEW]], w[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -317,6 +348,8 @@ define i64 @test_atomic_load_or_i64(i64 %offset) nounwind { ; x0 below is a reasonable guess but could change: it certainly comes into the ; function there. ; CHECK-NEXT: orr [[NEW:x[0-9]+]], x[[OLD]], x0 +; CHECK-REG: orr x[[NEW:[0-9]+]], x{{[0-9]+}}, x0 +; CHECK-REG-NOT: stlxr w[[NEW]], x[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -337,6 +370,8 @@ define i8 @test_atomic_load_xor_i8(i8 %offset) nounwind { ; w0 below is a reasonable guess but could change: it certainly comes into the ; function there. ; CHECK-NEXT: eor [[NEW:w[0-9]+]], w[[OLD]], w0 +; CHECK-REG: eor w[[NEW:[0-9]+]], w{{[0-9]+}}, w0 +; CHECK-REG-NOT: stxrb w[[NEW]], w[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -357,6 +392,8 @@ define i16 @test_atomic_load_xor_i16(i16 %offset) nounwind { ; w0 below is a reasonable guess but could change: it certainly comes into the ; function there. ; CHECK-NEXT: eor [[NEW:w[0-9]+]], w[[OLD]], w0 +; CHECK-REG: eor w[[NEW:[0-9]+]], w{{[0-9]+}}, w0 +; CHECK-REG-NOT: stxrh w[[NEW]], w[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stlxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -377,6 +414,8 @@ define i32 @test_atomic_load_xor_i32(i32 %offset) nounwind { ; w0 below is a reasonable guess but could change: it certainly comes into the ; function there. ; CHECK-NEXT: eor [[NEW:w[0-9]+]], w[[OLD]], w0 +; CHECK-REG: eor w[[NEW:[0-9]+]], w{{[0-9]+}}, w0 +; CHECK-REG-NOT: stlxr w[[NEW]], w[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -397,6 +436,8 @@ define i64 @test_atomic_load_xor_i64(i64 %offset) nounwind { ; x0 below is a reasonable guess but could change: it certainly comes into the ; function there. ; CHECK-NEXT: eor [[NEW:x[0-9]+]], x[[OLD]], x0 +; CHECK-REG: eor x[[NEW:[0-9]+]], x{{[0-9]+}}, x0 +; CHECK-REG-NOT: stxr w[[NEW]], x[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -416,6 +457,7 @@ define i8 @test_atomic_load_xchg_i8(i8 %offset) nounwind { ; CHECK-NEXT: ldxrb w[[OLD:[0-9]+]], [x[[ADDR]]] ; w0 below is a reasonable guess but could change: it certainly comes into the ; function there. +; CHECK-REG-NOT: stxrb w0, w0, [x{{[0-9]+}}] ; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], w0, [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -435,6 +477,7 @@ define i16 @test_atomic_load_xchg_i16(i16 %offset) nounwind { ; CHECK-NEXT: ldaxrh w[[OLD:[0-9]+]], [x[[ADDR]]] ; w0 below is a reasonable guess but could change: it certainly comes into the ; function there. +; CHECK-REG-NOT: stlxrh w0, w0, [x{{[0-9]+}}] ; CHECK-NEXT: stlxrh [[STATUS:w[0-9]+]], w0, [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -454,6 +497,7 @@ define i32 @test_atomic_load_xchg_i32(i32 %offset) nounwind { ; CHECK-NEXT: ldxr w[[OLD:[0-9]+]], [x[[ADDR]]] ; w0 below is a reasonable guess but could change: it certainly comes into the ; function there. +; CHECK-REG-NOT: stlxr w0, w0, [x{{[0-9]+}}] ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], w0, [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -473,6 +517,7 @@ define i64 @test_atomic_load_xchg_i64(i64 %offset) nounwind { ; CHECK-NEXT: ldaxr x[[OLD:[0-9]+]], [x[[ADDR]]] ; x0 below is a reasonable guess but could change: it certainly comes into the ; function there. +; CHECK-REG-NOT: stxr w0, x0, [x{{[0-9]+}}] ; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], x0, [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -495,6 +540,8 @@ define i8 @test_atomic_load_min_i8(i8 %offset) nounwind { ; function there. ; CHECK-NEXT: cmp w0, w[[OLD]], sxtb ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, gt +; CHECK-REG: csel w[[NEW:[0-9]+]], w{{[0-9]+}}, w0, gt +; CHECK-REG-NOT: stxrb w[[NEW]], w[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -516,6 +563,8 @@ define i16 @test_atomic_load_min_i16(i16 %offset) nounwind { ; function there. ; CHECK-NEXT: cmp w0, w[[OLD]], sxth ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, gt +; CHECK-REG: csel w[[NEW:[0-9]+]], w{{[0-9]+}}, w0, gt +; CHECK-REG-NOT: stlxrh w[[NEW]], w[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stlxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -537,6 +586,8 @@ define i32 @test_atomic_load_min_i32(i32 %offset) nounwind { ; function there. ; CHECK-NEXT: cmp w0, w[[OLD]] ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, gt +; CHECK-REG: csel w[[NEW:[0-9]+]], w{{[0-9]+}}, w0, gt +; CHECK-REG-NOT: stxr w[[NEW]], w[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -558,6 +609,8 @@ define i64 @test_atomic_load_min_i64(i64 %offset) nounwind { ; function there. ; CHECK-NEXT: cmp x0, x[[OLD]] ; CHECK-NEXT: csel [[NEW:x[0-9]+]], x[[OLD]], x0, gt +; CHECK-REG: csel x[[NEW:[0-9]+]], x{{[0-9]+}}, x0, gt +; CHECK-REG-NOT: stlxr w[[NEW]], x[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -579,6 +632,8 @@ define i8 @test_atomic_load_max_i8(i8 %offset) nounwind { ; function there. ; CHECK-NEXT: cmp w0, w[[OLD]], sxtb ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, lt +; CHECK-REG: csel w[[NEW:[0-9]+]], w{{[0-9]+}}, w0, lt +; CHECK-REG-NOT: stlxrb w[[NEW]], w[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stlxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -600,6 +655,8 @@ define i16 @test_atomic_load_max_i16(i16 %offset) nounwind { ; function there. ; CHECK-NEXT: cmp w0, w[[OLD]], sxth ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, lt +; CHECK-REG: csel w[[NEW:[0-9]+]], w{{[0-9]+}}, w0, lt +; CHECK-REG-NOT: stxrh w[[NEW]], w[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -621,6 +678,8 @@ define i32 @test_atomic_load_max_i32(i32 %offset) nounwind { ; function there. ; CHECK-NEXT: cmp w0, w[[OLD]] ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, lt +; CHECK-REG: csel w[[NEW:[0-9]+]], w{{[0-9]+}}, w0, lt +; CHECK-REG-NOT: stlxr w[[NEW]], w[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -642,6 +701,8 @@ define i64 @test_atomic_load_max_i64(i64 %offset) nounwind { ; function there. ; CHECK-NEXT: cmp x0, x[[OLD]] ; CHECK-NEXT: csel [[NEW:x[0-9]+]], x[[OLD]], x0, lt +; CHECK-REG: csel x[[NEW:[0-9]+]], x{{[0-9]+}}, x0, lt +; CHECK-REG-NOT: stlxr w[[NEW]], x[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -663,6 +724,8 @@ define i8 @test_atomic_load_umin_i8(i8 %offset) nounwind { ; function there. ; CHECK-NEXT: cmp w0, w[[OLD]], uxtb ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, hi +; CHECK-REG: csel w[[NEW:[0-9]+]], w{{[0-9]+}}, w0, hi +; CHECK-REG-NOT: stlxr w[[NEW]], w[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -684,6 +747,8 @@ define i16 @test_atomic_load_umin_i16(i16 %offset) nounwind { ; function there. ; CHECK-NEXT: cmp w0, w[[OLD]], uxth ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, hi +; CHECK-REG: csel w[[NEW:[0-9]+]], w{{[0-9]+}}, w0, hi +; CHECK-REG-NOT: stxrh w[[NEW]], w[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -705,6 +770,8 @@ define i32 @test_atomic_load_umin_i32(i32 %offset) nounwind { ; function there. ; CHECK-NEXT: cmp w0, w[[OLD]] ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, hi +; CHECK-REG: csel w[[NEW:[0-9]+]], w{{[0-9]+}}, w0, hi +; CHECK-REG-NOT: stlxr w[[NEW]], w[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -726,6 +793,8 @@ define i64 @test_atomic_load_umin_i64(i64 %offset) nounwind { ; function there. ; CHECK-NEXT: cmp x0, x[[OLD]] ; CHECK-NEXT: csel [[NEW:x[0-9]+]], x[[OLD]], x0, hi +; CHECK-REG: csel x[[NEW:[0-9]+]], x{{[0-9]+}}, x0, hi +; CHECK-REG-NOT: stlxr w[[NEW]], x[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -747,6 +816,8 @@ define i8 @test_atomic_load_umax_i8(i8 %offset) nounwind { ; function there. ; CHECK-NEXT: cmp w0, w[[OLD]], uxtb ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, lo +; CHECK-REG: csel w[[NEW:[0-9]+]], w{{[0-9]+}}, w0, lo +; CHECK-REG-NOT: stlxrb w[[NEW]], w[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stlxrb [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -768,6 +839,8 @@ define i16 @test_atomic_load_umax_i16(i16 %offset) nounwind { ; function there. ; CHECK-NEXT: cmp w0, w[[OLD]], uxth ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, lo +; CHECK-REG: csel w[[NEW:[0-9]+]], w{{[0-9]+}}, w0, lo +; CHECK-REG-NOT: stxrh w[[NEW]], w[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stxrh [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -789,6 +862,8 @@ define i32 @test_atomic_load_umax_i32(i32 %offset) nounwind { ; function there. ; CHECK-NEXT: cmp w0, w[[OLD]] ; CHECK-NEXT: csel [[NEW:w[0-9]+]], w[[OLD]], w0, lo +; CHECK-REG: csel w[[NEW:[0-9]+]], w{{[0-9]+}}, w0, lo +; CHECK-REG-NOT: stlxr w[[NEW]], w[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -810,6 +885,8 @@ define i64 @test_atomic_load_umax_i64(i64 %offset) nounwind { ; function there. ; CHECK-NEXT: cmp x0, x[[OLD]] ; CHECK-NEXT: csel [[NEW:x[0-9]+]], x[[OLD]], x0, lo +; CHECK-REG: csel x[[NEW:[0-9]+]], x{{[0-9]+}}, x0, lo +; CHECK-REG-NOT: stlxr w[[NEW]], x[[NEW]], [x{{[0-9]+}}] ; CHECK-NEXT: stlxr [[STATUS:w[0-9]+]], [[NEW]], [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], .LBB{{[0-9]+}}_1 ; CHECK-NOT: dmb @@ -832,6 +909,7 @@ define i8 @test_atomic_cmpxchg_i8(i8 %wanted, i8 %new) nounwind { ; CHECK-NEXT: cmp w[[OLD]], w0 ; CHECK-NEXT: b.ne [[GET_OUT:.LBB[0-9]+_[0-9]+]] ; As above, w1 is a reasonable guess. +; CHECK-REG-NOT: stxrb w1, w1, [x{{[0-9]+}}] ; CHECK: stxrb [[STATUS:w[0-9]+]], w1, [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], [[STARTAGAIN]] ; CHECK-NOT: dmb @@ -854,6 +932,7 @@ define i16 @test_atomic_cmpxchg_i16(i16 %wanted, i16 %new) nounwind { ; CHECK-NEXT: cmp w[[OLD]], w0 ; CHECK-NEXT: b.ne [[GET_OUT:.LBB[0-9]+_[0-9]+]] ; As above, w1 is a reasonable guess. +; CHECK-REG-NOT: stlxrh w1, w1, [x{{[0-9]+}}] ; CHECK: stlxrh [[STATUS:w[0-9]+]], w1, [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], [[STARTAGAIN]] ; CHECK-NOT: dmb @@ -876,6 +955,7 @@ define i32 @test_atomic_cmpxchg_i32(i32 %wanted, i32 %new) nounwind { ; CHECK-NEXT: cmp w[[OLD]], w0 ; CHECK-NEXT: b.ne [[GET_OUT:.LBB[0-9]+_[0-9]+]] ; As above, w1 is a reasonable guess. +; CHECK-REG-NOT: stlxr w1, w1, [x{{[0-9]+}}] ; CHECK: stlxr [[STATUS:w[0-9]+]], w1, [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], [[STARTAGAIN]] ; CHECK-NOT: dmb @@ -898,6 +978,7 @@ define i64 @test_atomic_cmpxchg_i64(i64 %wanted, i64 %new) nounwind { ; CHECK-NEXT: cmp x[[OLD]], x0 ; CHECK-NEXT: b.ne [[GET_OUT:.LBB[0-9]+_[0-9]+]] ; As above, w1 is a reasonable guess. +; CHECK-REG-NOT: stxr w1, x1, [x{{[0-9]+}}] ; CHECK: stxr [[STATUS:w[0-9]+]], x1, [x[[ADDR]]] ; CHECK-NEXT: cbnz [[STATUS]], [[STARTAGAIN]] ; CHECK-NOT: dmb diff --git a/test/CodeGen/AArch64/init-array.ll b/test/CodeGen/AArch64/init-array.ll index 3ff1c1a86ec6..076ae27721df 100644 --- a/test/CodeGen/AArch64/init-array.ll +++ b/test/CodeGen/AArch64/init-array.ll @@ -1,4 +1,5 @@ ; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs -use-init-array < %s | FileCheck %s +; RUN: llc -mtriple=aarch64-none-none-eabi -verify-machineinstrs -use-init-array < %s | FileCheck %s define internal void @_GLOBAL__I_a() section ".text.startup" { ret void diff --git a/test/CodeGen/AArch64/variadic.ll b/test/CodeGen/AArch64/variadic.ll index f3d376beeb28..4c219eb83788 100644 --- a/test/CodeGen/AArch64/variadic.ll +++ b/test/CodeGen/AArch64/variadic.ll @@ -179,24 +179,19 @@ define void @test_va_copy() { ; Check beginning and end again: -; CHECK: ldr [[BLOCK:x[0-9]+]], [{{x[0-9]+}}, #:lo12:var] ; CHECK: add x[[SRC_LIST:[0-9]+]], {{x[0-9]+}}, #:lo12:var -; CHECK-NOFP: ldr [[BLOCK:x[0-9]+]], [{{x[0-9]+}}, #:lo12:var] -; CHECK-NOFP: add x[[SRC_LIST:[0-9]+]], {{x[0-9]+}}, #:lo12:var - -; CHECK: str [[BLOCK]], [{{x[0-9]+}}, #:lo12:second_list] - -; CHECK: ldr [[BLOCK:x[0-9]+]], [x[[SRC_LIST]], #24] ; CHECK: add x[[DEST_LIST:[0-9]+]], {{x[0-9]+}}, #:lo12:second_list +; CHECK: ldr [[BLOCK1:x[0-9]+]], [{{x[0-9]+}}, #:lo12:var] +; CHECK: ldr [[BLOCK2:x[0-9]+]], [x[[SRC_LIST]], #24] +; CHECK: str [[BLOCK1]], [{{x[0-9]+}}, #:lo12:second_list] +; CHECK: str [[BLOCK2]], [x[[DEST_LIST]], #24] -; CHECK: str [[BLOCK]], [x[[DEST_LIST]], #24] - -; CHECK-NOFP: str [[BLOCK]], [{{x[0-9]+}}, #:lo12:second_list] - -; CHECK-NOFP: ldr [[BLOCK:x[0-9]+]], [x[[SRC_LIST]], #24] +; CHECK-NOFP: add x[[SRC_LIST:[0-9]+]], {{x[0-9]+}}, #:lo12:var ; CHECK-NOFP: add x[[DEST_LIST:[0-9]+]], {{x[0-9]+}}, #:lo12:second_list - -; CHECK-NOFP: str [[BLOCK]], [x[[DEST_LIST]], #24] +; CHECK-NOFP: ldr [[BLOCK1:x[0-9]+]], [{{x[0-9]+}}, #:lo12:var] +; CHECK-NOFP: ldr [[BLOCK2:x[0-9]+]], [x[[SRC_LIST]], #24] +; CHECK-NOFP: str [[BLOCK1]], [{{x[0-9]+}}, #:lo12:second_list] +; CHECK-NOFP: str [[BLOCK2]], [x[[DEST_LIST]], #24] ret void ; CHECK: ret diff --git a/test/CodeGen/ARM/a15-SD-dep.ll b/test/CodeGen/ARM/a15-SD-dep.ll index 019ff6129b00..5e5ca4b873f3 100644 --- a/test/CodeGen/ARM/a15-SD-dep.ll +++ b/test/CodeGen/ARM/a15-SD-dep.ll @@ -56,3 +56,62 @@ define arm_aapcs_vfpcc <4 x float> @t5(<4 x float> %q, float %f) { %i2 = fadd <4 x float> %i1, %i1 ret <4 x float> %i2 } + +; Test that DPair can be successfully passed as QPR. +; CHECK-ENABLED-LABEL: test_DPair1: +; CHECK-DISABLED-LABEL: test_DPair1: +define void @test_DPair1(i32 %vsout, i8* nocapture %out, float %x, float %y) { +entry: + %0 = insertelement <4 x float> undef, float %x, i32 1 + %1 = insertelement <4 x float> %0, float %y, i32 0 + ; CHECK-ENABLED: vdup.32 d{{[0-9]*}}, d{{[0-9]*}}[0] + ; CHECK-ENABLED: vdup.32 d{{[0-9]*}}, d{{[0-9]*}}[1] + ; CHECK-ENABLED: vdup.32 d{{[0-9]*}}, d{{[0-9]*}}[0] + ; CHECK-ENABLED: vdup.32 d{{[0-9]*}}, d{{[0-9]*}}[1] + ; CHECK-DISABLED-NOT: vdup + switch i32 %vsout, label %sw.epilog [ + i32 1, label %sw.bb + i32 0, label %sw.bb6 + ] + +sw.bb: ; preds = %entry + %2 = insertelement <4 x float> %1, float 0.000000e+00, i32 0 + br label %sw.bb6 + +sw.bb6: ; preds = %sw.bb, %entry + %sum.0 = phi <4 x float> [ %1, %entry ], [ %2, %sw.bb ] + %3 = extractelement <4 x float> %sum.0, i32 0 + %conv = fptoui float %3 to i8 + store i8 %conv, i8* %out, align 1 + ret void + +sw.epilog: ; preds = %entry + ret void +} + +; CHECK-ENABLED-LABEL: test_DPair2: +; CHECK-DISABLED-LABEL: test_DPair2: +define void @test_DPair2(i32 %vsout, i8* nocapture %out, float %x) { +entry: + %0 = insertelement <4 x float> undef, float %x, i32 0 + ; CHECK-ENABLED: vdup.32 q{{[0-9]*}}, d{{[0-9]*}}[0] + ; CHECK-DISABLED-NOT: vdup + switch i32 %vsout, label %sw.epilog [ + i32 1, label %sw.bb + i32 0, label %sw.bb1 + ] + +sw.bb: ; preds = %entry + %1 = insertelement <4 x float> %0, float 0.000000e+00, i32 0 + br label %sw.bb1 + +sw.bb1: ; preds = %entry, %sw.bb + %sum.0 = phi <4 x float> [ %0, %entry ], [ %1, %sw.bb ] + %2 = extractelement <4 x float> %sum.0, i32 0 + %conv = fptoui float %2 to i8 + store i8 %conv, i8* %out, align 1 + br label %sw.epilog + +sw.epilog: ; preds = %entry, %sw.bb1 + ret void +} \ No newline at end of file diff --git a/test/CodeGen/ARM/vld3.ll b/test/CodeGen/ARM/vld3.ll index 400541fb90a2..d6eb4c2f6dd3 100644 --- a/test/CodeGen/ARM/vld3.ll +++ b/test/CodeGen/ARM/vld3.ll @@ -83,6 +83,19 @@ define <1 x i64> @vld3i64(i64* %A) nounwind { ret <1 x i64> %tmp4 } +define <1 x i64> @vld3i64_update(i64** %ptr, i64* %A) nounwind { +;CHECK-LABEL: vld3i64_update: +;CHECK: vld1.64 {d16, d17, d18}, [r1:64]! + %tmp0 = bitcast i64* %A to i8* + %tmp1 = call %struct.__neon_int64x1x3_t @llvm.arm.neon.vld3.v1i64(i8* %tmp0, i32 16) + %tmp5 = getelementptr i64* %A, i32 3 + store i64* %tmp5, i64** %ptr + %tmp2 = extractvalue %struct.__neon_int64x1x3_t %tmp1, 0 + %tmp3 = extractvalue %struct.__neon_int64x1x3_t %tmp1, 2 + %tmp4 = add <1 x i64> %tmp2, %tmp3 + ret <1 x i64> %tmp4 +} + define <16 x i8> @vld3Qi8(i8* %A) nounwind { ;CHECK-LABEL: vld3Qi8: ;Check the alignment value. Max for this instruction is 64 bits: diff --git a/test/CodeGen/ARM/vld4.ll b/test/CodeGen/ARM/vld4.ll index f7376b503a30..ff162bb022e1 100644 --- a/test/CodeGen/ARM/vld4.ll +++ b/test/CodeGen/ARM/vld4.ll @@ -83,6 +83,19 @@ define <1 x i64> @vld4i64(i64* %A) nounwind { ret <1 x i64> %tmp4 } +define <1 x i64> @vld4i64_update(i64** %ptr, i64* %A) nounwind { +;CHECK-LABEL: vld4i64_update: +;CHECK: vld1.64 {d16, d17, d18, d19}, [r1:256]! + %tmp0 = bitcast i64* %A to i8* + %tmp1 = call %struct.__neon_int64x1x4_t @llvm.arm.neon.vld4.v1i64(i8* %tmp0, i32 64) + %tmp5 = getelementptr i64* %A, i32 4 + store i64* %tmp5, i64** %ptr + %tmp2 = extractvalue %struct.__neon_int64x1x4_t %tmp1, 0 + %tmp3 = extractvalue %struct.__neon_int64x1x4_t %tmp1, 2 + %tmp4 = add <1 x i64> %tmp2, %tmp3 + ret <1 x i64> %tmp4 +} + define <16 x i8> @vld4Qi8(i8* %A) nounwind { ;CHECK-LABEL: vld4Qi8: ;Check the alignment value. Max for this instruction is 256 bits: diff --git a/test/CodeGen/ARM/vst3.ll b/test/CodeGen/ARM/vst3.ll index 91eb7fce2b74..65625de34573 100644 --- a/test/CodeGen/ARM/vst3.ll +++ b/test/CodeGen/ARM/vst3.ll @@ -61,6 +61,18 @@ define void @vst3i64(i64* %A, <1 x i64>* %B) nounwind { ret void } +define void @vst3i64_update(i64** %ptr, <1 x i64>* %B) nounwind { +;CHECK-LABEL: vst3i64_update +;CHECK: vst1.64 {d{{.*}}, d{{.*}}, d{{.*}}}, [r{{.*}}]! + %A = load i64** %ptr + %tmp0 = bitcast i64* %A to i8* + %tmp1 = load <1 x i64>* %B + call void @llvm.arm.neon.vst3.v1i64(i8* %tmp0, <1 x i64> %tmp1, <1 x i64> %tmp1, <1 x i64> %tmp1, i32 1) + %tmp2 = getelementptr i64* %A, i32 3 + store i64* %tmp2, i64** %ptr + ret void +} + define void @vst3Qi8(i8* %A, <16 x i8>* %B) nounwind { ;CHECK-LABEL: vst3Qi8: ;Check the alignment value. Max for this instruction is 64 bits: diff --git a/test/CodeGen/ARM/vst4.ll b/test/CodeGen/ARM/vst4.ll index ef5c83a57dbb..83a6c7048650 100644 --- a/test/CodeGen/ARM/vst4.ll +++ b/test/CodeGen/ARM/vst4.ll @@ -60,6 +60,18 @@ define void @vst4i64(i64* %A, <1 x i64>* %B) nounwind { ret void } +define void @vst4i64_update(i64** %ptr, <1 x i64>* %B) nounwind { +;CHECK-LABEL: vst4i64_update: +;CHECK: vst1.64 {d16, d17, d18, d19}, [r1]! + %A = load i64** %ptr + %tmp0 = bitcast i64* %A to i8* + %tmp1 = load <1 x i64>* %B + call void @llvm.arm.neon.vst4.v1i64(i8* %tmp0, <1 x i64> %tmp1, <1 x i64> %tmp1, <1 x i64> %tmp1, <1 x i64> %tmp1, i32 1) + %tmp2 = getelementptr i64* %A, i32 4 + store i64* %tmp2, i64** %ptr + ret void +} + define void @vst4Qi8(i8* %A, <16 x i8>* %B) nounwind { ;CHECK-LABEL: vst4Qi8: ;Check the alignment value. Max for this instruction is 256 bits: diff --git a/test/CodeGen/PowerPC/anon_aggr.ll b/test/CodeGen/PowerPC/anon_aggr.ll index 1525e05501ee..ce07d8845ddb 100644 --- a/test/CodeGen/PowerPC/anon_aggr.ll +++ b/test/CodeGen/PowerPC/anon_aggr.ll @@ -119,9 +119,9 @@ unequal: ; CHECK: ld 3, -[[OFFSET1]](1) ; DARWIN32: _func3: -; DARWIN32: addi r[[REG1:[0-9]+]], r[[REGSP:[0-9]+]], 40 +; DARWIN32: addi r[[REG1:[0-9]+]], r[[REGSP:[0-9]+]], 36 ; DARWIN32: addi r[[REG2:[0-9]+]], r[[REGSP]], 24 -; DARWIN32: lwz r[[REG3:[0-9]+]], 48(r[[REGSP]]) +; DARWIN32: lwz r[[REG3:[0-9]+]], 44(r[[REGSP]]) ; DARWIN32: lwz r[[REG4:[0-9]+]], 32(r[[REGSP]]) ; DARWIN32: cmplw cr{{[0-9]+}}, r[[REG4]], r[[REG3]] ; DARWIN32: stw r[[REG3]], -[[OFFSET1:[0-9]+]] diff --git a/test/CodeGen/PowerPC/byval-agg-info.ll b/test/CodeGen/PowerPC/byval-agg-info.ll new file mode 100644 index 000000000000..89ad8e4dcf98 --- /dev/null +++ b/test/CodeGen/PowerPC/byval-agg-info.ll @@ -0,0 +1,17 @@ +; RUN: llc < %s -print-after=prologepilog >%t 2>&1 && FileCheck <%t %s +target datalayout = "E-m:e-i64:64-n32:64" +target triple = "powerpc64-unknown-linux-gnu" + +%struct.anon = type { i32, i32 } + +declare void @foo(%struct.anon* %v) +define void @test(i32 %a, i32 %b, %struct.anon* byval nocapture %v) { +entry: + call void @foo(%struct.anon* %v) + ret void +} + +; Make sure that the MMO on the store has no offset from the byval +; variable itself (we used to have mem:ST8[%v+64]). +; CHECK: STD %X5, 176, %X1; mem:ST8[%v](align=16) + diff --git a/test/CodeGen/PowerPC/cc.ll b/test/CodeGen/PowerPC/cc.ll new file mode 100644 index 000000000000..ab724f5a7e2d --- /dev/null +++ b/test/CodeGen/PowerPC/cc.ll @@ -0,0 +1,70 @@ +; RUN: llc -mcpu=pwr7 < %s | FileCheck %s +target datalayout = "E-m:e-i64:64-n32:64" +target triple = "powerpc64-unknown-linux-gnu" + +define i64 @test1(i64 %a, i64 %b) { +entry: + %c = icmp eq i64 %a, %b + br label %foo + +foo: + call { i64, i64 } asm sideeffect "sc", "={r0},={r3},{r0},~{cr0},~{cr1},~{cr2},~{cr3},~{cr4},~{cr5},~{cr6},~{cr7}" (i64 %a) + br i1 %c, label %bar, label %end + +bar: + ret i64 %b + +end: + ret i64 %a + +; CHECK-LABEL: @test1 +; CHECK: mfcr [[REG1:[0-9]+]] +; CHECK-DAG: cmpld +; CHECK-DAG: mfocrf [[REG2:[0-9]+]], +; CHECK-DAG: stw [[REG1]], 8(1) +; CHECK-DAG: stw [[REG2]], -4(1) + +; CHECK: sc +; CHECK: lwz [[REG3:[0-9]+]], -4(1) +; CHECK: mtocrf 128, [[REG3]] + +; CHECK: lwz [[REG4:[0-9]+]], 8(1) +; CHECK-DAG: mtocrf 32, [[REG4]] +; CHECK-DAG: mtocrf 16, [[REG4]] +; CHECK-DAG: mtocrf 8, [[REG4]] +; CHECK: blr +} + +define i64 @test2(i64 %a, i64 %b) { +entry: + %c = icmp eq i64 %a, %b + br label %foo + +foo: + call { i64, i64 } asm sideeffect "sc", "={r0},={r3},{r0},~{cc}" (i64 %a) + br i1 %c, label %bar, label %end + +bar: + ret i64 %b + +end: + ret i64 %a + +; CHECK-LABEL: @test2 +; CHECK: mfcr [[REG1:[0-9]+]] +; CHECK-DAG: cmpld +; CHECK-DAG: mfocrf [[REG2:[0-9]+]], +; CHECK-DAG: stw [[REG1]], 8(1) +; CHECK-DAG: stw [[REG2]], -4(1) + +; CHECK: sc +; CHECK: lwz [[REG3:[0-9]+]], -4(1) +; CHECK: mtocrf 128, [[REG3]] + +; CHECK: lwz [[REG4:[0-9]+]], 8(1) +; CHECK-DAG: mtocrf 32, [[REG4]] +; CHECK-DAG: mtocrf 16, [[REG4]] +; CHECK-DAG: mtocrf 8, [[REG4]] +; CHECK: blr +} + diff --git a/test/CodeGen/PowerPC/ctrloop-udivti3.ll b/test/CodeGen/PowerPC/ctrloop-udivti3.ll new file mode 100644 index 000000000000..d07a11fe60fb --- /dev/null +++ b/test/CodeGen/PowerPC/ctrloop-udivti3.ll @@ -0,0 +1,31 @@ +; RUN: llc < %s -march=ppc64 | FileCheck %s +target datalayout = "E-m:e-i64:64-n32:64" +target triple = "powerpc64-unknown-linux-gnu" + +; Function Attrs: nounwind +define hidden void @_mpd_shortdiv(i64 %n) #0 { +entry: + br i1 undef, label %for.end, label %for.body.lr.ph + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body, %for.body.lr.ph + %i.018.in = phi i64 [ %n, %for.body.lr.ph ], [ %i.018, %for.body ] + %i.018 = add i64 %i.018.in, -1 + %add.i = or i128 undef, undef + %div.i = udiv i128 %add.i, 0 + %conv3.i11 = trunc i128 %div.i to i64 + store i64 %conv3.i11, i64* undef, align 8 + %cmp = icmp eq i64 %i.018, 0 + br i1 %cmp, label %for.end, label %for.body + +for.end: ; preds = %for.body, %entry + ret void +} + +; CHECK-LABEL: @_mpd_shortdiv +; CHECK-NOT: mtctr + +attributes #0 = { nounwind } + diff --git a/test/CodeGen/PowerPC/fast-isel-conversion-p5.ll b/test/CodeGen/PowerPC/fast-isel-conversion-p5.ll new file mode 100644 index 000000000000..db0d8ed0ffa4 --- /dev/null +++ b/test/CodeGen/PowerPC/fast-isel-conversion-p5.ll @@ -0,0 +1,153 @@ +; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr5 | FileCheck %s --check-prefix=ELF64 + +; Test sitofp + +define void @sitofp_double_i32(i32 %a, double %b) nounwind ssp { +entry: +; ELF64: sitofp_double_i32 + %b.addr = alloca double, align 8 + %conv = sitofp i32 %a to double +; ELF64: std {{[0-9]+}}, -[[OFFSET:[0-9]+]](1) +; ELF64: lfd {{[0-9]+}}, -[[OFFSET]](1) +; ELF64: fcfid + store double %conv, double* %b.addr, align 8 + ret void +} + +define void @sitofp_double_i64(i64 %a, double %b) nounwind ssp { +entry: +; ELF64: sitofp_double_i64 + %b.addr = alloca double, align 8 + %conv = sitofp i64 %a to double +; ELF64: std {{[0-9]+}}, -[[OFFSET:[0-9]+]](1) +; ELF64: lfd {{[0-9]+}}, -[[OFFSET]](1) +; ELF64: fcfid + store double %conv, double* %b.addr, align 8 + ret void +} + +define void @sitofp_double_i16(i16 %a, double %b) nounwind ssp { +entry: +; ELF64: sitofp_double_i16 + %b.addr = alloca double, align 8 + %conv = sitofp i16 %a to double +; ELF64: extsh +; ELF64: std {{[0-9]+}}, -[[OFFSET:[0-9]+]](1) +; ELF64: lfd {{[0-9]+}}, -[[OFFSET]](1) +; ELF64: fcfid + store double %conv, double* %b.addr, align 8 + ret void +} + +define void @sitofp_double_i8(i8 %a, double %b) nounwind ssp { +entry: +; ELF64: sitofp_double_i8 + %b.addr = alloca double, align 8 + %conv = sitofp i8 %a to double +; ELF64: extsb +; ELF64: std {{[0-9]+}}, -[[OFFSET:[0-9]+]](1) +; ELF64: lfd {{[0-9]+}}, -[[OFFSET]](1) +; ELF64: fcfid + store double %conv, double* %b.addr, align 8 + ret void +} + +; Test fptosi + +define void @fptosi_float_i32(float %a) nounwind ssp { +entry: +; ELF64: fptosi_float_i32 + %b.addr = alloca i32, align 4 + %conv = fptosi float %a to i32 +; ELF64: fctiwz +; ELF64: stfd +; ELF64: lwa + store i32 %conv, i32* %b.addr, align 4 + ret void +} + +define void @fptosi_float_i64(float %a) nounwind ssp { +entry: +; ELF64: fptosi_float_i64 + %b.addr = alloca i64, align 4 + %conv = fptosi float %a to i64 +; ELF64: fctidz +; ELF64: stfd +; ELF64: ld + store i64 %conv, i64* %b.addr, align 4 + ret void +} + +define void @fptosi_double_i32(double %a) nounwind ssp { +entry: +; ELF64: fptosi_double_i32 + %b.addr = alloca i32, align 8 + %conv = fptosi double %a to i32 +; ELF64: fctiwz +; ELF64: stfd +; ELF64: lwa + store i32 %conv, i32* %b.addr, align 8 + ret void +} + +define void @fptosi_double_i64(double %a) nounwind ssp { +entry: +; ELF64: fptosi_double_i64 + %b.addr = alloca i64, align 8 + %conv = fptosi double %a to i64 +; ELF64: fctidz +; ELF64: stfd +; ELF64: ld + store i64 %conv, i64* %b.addr, align 8 + ret void +} + +; Test fptoui + +define void @fptoui_float_i32(float %a) nounwind ssp { +entry: +; ELF64: fptoui_float_i32 + %b.addr = alloca i32, align 4 + %conv = fptoui float %a to i32 +; ELF64: fctidz +; ELF64: stfd +; ELF64: lwz + store i32 %conv, i32* %b.addr, align 4 + ret void +} + +define void @fptoui_float_i64(float %a) nounwind ssp { +entry: +; ELF64: fptoui_float_i64 + %b.addr = alloca i64, align 4 + %conv = fptoui float %a to i64 +; ELF64: fctiduz +; ELF64: stfd +; ELF64: ld + store i64 %conv, i64* %b.addr, align 4 + ret void +} + +define void @fptoui_double_i32(double %a) nounwind ssp { +entry: +; ELF64: fptoui_double_i32 + %b.addr = alloca i32, align 8 + %conv = fptoui double %a to i32 +; ELF64: fctidz +; ELF64: stfd +; ELF64: lwz + store i32 %conv, i32* %b.addr, align 8 + ret void +} + +define void @fptoui_double_i64(double %a) nounwind ssp { +entry: +; ELF64: fptoui_double_i64 + %b.addr = alloca i64, align 8 + %conv = fptoui double %a to i64 +; ELF64: fctiduz +; ELF64: stfd +; ELF64: ld + store i64 %conv, i64* %b.addr, align 8 + ret void +} diff --git a/test/CodeGen/PowerPC/spill-nor0.ll b/test/CodeGen/PowerPC/spill-nor0.ll new file mode 100644 index 000000000000..65bdc0914350 --- /dev/null +++ b/test/CodeGen/PowerPC/spill-nor0.ll @@ -0,0 +1,23 @@ +; RUN: llc < %s -O0 -mcpu=ppc64 | FileCheck %s +target datalayout = "E-m:e-i64:64-n32:64" +target triple = "powerpc64-unknown-linux-gnu" + +; Function Attrs: nounwind +define void @_ZN4llvm3sys17RunningOnValgrindEv() #0 { +entry: + br i1 undef, label %if.then, label %if.end + +if.then: ; preds = %entry + ret void + +if.end: ; preds = %entry + %0 = call i64 asm sideeffect "mr 3,$1\0A\09mr 4,$2\0A\09rotldi 0,0,3 ; rotldi 0,0,13\0A\09rotldi 0,0,61 ; rotldi 0,0,51\0A\09or 1,1,1\0A\09mr $0,3", "=b,b,b,~{cc},~{memory},~{r3},~{r4}"(i32 0, i64* undef) #0 + unreachable + +; CHECK-LABEL: @_ZN4llvm3sys17RunningOnValgrindEv +; CHECK: stw +; CHECK: lwz +} + +attributes #0 = { nounwind } + diff --git a/test/CodeGen/PowerPC/weak_def_can_be_hidden.ll b/test/CodeGen/PowerPC/weak_def_can_be_hidden.ll new file mode 100644 index 000000000000..130d8faaf8bc --- /dev/null +++ b/test/CodeGen/PowerPC/weak_def_can_be_hidden.ll @@ -0,0 +1,38 @@ +; taken from X86 version of the same test +; RUN: llc -mtriple=powerpc-apple-darwin10 -O0 < %s | FileCheck %s +; RUN: llc -mtriple=powerpc-apple-darwin9 -O0 < %s | FileCheck --check-prefix=CHECK-D89 %s +; RUN: llc -mtriple=powerpc-apple-darwin8 -O0 < %s | FileCheck --check-prefix=CHECK-D89 %s + +@v1 = linkonce_odr global i32 32 +; CHECK: .globl _v1 +; CHECK: .weak_def_can_be_hidden _v1 + +; CHECK-D89: .globl _v1 +; CHECK-D89: .weak_definition _v1 + +define i32 @f1() { + %x = load i32 * @v1 + ret i32 %x +} + +@v2 = linkonce_odr global i32 32 +; CHECK: .globl _v2 +; CHECK: .weak_definition _v2 + +; CHECK-D89: .globl _v2 +; CHECK-D89: .weak_definition _v2 + +@v3 = linkonce_odr unnamed_addr global i32 32 +; CHECK: .globl _v3 +; CHECK: .weak_def_can_be_hidden _v3 + +; CHECK-D89: .globl _v3 +; CHECK-D89: .weak_definition _v3 + +define i32* @f2() { + ret i32* @v2 +} + +define i32* @f3() { + ret i32* @v3 +} diff --git a/test/CodeGen/R600/bfe_uint.ll b/test/CodeGen/R600/bfe_uint.ll index 92570c315299..fe466e6ad5fd 100644 --- a/test/CodeGen/R600/bfe_uint.ll +++ b/test/CodeGen/R600/bfe_uint.ll @@ -1,5 +1,7 @@ ; RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s +; XFAIL: * + ; CHECK: @bfe_def ; CHECK: BFE_UINT define void @bfe_def(i32 addrspace(1)* %out, i32 %x) { diff --git a/test/CodeGen/R600/fabs.ll b/test/CodeGen/R600/fabs.ll index a5f5df96b5d9..2cd3a4f604f2 100644 --- a/test/CodeGen/R600/fabs.ll +++ b/test/CodeGen/R600/fabs.ll @@ -9,7 +9,7 @@ ; R600-CHECK-NOT: AND ; R600-CHECK: |PV.{{[XYZW]}}| ; SI-CHECK-LABEL: @fabs_free -; SI-CHECK: V_ADD_F32_e64 v{{[0-9]}}, s{{[0-9]}}, 0, 1, 0, 0, 0 +; SI-CHECK: V_AND_B32 define void @fabs_free(float addrspace(1)* %out, i32 %in) { entry: @@ -23,8 +23,8 @@ entry: ; R600-CHECK: |{{(PV|T[0-9])\.[XYZW]}}| ; R600-CHECK: |{{(PV|T[0-9])\.[XYZW]}}| ; SI-CHECK-LABEL: @fabs_v2 -; SI-CHECK: V_ADD_F32_e64 v{{[0-9]}}, s{{[0-9]}}, 0, 1, 0, 0, 0 -; SI-CHECK: V_ADD_F32_e64 v{{[0-9]}}, s{{[0-9]}}, 0, 1, 0, 0, 0 +; SI-CHECK: V_AND_B32 +; SI-CHECK: V_AND_B32 define void @fabs_v2(<2 x float> addrspace(1)* %out, <2 x float> %in) { entry: %0 = call <2 x float> @llvm.fabs.v2f32(<2 x float> %in) @@ -38,10 +38,10 @@ entry: ; R600-CHECK: |{{(PV|T[0-9])\.[XYZW]}}| ; R600-CHECK: |{{(PV|T[0-9])\.[XYZW]}}| ; SI-CHECK-LABEL: @fabs_v4 -; SI-CHECK: V_ADD_F32_e64 v{{[0-9]}}, s{{[0-9]}}, 0, 1, 0, 0, 0 -; SI-CHECK: V_ADD_F32_e64 v{{[0-9]}}, s{{[0-9]}}, 0, 1, 0, 0, 0 -; SI-CHECK: V_ADD_F32_e64 v{{[0-9]}}, s{{[0-9]}}, 0, 1, 0, 0, 0 -; SI-CHECK: V_ADD_F32_e64 v{{[0-9]}}, s{{[0-9]}}, 0, 1, 0, 0, 0 +; SI-CHECK: V_AND_B32 +; SI-CHECK: V_AND_B32 +; SI-CHECK: V_AND_B32 +; SI-CHECK: V_AND_B32 define void @fabs_v4(<4 x float> addrspace(1)* %out, <4 x float> %in) { entry: %0 = call <4 x float> @llvm.fabs.v4f32(<4 x float> %in) diff --git a/test/CodeGen/R600/fneg-fabs.ll b/test/CodeGen/R600/fneg-fabs.ll new file mode 100644 index 000000000000..d95e1311bc10 --- /dev/null +++ b/test/CodeGen/R600/fneg-fabs.ll @@ -0,0 +1,55 @@ +; RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s --check-prefix=R600-CHECK +; RUN: llc < %s -march=r600 -mcpu=SI -verify-machineinstrs | FileCheck %s --check-prefix=SI-CHECK + +; DAGCombiner will transform: +; (fabs (f32 bitcast (i32 a))) => (f32 bitcast (and (i32 a), 0x7FFFFFFF)) +; unless isFabsFree returns true + +; R600-CHECK-LABEL: @fneg_fabs_free +; R600-CHECK-NOT: AND +; R600-CHECK: |PV.{{[XYZW]}}| +; R600-CHECK: -PV +; SI-CHECK-LABEL: @fneg_fabs_free +; SI-CHECK: V_OR_B32 + +define void @fneg_fabs_free(float addrspace(1)* %out, i32 %in) { +entry: + %0 = bitcast i32 %in to float + %1 = call float @fabs(float %0) + %2 = fsub float -0.000000e+00, %1 + store float %2, float addrspace(1)* %out + ret void +} + +; R600-CHECK-LABEL: @fneg_fabs_v2 +; R600-CHECK: |{{(PV|T[0-9])\.[XYZW]}}| +; R600-CHECK: -PV +; R600-CHECK: |{{(PV|T[0-9])\.[XYZW]}}| +; R600-CHECK: -PV +; SI-CHECK-LABEL: @fneg_fabs_v2 +; SI-CHECK: V_OR_B32 +; SI-CHECK: V_OR_B32 +define void @fneg_fabs_v2(<2 x float> addrspace(1)* %out, <2 x float> %in) { +entry: + %0 = call <2 x float> @llvm.fabs.v2f32(<2 x float> %in) + %1 = fsub <2 x float> , %0 + store <2 x float> %1, <2 x float> addrspace(1)* %out + ret void +} + +; SI-CHECK-LABEL: @fneg_fabs_v4 +; SI-CHECK: V_OR_B32 +; SI-CHECK: V_OR_B32 +; SI-CHECK: V_OR_B32 +; SI-CHECK: V_OR_B32 +define void @fneg_fabs_v4(<4 x float> addrspace(1)* %out, <4 x float> %in) { +entry: + %0 = call <4 x float> @llvm.fabs.v4f32(<4 x float> %in) + %1 = fsub <4 x float> , %0 + store <4 x float> %1, <4 x float> addrspace(1)* %out + ret void +} + +declare float @fabs(float ) readnone +declare <2 x float> @llvm.fabs.v2f32(<2 x float> ) readnone +declare <4 x float> @llvm.fabs.v4f32(<4 x float> ) readnone diff --git a/test/CodeGen/R600/fneg.ll b/test/CodeGen/R600/fneg.ll index 9446aa8ea9c3..f4e6be62467a 100644 --- a/test/CodeGen/R600/fneg.ll +++ b/test/CodeGen/R600/fneg.ll @@ -4,7 +4,7 @@ ; R600-CHECK-LABEL: @fneg ; R600-CHECK: -PV ; SI-CHECK-LABEL: @fneg -; SI-CHECK: V_ADD_F32_e64 v{{[0-9]}}, s{{[0-9]}}, 0, 0, 0, 0, 1 +; SI-CHECK: V_XOR_B32 define void @fneg(float addrspace(1)* %out, float %in) { entry: %0 = fsub float -0.000000e+00, %in @@ -16,8 +16,8 @@ entry: ; R600-CHECK: -PV ; R600-CHECK: -PV ; SI-CHECK-LABEL: @fneg_v2 -; SI-CHECK: V_ADD_F32_e64 v{{[0-9]}}, s{{[0-9]}}, 0, 0, 0, 0, 1 -; SI-CHECK: V_ADD_F32_e64 v{{[0-9]}}, s{{[0-9]}}, 0, 0, 0, 0, 1 +; SI-CHECK: V_XOR_B32 +; SI-CHECK: V_XOR_B32 define void @fneg_v2(<2 x float> addrspace(1)* nocapture %out, <2 x float> %in) { entry: %0 = fsub <2 x float> , %in @@ -31,10 +31,10 @@ entry: ; R600-CHECK: -PV ; R600-CHECK: -PV ; SI-CHECK-LABEL: @fneg_v4 -; SI-CHECK: V_ADD_F32_e64 v{{[0-9]}}, s{{[0-9]}}, 0, 0, 0, 0, 1 -; SI-CHECK: V_ADD_F32_e64 v{{[0-9]}}, s{{[0-9]}}, 0, 0, 0, 0, 1 -; SI-CHECK: V_ADD_F32_e64 v{{[0-9]}}, s{{[0-9]}}, 0, 0, 0, 0, 1 -; SI-CHECK: V_ADD_F32_e64 v{{[0-9]}}, s{{[0-9]}}, 0, 0, 0, 0, 1 +; SI-CHECK: V_XOR_B32 +; SI-CHECK: V_XOR_B32 +; SI-CHECK: V_XOR_B32 +; SI-CHECK: V_XOR_B32 define void @fneg_v4(<4 x float> addrspace(1)* nocapture %out, <4 x float> %in) { entry: %0 = fsub <4 x float> , %in diff --git a/test/CodeGen/R600/lds-oqap-crash.ll b/test/CodeGen/R600/lds-oqap-crash.ll new file mode 100644 index 000000000000..79591506e8cb --- /dev/null +++ b/test/CodeGen/R600/lds-oqap-crash.ll @@ -0,0 +1,28 @@ +; RUN: llc < %s -march=r600 -mcpu=redwood -verify-machineinstrs | FileCheck %s + +; The test is for a bug in R600EmitClauseMarkers.cpp where this pass +; was searching for a use of the OQAP register in order to determine +; if an LDS instruction could fit in the current clause, but never finding +; one. This created an infinite loop and hung the compiler. +; +; The LDS instruction should not have been defining OQAP in the first place, +; because the LDS instructions are pseudo instructions and the OQAP +; reads and writes are bundled together in the same instruction. + +; CHECK: @lds_crash +define void @lds_crash(i32 addrspace(1)* %out, i32 addrspace(3)* %in, i32 %a, i32 %b, i32 %c) { +entry: + %0 = load i32 addrspace(3)* %in + ; This block needs to be > 115 ISA instructions to hit the bug, + ; so we'll use udiv instructions. + %div0 = udiv i32 %0, %b + %div1 = udiv i32 %div0, %a + %div2 = udiv i32 %div1, 11 + %div3 = udiv i32 %div2, %a + %div4 = udiv i32 %div3, %b + %div5 = udiv i32 %div4, %c + %div6 = udiv i32 %div5, %div0 + %div7 = udiv i32 %div6, %div1 + store i32 %div7, i32 addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/R600/llvm.AMDGPU.kill.ll b/test/CodeGen/R600/llvm.AMDGPU.kill.ll new file mode 100644 index 000000000000..bec5cdf65f1b --- /dev/null +++ b/test/CodeGen/R600/llvm.AMDGPU.kill.ll @@ -0,0 +1,18 @@ +; RUN: llc < %s -march=r600 -mcpu=verde -verify-machineinstrs | FileCheck --check-prefix=SI %s + +; SI-LABEL: @kill_gs +; SI: V_CMPX_LE_F32 + +define void @kill_gs() #0 { +main_body: + %0 = icmp ule i32 0, 3 + %1 = select i1 %0, float 1.000000e+00, float -1.000000e+00 + call void @llvm.AMDGPU.kill(float %1) + ret void +} + +declare void @llvm.AMDGPU.kill(float) + +attributes #0 = { "ShaderType"="2" } + +!0 = metadata !{metadata !"const", null, i32 1} diff --git a/test/CodeGen/R600/llvm.SI.load.dword.ll b/test/CodeGen/R600/llvm.SI.load.dword.ll new file mode 100644 index 000000000000..a6227755b72e --- /dev/null +++ b/test/CodeGen/R600/llvm.SI.load.dword.ll @@ -0,0 +1,40 @@ +;RUN: llc < %s -march=r600 -mcpu=verde -verify-machineinstrs | FileCheck %s + +; Example of a simple geometry shader loading vertex attributes from the +; ESGS ring buffer + +; CHECK-LABEL: @main +; CHECK: BUFFER_LOAD_DWORD +; CHECK: BUFFER_LOAD_DWORD +; CHECK: BUFFER_LOAD_DWORD +; CHECK: BUFFER_LOAD_DWORD + +define void @main([17 x <16 x i8>] addrspace(2)* byval, [32 x <16 x i8>] addrspace(2)* byval, [16 x <32 x i8>] addrspace(2)* byval, [2 x <16 x i8>] addrspace(2)* byval, [17 x <16 x i8>] addrspace(2)* inreg, [17 x <16 x i8>] addrspace(2)* inreg, i32, i32, i32, i32) #0 { +main_body: + %10 = getelementptr [2 x <16 x i8>] addrspace(2)* %3, i64 0, i32 1 + %11 = load <16 x i8> addrspace(2)* %10, !tbaa !0 + %12 = shl i32 %6, 2 + %13 = call i32 @llvm.SI.buffer.load.dword.i32.i32(<16 x i8> %11, i32 0, i32 0, i32 0, i32 0, i32 0, i32 1, i32 1, i32 0) + %14 = bitcast i32 %13 to float + %15 = call i32 @llvm.SI.buffer.load.dword.i32.i32(<16 x i8> %11, i32 %12, i32 0, i32 0, i32 1, i32 0, i32 1, i32 1, i32 0) + %16 = bitcast i32 %15 to float + %17 = call i32 @llvm.SI.buffer.load.dword.i32.i32(<16 x i8> %11, i32 %12, i32 0, i32 0, i32 0, i32 1, i32 1, i32 1, i32 0) + %18 = bitcast i32 %17 to float + %19 = call i32 @llvm.SI.buffer.load.dword.i32.v2i32(<16 x i8> %11, <2 x i32> , i32 0, i32 0, i32 1, i32 1, i32 1, i32 1, i32 0) + %20 = bitcast i32 %19 to float + call void @llvm.SI.export(i32 15, i32 0, i32 1, i32 12, i32 0, float %14, float %16, float %18, float %20) + ret void +} + +; Function Attrs: nounwind readonly +declare i32 @llvm.SI.buffer.load.dword.i32.i32(<16 x i8>, i32, i32, i32, i32, i32, i32, i32, i32) #1 + +; Function Attrs: nounwind readonly +declare i32 @llvm.SI.buffer.load.dword.i32.v2i32(<16 x i8>, <2 x i32>, i32, i32, i32, i32, i32, i32, i32) #1 + +declare void @llvm.SI.export(i32, i32, i32, i32, i32, float, float, float, float) + +attributes #0 = { "ShaderType"="1" } +attributes #1 = { nounwind readonly } + +!0 = metadata !{metadata !"const", null, i32 1} diff --git a/test/CodeGen/R600/llvm.SI.sendmsg.ll b/test/CodeGen/R600/llvm.SI.sendmsg.ll new file mode 100644 index 000000000000..cfcc7c4e40ee --- /dev/null +++ b/test/CodeGen/R600/llvm.SI.sendmsg.ll @@ -0,0 +1,21 @@ +;RUN: llc < %s -march=r600 -mcpu=verde -verify-machineinstrs | FileCheck %s + +; CHECK-LABEL: @main +; CHECK: S_SENDMSG 34 +; CHECK: S_SENDMSG 274 +; CHECK: S_SENDMSG 562 +; CHECK: S_SENDMSG 3 + +define void @main() { +main_body: + call void @llvm.SI.sendmsg(i32 34, i32 0); + call void @llvm.SI.sendmsg(i32 274, i32 0); + call void @llvm.SI.sendmsg(i32 562, i32 0); + call void @llvm.SI.sendmsg(i32 3, i32 0); + ret void +} + +; Function Attrs: nounwind +declare void @llvm.SI.sendmsg(i32, i32) #0 + +attributes #0 = { nounwind } diff --git a/test/CodeGen/R600/load.ll b/test/CodeGen/R600/load.ll index e4492d7d6e7b..0153524d136c 100644 --- a/test/CodeGen/R600/load.ll +++ b/test/CodeGen/R600/load.ll @@ -445,6 +445,7 @@ define void @load_const_addrspace_f32(float addrspace(1)* %out, float addrspace( ; R600-CHECK: LDS_UBYTE_READ_RET ; SI-CHECK-LABEL: @load_i8_local ; SI-CHECK-NOT: S_WQM_B64 +; SI-CHECK: S_MOV_B32 m0 ; SI-CHECK: DS_READ_U8 define void @load_i8_local(i32 addrspace(1)* %out, i8 addrspace(3)* %in) { %1 = load i8 addrspace(3)* %in @@ -458,6 +459,7 @@ define void @load_i8_local(i32 addrspace(1)* %out, i8 addrspace(3)* %in) { ; R600-CHECK: ASHR ; SI-CHECK-LABEL: @load_i8_sext_local ; SI-CHECK-NOT: S_WQM_B64 +; SI-CHECK: S_MOV_B32 m0 ; SI-CHECK: DS_READ_I8 define void @load_i8_sext_local(i32 addrspace(1)* %out, i8 addrspace(3)* %in) { entry: @@ -472,6 +474,7 @@ entry: ; R600-CHECK: LDS_UBYTE_READ_RET ; SI-CHECK-LABEL: @load_v2i8_local ; SI-CHECK-NOT: S_WQM_B64 +; SI-CHECK: S_MOV_B32 m0 ; SI-CHECK: DS_READ_U8 ; SI-CHECK: DS_READ_U8 define void @load_v2i8_local(<2 x i32> addrspace(1)* %out, <2 x i8> addrspace(3)* %in) { @@ -489,6 +492,7 @@ entry: ; R600-CHECK-DAG: ASHR ; SI-CHECK-LABEL: @load_v2i8_sext_local ; SI-CHECK-NOT: S_WQM_B64 +; SI-CHECK: S_MOV_B32 m0 ; SI-CHECK: DS_READ_I8 ; SI-CHECK: DS_READ_I8 define void @load_v2i8_sext_local(<2 x i32> addrspace(1)* %out, <2 x i8> addrspace(3)* %in) { @@ -506,6 +510,7 @@ entry: ; R600-CHECK: LDS_UBYTE_READ_RET ; SI-CHECK-LABEL: @load_v4i8_local ; SI-CHECK-NOT: S_WQM_B64 +; SI-CHECK: S_MOV_B32 m0 ; SI-CHECK: DS_READ_U8 ; SI-CHECK: DS_READ_U8 ; SI-CHECK: DS_READ_U8 @@ -529,6 +534,7 @@ entry: ; R600-CHECK-DAG: ASHR ; SI-CHECK-LABEL: @load_v4i8_sext_local ; SI-CHECK-NOT: S_WQM_B64 +; SI-CHECK: S_MOV_B32 m0 ; SI-CHECK: DS_READ_I8 ; SI-CHECK: DS_READ_I8 ; SI-CHECK: DS_READ_I8 @@ -546,6 +552,7 @@ entry: ; R600-CHECK: LDS_USHORT_READ_RET ; SI-CHECK-LABEL: @load_i16_local ; SI-CHECK-NOT: S_WQM_B64 +; SI-CHECK: S_MOV_B32 m0 ; SI-CHECK: DS_READ_U16 define void @load_i16_local(i32 addrspace(1)* %out, i16 addrspace(3)* %in) { entry: @@ -560,6 +567,7 @@ entry: ; R600-CHECK: ASHR ; SI-CHECK-LABEL: @load_i16_sext_local ; SI-CHECK-NOT: S_WQM_B64 +; SI-CHECK: S_MOV_B32 m0 ; SI-CHECK: DS_READ_I16 define void @load_i16_sext_local(i32 addrspace(1)* %out, i16 addrspace(3)* %in) { entry: @@ -574,6 +582,7 @@ entry: ; R600-CHECK: LDS_USHORT_READ_RET ; SI-CHECK-LABEL: @load_v2i16_local ; SI-CHECK-NOT: S_WQM_B64 +; SI-CHECK: S_MOV_B32 m0 ; SI-CHECK: DS_READ_U16 ; SI-CHECK: DS_READ_U16 define void @load_v2i16_local(<2 x i32> addrspace(1)* %out, <2 x i16> addrspace(3)* %in) { @@ -591,6 +600,7 @@ entry: ; R600-CHECK-DAG: ASHR ; SI-CHECK-LABEL: @load_v2i16_sext_local ; SI-CHECK-NOT: S_WQM_B64 +; SI-CHECK: S_MOV_B32 m0 ; SI-CHECK: DS_READ_I16 ; SI-CHECK: DS_READ_I16 define void @load_v2i16_sext_local(<2 x i32> addrspace(1)* %out, <2 x i16> addrspace(3)* %in) { @@ -608,6 +618,7 @@ entry: ; R600-CHECK: LDS_USHORT_READ_RET ; SI-CHECK-LABEL: @load_v4i16_local ; SI-CHECK-NOT: S_WQM_B64 +; SI-CHECK: S_MOV_B32 m0 ; SI-CHECK: DS_READ_U16 ; SI-CHECK: DS_READ_U16 ; SI-CHECK: DS_READ_U16 @@ -631,6 +642,7 @@ entry: ; R600-CHECK-DAG: ASHR ; SI-CHECK-LABEL: @load_v4i16_sext_local ; SI-CHECK-NOT: S_WQM_B64 +; SI-CHECK: S_MOV_B32 m0 ; SI-CHECK: DS_READ_I16 ; SI-CHECK: DS_READ_I16 ; SI-CHECK: DS_READ_I16 @@ -643,11 +655,12 @@ entry: ret void } -; load an i32 value from the glocal address space. +; load an i32 value from the local address space. ; R600-CHECK-LABEL: @load_i32_local ; R600-CHECK: LDS_READ_RET ; SI-CHECK-LABEL: @load_i32_local ; SI-CHECK-NOT: S_WQM_B64 +; SI-CHECK: S_MOV_B32 m0 ; SI-CHECK: DS_READ_B32 define void @load_i32_local(i32 addrspace(1)* %out, i32 addrspace(3)* %in) { entry: @@ -656,10 +669,11 @@ entry: ret void } -; load a f32 value from the global address space. +; load a f32 value from the local address space. ; R600-CHECK-LABEL: @load_f32_local ; R600-CHECK: LDS_READ_RET ; SI-CHECK-LABEL: @load_f32_local +; SI-CHECK: S_MOV_B32 m0 ; SI-CHECK: DS_READ_B32 define void @load_f32_local(float addrspace(1)* %out, float addrspace(3)* %in) { entry: @@ -673,6 +687,7 @@ entry: ; R600-CHECK: LDS_READ_RET ; R600-CHECK: LDS_READ_RET ; SI-CHECK-LABEL: @load_v2f32_local +; SI-CHECK: S_MOV_B32 m0 ; SI-CHECK: DS_READ_B32 ; SI-CHECK: DS_READ_B32 define void @load_v2f32_local(<2 x float> addrspace(1)* %out, <2 x float> addrspace(3)* %in) { diff --git a/test/CodeGen/R600/trunc.ll b/test/CodeGen/R600/trunc.ll index 0bd320ad9ceb..6bbd7f7b510e 100644 --- a/test/CodeGen/R600/trunc.ll +++ b/test/CodeGen/R600/trunc.ll @@ -28,3 +28,13 @@ define void @trunc_shl_i64(i32 addrspace(1)* %out, i64 %a) { store i32 %result, i32 addrspace(1)* %out, align 4 ret void } + +; SI-LABEL: @trunc_i32_to_i1: +; SI: V_AND_B32 +; SI: V_CMP_EQ_I32 +define void @trunc_i32_to_i1(i32 addrspace(1)* %out, i32 %a) { + %trunc = trunc i32 %a to i1 + %result = select i1 %trunc, i32 1, i32 0 + store i32 %result, i32 addrspace(1)* %out, align 4 + ret void +} diff --git a/test/CodeGen/R600/vtx-fetch-branch.ll b/test/CodeGen/R600/vtx-fetch-branch.ll new file mode 100644 index 000000000000..0fc99dee0dbe --- /dev/null +++ b/test/CodeGen/R600/vtx-fetch-branch.ll @@ -0,0 +1,29 @@ +; RUN: llc -march=r600 -mcpu=redwood %s -o - | FileCheck %s + +; This tests for a bug where vertex fetch clauses right before an ENDIF +; instruction where being emitted after the ENDIF. We were using ALU_POP_AFTER +; for the ALU clause before the vetex fetch instead of emitting a POP instruction +; after the fetch clause. + + +; CHECK-LABEL: @test +; CHECK-NOT: ALU_POP_AFTER +; CHECK: TEX +; CHECK-NEXT: POP +define void @test(i32 addrspace(1)* %out, i32 addrspace(1)* %in, i32 %cond) { +entry: + %0 = icmp eq i32 %cond, 0 + br i1 %0, label %endif, label %if + +if: + %1 = load i32 addrspace(1)* %in + br label %endif + +endif: + %x = phi i32 [ %1, %if], [ 0, %entry] + store i32 %x, i32 addrspace(1)* %out + br label %done + +done: + ret void +} diff --git a/test/CodeGen/R600/zero_extend.ll b/test/CodeGen/R600/zero_extend.ll index 481b3b328259..a114bfc4a02b 100644 --- a/test/CodeGen/R600/zero_extend.ll +++ b/test/CodeGen/R600/zero_extend.ll @@ -16,3 +16,13 @@ entry: store i64 %2, i64 addrspace(1)* %out ret void } + +; SI-CHECK-LABEL: @testi1toi32 +; SI-CHECK: V_CNDMASK_B32 +define void @testi1toi32(i32 addrspace(1)* %out, i32 %a, i32 %b) { +entry: + %0 = icmp eq i32 %a, %b + %1 = zext i1 %0 to i32 + store i32 %1, i32 addrspace(1)* %out + ret void +} diff --git a/test/CodeGen/X86/2009-06-05-VZextByteShort.ll b/test/CodeGen/X86/2009-06-05-VZextByteShort.ll index 5f5d5cccf714..50c62dfb73b8 100644 --- a/test/CodeGen/X86/2009-06-05-VZextByteShort.ll +++ b/test/CodeGen/X86/2009-06-05-VZextByteShort.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=x86 -mattr=+mmx,+sse2 > %t1 +; RUN: llc < %s -march=x86 -mcpu=core2 > %t1 ; RUN: grep movzwl %t1 | count 2 ; RUN: grep movzbl %t1 | count 1 ; RUN: grep movd %t1 | count 4 diff --git a/test/CodeGen/X86/bswap-vector.ll b/test/CodeGen/X86/bswap-vector.ll new file mode 100644 index 000000000000..7a7a8a4ebb18 --- /dev/null +++ b/test/CodeGen/X86/bswap-vector.ll @@ -0,0 +1,19 @@ +; RUN: llc < %s -mcpu=core | FileCheck %s +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +declare <2 x i64> @llvm.bswap.v2i64(<2 x i64>) + +define <2 x i64> @foo(<2 x i64> %v) #0 { +entry: + %r = call <2 x i64> @llvm.bswap.v2i64(<2 x i64> %v) + ret <2 x i64> %r +} + +; CHECK-LABEL: @foo +; CHECK: bswapq +; CHECK: bswapq +; CHECK: ret + +attributes #0 = { nounwind uwtable } + diff --git a/test/CodeGen/X86/fma4-intrinsics-x86_64.ll b/test/CodeGen/X86/fma4-intrinsics-x86_64.ll index 7a1a9ae46147..494cb28677a4 100644 --- a/test/CodeGen/X86/fma4-intrinsics-x86_64.ll +++ b/test/CodeGen/X86/fma4-intrinsics-x86_64.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple=x86_64-unknown-unknown -march=x86-64 -mattr=+avx,+fma4 | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-unknown-unknown -march=x86-64 -mcpu=corei7-avx -mattr=+fma4 | FileCheck %s ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=bdver2 -mattr=+avx,-fma | FileCheck %s ; VFMADD diff --git a/test/CodeGen/X86/fp-fast.ll b/test/CodeGen/X86/fp-fast.ll index 07baca84804e..7b08ad67220b 100644 --- a/test/CodeGen/X86/fp-fast.ll +++ b/test/CodeGen/X86/fp-fast.ll @@ -1,4 +1,4 @@ -; RUN: llc -march=x86-64 -mattr=+avx,-fma4 -mtriple=x86_64-apple-darwin -enable-unsafe-fp-math < %s | FileCheck %s +; RUN: llc -march=x86-64 -mcpu=corei7-avx -enable-unsafe-fp-math < %s | FileCheck %s ; CHECK-LABEL: test1 define float @test1(float %a) { diff --git a/test/CodeGen/X86/inline-asm-modifier-q.ll b/test/CodeGen/X86/inline-asm-modifier-q.ll new file mode 100644 index 000000000000..d20f06d29054 --- /dev/null +++ b/test/CodeGen/X86/inline-asm-modifier-q.ll @@ -0,0 +1,12 @@ +; RUN: llc < %s -march=x86 | FileCheck %s + +; If the target does not have 64-bit integer registers, emit 32-bit register +; names. + +; CHECK: movq (%e{{[abcd]}}x, %ebx, 4) + +define void @q_modifier(i32* %p) { +entry: + tail call void asm sideeffect "movq (${0:q}, %ebx, 4), %mm0", "r,~{dirflag},~{fpsr},~{flags}"(i32* %p) + ret void +} diff --git a/test/CodeGen/X86/isint.ll b/test/CodeGen/X86/isint.ll index 4a98e63f38fc..38d05c662bd5 100644 --- a/test/CodeGen/X86/isint.ll +++ b/test/CodeGen/X86/isint.ll @@ -1,6 +1,11 @@ -; RUN: llc < %s -march=x86 -mattr=+sse2 | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-pc-unknown -mattr=+sse2 -mcpu=penryn | FileCheck %s +; RUN: llc < %s -mtriple=i686-pc-unknown -mattr=+sse2 -mcpu=penryn | FileCheck %s + +; PR19059 +; RUN: llc < %s -mtriple=i686-pc-unknown -mattr=+sse2 -mcpu=penryn | FileCheck -check-prefix=CHECK32 %s define i32 @isint_return(double %d) nounwind { +; CHECK-LABEL: isint_return: ; CHECK-NOT: xor ; CHECK: cvt %i = fptosi double %d to i32 @@ -8,6 +13,24 @@ define i32 @isint_return(double %d) nounwind { %e = sitofp i32 %i to double ; CHECK: cmpeqsd %c = fcmp oeq double %d, %e +; CHECK32-NOT: movd {{.*}}, %r{{.*}} +; CHECK32-NOT: andq +; CHECK-NEXT: movd +; CHECK-NEXT: andl + %z = zext i1 %c to i32 + ret i32 %z +} + +define i32 @isint_float_return(float %f) nounwind { +; CHECK-LABEL: isint_float_return: +; CHECK-NOT: xor +; CHECK: cvt + %i = fptosi float %f to i32 +; CHECK-NEXT: cvt + %g = sitofp i32 %i to float +; CHECK: cmpeqss + %c = fcmp oeq float %f, %g +; CHECK-NOT: movd {{.*}}, %r{{.*}} ; CHECK-NEXT: movd ; CHECK-NEXT: andl %z = zext i1 %c to i32 @@ -17,6 +40,7 @@ define i32 @isint_return(double %d) nounwind { declare void @foo() define void @isint_branch(double %d) nounwind { +; CHECK-LABEL: isint_branch: ; CHECK: cvt %i = fptosi double %d to i32 ; CHECK-NEXT: cvt diff --git a/test/CodeGen/X86/pr10420.ll b/test/CodeGen/X86/pr10420.ll index 3993f24954ee..62951892619b 100644 --- a/test/CodeGen/X86/pr10420.ll +++ b/test/CodeGen/X86/pr10420.ll @@ -1,4 +1,9 @@ -; RUN: llc < %s -mtriple=x86_64-apple-macosx -disable-cfi | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-apple-macosx10.7 -disable-cfi | FileCheck --check-prefix=CHECK-64-D11 %s +; RUN: llc < %s -mtriple=x86_64-apple-macosx10.6 -disable-cfi | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-apple-macosx10.5 -disable-cfi | FileCheck --check-prefix=CHECK-64-D89 %s +; RUN: llc < %s -mtriple=i686-apple-macosx10.6 -disable-cfi | FileCheck --check-prefix=CHECK-I686-D10 %s +; RUN: llc < %s -mtriple=i686-apple-macosx10.5 -disable-cfi | FileCheck --check-prefix=CHECK-I686-D89 %s +; RUN: llc < %s -mtriple=i686-apple-macosx10.4 -disable-cfi | FileCheck --check-prefix=CHECK-I686-D89 %s define private void @foo() { ret void @@ -19,3 +24,44 @@ define void @bar() { ; CHECK: Ltmp19: ; CHECK-NEXT: Ltmp20 = Ltmp2-Ltmp19 ## FDE initial location ; CHECK-NEXT: .quad Ltmp20 + + +; CHECK-64-D11: Ltmp13: +; CHECK-64-D11-NEXT: Ltmp14 = L_foo-Ltmp13 ## FDE initial location +; CHECK-64-D11-NEXT: .quad Ltmp14 + +; CHECK-64-D11: Ltmp20: +; CHECK-64-D11-NEXT: Ltmp21 = Ltmp2-Ltmp20 ## FDE initial location +; CHECK-64-D11-NEXT: .quad Ltmp21 + + +; CHECK-64-D89: Ltmp12: +; CHECK-64-D89-NEXT: .quad L_foo-Ltmp12 ## FDE initial location +; CHECK-64-D89-NEXT: Ltmp13 = (Ltmp0-L_foo)-0 ## FDE address range +; CHECK-64-D89-NEXT: .quad Ltmp13 + +; CHECK-64-D89: Ltmp18: +; CHECK-64-D89-NEXT: .quad Ltmp2-Ltmp18 ## FDE initial location +; CHECK-64-D89-NEXT: Ltmp19 = (Ltmp4-Ltmp2)-0 ## FDE address range +; CHECK-64-D89-NEXT: .quad Ltmp19 + + +; CHECK-I686-D10: Ltmp12: +; CHECK-I686-D10-NEXT: Ltmp13 = L_foo-Ltmp12 ## FDE initial location +; CHECK-I686-D10-NEXT: .long Ltmp13 + +; CHECK-I686-D10: Ltmp19: +; CHECK-I686-D10-NEXT: Ltmp20 = Ltmp2-Ltmp19 ## FDE initial location +; CHECK-I686-D10-NEXT: .long Ltmp20 + + +; CHECK-I686-D89: Ltmp12: +; CHECK-I686-D89-NEXT: .long L_foo-Ltmp12 ## FDE initial location +; CHECK-I686-D89-NEXT: Ltmp13 = (Ltmp0-L_foo)-0 ## FDE address range +; CHECK-I686-D89-NEXT: .long Ltmp13 + +; CHECK-I686-D89: Ltmp18: +; CHECK-I686-D89-NEXT: .long Ltmp2-Ltmp18 ## FDE initial location +; CHECK-I686-D89-NEXT: Ltmp19 = (Ltmp4-Ltmp2)-0 ## FDE address range +; CHECK-I686-D89-NEXT: .long Ltmp19 + diff --git a/test/CodeGen/X86/stores-merging.ll b/test/CodeGen/X86/stores-merging.ll new file mode 100644 index 000000000000..61dea088995b --- /dev/null +++ b/test/CodeGen/X86/stores-merging.ll @@ -0,0 +1,23 @@ +; RUN: llc < %s | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +%structTy = type { i8, i32, i32 } + +@e = common global %structTy zeroinitializer, align 4 + +; CHECK-LABEL: f +define void @f() { +entry: + +; CHECK: movabsq $528280977409, %rax +; CHECK: movq %rax, e+4(%rip) +; CHECK: movl $456, e+8(%rip) + + store i32 1, i32* getelementptr inbounds (%structTy* @e, i64 0, i32 1), align 4 + store i32 123, i32* getelementptr inbounds (%structTy* @e, i64 0, i32 2), align 4 + store i32 456, i32* getelementptr inbounds (%structTy* @e, i64 0, i32 2), align 4 + ret void +} + diff --git a/test/CodeGen/X86/vaargs.ll b/test/CodeGen/X86/vaargs.ll new file mode 100644 index 000000000000..ddeb7a336d4a --- /dev/null +++ b/test/CodeGen/X86/vaargs.ll @@ -0,0 +1,67 @@ +; RUN: llc -mcpu=corei7-avx %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=NO-FLAGS +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.9.0" + +%struct.__va_list_tag = type { i32, i32, i8*, i8* } + +; Check that vastart gets the right thing. +define i32 @sum(i32 %count, ...) nounwind optsize ssp uwtable { +; CHECK: testb %al, %al +; CHECK-NEXT: je +; CHECK-NEXT: ## BB#{{[0-9]+}}: +; CHECK-NEXT: vmovaps %xmm0, 48(%rsp) +; CHECK-NEXT: vmovaps %xmm1, 64(%rsp) +; CHECK-NEXT: vmovaps %xmm2, 80(%rsp) +; CHECK-NEXT: vmovaps %xmm3, 96(%rsp) +; CHECK-NEXT: vmovaps %xmm4, 112(%rsp) +; CHECK-NEXT: vmovaps %xmm5, 128(%rsp) +; CHECK-NEXT: vmovaps %xmm6, 144(%rsp) +; CHECK-NEXT: vmovaps %xmm7, 160(%rsp) + +; Check that [EFLAGS] hasn't been pulled in. +; NO-FLAGS-NOT: %flags + + %ap = alloca [1 x %struct.__va_list_tag], align 16 + %1 = bitcast [1 x %struct.__va_list_tag]* %ap to i8* + call void @llvm.va_start(i8* %1) + %2 = icmp sgt i32 %count, 0 + br i1 %2, label %.lr.ph, label %._crit_edge + +.lr.ph: ; preds = %0 + %3 = getelementptr inbounds [1 x %struct.__va_list_tag]* %ap, i64 0, i64 0, i32 0 + %4 = getelementptr inbounds [1 x %struct.__va_list_tag]* %ap, i64 0, i64 0, i32 2 + %.pre = load i32* %3, align 16 + br label %5 + +;