IFC @r273338

This commit is contained in:
neel 2014-10-21 01:57:36 +00:00
commit b02cd3e378
126 changed files with 7149 additions and 721 deletions

View File

@ -48,6 +48,8 @@ OLD_FILES+=etc/rc.d/hv_kvpd
# 20140917: libnv was accidentally being installed to /usr/lib instead of /lib
OLD_LIBS+=usr/lib/libnv.a
OLD_LIBS+=usr/lib/libnv.so.0
# 20140829: rc.d/kerberos removed
OLD_FILES+=etc/rc.d/kerberos
# 20140814: libopie version bump
OLD_LIBS+=usr/lib/libopie.so.7
OLD_LIBS+=usr/lib32/libopie.so.7

View File

@ -125,6 +125,7 @@ static void consumetoken(int);
static void synexpect(int) __dead2;
static void synerror(const char *) __dead2;
static void setprompt(int);
static int pgetc_linecont(void);
static void *
@ -899,17 +900,17 @@ xxreadtoken(void)
case PEOF:
RETURN(TEOF);
case '&':
if (pgetc() == '&')
if (pgetc_linecont() == '&')
RETURN(TAND);
pungetc();
RETURN(TBACKGND);
case '|':
if (pgetc() == '|')
if (pgetc_linecont() == '|')
RETURN(TOR);
pungetc();
RETURN(TPIPE);
case ';':
c = pgetc();
c = pgetc_linecont();
if (c == ';')
RETURN(TENDCASE);
else if (c == '&')
@ -991,7 +992,7 @@ parseredir(char *out, int c)
np = (union node *)stalloc(sizeof (struct nfile));
if (c == '>') {
np->nfile.fd = 1;
c = pgetc();
c = pgetc_linecont();
if (c == '>')
np->type = NAPPEND;
else if (c == '&')
@ -1004,7 +1005,7 @@ parseredir(char *out, int c)
}
} else { /* c == '<' */
np->nfile.fd = 0;
c = pgetc();
c = pgetc_linecont();
if (c == '<') {
if (sizeof (struct nfile) != sizeof (struct nhere)) {
np = (union node *)stalloc(sizeof (struct nhere));
@ -1013,7 +1014,7 @@ parseredir(char *out, int c)
np->type = NHERE;
heredoc = (struct heredoc *)stalloc(sizeof (struct heredoc));
heredoc->here = np;
if ((c = pgetc()) == '-') {
if ((c = pgetc_linecont()) == '-') {
heredoc->striptabs = 1;
} else {
heredoc->striptabs = 0;
@ -1094,25 +1095,12 @@ parsebackq(char *out, struct nodelist **pbqlist,
needprompt = 0;
}
CHECKSTRSPACE(2, oout);
c = pgetc();
c = pgetc_linecont();
if (c == '`')
break;
switch (c) {
case '\\':
if ((c = pgetc()) == '\n') {
plinno++;
if (doprompt)
setprompt(2);
else
setprompt(0);
/*
* If eating a newline, avoid putting
* the newline into the new character
* stream (via the USTPUTC after the
* switch).
*/
continue;
}
c = pgetc();
if (c != '\\' && c != '`' && c != '$'
&& (!dblquote || c != '"'))
USTPUTC('\\', oout);
@ -1507,7 +1495,7 @@ readtoken1(int firstc, char const *initialsyntax, const char *eofmark,
USTPUTC(c, out);
--state[level].parenlevel;
} else {
if (pgetc() == ')') {
if (pgetc_linecont() == ')') {
if (level > 0 &&
state[level].category == TSTATE_ARITH) {
level--;
@ -1593,9 +1581,9 @@ parsesub: {
int length;
int c1;
c = pgetc();
c = pgetc_linecont();
if (c == '(') { /* $(command) or $((arith)) */
if (pgetc() == '(') {
if (pgetc_linecont() == '(') {
PARSEARITH();
} else {
pungetc();
@ -1613,7 +1601,7 @@ parsesub: {
flags = 0;
if (c == '{') {
bracketed_name = 1;
c = pgetc();
c = pgetc_linecont();
subtype = 0;
}
varname:
@ -1621,7 +1609,7 @@ varname:
length = 0;
do {
STPUTC(c, out);
c = pgetc();
c = pgetc_linecont();
length++;
} while (!is_eof(c) && is_in_name(c));
if (length == 6 &&
@ -1640,22 +1628,22 @@ varname:
if (bracketed_name) {
do {
STPUTC(c, out);
c = pgetc();
c = pgetc_linecont();
} while (is_digit(c));
} else {
STPUTC(c, out);
c = pgetc();
c = pgetc_linecont();
}
} else if (is_special(c)) {
c1 = c;
c = pgetc();
c = pgetc_linecont();
if (subtype == 0 && c1 == '#') {
subtype = VSLENGTH;
if (strchr(types, c) == NULL && c != ':' &&
c != '#' && c != '%')
goto varname;
c1 = c;
c = pgetc();
c = pgetc_linecont();
if (c1 != '}' && c == '}') {
pungetc();
c = c1;
@ -1680,7 +1668,7 @@ varname:
switch (c) {
case ':':
flags |= VSNUL;
c = pgetc();
c = pgetc_linecont();
/*FALLTHROUGH*/
default:
p = strchr(types, c);
@ -1700,7 +1688,7 @@ varname:
int cc = c;
subtype = c == '#' ? VSTRIMLEFT :
VSTRIMRIGHT;
c = pgetc();
c = pgetc_linecont();
if (c == cc)
subtype++;
else
@ -1909,6 +1897,29 @@ setprompt(int which)
}
}
static int
pgetc_linecont(void)
{
int c;
while ((c = pgetc_macro()) == '\\') {
c = pgetc();
if (c == '\n') {
plinno++;
if (doprompt)
setprompt(2);
else
setprompt(0);
} else {
pungetc();
/* Allow the backslash to be pushed back. */
pushstring("\\", 1, NULL);
return (pgetc());
}
}
return (c);
}
/*
* called by editline -- any expansions to the prompt
* should be added here.

View File

@ -55,6 +55,17 @@ FILES+= heredoc9.0
FILES+= heredoc10.0
FILES+= heredoc11.0
FILES+= heredoc12.0
FILES+= line-cont1.0
FILES+= line-cont2.0
FILES+= line-cont3.0
FILES+= line-cont4.0
FILES+= line-cont5.0
FILES+= line-cont6.0
FILES+= line-cont7.0
FILES+= line-cont8.0
FILES+= line-cont9.0
FILES+= line-cont10.0
FILES+= line-cont11.0
FILES+= no-space1.0
FILES+= no-space2.0
FILES+= only-redir1.0

View File

@ -0,0 +1,16 @@
# $FreeBSD$
i\
f
t\
r\
u\
e
t\
h\
e\
n
:
\
f\
i

View File

@ -0,0 +1,18 @@
# $FreeBSD$
v=XaaaXbbbX
[ "${v\
#\
*\
a}.${v\
#\
#\
*\
a}.${v\
%\
b\
*}.${v\
%\
%\
b\
*}" = aaXbbbX.XbbbX.XaaaXbb.XaaaX ]

View File

@ -0,0 +1,23 @@
# $FreeBSD$
T=$(mktemp "${TMPDIR:-/tmp}/sh-test.XXXXXXXX") || exit
trap 'rm -f -- "$T"' 0
w='#A'
# A naive pgetc_linecont() would push back two characters here, which
# fails if a new buffer is read between the two characters.
c='${w#\#}'
c=$c$c$c$c
c=$c$c$c$c
c=$c$c$c$c
c=$c$c$c$c
c=$c$c$c$c
c=$c$c$c$c
printf 'v=%s\n' "$c" >"$T"
. "$T"
if [ "${#v}" != 4096 ]; then
echo "Length is bad (${#v})"
exit 3
fi
case $v in
*[!A]*) echo "Content is bad"; exit 3 ;;
esac

View File

@ -0,0 +1,4 @@
# $FreeBSD$
[ "a\
b" = ab ]

View File

@ -0,0 +1,7 @@
# $FreeBSD$
v=`printf %s 'a\
b'`
w="`printf %s 'c\
d'`"
[ "$v$w" = abcd ]

View File

@ -0,0 +1,8 @@
# $FreeBSD$
v=abcd
[ "$\
v.$\
{v}.${\
v}.${v\
}" = abcd.abcd.abcd.abcd ]

View File

@ -0,0 +1,14 @@
# $FreeBSD$
bad=1
case x in
x\
) ;\
; *) exit 7
esac &\
& bad= &\
& : >\
>/dev/null
false |\
| [ -z "$bad" ]

View File

@ -0,0 +1,23 @@
# $FreeBSD$
v0\
=abc
v=$(cat <\
<\
E\
O\
F
${v0}d
EOF
)
w=$(cat <\
<\
-\
EOF
efgh
EOF
)
[ "$v.$w" = "abcd.efgh" ]

View File

@ -0,0 +1,7 @@
# $FreeBSD$
[ "$(\
(
1\
+ 1)\
)" = 2 ]

View File

@ -0,0 +1,6 @@
# $FreeBSD$
set -- a b c d e f g h i j
[ "${1\
0\
}" = j ]

View File

@ -0,0 +1,6 @@
# $FreeBSD$
[ "${$\
:\
+\
xyz}" = xyz ]

View File

@ -116,6 +116,7 @@ typedef struct tcpsinfo {
uint32_t tcps_rto; /* round-trip timeout, msec */
uint32_t tcps_mss; /* max segment size */
int tcps_retransmit; /* retransmit send event, boolean */
int tcps_srtt; /* smoothed RTT in units of (TCP_RTT_SCALE*hz) */
} tcpsinfo_t;
/*
@ -200,6 +201,7 @@ translator tcpsinfo_t < struct tcpcb *p > {
tcps_rto = p == NULL ? -1 : p->t_rxtcur / 1000; /* XXX */
tcps_mss = p == NULL ? -1 : p->t_maxseg;
tcps_retransmit = p == NULL ? -1 : p->t_rxtshift > 0 ? 1 : 0;
tcps_srtt = p == NULL ? -1 : p->t_srtt; /* smoothed RTT in units of (TCP_RTT_SCALE*hz) */
};
#pragma D binding "1.6.3" translator

View File

@ -55,18 +55,35 @@ openpam_readword(FILE *f, int *lineno, size_t *lenp)
{
char *word;
size_t size, len;
int ch, comment, escape, quote;
int ch, escape, quote;
int serrno;
errno = 0;
/* skip initial whitespace */
comment = 0;
while ((ch = getc(f)) != EOF && ch != '\n') {
if (ch == '#')
comment = 1;
if (!is_lws(ch) && !comment)
escape = quote = 0;
while ((ch = getc(f)) != EOF) {
if (ch == '\n') {
/* either EOL or line continuation */
if (!escape)
break;
if (lineno != NULL)
++*lineno;
escape = 0;
} else if (escape) {
/* escaped something else */
break;
} else if (ch == '#') {
/* comment: until EOL, no continuation */
while ((ch = getc(f)) != EOF)
if (ch == '\n')
break;
break;
} else if (ch == '\\') {
escape = 1;
} else if (!is_ws(ch)) {
break;
}
}
if (ch == EOF)
return (NULL);
@ -76,7 +93,6 @@ openpam_readword(FILE *f, int *lineno, size_t *lenp)
word = NULL;
size = len = 0;
escape = quote = 0;
while ((ch = fgetc(f)) != EOF && (!is_ws(ch) || quote || escape)) {
if (ch == '\\' && !escape && quote != '\'') {
/* escape next character */
@ -90,7 +106,7 @@ openpam_readword(FILE *f, int *lineno, size_t *lenp)
} else if (ch == quote && !escape) {
/* end quote */
quote = 0;
} else if (ch == '\n' && escape && quote != '\'') {
} else if (ch == '\n' && escape) {
/* line continuation */
escape = 0;
} else {

View File

@ -70,12 +70,12 @@ FILES= DAEMON \
iscsictl \
iscsid \
jail \
kadmind \
kdc \
kfd \
${_kadmind} \
${_kdc} \
${_kfd} \
kld \
kldxref \
kpasswdd \
${_kpasswdd} \
ldconfig \
local \
localpkg \
@ -181,6 +181,13 @@ _casperd= casperd
_nscd= nscd
.endif
.if ${MK_KERBEROS} != "no"
_kadmind= kadmind
_kdc= kdc
_kfd= kfd
_kpasswdd= kpasswdd
.endif
.if ${MK_OFED} != "no"
_opensm= opensm
.endif

View File

@ -498,7 +498,8 @@ case ${firewall_type} in
${fwcmd} add pass udp from $i to me ${j%/[Uu][Dd][Pp]}
;;
*[0-9A-Za-z])
echo "Consider using tcp/$j in firewall_myservices." > /dev/stderr
echo "Consider using ${j}/tcp in firewall_myservices." \
> /dev/stderr
${fwcmd} add pass tcp from $i to me $j
;;
*)

View File

@ -132,8 +132,10 @@ _kvm_initvtop(kvm_t *kd)
u_long kernbase, physaddr, pa;
pd_entry_t *l1pt;
Elf32_Ehdr *ehdr;
Elf32_Phdr *phdr;
size_t hdrsz;
char minihdr[8];
int found, i;
if (!kd->rawdump) {
if (pread(kd->pmfd, &minihdr, 8, 0) == 8) {
@ -158,19 +160,33 @@ _kvm_initvtop(kvm_t *kd)
hdrsz = ehdr->e_phoff + ehdr->e_phentsize * ehdr->e_phnum;
if (_kvm_maphdrs(kd, hdrsz) == -1)
return (-1);
nl[0].n_name = "kernbase";
nl[1].n_name = NULL;
if (kvm_nlist(kd, nl) != 0)
kernbase = KERNBASE;
else
kernbase = nl[0].n_value;
nl[0].n_name = "physaddr";
if (kvm_nlist(kd, nl) != 0) {
_kvm_err(kd, kd->program, "couldn't get phys addr");
return (-1);
phdr = (Elf32_Phdr *)((uint8_t *)ehdr + ehdr->e_phoff);
found = 0;
for (i = 0; i < ehdr->e_phnum; i++) {
if (phdr[i].p_type == PT_DUMP_DELTA) {
kernbase = phdr[i].p_vaddr;
physaddr = phdr[i].p_paddr;
found = 1;
break;
}
}
nl[1].n_name = NULL;
if (!found) {
nl[0].n_name = "kernbase";
if (kvm_nlist(kd, nl) != 0)
kernbase = KERNBASE;
else
kernbase = nl[0].n_value;
nl[0].n_name = "physaddr";
if (kvm_nlist(kd, nl) != 0) {
_kvm_err(kd, kd->program, "couldn't get phys addr");
return (-1);
}
physaddr = nl[0].n_value;
}
physaddr = nl[0].n_value;
nl[0].n_name = "kernel_l1pa";
if (kvm_nlist(kd, nl) != 0) {
_kvm_err(kd, kd->program, "bad namelist");

View File

@ -431,6 +431,24 @@ nopgrp:
strlcpy(kp->ki_tdname, mtd.td_name, sizeof(kp->ki_tdname));
kp->ki_pctcpu = 0;
kp->ki_rqindex = 0;
/*
* Note: legacy fields; wraps at NO_CPU_OLD or the
* old max CPU value as appropriate
*/
if (mtd.td_lastcpu == NOCPU)
kp->ki_lastcpu_old = NOCPU_OLD;
else if (mtd.td_lastcpu > MAXCPU_OLD)
kp->ki_lastcpu_old = MAXCPU_OLD;
else
kp->ki_lastcpu_old = mtd.td_lastcpu;
if (mtd.td_oncpu == NOCPU)
kp->ki_oncpu_old = NOCPU_OLD;
else if (mtd.td_oncpu > MAXCPU_OLD)
kp->ki_oncpu_old = MAXCPU_OLD;
else
kp->ki_oncpu_old = mtd.td_oncpu;
} else {
kp->ki_stat = SZOMB;
}

View File

@ -30,6 +30,7 @@ SRCS+= ifmac.c # MAC support
SRCS+= ifmedia.c # SIOC[GS]IFMEDIA support
SRCS+= iffib.c # non-default FIB support
SRCS+= ifvlan.c # SIOC[GS]ETVLAN support
SRCS+= ifvxlan.c # VXLAN support
SRCS+= ifgre.c # GRE keys etc
SRCS+= ifgif.c # GIF reversed header workaround

View File

@ -28,7 +28,7 @@
.\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94
.\" $FreeBSD$
.\"
.Dd October 1, 2014
.Dd October 20, 2014
.Dt IFCONFIG 8
.Os
.Sh NAME
@ -2541,6 +2541,76 @@ argument is useless and hence deprecated.
.El
.Pp
The following parameters are used to configure
.Xr vxlan 4
interfaces.
.Bl -tag -width indent
.It Cm vni Ar identifier
This value is a 24-bit VXLAN Network Identifier (VNI) that identifies the
virtual network segment membership of the interface.
.It Cm local Ar address
The source address used in the encapsulating IPv4/IPv6 header.
The address should already be assigned to an existing interface.
When the interface is configured in unicast mode, the listening socket
is bound to this address.
.It Cm remote Ar address
The interface can be configured in a unicast, or point-to-point, mode
to create a tunnel between two hosts.
This is the IP address of the remote end of the tunnel.
.It Cm group Ar address
The interface can be configured in a multicast mode
to create a virtual network of hosts.
This is the IP multicast group address the interface will join.
.It Cm localport Ar port
The port number the interface will listen on.
The default port number is 4789.
.It Cm remoteport Ar port
The destination port number used in the encapsulating IPv4/IPv6 header.
The remote host should be listening on this port.
The default port number is 4789.
Note some other implementations, such as Linux,
do not default to the IANA assigned port,
but instead listen on port 8472.
.It Cm portrange Ar low high
The range of source ports used in the encapsulating IPv4/IPv6 header.
The port selected within the range is based on a hash of the inner frame.
A range is useful to provide entropy within the outer IP header
for more effective load balancing.
The default range is between the
.Xr sysctl 8
variables
.Va net.inet.ip.portrange.first
and
.Va net.inet.ip.portrange.last
.It Cm timeout Ar timeout
The maximum time, in seconds, before an entry in the forwarding table
is pruned.
The default is 1200 seconds (20 minutes).
.It Cm maxaddr Ar max
The maximum number of entries in the forwarding table.
The default is 2000.
.It Cm vxlandev Ar dev
When the interface is configured in multicast mode, the
.Cm dev
interface is used to transmit IP multicast packets.
.It Cm ttl Ar ttl
The TTL used in the encapsulating IPv4/IPv6 header.
The default is 64.
.It Cm learn
The source IP address and inner source Ethernet MAC address of
received packets are used to dynamically populate the forwarding table.
When in multicast mode, an entry in the forwarding table allows the
interface to send the frame directly to the remote host instead of
broadcasting the frame to the multicast group.
This is the default.
.It Fl learn
The forwarding table is not populated by recevied packets.
.It Cm flush
Delete all dynamically-learned addresses from the forwarding table.
.It Cm flushall
Delete all addresses, including static addresses, from the forwarding table.
.El
.Pp
The following parameters are used to configure
.Xr carp 4
protocol on an interface:
.Bl -tag -width indent
@ -2745,6 +2815,7 @@ tried to alter an interface's configuration.
.Xr pfsync 4 ,
.Xr polling 4 ,
.Xr vlan 4 ,
.Xr vxlan 4 ,
.Xr devd.conf 5 ,
.\" .Xr eon 5 ,
.Xr devd 8 ,

648
sbin/ifconfig/ifvxlan.c Normal file
View File

@ -0,0 +1,648 @@
/*-
* Copyright (c) 2014, Bryan Venteicher <bryanv@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice unmodified, this list of conditions, and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <netdb.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_vxlan.h>
#include <net/route.h>
#include <netinet/in.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <err.h>
#include <errno.h>
#include "ifconfig.h"
static struct ifvxlanparam params = {
.vxlp_vni = VXLAN_VNI_MAX,
};
static int
get_val(const char *cp, u_long *valp)
{
char *endptr;
u_long val;
errno = 0;
val = strtoul(cp, &endptr, 0);
if (cp[0] == '\0' || endptr[0] != '\0' || errno == ERANGE)
return (-1);
*valp = val;
return (0);
}
static int
do_cmd(int sock, u_long op, void *arg, size_t argsize, int set)
{
struct ifdrv ifd;
bzero(&ifd, sizeof(ifd));
strlcpy(ifd.ifd_name, ifr.ifr_name, sizeof(ifd.ifd_name));
ifd.ifd_cmd = op;
ifd.ifd_len = argsize;
ifd.ifd_data = arg;
return (ioctl(sock, set ? SIOCSDRVSPEC : SIOCGDRVSPEC, &ifd));
}
static int
vxlan_exists(int sock)
{
struct ifvxlancfg cfg;
bzero(&cfg, sizeof(cfg));
return (do_cmd(sock, VXLAN_CMD_GET_CONFIG, &cfg, sizeof(cfg), 0) != -1);
}
static void
vxlan_status(int s)
{
struct ifvxlancfg cfg;
char src[NI_MAXHOST], dst[NI_MAXHOST];
char srcport[NI_MAXSERV], dstport[NI_MAXSERV];
struct sockaddr *lsa, *rsa;
int vni, mc, ipv6;
bzero(&cfg, sizeof(cfg));
if (do_cmd(s, VXLAN_CMD_GET_CONFIG, &cfg, sizeof(cfg), 0) < 0)
return;
vni = cfg.vxlc_vni;
lsa = &cfg.vxlc_local_sa.sa;
rsa = &cfg.vxlc_remote_sa.sa;
ipv6 = rsa->sa_family == AF_INET6;
/* Just report nothing if the network identity isn't set yet. */
if (vni >= VXLAN_VNI_MAX)
return;
if (getnameinfo(lsa, lsa->sa_len, src, sizeof(src),
srcport, sizeof(srcport), NI_NUMERICHOST | NI_NUMERICSERV) != 0)
src[0] = srcport[0] = '\0';
if (getnameinfo(rsa, rsa->sa_len, dst, sizeof(dst),
dstport, sizeof(dstport), NI_NUMERICHOST | NI_NUMERICSERV) != 0)
dst[0] = dstport[0] = '\0';
if (!ipv6) {
struct sockaddr_in *sin = (struct sockaddr_in *)rsa;
mc = IN_MULTICAST(ntohl(sin->sin_addr.s_addr));
} else {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)rsa;
mc = IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr);
}
printf("\tvxlan vni %d", vni);
printf(" local %s%s%s:%s", ipv6 ? "[" : "", src, ipv6 ? "]" : "",
srcport);
printf(" %s %s%s%s:%s", mc ? "group" : "remote", ipv6 ? "[" : "",
dst, ipv6 ? "]" : "", dstport);
if (verbose) {
printf("\n\t\tconfig: ");
printf("%slearning portrange %d-%d ttl %d",
cfg.vxlc_learn ? "" : "no", cfg.vxlc_port_min,
cfg.vxlc_port_max, cfg.vxlc_ttl);
printf("\n\t\tftable: ");
printf("cnt %d max %d timeout %d",
cfg.vxlc_ftable_cnt, cfg.vxlc_ftable_max,
cfg.vxlc_ftable_timeout);
}
putchar('\n');
}
#define _LOCAL_ADDR46 \
(VXLAN_PARAM_WITH_LOCAL_ADDR4 | VXLAN_PARAM_WITH_LOCAL_ADDR6)
#define _REMOTE_ADDR46 \
(VXLAN_PARAM_WITH_REMOTE_ADDR4 | VXLAN_PARAM_WITH_REMOTE_ADDR6)
static void
vxlan_check_params(void)
{
if ((params.vxlp_with & _LOCAL_ADDR46) == _LOCAL_ADDR46)
errx(1, "cannot specify both local IPv4 and IPv6 addresses");
if ((params.vxlp_with & _REMOTE_ADDR46) == _REMOTE_ADDR46)
errx(1, "cannot specify both remote IPv4 and IPv6 addresses");
if ((params.vxlp_with & VXLAN_PARAM_WITH_LOCAL_ADDR4 &&
params.vxlp_with & VXLAN_PARAM_WITH_REMOTE_ADDR6) ||
(params.vxlp_with & VXLAN_PARAM_WITH_LOCAL_ADDR6 &&
params.vxlp_with & VXLAN_PARAM_WITH_REMOTE_ADDR4))
errx(1, "cannot mix IPv4 and IPv6 addresses");
}
#undef _LOCAL_ADDR46
#undef _REMOTE_ADDR46
static void
vxlan_cb(int s, void *arg)
{
}
static void
vxlan_create(int s, struct ifreq *ifr)
{
vxlan_check_params();
ifr->ifr_data = (caddr_t) &params;
if (ioctl(s, SIOCIFCREATE2, ifr) < 0)
err(1, "SIOCIFCREATE2");
}
static
DECL_CMD_FUNC(setvxlan_vni, arg, d)
{
struct ifvxlancmd cmd;
u_long val;
if (get_val(arg, &val) < 0 || val >= VXLAN_VNI_MAX)
errx(1, "invalid network identifier: %s", arg);
if (!vxlan_exists(s)) {
params.vxlp_with |= VXLAN_PARAM_WITH_VNI;
params.vxlp_vni = val;
return;
}
bzero(&cmd, sizeof(cmd));
cmd.vxlcmd_vni = val;
if (do_cmd(s, VXLAN_CMD_SET_VNI, &cmd, sizeof(cmd), 1) < 0)
err(1, "VXLAN_CMD_SET_VNI");
}
static
DECL_CMD_FUNC(setvxlan_local, addr, d)
{
struct ifvxlancmd cmd;
struct addrinfo *ai;
struct sockaddr *sa;
int error;
bzero(&cmd, sizeof(cmd));
if ((error = getaddrinfo(addr, NULL, NULL, &ai)) != 0)
errx(1, "error in parsing local address string: %s",
gai_strerror(error));
sa = ai->ai_addr;
switch (ai->ai_family) {
#ifdef INET
case AF_INET: {
struct in_addr addr = ((struct sockaddr_in *) sa)->sin_addr;
if (IN_MULTICAST(ntohl(addr.s_addr)))
errx(1, "local address cannot be multicast");
cmd.vxlcmd_sa.in4.sin_family = AF_INET;
cmd.vxlcmd_sa.in4.sin_addr = addr;
break;
}
#endif
#ifdef INET6
case AF_INET6: {
struct in6_addr *addr = &((struct sockaddr_in6 *)sa)->sin6_addr;
if (IN6_IS_ADDR_MULTICAST(addr))
errx(1, "local address cannot be multicast");
cmd.vxlcmd_sa.in6.sin6_family = AF_INET6;
cmd.vxlcmd_sa.in6.sin6_addr = *addr;
break;
}
#endif
default:
errx(1, "local address %s not supported", addr);
}
freeaddrinfo(ai);
if (!vxlan_exists(s)) {
if (cmd.vxlcmd_sa.sa.sa_family == AF_INET) {
params.vxlp_with |= VXLAN_PARAM_WITH_LOCAL_ADDR4;
params.vxlp_local_in4 = cmd.vxlcmd_sa.in4.sin_addr;
} else {
params.vxlp_with |= VXLAN_PARAM_WITH_LOCAL_ADDR6;
params.vxlp_local_in6 = cmd.vxlcmd_sa.in6.sin6_addr;
}
return;
}
if (do_cmd(s, VXLAN_CMD_SET_LOCAL_ADDR, &cmd, sizeof(cmd), 1) < 0)
err(1, "VXLAN_CMD_SET_LOCAL_ADDR");
}
static
DECL_CMD_FUNC(setvxlan_remote, addr, d)
{
struct ifvxlancmd cmd;
struct addrinfo *ai;
struct sockaddr *sa;
int error;
bzero(&cmd, sizeof(cmd));
if ((error = getaddrinfo(addr, NULL, NULL, &ai)) != 0)
errx(1, "error in parsing remote address string: %s",
gai_strerror(error));
sa = ai->ai_addr;
switch (ai->ai_family) {
#ifdef INET
case AF_INET: {
struct in_addr addr = ((struct sockaddr_in *)sa)->sin_addr;
if (IN_MULTICAST(ntohl(addr.s_addr)))
errx(1, "remote address cannot be multicast");
cmd.vxlcmd_sa.in4.sin_family = AF_INET;
cmd.vxlcmd_sa.in4.sin_addr = addr;
break;
}
#endif
#ifdef INET6
case AF_INET6: {
struct in6_addr *addr = &((struct sockaddr_in6 *)sa)->sin6_addr;
if (IN6_IS_ADDR_MULTICAST(addr))
errx(1, "remote address cannot be multicast");
cmd.vxlcmd_sa.in6.sin6_family = AF_INET6;
cmd.vxlcmd_sa.in6.sin6_addr = *addr;
break;
}
#endif
default:
errx(1, "remote address %s not supported", addr);
}
freeaddrinfo(ai);
if (!vxlan_exists(s)) {
if (cmd.vxlcmd_sa.sa.sa_family == AF_INET) {
params.vxlp_with |= VXLAN_PARAM_WITH_REMOTE_ADDR4;
params.vxlp_remote_in4 = cmd.vxlcmd_sa.in4.sin_addr;
} else {
params.vxlp_with |= VXLAN_PARAM_WITH_REMOTE_ADDR6;
params.vxlp_remote_in6 = cmd.vxlcmd_sa.in6.sin6_addr;
}
return;
}
if (do_cmd(s, VXLAN_CMD_SET_REMOTE_ADDR, &cmd, sizeof(cmd), 1) < 0)
err(1, "VXLAN_CMD_SET_REMOTE_ADDR");
}
static
DECL_CMD_FUNC(setvxlan_group, addr, d)
{
struct ifvxlancmd cmd;
struct addrinfo *ai;
struct sockaddr *sa;
int error;
bzero(&cmd, sizeof(cmd));
if ((error = getaddrinfo(addr, NULL, NULL, &ai)) != 0)
errx(1, "error in parsing group address string: %s",
gai_strerror(error));
sa = ai->ai_addr;
switch (ai->ai_family) {
#ifdef INET
case AF_INET: {
struct in_addr addr = ((struct sockaddr_in *)sa)->sin_addr;
if (!IN_MULTICAST(ntohl(addr.s_addr)))
errx(1, "group address must be multicast");
cmd.vxlcmd_sa.in4.sin_family = AF_INET;
cmd.vxlcmd_sa.in4.sin_addr = addr;
break;
}
#endif
#ifdef INET6
case AF_INET6: {
struct in6_addr *addr = &((struct sockaddr_in6 *)sa)->sin6_addr;
if (!IN6_IS_ADDR_MULTICAST(addr))
errx(1, "group address must be multicast");
cmd.vxlcmd_sa.in6.sin6_family = AF_INET6;
cmd.vxlcmd_sa.in6.sin6_addr = *addr;
break;
}
#endif
default:
errx(1, "group address %s not supported", addr);
}
freeaddrinfo(ai);
if (!vxlan_exists(s)) {
if (cmd.vxlcmd_sa.sa.sa_family == AF_INET) {
params.vxlp_with |= VXLAN_PARAM_WITH_REMOTE_ADDR4;
params.vxlp_remote_in4 = cmd.vxlcmd_sa.in4.sin_addr;
} else {
params.vxlp_with |= VXLAN_PARAM_WITH_REMOTE_ADDR6;
params.vxlp_remote_in6 = cmd.vxlcmd_sa.in6.sin6_addr;
}
return;
}
if (do_cmd(s, VXLAN_CMD_SET_REMOTE_ADDR, &cmd, sizeof(cmd), 1) < 0)
err(1, "VXLAN_CMD_SET_REMOTE_ADDR");
}
static
DECL_CMD_FUNC(setvxlan_local_port, arg, d)
{
struct ifvxlancmd cmd;
u_long val;
if (get_val(arg, &val) < 0 || val >= UINT16_MAX)
errx(1, "invalid local port: %s", arg);
if (!vxlan_exists(s)) {
params.vxlp_with |= VXLAN_PARAM_WITH_LOCAL_PORT;
params.vxlp_local_port = val;
return;
}
bzero(&cmd, sizeof(cmd));
cmd.vxlcmd_port = val;
if (do_cmd(s, VXLAN_CMD_SET_LOCAL_PORT, &cmd, sizeof(cmd), 1) < 0)
err(1, "VXLAN_CMD_SET_LOCAL_PORT");
}
static
DECL_CMD_FUNC(setvxlan_remote_port, arg, d)
{
struct ifvxlancmd cmd;
u_long val;
if (get_val(arg, &val) < 0 || val >= UINT16_MAX)
errx(1, "invalid remote port: %s", arg);
if (!vxlan_exists(s)) {
params.vxlp_with |= VXLAN_PARAM_WITH_REMOTE_PORT;
params.vxlp_remote_port = val;
return;
}
bzero(&cmd, sizeof(cmd));
cmd.vxlcmd_port = val;
if (do_cmd(s, VXLAN_CMD_SET_REMOTE_PORT, &cmd, sizeof(cmd), 1) < 0)
err(1, "VXLAN_CMD_SET_REMOTE_PORT");
}
static
DECL_CMD_FUNC2(setvxlan_port_range, arg1, arg2)
{
struct ifvxlancmd cmd;
u_long min, max;
if (get_val(arg1, &min) < 0 || min >= UINT16_MAX)
errx(1, "invalid port range minimum: %s", arg1);
if (get_val(arg2, &max) < 0 || max >= UINT16_MAX)
errx(1, "invalid port range maximum: %s", arg2);
if (max < min)
errx(1, "invalid port range");
if (!vxlan_exists(s)) {
params.vxlp_with |= VXLAN_PARAM_WITH_PORT_RANGE;
params.vxlp_min_port = min;
params.vxlp_max_port = max;
return;
}
bzero(&cmd, sizeof(cmd));
cmd.vxlcmd_port_min = min;
cmd.vxlcmd_port_max = max;
if (do_cmd(s, VXLAN_CMD_SET_PORT_RANGE, &cmd, sizeof(cmd), 1) < 0)
err(1, "VXLAN_CMD_SET_PORT_RANGE");
}
static
DECL_CMD_FUNC(setvxlan_timeout, arg, d)
{
struct ifvxlancmd cmd;
u_long val;
if (get_val(arg, &val) < 0 || (val & ~0xFFFFFFFF) != 0)
errx(1, "invalid timeout value: %s", arg);
if (!vxlan_exists(s)) {
params.vxlp_with |= VXLAN_PARAM_WITH_FTABLE_TIMEOUT;
params.vxlp_ftable_timeout = val & 0xFFFFFFFF;
return;
}
bzero(&cmd, sizeof(cmd));
cmd.vxlcmd_ftable_timeout = val & 0xFFFFFFFF;
if (do_cmd(s, VXLAN_CMD_SET_FTABLE_TIMEOUT, &cmd, sizeof(cmd), 1) < 0)
err(1, "VXLAN_CMD_SET_FTABLE_TIMEOUT");
}
static
DECL_CMD_FUNC(setvxlan_maxaddr, arg, d)
{
struct ifvxlancmd cmd;
u_long val;
if (get_val(arg, &val) < 0 || (val & ~0xFFFFFFFF) != 0)
errx(1, "invalid maxaddr value: %s", arg);
if (!vxlan_exists(s)) {
params.vxlp_with |= VXLAN_PARAM_WITH_FTABLE_MAX;
params.vxlp_ftable_max = val & 0xFFFFFFFF;
return;
}
bzero(&cmd, sizeof(cmd));
cmd.vxlcmd_ftable_max = val & 0xFFFFFFFF;
if (do_cmd(s, VXLAN_CMD_SET_FTABLE_MAX, &cmd, sizeof(cmd), 1) < 0)
err(1, "VXLAN_CMD_SET_FTABLE_MAX");
}
static
DECL_CMD_FUNC(setvxlan_dev, arg, d)
{
struct ifvxlancmd cmd;
if (!vxlan_exists(s)) {
params.vxlp_with |= VXLAN_PARAM_WITH_MULTICAST_IF;
strlcpy(params.vxlp_mc_ifname, arg,
sizeof(params.vxlp_mc_ifname));
return;
}
bzero(&cmd, sizeof(cmd));
strlcpy(cmd.vxlcmd_ifname, arg, sizeof(cmd.vxlcmd_ifname));
if (do_cmd(s, VXLAN_CMD_SET_MULTICAST_IF, &cmd, sizeof(cmd), 1) < 0)
err(1, "VXLAN_CMD_SET_MULTICAST_IF");
}
static
DECL_CMD_FUNC(setvxlan_ttl, arg, d)
{
struct ifvxlancmd cmd;
u_long val;
if (get_val(arg, &val) < 0 || val > 256)
errx(1, "invalid TTL value: %s", arg);
if (!vxlan_exists(s)) {
params.vxlp_with |= VXLAN_PARAM_WITH_TTL;
params.vxlp_ttl = val;
return;
}
bzero(&cmd, sizeof(cmd));
cmd.vxlcmd_ttl = val;
if (do_cmd(s, VXLAN_CMD_SET_TTL, &cmd, sizeof(cmd), 1) < 0)
err(1, "VXLAN_CMD_SET_TTL");
}
static
DECL_CMD_FUNC(setvxlan_learn, arg, d)
{
struct ifvxlancmd cmd;
if (!vxlan_exists(s)) {
params.vxlp_with |= VXLAN_PARAM_WITH_LEARN;
params.vxlp_learn = d;
return;
}
bzero(&cmd, sizeof(cmd));
if (d != 0)
cmd.vxlcmd_flags |= VXLAN_CMD_FLAG_LEARN;
if (do_cmd(s, VXLAN_CMD_SET_LEARN, &cmd, sizeof(cmd), 1) < 0)
err(1, "VXLAN_CMD_SET_LEARN");
}
static void
setvxlan_flush(const char *val, int d, int s, const struct afswtch *afp)
{
struct ifvxlancmd cmd;
bzero(&cmd, sizeof(cmd));
if (d != 0)
cmd.vxlcmd_flags |= VXLAN_CMD_FLAG_FLUSH_ALL;
if (do_cmd(s, VXLAN_CMD_FLUSH, &cmd, sizeof(cmd), 1) < 0)
err(1, "VXLAN_CMD_FLUSH");
}
static struct cmd vxlan_cmds[] = {
DEF_CLONE_CMD_ARG("vni", setvxlan_vni),
DEF_CLONE_CMD_ARG("local", setvxlan_local),
DEF_CLONE_CMD_ARG("remote", setvxlan_remote),
DEF_CLONE_CMD_ARG("group", setvxlan_group),
DEF_CLONE_CMD_ARG("localport", setvxlan_local_port),
DEF_CLONE_CMD_ARG("remoteport", setvxlan_remote_port),
DEF_CLONE_CMD_ARG2("portrange", setvxlan_port_range),
DEF_CLONE_CMD_ARG("timeout", setvxlan_timeout),
DEF_CLONE_CMD_ARG("maxaddr", setvxlan_maxaddr),
DEF_CLONE_CMD_ARG("vxlandev", setvxlan_dev),
DEF_CLONE_CMD_ARG("ttl", setvxlan_ttl),
DEF_CLONE_CMD("learn", 1, setvxlan_learn),
DEF_CLONE_CMD("-learn", 0, setvxlan_learn),
DEF_CMD_ARG("vni", setvxlan_vni),
DEF_CMD_ARG("local", setvxlan_local),
DEF_CMD_ARG("remote", setvxlan_remote),
DEF_CMD_ARG("group", setvxlan_group),
DEF_CMD_ARG("localport", setvxlan_local_port),
DEF_CMD_ARG("remoteport", setvxlan_remote_port),
DEF_CMD_ARG2("portrange", setvxlan_port_range),
DEF_CMD_ARG("timeout", setvxlan_timeout),
DEF_CMD_ARG("maxaddr", setvxlan_maxaddr),
DEF_CMD_ARG("vxlandev", setvxlan_dev),
DEF_CMD_ARG("ttl", setvxlan_ttl),
DEF_CMD("learn", 1, setvxlan_learn),
DEF_CMD("-learn", 0, setvxlan_learn),
DEF_CMD("flush", 0, setvxlan_flush),
DEF_CMD("flushall", 1, setvxlan_flush),
};
static struct afswtch af_vxlan = {
.af_name = "af_vxlan",
.af_af = AF_UNSPEC,
.af_other_status = vxlan_status,
};
static __constructor void
vxlan_ctor(void)
{
#define N(a) (sizeof(a) / sizeof(a[0]))
size_t i;
for (i = 0; i < N(vxlan_cmds); i++)
cmd_register(&vxlan_cmds[i]);
af_register(&af_vxlan);
callback_register(vxlan_cb, NULL);
clone_setdefcallback("vxlan", vxlan_create);
#undef N
}

View File

@ -2138,7 +2138,7 @@ ipfw_sets_handler(char *av[])
{
uint32_t masks[2];
int i;
uint8_t cmd, new_set, rulenum;
uint8_t cmd, rulenum;
ipfw_range_tlv rt;
char *msg;
size_t size;
@ -2202,7 +2202,7 @@ ipfw_sets_handler(char *av[])
if (!isdigit(*(av[0])) || (cmd == 3 && rt.set > RESVD_SET) ||
(cmd == 2 && rt.start_rule == IPFW_DEFAULT_RULE) )
errx(EX_DATAERR, "invalid source number %s\n", av[0]);
if (!isdigit(*(av[2])) || new_set > RESVD_SET)
if (!isdigit(*(av[2])) || rt.new_set > RESVD_SET)
errx(EX_DATAERR, "invalid dest. set %s\n", av[1]);
i = do_range_cmd(cmd, &rt);
} else if (_substrcmp(*av, "disable") == 0 ||
@ -2530,7 +2530,7 @@ ipfw_show_config(struct cmdline_opts *co, struct format_opts *fo,
int lac;
char **lav;
char *endptr;
size_t read;
size_t readsz;
struct buf_pr bp;
ipfw_obj_ctlv *ctlv, *tstate;
ipfw_obj_tlv *rbase;
@ -2542,7 +2542,8 @@ ipfw_show_config(struct cmdline_opts *co, struct format_opts *fo,
rbase = NULL;
dynbase = NULL;
dynsz = 0;
read = sizeof(*cfg);
readsz = sizeof(*cfg);
rcnt = 0;
fo->set_mask = cfg->set_mask;
@ -2552,7 +2553,7 @@ ipfw_show_config(struct cmdline_opts *co, struct format_opts *fo,
/* We've requested static rules */
if (ctlv->head.type == IPFW_TLV_TBLNAME_LIST) {
fo->tstate = ctlv;
read += ctlv->head.length;
readsz += ctlv->head.length;
ctlv = (ipfw_obj_ctlv *)((caddr_t)ctlv +
ctlv->head.length);
}
@ -2560,15 +2561,15 @@ ipfw_show_config(struct cmdline_opts *co, struct format_opts *fo,
if (ctlv->head.type == IPFW_TLV_RULE_LIST) {
rbase = (ipfw_obj_tlv *)(ctlv + 1);
rcnt = ctlv->count;
read += ctlv->head.length;
readsz += ctlv->head.length;
ctlv = (ipfw_obj_ctlv *)((caddr_t)ctlv +
ctlv->head.length);
}
}
if ((cfg->flags & IPFW_CFG_GET_STATES) && (read != sz)) {
if ((cfg->flags & IPFW_CFG_GET_STATES) && (readsz != sz)) {
/* We may have some dynamic states */
dynsz = sz - read;
dynsz = sz - readsz;
/* Skip empty header */
if (dynsz != sizeof(ipfw_obj_ctlv))
dynbase = (caddr_t)ctlv;
@ -4685,6 +4686,7 @@ ipfw_add(char *av[])
ipfw_obj_ctlv *ctlv, *tstate;
rbufsize = sizeof(rulebuf);
memset(rulebuf, 0, rbufsize);
memset(&ts, 0, sizeof(ts));
/* Optimize case with no tables */

View File

@ -1908,7 +1908,7 @@ ipfw_list_values(int ac, char *av[])
for (i = 0; i < olh->count; i++) {
table_show_value(buf, sizeof(buf), (ipfw_table_value *)v,
vmask, 0);
printf("[%u] refs=%ju %s\n", v->spare1, v->refcnt, buf);
printf("[%u] refs=%lu %s\n", v->spare1, (u_long)v->refcnt, buf);
v = (struct _table_value *)((caddr_t)v + olh->objsize);
}

View File

@ -7,7 +7,7 @@ PROG= ping
MAN= ping.8
BINOWN= root
BINMODE=4555
WARNS?= 2
WARNS?= 3
DPADD= ${LIBM}
LDADD= -lm

View File

@ -122,7 +122,7 @@ struct tv32 {
};
/* various options */
int options;
static int options;
#define F_FLOOD 0x0001
#define F_INTERVAL 0x0002
#define F_NUMERIC 0x0004
@ -157,52 +157,52 @@ int options;
* to 8192 for complete accuracy...
*/
#define MAX_DUP_CHK (8 * 128)
int mx_dup_ck = MAX_DUP_CHK;
char rcvd_tbl[MAX_DUP_CHK / 8];
static int mx_dup_ck = MAX_DUP_CHK;
static char rcvd_tbl[MAX_DUP_CHK / 8];
struct sockaddr_in whereto; /* who to ping */
int datalen = DEFDATALEN;
int maxpayload;
int ssend; /* send socket file descriptor */
int srecv; /* receive socket file descriptor */
u_char outpackhdr[IP_MAXPACKET], *outpack;
char BBELL = '\a'; /* characters written for MISSED and AUDIBLE */
char BSPACE = '\b'; /* characters written for flood */
char DOT = '.';
char *hostname;
char *shostname;
int ident; /* process id to identify our packets */
int uid; /* cached uid for micro-optimization */
u_char icmp_type = ICMP_ECHO;
u_char icmp_type_rsp = ICMP_ECHOREPLY;
int phdr_len = 0;
int send_len;
static struct sockaddr_in whereto; /* who to ping */
static int datalen = DEFDATALEN;
static int maxpayload;
static int ssend; /* send socket file descriptor */
static int srecv; /* receive socket file descriptor */
static u_char outpackhdr[IP_MAXPACKET], *outpack;
static char BBELL = '\a'; /* characters written for MISSED and AUDIBLE */
static char BSPACE = '\b'; /* characters written for flood */
static char DOT = '.';
static char *hostname;
static char *shostname;
static int ident; /* process id to identify our packets */
static int uid; /* cached uid for micro-optimization */
static u_char icmp_type = ICMP_ECHO;
static u_char icmp_type_rsp = ICMP_ECHOREPLY;
static int phdr_len = 0;
static int send_len;
/* counters */
long nmissedmax; /* max value of ntransmitted - nreceived - 1 */
long npackets; /* max packets to transmit */
long nreceived; /* # of packets we got back */
long nrepeats; /* number of duplicates */
long ntransmitted; /* sequence # for outbound packets = #sent */
long snpackets; /* max packets to transmit in one sweep */
long snreceived; /* # of packets we got back in this sweep */
long sntransmitted; /* # of packets we sent in this sweep */
int sweepmax; /* max value of payload in sweep */
int sweepmin = 0; /* start value of payload in sweep */
int sweepincr = 1; /* payload increment in sweep */
int interval = 1000; /* interval between packets, ms */
int waittime = MAXWAIT; /* timeout for each packet */
long nrcvtimeout = 0; /* # of packets we got back after waittime */
static long nmissedmax; /* max value of ntransmitted - nreceived - 1 */
static long npackets; /* max packets to transmit */
static long nreceived; /* # of packets we got back */
static long nrepeats; /* number of duplicates */
static long ntransmitted; /* sequence # for outbound packets = #sent */
static long snpackets; /* max packets to transmit in one sweep */
static long sntransmitted; /* # of packets we sent in this sweep */
static int sweepmax; /* max value of payload in sweep */
static int sweepmin = 0; /* start value of payload in sweep */
static int sweepincr = 1; /* payload increment in sweep */
static int interval = 1000; /* interval between packets, ms */
static int waittime = MAXWAIT; /* timeout for each packet */
static long nrcvtimeout = 0; /* # of packets we got back after waittime */
/* timing */
int timing; /* flag to do timing */
double tmin = 999999999.0; /* minimum round trip time */
double tmax = 0.0; /* maximum round trip time */
double tsum = 0.0; /* sum of all times, for doing average */
double tsumsq = 0.0; /* sum of all times squared, for std. dev. */
static int timing; /* flag to do timing */
static double tmin = 999999999.0; /* minimum round trip time */
static double tmax = 0.0; /* maximum round trip time */
static double tsum = 0.0; /* sum of all times, for doing average */
static double tsumsq = 0.0; /* sum of all times squared, for std. dev. */
volatile sig_atomic_t finish_up; /* nonzero if we've been told to finish up */
volatile sig_atomic_t siginfo_p;
/* nonzero if we've been told to finish up */
static volatile sig_atomic_t finish_up;
static volatile sig_atomic_t siginfo_p;
#ifdef HAVE_LIBCAPSICUM
static cap_channel_t *capdns;
@ -1150,7 +1150,8 @@ pr_pack(char *buf, int cc, struct sockaddr_in *from, struct timeval *tv)
#endif
tp = (const char *)tp + phdr_len;
if (cc - ICMP_MINLEN - phdr_len >= sizeof(tv1)) {
if ((size_t)(cc - ICMP_MINLEN - phdr_len) >=
sizeof(tv1)) {
/* Copy to avoid alignment problems: */
memcpy(&tv32, tp, sizeof(tv32));
tv1.tv_sec = ntohl(tv32.tv32_sec);

View File

@ -5,7 +5,7 @@ MAN= ping6.8
CFLAGS+=-DIPSEC -DKAME_SCOPEID -DUSE_RFC2292BIS \
-DHAVE_ARC4RANDOM
WARNS?= 2
WARNS?= 3
BINOWN= root
BINMODE=4555

View File

@ -205,84 +205,83 @@ u_int options;
* to 8192 for complete accuracy...
*/
#define MAX_DUP_CHK (8 * 8192)
int mx_dup_ck = MAX_DUP_CHK;
char rcvd_tbl[MAX_DUP_CHK / 8];
static int mx_dup_ck = MAX_DUP_CHK;
static char rcvd_tbl[MAX_DUP_CHK / 8];
struct sockaddr_in6 dst; /* who to ping6 */
struct sockaddr_in6 src; /* src addr of this packet */
socklen_t srclen;
int datalen = DEFDATALEN;
int s; /* socket file descriptor */
u_char outpack[MAXPACKETLEN];
char BSPACE = '\b'; /* characters written for flood */
char BBELL = '\a'; /* characters written for AUDIBLE */
char DOT = '.';
char *hostname;
int ident; /* process id to identify our packets */
u_int8_t nonce[8]; /* nonce field for node information */
int hoplimit = -1; /* hoplimit */
int pathmtu = 0; /* path MTU for the destination. 0 = unspec. */
u_char *packet = NULL;
static struct sockaddr_in6 dst; /* who to ping6 */
static struct sockaddr_in6 src; /* src addr of this packet */
static socklen_t srclen;
static size_t datalen = DEFDATALEN;
static int s; /* socket file descriptor */
static u_char outpack[MAXPACKETLEN];
static char BSPACE = '\b'; /* characters written for flood */
static char BBELL = '\a'; /* characters written for AUDIBLE */
static char DOT = '.';
static char *hostname;
static int ident; /* process id to identify our packets */
static u_int8_t nonce[8]; /* nonce field for node information */
static int hoplimit = -1; /* hoplimit */
static u_char *packet = NULL;
/* counters */
long nmissedmax; /* max value of ntransmitted - nreceived - 1 */
long npackets; /* max packets to transmit */
long nreceived; /* # of packets we got back */
long nrepeats; /* number of duplicates */
long ntransmitted; /* sequence # for outbound packets = #sent */
int interval = 1000; /* interval between packets in ms */
int waittime = MAXWAIT; /* timeout for each packet */
long nrcvtimeout = 0; /* # of packets we got back after waittime */
static long nmissedmax; /* max value of ntransmitted - nreceived - 1 */
static long npackets; /* max packets to transmit */
static long nreceived; /* # of packets we got back */
static long nrepeats; /* number of duplicates */
static long ntransmitted; /* sequence # for outbound packets = #sent */
static int interval = 1000; /* interval between packets in ms */
static int waittime = MAXWAIT; /* timeout for each packet */
static long nrcvtimeout = 0; /* # of packets we got back after waittime */
/* timing */
int timing; /* flag to do timing */
double tmin = 999999999.0; /* minimum round trip time */
double tmax = 0.0; /* maximum round trip time */
double tsum = 0.0; /* sum of all times, for doing average */
double tsumsq = 0.0; /* sum of all times squared, for std. dev. */
static int timing; /* flag to do timing */
static double tmin = 999999999.0; /* minimum round trip time */
static double tmax = 0.0; /* maximum round trip time */
static double tsum = 0.0; /* sum of all times, for doing average */
static double tsumsq = 0.0; /* sum of all times squared, for std. dev. */
/* for node addresses */
u_short naflags;
static u_short naflags;
/* for ancillary data(advanced API) */
struct msghdr smsghdr;
struct iovec smsgiov;
char *scmsg = 0;
static struct msghdr smsghdr;
static struct iovec smsgiov;
static char *scmsg = 0;
volatile sig_atomic_t seenint;
static volatile sig_atomic_t seenint;
#ifdef SIGINFO
volatile sig_atomic_t seeninfo;
static volatile sig_atomic_t seeninfo;
#endif
int main(int, char *[]);
void fill(char *, char *);
int get_hoplim(struct msghdr *);
int get_pathmtu(struct msghdr *);
struct in6_pktinfo *get_rcvpktinfo(struct msghdr *);
void onsignal(int);
void onint(int);
size_t pingerlen(void);
int pinger(void);
const char *pr_addr(struct sockaddr *, int);
void pr_icmph(struct icmp6_hdr *, u_char *);
void pr_iph(struct ip6_hdr *);
void pr_suptypes(struct icmp6_nodeinfo *, size_t);
void pr_nodeaddr(struct icmp6_nodeinfo *, int);
int myechoreply(const struct icmp6_hdr *);
int mynireply(const struct icmp6_nodeinfo *);
char *dnsdecode(const u_char **, const u_char *, const u_char *,
char *, size_t);
void pr_pack(u_char *, int, struct msghdr *);
void pr_exthdrs(struct msghdr *);
void pr_ip6opt(void *, size_t);
void pr_rthdr(void *, size_t);
int pr_bitrange(u_int32_t, int, int);
void pr_retip(struct ip6_hdr *, u_char *);
void summary(void);
void tvsub(struct timeval *, struct timeval *);
int setpolicy(int, char *);
char *nigroup(char *, int);
void usage(void);
static void fill(char *, char *);
static int get_hoplim(struct msghdr *);
static int get_pathmtu(struct msghdr *);
static struct in6_pktinfo *get_rcvpktinfo(struct msghdr *);
static void onsignal(int);
static void onint(int);
static size_t pingerlen(void);
static int pinger(void);
static const char *pr_addr(struct sockaddr *, int);
static void pr_icmph(struct icmp6_hdr *, u_char *);
static void pr_iph(struct ip6_hdr *);
static void pr_suptypes(struct icmp6_nodeinfo *, size_t);
static void pr_nodeaddr(struct icmp6_nodeinfo *, int);
static int myechoreply(const struct icmp6_hdr *);
static int mynireply(const struct icmp6_nodeinfo *);
static char *dnsdecode(const u_char **, const u_char *, const u_char *,
char *, size_t);
static void pr_pack(u_char *, int, struct msghdr *);
static void pr_exthdrs(struct msghdr *);
static void pr_ip6opt(void *, size_t);
static void pr_rthdr(void *, size_t);
static int pr_bitrange(u_int32_t, int, int);
static void pr_retip(struct ip6_hdr *, u_char *);
static void summary(void);
static void tvsub(struct timeval *, struct timeval *);
static int setpolicy(int, char *);
static char *nigroup(char *, int);
static void usage(void);
int
main(int argc, char *argv[])
@ -390,9 +389,9 @@ main(int argc, char *argv[])
errno = 0;
e = NULL;
lsockbufsize = strtoul(optarg, &e, 10);
sockbufsize = lsockbufsize;
sockbufsize = (int)lsockbufsize;
if (errno || !*optarg || *e ||
sockbufsize != lsockbufsize)
lsockbufsize > INT_MAX)
errx(1, "invalid socket buffer size");
#else
errx(1,
@ -751,7 +750,7 @@ main(int argc, char *argv[])
*((int *)&nonce[i]) = rand();
#else
memset(nonce, 0, sizeof(nonce));
for (i = 0; i < sizeof(nonce); i += sizeof(u_int32_t))
for (i = 0; i < (int)sizeof(nonce); i += sizeof(u_int32_t))
*((u_int32_t *)&nonce[i]) = arc4random();
#endif
optval = 1;
@ -1009,7 +1008,7 @@ main(int argc, char *argv[])
#if defined(SO_SNDBUF) && defined(SO_RCVBUF)
if (sockbufsize) {
if (datalen > sockbufsize)
if (datalen > (size_t)sockbufsize)
warnx("you need -b to increase socket buffer size");
if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sockbufsize,
sizeof(sockbufsize)) < 0)
@ -1222,7 +1221,7 @@ main(int argc, char *argv[])
exit(nreceived == 0 ? 2 : 0);
}
void
static void
onsignal(int sig)
{
@ -1247,7 +1246,7 @@ onsignal(int sig)
* of the data portion are used to hold a UNIX "timeval" struct in VAX
* byte-order, to compute the round-trip time.
*/
size_t
static size_t
pingerlen(void)
{
size_t l;
@ -1266,7 +1265,7 @@ pingerlen(void)
return l;
}
int
static int
pinger(void)
{
struct icmp6_hdr *icp;
@ -1381,7 +1380,7 @@ pinger(void)
return(0);
}
int
static int
myechoreply(const struct icmp6_hdr *icp)
{
if (ntohs(icp->icmp6_id) == ident)
@ -1390,7 +1389,7 @@ myechoreply(const struct icmp6_hdr *icp)
return 0;
}
int
static int
mynireply(const struct icmp6_nodeinfo *nip)
{
if (memcmp(nip->icmp6_ni_nonce + sizeof(u_int16_t),
@ -1401,7 +1400,7 @@ mynireply(const struct icmp6_nodeinfo *nip)
return 0;
}
char *
static char *
dnsdecode(const u_char **sp, const u_char *ep, const u_char *base, char *buf,
size_t bufsiz)
/*base for compressed name*/
@ -1445,7 +1444,7 @@ dnsdecode(const u_char **sp, const u_char *ep, const u_char *base, char *buf,
while (i-- > 0 && cp < ep) {
l = snprintf(cresult, sizeof(cresult),
isprint(*cp) ? "%c" : "\\%03o", *cp & 0xff);
if (l >= sizeof(cresult) || l < 0)
if ((size_t)l >= sizeof(cresult) || l < 0)
return NULL;
if (strlcat(buf, cresult, bufsiz) >= bufsiz)
return NULL; /*result overrun*/
@ -1468,7 +1467,7 @@ dnsdecode(const u_char **sp, const u_char *ep, const u_char *base, char *buf,
* which arrive ('tis only fair). This permits multiple copies of this
* program to be run without having intermingled output (or statistics!).
*/
void
static void
pr_pack(u_char *buf, int cc, struct msghdr *mhdr)
{
#define safeputc(c) printf((isprint((c)) ? "%c" : "\\%03o"), c)
@ -1500,7 +1499,7 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr)
}
from = (struct sockaddr *)mhdr->msg_name;
fromlen = mhdr->msg_namelen;
if (cc < sizeof(struct icmp6_hdr)) {
if (cc < (int)sizeof(struct icmp6_hdr)) {
if (options & F_VERBOSE)
warnx("packet too short (%d bytes) from %s", cc,
pr_addr(from, fromlen));
@ -1754,7 +1753,7 @@ pr_pack(u_char *buf, int cc, struct msghdr *mhdr)
#undef safeputc
}
void
static void
pr_exthdrs(struct msghdr *mhdr)
{
ssize_t bufsize;
@ -1792,7 +1791,7 @@ pr_exthdrs(struct msghdr *mhdr)
}
#ifdef USE_RFC2292BIS
void
static void
pr_ip6opt(void *extbuf, size_t bufsize)
{
struct ip6_hbh *ext;
@ -1855,7 +1854,7 @@ pr_ip6opt(void *extbuf, size_t bufsize)
}
#else /* !USE_RFC2292BIS */
/* ARGSUSED */
void
static void
pr_ip6opt(void *extbuf, size_t bufsize __unused)
{
putchar('\n');
@ -1864,7 +1863,7 @@ pr_ip6opt(void *extbuf, size_t bufsize __unused)
#endif /* USE_RFC2292BIS */
#ifdef USE_RFC2292BIS
void
static void
pr_rthdr(void *extbuf, size_t bufsize)
{
struct in6_addr *in6;
@ -1921,7 +1920,7 @@ pr_rthdr(void *extbuf, size_t bufsize)
#else /* !USE_RFC2292BIS */
/* ARGSUSED */
void
static void
pr_rthdr(void *extbuf, size_t bufsize __unused)
{
putchar('\n');
@ -1929,7 +1928,7 @@ pr_rthdr(void *extbuf, size_t bufsize __unused)
}
#endif /* USE_RFC2292BIS */
int
static int
pr_bitrange(u_int32_t v, int soff, int ii)
{
int off;
@ -1975,7 +1974,7 @@ pr_bitrange(u_int32_t v, int soff, int ii)
return ii;
}
void
static void
pr_suptypes(struct icmp6_nodeinfo *ni, size_t nilen)
/* ni->qtype must be SUPTYPES */
{
@ -2041,7 +2040,7 @@ pr_suptypes(struct icmp6_nodeinfo *ni, size_t nilen)
}
}
void
static void
pr_nodeaddr(struct icmp6_nodeinfo *ni, int nilen)
/* ni->qtype must be NODEADDR */
{
@ -2107,7 +2106,7 @@ pr_nodeaddr(struct icmp6_nodeinfo *ni, int nilen)
}
}
int
static int
get_hoplim(struct msghdr *mhdr)
{
struct cmsghdr *cm;
@ -2126,7 +2125,7 @@ get_hoplim(struct msghdr *mhdr)
return(-1);
}
struct in6_pktinfo *
static struct in6_pktinfo *
get_rcvpktinfo(struct msghdr *mhdr)
{
struct cmsghdr *cm;
@ -2145,7 +2144,7 @@ get_rcvpktinfo(struct msghdr *mhdr)
return(NULL);
}
int
static int
get_pathmtu(struct msghdr *mhdr)
{
#ifdef IPV6_RECVPATHMTU
@ -2205,7 +2204,7 @@ get_pathmtu(struct msghdr *mhdr)
* Subtract 2 timeval structs: out = out - in. Out is assumed to
* be >= in.
*/
void
static void
tvsub(struct timeval *out, struct timeval *in)
{
if ((out->tv_usec -= in->tv_usec) < 0) {
@ -2220,7 +2219,7 @@ tvsub(struct timeval *out, struct timeval *in)
* SIGINT handler.
*/
/* ARGSUSED */
void
static void
onint(int notused __unused)
{
/*
@ -2235,7 +2234,7 @@ onint(int notused __unused)
* summary --
* Print out statistics.
*/
void
static void
summary(void)
{
@ -2285,7 +2284,7 @@ static const char *nircode[] = {
* pr_icmph --
* Print a descriptive string about an ICMP header.
*/
void
static void
pr_icmph(struct icmp6_hdr *icp, u_char *end)
{
char ntop_buf[INET6_ADDRSTRLEN];
@ -2515,7 +2514,7 @@ pr_icmph(struct icmp6_hdr *icp, u_char *end)
* pr_iph --
* Print an IP6 header.
*/
void
static void
pr_iph(struct ip6_hdr *ip6)
{
u_int32_t flow = ip6->ip6_flow & IPV6_FLOWLABEL_MASK;
@ -2543,7 +2542,7 @@ pr_iph(struct ip6_hdr *ip6)
* Return an ascii host address as a dotted quad and optionally with
* a hostname.
*/
const char *
static const char *
pr_addr(struct sockaddr *addr, int addrlen)
{
static char buf[NI_MAXHOST];
@ -2562,13 +2561,13 @@ pr_addr(struct sockaddr *addr, int addrlen)
* pr_retip --
* Dump some info on a returned (via ICMPv6) IPv6 packet.
*/
void
static void
pr_retip(struct ip6_hdr *ip6, u_char *end)
{
u_char *cp = (u_char *)ip6, nh;
int hlen;
if (end - (u_char *)ip6 < sizeof(*ip6)) {
if ((size_t)(end - (u_char *)ip6) < sizeof(*ip6)) {
printf("IP6");
goto trunc;
}
@ -2642,7 +2641,7 @@ pr_retip(struct ip6_hdr *ip6, u_char *end)
return;
}
void
static void
fill(char *bp, char *patp)
{
int ii, jj, kk;
@ -2661,7 +2660,7 @@ fill(char *bp, char *patp)
/* xxx */
if (ii > 0)
for (kk = 0;
kk <= MAXDATALEN - (8 + sizeof(struct tv32) + ii);
(size_t)kk <= MAXDATALEN - 8 + sizeof(struct tv32) + ii;
kk += ii)
for (jj = 0; jj < ii; ++jj)
bp[jj + kk] = pat[jj];
@ -2675,7 +2674,7 @@ fill(char *bp, char *patp)
#ifdef IPSEC
#ifdef IPSEC_POLICY_IPSEC
int
static int
setpolicy(int so __unused, char *policy)
{
char *buf;
@ -2696,7 +2695,7 @@ setpolicy(int so __unused, char *policy)
#endif
#endif
char *
static char *
nigroup(char *name, int nig_oldmcprefix)
{
char *p;
@ -2755,7 +2754,7 @@ nigroup(char *name, int nig_oldmcprefix)
return strdup(hbuf);
}
void
static void
usage(void)
{
(void)fprintf(stderr,

View File

@ -567,6 +567,7 @@ MAN= aac.4 \
${_virtio_scsi.4} \
vkbd.4 \
vlan.4 \
vxlan.4 \
${_vmx.4} \
vpo.4 \
vr.4 \
@ -743,6 +744,7 @@ MLINKS+=urndis.4 if_urndis.4
MLINKS+=${_urtw.4} ${_if_urtw.4}
MLINKS+=vge.4 if_vge.4
MLINKS+=vlan.4 if_vlan.4
MLINKS+=vxlan.4 if_vxlan.4
MLINKS+=${_vmx.4} ${_if_vmx.4}
MLINKS+=vpo.4 imm.4
MLINKS+=vr.4 if_vr.4

View File

@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd October 16, 2014
.Dd October 20, 2014
.Dt "VIRTUAL TERMINALS" 4
.Os
.Sh NAME
@ -273,7 +273,8 @@ on a black background, or black on a bright red background when reversed.
.Xr getty 8 ,
.Xr kbdmux 8 ,
.Xr kldload 8 ,
.Xr moused 8
.Xr moused 8 ,
.Xr vtfontcvt 8
.Sh HISTORY
The
.Nm

235
share/man/man4/vxlan.4 Normal file
View File

@ -0,0 +1,235 @@
.\" Copyright (c) 2014 Bryan Venteicher
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $FreeBSD$
.\"
.Dd October 20, 2014
.Dt VXLAN 4
.Os
.Sh NAME
.Nm vxlan
.Nd "Virtual eXtensible LAN interface"
.Sh SYNOPSIS
To compile this driver into the kernel,
place the following line in your
kernel configuration file:
.Bd -ragged -offset indent
.Cd "device vxlan"
.Ed
.Pp
Alternatively, to load the driver as a
module at boot time, place the following line in
.Xr loader.conf 5 :
.Bd -literal -offset indent
if_vxlan_load="YES"
.Ed
.Sh DESCRIPTION
The
.Nm
driver creates a virtual tunnel endpoint in a
.Nm
segment.
A
.Nm
segment is a virtual Layer 2 (Ethernet) network that is overlaid
in a Layer 3 (IP/UDP) network.
.Nm
is analogous to
.Xr vlan 4
but is designed to be better suited for large, multiple tenant
data center environments.
.Pp
Each
.Nm
interface is created at runtime using interface cloning.
This is most easily done with the
.Xr ifconfig 8
.Cm create
command or using the
.Va cloned_interfaces
variable in
.Xr rc.conf 5 .
The interface may be removed with the
.Xr ifconfig 8
.Cm destroy
command.
.Pp
The
.Nm
driver creates a pseudo Ethernet network interface
that supports the usual network
.Xr ioctl 2 Ns s
and is thus can be used with
.Xr ifconfig 8
like any other Ethernet interface.
The
.Nm
interface encapsulates the Ethernet frame
by prepending IP/UDP and
.Nm
headers.
Thus, the encapsulated (inner) frame is able to transmitted
over a routed, Layer 3 network to the remote host.
.Pp
The
.Nm
interface may be configured in either unicast or multicast mode.
When in unicast mode,
the interface creates a tunnel to a single remote host,
and all traffic is transmitted to that host.
When in multicast mode,
the interface joins an IP multicast group,
and receives packets sent to the group address,
and transmits packets to either the multicast group address,
or directly the remote host if there is an appropriate
forwarding table entry.
.Pp
When the
.Nm
interface is brought up, a
.Xr UDP 4
.Xr socket 9
is created based on the configuration,
such as the local address for unicast mode or
the group address for multicast mode,
and the listening (local) port number.
Since multiple
.Nm
interfaces may be created that either
use the same local address
or join the same group address,
and use the same port,
the driver may share a socket among multiple interfaces.
However, each interface within a socket must belong to
a unique
.Nm
segment.
The analogous
.Xr vlan 4
configuration would be a physical interface configured as
the parent device for multiple VLAN interfaces, each with
a unique VLAN tag.
Each
.Nm
segment is identified by a 24-bit value in the
.Nm
header called the
.Dq VXLAN Network Identifier ,
or VNI.
.Pp
When configured with the
.Xr ifconfig 8
.Cm learn
parameter, the interface dynamically creates forwarding table entries
from received packets.
An entry in the forwarding table maps the inner source MAC address
to the outer remote IP address.
During transmit, the interface attempts to lookup an entry for
the encapsulated destination MAC address.
If an entry is found, the IP address in the entry is used to directly
transmit the encapsulated frame to the destination.
Otherwise, when configured in multicast mode,
the interface must flood the frame to all hosts in the group.
The maximum number of entries in the table is configurable with the
.Xr ifconfig 8
.Cm maxaddr
command.
Stale entries in the table periodically pruned.
The timeout is configurable with the
.Xr ifconfig 8
.Cm timeout
command.
The table may be viewed with the
.Xr sysctl 8
.Cm net.link.vlxan.N.ftable.dump
command.
.Sh MTU
Since the
.Nm
interface encapsulates the Ethernet frame with an IP, UDP, and
.Nm
header, the resulting frame may be larger than the MTU of the
physical network.
The
.Nm
specification recommends the physical network MTU be configured
to use jumbo frames to accommodate the encapsulated frame size.
Alternatively, the
.Xr ifconfig 8
.Cm mtu
command may be used to reduce the MTU size on the
.Nm
interface to allow the encapsulated frame to fit in the
current MTU of the physical network.
.Sh EXAMPLES
Create a
.Nm
interface in unicast mode
with the
.Cm local
tunnel address of 192.168.100.1,
and the
.Cm remote
tunnel address of 192.168.100.2.
.Bd -literal -offset indent
ifconfig vxlan create vni 108 local 192.168.100.1 remote 192.168.100.2
.Ed
.Pp
Create a
.Nm
interface in multicast mode,
with the
.Cm local
address of 192.168.10.95,
and the
.Cm group
address of 224.0.2.6.
The em0 interface will be used to transmit multicast packets.
.Bd -literal -offset indent
ifconfig vxlan create vni 42 local 192.168.10.95 group 224.0.2.6 vxlandev em0
.Ed
.Pp
Once created, the
.Nm
interface can be configured with
.Xr ifconfig 8 .
.Sh SEE ALSO
.Xr ifconfig 8 ,
.Xr inet 4 ,
.Xr inet 6 ,
.Xr sysctl 8 ,
.Xr vlan 8
.Rs
.%A "M. Mahalingam"
.%A "et al"
.%T "Virtual eXtensible Local Area Network (VXLAN): A Framework for Overlaying Virtualized Layer 2 Networks over Layer 3 Networks"
.%D August 2014
.%O "RFC 7348"
.Re
.Sh AUTHOR
.An -nosplit
The
.Nm
driver was written by
.An Bryan Venteicher Aq bryanv@freebsd.org .

View File

@ -11,6 +11,7 @@ MAN= crash.8 \
rc.sendmail.8 \
rc.subr.8 \
rescue.8 \
${_uefi.8} \
yp.8
MLINKS= rc.8 rc.atm.8 \
@ -25,4 +26,8 @@ MLINKS+=yp.8 NIS.8 \
yp.8 nis.8 \
yp.8 YP.8
.if ${MACHINE_CPUARCH} == "amd64"
_uefi.8= uefi.8
.endif
.include <bsd.prog.mk>

152
share/man/man8/uefi.8 Normal file
View File

@ -0,0 +1,152 @@
.\" Copyright (c) 2014 The FreeBSD Foundation
.\" 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 October 17, 2014
.Dt UEFI 8
.Os
.Sh NAME
.Nm UEFI
.Nd Unified Extensible Firmware Interface bootstrapping procedures
.Sh DESCRIPTION
The
.Nm
Unified Extensible Firmware Interface provides boot- and run-time services
to operating systems.
.Nm
is a replacement for the legacy BIOS on the i386 and amd64 CPU architectures,
and is also used on arm64 and ia64.
.Pp
The
.Nm
boot process loads system bootstrap code located in an EFI System Partition
(ESP).
The ESP is a GPT or MBR partition with a specific identifier that contains an
.Xr msdosfs 5
FAT file system with a specified file hierarchy.
.Bl -column -offset indent ".Sy Partition Scheme" ".Sy ESP Identifier"
.It Sy "Partition Scheme" Ta Sy "ESP Identifier"
.It GPT Ta C12A7328-F81F-11D2-BA4B-00A0C93EC93B
.It MBR Ta 0xEF
.El
.Pp
The
.Nm
boot process proceeds as follows:
.Bl -enum -offset indent -compact
.It
.Nm
firmware runs at power up and searches for an OS loader in the EFI system
partition.
The path to the loader may be set by an EFI environment variable.
If not set, the default is
.Pa /EFI/BOOT/BOOTX64.EFI .
The default
.Nm
boot configuration for
.Fx
installs
.Pa boot1.efi
as
.Pa /EFI/BOOT/BOOTX64.EFI .
.It
.Pa boot1.efi
locates the first partition with the type
.Li freebsd-ufs ,
and from it loads
.Pa loader.efi .
.It
.Pa loader.efi
loads and boots the kernel, as described in
.Xr loader 8 .
.El
.Pp
The
.Xr vt 4
system console is automatically selected when booting via
.Nm .
.Sh FILES
.Bl -tag -width /boot/loader -compact
.It Pa /boot/boot1.efi
First stage
.Nm
bootstrap
.It Pa /boot/boot1.efifat
.Xr msdosfs 5
FAT file system image containing
.Pa boot1.efi
for use by
.Xr bsdinstall 8
and the
.Ar bootcode
argument to
.Xr gpart 8 .
.It Pa /boot/loader.efi
Final stage bootstrap
.It Pa /boot/kernel/kernel
default kernel
.It Pa /boot/kernel.old/kernel
typical non-default kernel (optional)
.El
.Sh SEE ALSO
.Xr vt 4 ,
.Xr msdosfs 5 ,
.Xr boot 8 ,
.Xr gpart 8
.Sh HISTORY
.Nm
boot support first appeared in
.Fx 10.1 .
.Sh AUTHORS
.An -nosplit
.Nm
boot support was developed by
.An Benno Rice Aq Mt benno@FreeBSD.org ,
.An Ed Maste Aq Mt emaste@FreeBSD.org ,
and
.An Nathan Whitehorn Aq Mt nwhitehorn@FreeBSD.org .
The
.Fx
Foundation sponsored portions of the work.
.Sh CAVEATS
EFI environment variables are not supported by
.Xr loader 8
or the kernel.
.Pp
.Pa boot1.efi
loads
.Pa loader.efi
from the first FreeBSD-UFS file system it locates, even if it is on a
different disk.
.Pp
.Pa boot1.efi
cannot load
.Pa loader.efi
from a
.Xr ZFS 8
file system.
As a result,
.Nm
does not support a typical root file system on ZFS configuration.

View File

@ -26,7 +26,7 @@
.\" $OpenBSD: hash.9,v 1.5 2003/04/17 05:08:39 jmc Exp $
.\" $FreeBSD$
.\"
.Dd September 4, 2012
.Dd October 18, 2014
.Dt HASH 9
.Os
.Sh NAME
@ -37,8 +37,10 @@
.Nm hash32_strn ,
.Nm hash32_stre ,
.Nm hash32_strne ,
.Nm jenkins_hash ,
.Nm jenkins_hash32 ,
.Nm jenkins_hash
.Nm murmur3_32_hash ,
.Nm murmur3_32_hash32
.Nd general kernel hashing functions
.Sh SYNOPSIS
.In sys/hash.h
@ -56,6 +58,10 @@
.Fn jenkins_hash "const void *buf" "size_t len" "uint32_t hash"
.Ft uint32_t
.Fn jenkins_hash32 "const uint32_t *buf" "size_t count" "uint32_t hash"
.Ft uint32_t
.Fn murmur3_32_hash "const void *buf" "size_t len" "uint32_t hash"
.Ft uint32_t
.Fn murmur3_32_hash32 "const uint32_t *buf" "size_t count" "uint32_t hash"
.Sh DESCRIPTION
The
.Fn hash32
@ -130,6 +136,16 @@ sized arrays, thus is simplier and faster.
It accepts an array of
.Ft uint32_t
values in its first argument and size of this array in the second argument.
.Pp
The
.Fn murmur3_32_hash
and
.Fn murmur3_32_hash32
functions are similar to
.Fn jenkins_hash
and
.Fn jenkins_hash32 ,
but implement the 32-bit version of MurmurHash3.
.Sh RETURN VALUES
The
.Fn hash32
@ -185,6 +201,10 @@ The
.Nm jenkins_hash
functions were added in
.Fx 10.0 .
The
.Nm murmur3_32_hash
functions were added in
.Fx 10.1 .
.Sh AUTHORS
The
.Nm hash32
@ -192,5 +212,9 @@ functions were written by
.An Tobias Weingartner .
The
.Nm jenkins_hash
functions was written by
Bob Jenkins .
functions were written by
.An Bob Jenkins .
The
.Nm murmur3_32_hash
functions were written by
.An Dag-Erling Sm\(/orgrav Aq Mt des@FreeBSD.org .

View File

@ -315,6 +315,8 @@ FreeBSD 5.2 | | | |
| FreeBSD | | | |
| 9.3 | | | |
| | | | DragonFly 3.8.2
| Mac OS X | | |
| 10.10 | | |
| | | | |
| | | | |
| | | | |
@ -653,6 +655,7 @@ DragonFly 3.8.1 2014-06-16 [DFB]
DragonFly 3.6.3 2014-06-17 [DFB]
FreeBSD 9.3 2014-07-05 [FBD]
DragonFly 3.8.2 2014-08-08 [DFB]
Mac OS X 10.10 2014-10-16 [APL]
Bibliography
------------------------

View File

@ -21,3 +21,4 @@ arm/altera/socfpga/socfpga_mp.c optional smp
dev/dwc/if_dwc.c optional dwc
dev/mmc/host/dwmmc.c optional dwmmc
dev/beri/beri_ring.c optional beri_ring

View File

@ -245,6 +245,29 @@ cb_dumphdr(struct md_pa *mdp, int seqnr, void *arg)
return (error);
}
/*
* Add a header to be used by libkvm to get the va to pa delta
*/
static int
dump_os_header(struct dumperinfo *di)
{
Elf_Phdr phdr;
int error;
bzero(&phdr, sizeof(phdr));
phdr.p_type = PT_DUMP_DELTA;
phdr.p_flags = PF_R; /* XXX */
phdr.p_offset = 0;
phdr.p_vaddr = KERNVIRTADDR;
phdr.p_paddr = pmap_kextract(KERNVIRTADDR);
phdr.p_filesz = 0;
phdr.p_memsz = 0;
phdr.p_align = PAGE_SIZE;
error = buf_write(di, (char*)&phdr, sizeof(phdr));
return (error);
}
static int
cb_size(struct md_pa *mdp, int seqnr, void *arg)
{
@ -308,7 +331,7 @@ dumpsys(struct dumperinfo *di)
/* Calculate dump size. */
dumpsize = 0L;
ehdr.e_phnum = foreach_chunk(cb_size, &dumpsize);
ehdr.e_phnum = foreach_chunk(cb_size, &dumpsize) + 1;
hdrsz = ehdr.e_phoff + ehdr.e_phnum * ehdr.e_phentsize;
fileofs = MD_ALIGN(hdrsz);
dumpsize += fileofs;
@ -325,7 +348,7 @@ dumpsys(struct dumperinfo *di)
mkdumpheader(&kdh, KERNELDUMPMAGIC, KERNELDUMP_ARM_VERSION, dumpsize, di->blocksize);
printf("Dumping %llu MB (%d chunks)\n", (long long)dumpsize >> 20,
ehdr.e_phnum);
ehdr.e_phnum - 1);
/* Dump leader */
error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
@ -340,6 +363,8 @@ dumpsys(struct dumperinfo *di)
/* Dump program headers */
error = foreach_chunk(cb_dumphdr, di);
if (error >= 0)
error = dump_os_header(di);
if (error < 0)
goto fail;
buf_flush(di);

36
sys/arm/arm/elf_note.S Normal file
View File

@ -0,0 +1,36 @@
/*-
* Copyright (c) 2014 Andrew Turner <andrew@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <machine/asmacros.h>
/* An ELF note so GDB detects this as a FreeBSD elf file */
ELFNOTE(.note.tag, 1, "FreeBSD", .long, __FreeBSD_version);

View File

@ -42,6 +42,18 @@
__FBSDID("$FreeBSD$");
/*
* Sanity check the configuration.
* FLASHADDR and LOADERRAMADDR depend on PHYSADDR in some cases.
* ARMv4 and ARMv5 make assumptions on where they are loaded.
*
* TODO: Fix the ARMv4/v5 case.
*/
#if (defined(FLASHADDR) || defined(LOADERRAMADDR) || !defined(_ARM_ARCH_6)) && \
!defined(PHYSADDR)
#error PHYSADDR must be defined for this configuration
#endif
/* What size should this really be ? It is only used by initarm() */
#define INIT_ARM_STACK_SIZE (2048 * 4)
@ -54,15 +66,21 @@ __FBSDID("$FreeBSD$");
CPWAIT_BRANCH /* branch to next insn */
/*
* This is for kvm_mkdb, and should be the address of the beginning
* This is for libkvm, and should be the address of the beginning
* of the kernel text segment (not necessarily the same as kernbase).
*
* These are being phased out. Newer copies of libkvm don't need these
* values as the information is added to the core file by inspecting
* the running kernel.
*/
.text
.align 0
#ifdef PHYSADDR
.globl kernbase
.set kernbase,KERNBASE
.globl physaddr
.set physaddr,PHYSADDR
#endif
/*
* On entry for FreeBSD boot ABI:

View File

@ -395,7 +395,7 @@ bcm_bsc_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
/* If the controller is busy wait until it is available. */
while (sc->sc_flags & BCM_I2C_BUSY)
mtx_sleep(dev, &sc->sc_mtx, 0, "bcm_bsc", 0);
mtx_sleep(dev, &sc->sc_mtx, 0, "bscbusw", 0);
/* Now we have control over the BSC controller. */
sc->sc_flags = BCM_I2C_BUSY;
@ -439,19 +439,21 @@ bcm_bsc_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
BCM_BSC_CTRL_ST | read | intr);
/* Wait for the transaction to complete. */
err = mtx_sleep(dev, &sc->sc_mtx, 0, "bcm_bsc", hz);
err = mtx_sleep(dev, &sc->sc_mtx, 0, "bsciow", hz);
/* Check if we have a timeout or an I2C error. */
if ((sc->sc_flags & BCM_I2C_ERROR) || err == EWOULDBLOCK) {
device_printf(sc->sc_dev, "I2C error\n");
/* Check for errors. */
if (err != 0 && (sc->sc_flags & BCM_I2C_ERROR))
err = EIO;
if (err != 0)
break;
}
}
/* Clean the controller flags. */
sc->sc_flags = 0;
/* Wake up the threads waiting for bus. */
wakeup(dev);
BCM_BSC_UNLOCK(sc);
return (err);

View File

@ -312,21 +312,15 @@ RD4(struct bcm_sdhci_softc *sc, bus_size_t off)
static inline void
WR4(struct bcm_sdhci_softc *sc, bus_size_t off, uint32_t val)
{
bus_space_write_4(sc->sc_bst, sc->sc_bsh, off, val);
if ((off != SDHCI_BUFFER && off != SDHCI_INT_STATUS && off != SDHCI_CLOCK_CONTROL))
{
int timeout = 100000;
while (val != bus_space_read_4(sc->sc_bst, sc->sc_bsh, off)
&& --timeout > 0)
continue;
if (timeout <= 0)
printf("sdhci_brcm: writing 0x%X to reg 0x%X "
"always gives 0x%X\n",
val, (uint32_t)off,
bus_space_read_4(sc->sc_bst, sc->sc_bsh, off));
}
/*
* The Arasan HC has a bug where it may lose the content of
* consecutive writes to registers that are within two SD-card
* clock cycles of each other (a clock domain crossing problem).
*/
if (sc->sc_slot.clock > 0)
DELAY(((2 * 1000000) / sc->sc_slot.clock) + 1);
}
static uint8_t

View File

@ -108,6 +108,18 @@ device gpioled
# ADC support
device ti_adc
# Watchdog support
# If we don't enable the watchdog driver, the system could potentially
# reboot automatically because the boot loader might have enabled the
# watchdog.
device ti_wdt
# TI Programmable Realtime Unit support
device ti_pruss
# Mailbox support
device ti_mbox
# USB support
device usb
options USB_HOST_ALIGN=64 # Align usb buffers to cache line size.

140
sys/arm/conf/SOCKIT-BERI Normal file
View File

@ -0,0 +1,140 @@
# Kernel configuration for Terasic SoCKit (Altera Cyclone V SoC).
#
# For more information on this file, please read the config(5) manual page,
# and/or the handbook section on Kernel Configuration Files:
#
# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
#
# The handbook is also available locally in /usr/share/doc/handbook
# if you've installed the doc distribution, otherwise always see the
# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the
# latest information.
#
# An exhaustive list of options and more detailed explanations of the
# device lines is also present in the ../../conf/NOTES and NOTES files.
# If you are in doubt as to the purpose or necessity of a line, check first
# in NOTES.
#
# $FreeBSD$
ident SOCKIT-BERI
include "../altera/socfpga/std.socfpga"
makeoptions MODULES_OVERRIDE=""
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
makeoptions WERROR="-Werror"
options HZ=100
options SCHED_4BSD # 4BSD scheduler
options INET # InterNETworking
options INET6 # IPv6 communications protocols
options GEOM_PART_BSD # BSD partition scheme
options GEOM_PART_MBR # MBR partition scheme
options GEOM_PART_GPT # GUID partition tables
options TMPFS # Efficient memory filesystem
options FFS # Berkeley Fast Filesystem
options SOFTUPDATES
options UFS_ACL # Support for access control lists
options UFS_DIRHASH # Improve performance on big directories
options MSDOSFS # MSDOS Filesystem
options CD9660 # ISO 9660 Filesystem
options PROCFS # Process filesystem (requires PSEUDOFS)
options PSEUDOFS # Pseudo-filesystem framework
options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!]
options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
options KTRACE
options SYSVSHM # SYSV-style shared memory
options SYSVMSG # SYSV-style message queues
options SYSVSEM # SYSV-style semaphores
options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
options KBD_INSTALL_CDEV
options PREEMPTION
options FREEBSD_BOOT_LOADER
options VFP # vfp/neon
options SMP
# Debugging
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
options BREAK_TO_DEBUGGER
#options VERBOSE_SYSINIT # Enable verbose sysinit messages
options KDB
options DDB # Enable the kernel debugger
options INVARIANTS # Enable calls of extra sanity checking
options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
#options WITNESS # Enable checks to detect deadlocks and cycles
#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
#options DIAGNOSTIC
# NFS support
options NFSCL # Network Filesystem Client
options NFSLOCKD # Network Lock Manager
options NFS_ROOT # NFS usable as /, requires NFSCLIENT
# Uncomment this for NFS root
#options NFS_ROOT # NFS usable as /, requires NFSCL
#options BOOTP_NFSROOT
#options BOOTP_COMPAT
#options BOOTP
#options BOOTP_NFSV3
#options BOOTP_WIRED_TO=ue0
device mmc # mmc/sd bus
device mmcsd # mmc/sd flash cards
device dwmmc
options ROOTDEVNAME=\"ufs:/dev/mmcsd0s4\"
# Pseudo devices
device loop
device random
device pty
device md
device gpio
# USB support
options USB_HOST_ALIGN=64 # Align usb buffers to cache line size.
device usb
options USB_DEBUG
#options USB_REQ_DEBUG
#options USB_VERBOSE
#device musb
device dwcotg
device umass
device scbus # SCSI bus (required for ATA/SCSI)
device da # Direct Access (disks)
device pass
# Serial ports
device uart
device uart_ns8250
# I2C (TWSI)
device iic
device iicbus
# SPI
device spibus
# BERI specific
device beri_ring
# Ethernet
device ether
device mii
device smsc
device smscphy
device dwc
# USB ethernet support, requires miibus
device miibus
device axe # ASIX Electronics USB Ethernet
device bpf # Berkeley packet filter
#FDT
options FDT
options FDT_DTB_STATIC
makeoptions FDT_DTS_FILE=socfpga-sockit-beri.dts

View File

@ -98,6 +98,7 @@ struct imx6_anatop_softc {
uint32_t cpu_maxmv;
uint32_t cpu_maxmhz_hw;
boolean_t cpu_overclock_enable;
boolean_t cpu_init_done;
uint32_t refosc_mhz;
void *temp_intrhand;
uint32_t temp_high_val;
@ -623,6 +624,31 @@ intr_setup(void *arg)
config_intrhook_disestablish(&sc->intr_setup_hook);
}
static void
imx6_anatop_new_pass(device_t dev)
{
struct imx6_anatop_softc *sc;
const int cpu_init_pass = BUS_PASS_CPU + BUS_PASS_ORDER_MIDDLE;
/*
* We attach during BUS_PASS_BUS (because some day we will be a
* simplebus that has regulator devices as children), but some of our
* init work cannot be done until BUS_PASS_CPU (we rely on other devices
* that attach on the CPU pass).
*/
sc = device_get_softc(dev);
if (!sc->cpu_init_done && bus_current_pass >= cpu_init_pass) {
sc->cpu_init_done = true;
cpufreq_initialize(sc);
initialize_tempmon(sc);
if (bootverbose) {
device_printf(sc->dev, "CPU %uMHz @ %umV\n",
sc->cpu_curmhz, sc->cpu_curmv);
}
}
bus_generic_new_pass(dev);
}
static int
imx6_anatop_detach(device_t dev)
{
@ -666,13 +692,13 @@ imx6_anatop_attach(device_t dev)
imx6_anatop_write_4(IMX6_ANALOG_PMU_MISC0_SET,
IMX6_ANALOG_PMU_MISC0_SELFBIASOFF);
cpufreq_initialize(sc);
initialize_tempmon(sc);
/*
* Some day, when we're ready to deal with the actual anatop regulators
* that are described in fdt data as children of this "bus", this would
* be the place to invoke a simplebus helper routine to instantiate the
* children from the fdt data.
*/
if (bootverbose) {
device_printf(sc->dev, "CPU %uMHz @ %umV\n", sc->cpu_curmhz,
sc->cpu_curmv);
}
err = 0;
out:
@ -715,6 +741,9 @@ static device_method_t imx6_anatop_methods[] = {
DEVMETHOD(device_attach, imx6_anatop_attach),
DEVMETHOD(device_detach, imx6_anatop_detach),
/* Bus interface */
DEVMETHOD(bus_new_pass, imx6_anatop_new_pass),
DEVMETHOD_END
};
@ -727,5 +756,7 @@ static driver_t imx6_anatop_driver = {
static devclass_t imx6_anatop_devclass;
EARLY_DRIVER_MODULE(imx6_anatop, simplebus, imx6_anatop_driver,
imx6_anatop_devclass, 0, 0, BUS_PASS_CPU + BUS_PASS_ORDER_FIRST + 1);
imx6_anatop_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);
EARLY_DRIVER_MODULE(imx6_anatop, ofwbus, imx6_anatop_driver,
imx6_anatop_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);

View File

@ -45,6 +45,18 @@
ldr tmp, [tmp, #PC_CURTHREAD]
#endif
#define ELFNOTE(section, type, vendor, desctype, descdata...) \
.pushsection section ; \
.balign 4 ; \
.long 2f - 1f /* namesz */ ; \
.long 4f - 3f /* descsz */ ; \
.long type /* type */ ; \
1: .asciz vendor /* vendor name */ ; \
2: .balign 4 ; \
3: desctype descdata /* node */ ; \
4: .balign 4 ; \
.popsection
#endif /* LOCORE */
#endif /* _KERNEL */

View File

@ -0,0 +1,156 @@
/*-
* Copyright (c) 2012 Damjan Marion <dmarion@FreeBSD.org>
* Copyright (c) 2014 Andrew Turner <andrew@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/resource.h>
#include <sys/rman.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/intr.h>
#include <sys/gpio.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <arm/ti/ti_cpuid.h>
#include <arm/ti/ti_gpio.h>
#include <arm/ti/ti_scm.h>
#include <arm/ti/am335x/am335x_scm_padconf.h>
#include "ti_gpio_if.h"
static struct ofw_compat_data compat_data[] = {
{"ti,am335x-gpio", 1},
/* Linux uses ti,omap4-gpio on am335x so we need to support it */
{"ti,omap4-gpio", 1},
{"ti,gpio", 1},
{NULL, 0},
};
static int
am335x_gpio_probe(device_t dev)
{
if (ti_chip() != CHIP_AM335X)
return (ENXIO);
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
return (ENXIO);
device_set_desc(dev, "Ti AM335x General Purpose I/O (GPIO)");
return (0);
}
static int
am335x_gpio_set_flags(device_t dev, uint32_t gpio, uint32_t flags)
{
unsigned int state = 0;
if (flags & GPIO_PIN_OUTPUT) {
if (flags & GPIO_PIN_PULLUP)
state = PADCONF_OUTPUT_PULLUP;
else
state = PADCONF_OUTPUT;
} else if (flags & GPIO_PIN_INPUT) {
if (flags & GPIO_PIN_PULLUP)
state = PADCONF_INPUT_PULLUP;
else if (flags & GPIO_PIN_PULLDOWN)
state = PADCONF_INPUT_PULLDOWN;
else
state = PADCONF_INPUT;
}
return ti_scm_padconf_set_gpiomode(gpio, state);
}
static int
am335x_gpio_get_flags(device_t dev, uint32_t gpio, uint32_t *flags)
{
unsigned int state;
if (ti_scm_padconf_get_gpiomode(gpio, &state) != 0) {
*flags = 0;
return (EINVAL);
} else {
switch (state) {
case PADCONF_OUTPUT:
*flags = GPIO_PIN_OUTPUT;
break;
case PADCONF_OUTPUT_PULLUP:
*flags = GPIO_PIN_OUTPUT | GPIO_PIN_PULLUP;
break;
case PADCONF_INPUT:
*flags = GPIO_PIN_INPUT;
break;
case PADCONF_INPUT_PULLUP:
*flags = GPIO_PIN_INPUT | GPIO_PIN_PULLUP;
break;
case PADCONF_INPUT_PULLDOWN:
*flags = GPIO_PIN_INPUT | GPIO_PIN_PULLDOWN;
break;
default:
*flags = 0;
break;
}
}
return (0);
}
static device_method_t am335x_gpio_methods[] = {
/* bus interface */
DEVMETHOD(device_probe, am335x_gpio_probe),
/* ti_gpio interface */
DEVMETHOD(ti_gpio_set_flags, am335x_gpio_set_flags),
DEVMETHOD(ti_gpio_get_flags, am335x_gpio_get_flags),
DEVMETHOD_END
};
extern driver_t ti_gpio_driver;
static devclass_t am335x_gpio_devclass;
DEFINE_CLASS_1(gpio, am335x_gpio_driver, am335x_gpio_methods,
sizeof(struct ti_gpio_softc), ti_gpio_driver);
DRIVER_MODULE(am335x_gpio, simplebus, am335x_gpio_driver, am335x_gpio_devclass,
0, 0);

View File

@ -47,6 +47,8 @@ __FBSDID("$FreeBSD$");
#include <arm/ti/tivar.h>
#include <arm/ti/ti_scm.h>
#include <arm/ti/am335x/am335x_scm_padconf.h>
#define _PIN(r, b, gp, gm, m0, m1, m2, m3, m4, m5, m6, m7) \
{ .reg_off = r, \
.gpio_pin = gp, \
@ -62,18 +64,6 @@ __FBSDID("$FreeBSD$");
.muxmodes[7] = m7, \
}
#define SLEWCTRL (0x01 << 6) /* faster(0) or slower(1) slew rate. */
#define RXACTIVE (0x01 << 5) /* Input enable value for the Pad */
#define PULLTYPESEL (0x01 << 4) /* Pad pullup/pulldown type selection */
#define PULLUDEN (0x01 << 3) /* Pullup/pulldown disabled */
#define PADCONF_OUTPUT (0)
#define PADCONF_OUTPUT_PULLUP (PULLTYPESEL)
#define PADCONF_INPUT (RXACTIVE | PULLUDEN)
#define PADCONF_INPUT_PULLUP (RXACTIVE | PULLTYPESEL)
#define PADCONF_INPUT_PULLDOWN (RXACTIVE)
#define PADCONF_INPUT_PULLUP_SLOW (PADCONF_INPUT_PULLUP | SLEWCTRL)
const static struct ti_scm_padstate ti_padstate_devmap[] = {
{"output", PADCONF_OUTPUT },
{"output_pullup", PADCONF_OUTPUT_PULLUP },
@ -311,54 +301,3 @@ const struct ti_scm_device ti_scm_dev = {
.padstate = (struct ti_scm_padstate *) &ti_padstate_devmap,
.padconf = (struct ti_scm_padconf *) &ti_padconf_devmap,
};
int
ti_scm_padconf_set_gpioflags(uint32_t gpio, uint32_t flags)
{
unsigned int state = 0;
if (flags & GPIO_PIN_OUTPUT) {
if (flags & GPIO_PIN_PULLUP)
state = PADCONF_OUTPUT_PULLUP;
else
state = PADCONF_OUTPUT;
} else if (flags & GPIO_PIN_INPUT) {
if (flags & GPIO_PIN_PULLUP)
state = PADCONF_INPUT_PULLUP;
else if (flags & GPIO_PIN_PULLDOWN)
state = PADCONF_INPUT_PULLDOWN;
else
state = PADCONF_INPUT;
}
return ti_scm_padconf_set_gpiomode(gpio, state);
}
void
ti_scm_padconf_get_gpioflags(uint32_t gpio, uint32_t *flags)
{
unsigned int state;
if (ti_scm_padconf_get_gpiomode(gpio, &state) != 0)
*flags = 0;
else {
switch (state) {
case PADCONF_OUTPUT:
*flags = GPIO_PIN_OUTPUT;
break;
case PADCONF_OUTPUT_PULLUP:
*flags = GPIO_PIN_OUTPUT | GPIO_PIN_PULLUP;
break;
case PADCONF_INPUT:
*flags = GPIO_PIN_INPUT;
break;
case PADCONF_INPUT_PULLUP:
*flags = GPIO_PIN_INPUT | GPIO_PIN_PULLUP;
break;
case PADCONF_INPUT_PULLDOWN:
*flags = GPIO_PIN_INPUT | GPIO_PIN_PULLDOWN;
break;
default:
*flags = 0;
break;
}
}
}

View File

@ -0,0 +1,44 @@
/*-
* Copyright (c) 2012 Damjan Marion <dmarion@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef AM335X_SCM_PADCONF_H
#define AM335X_SCM_PADCONF_H
#define SLEWCTRL (0x01 << 6) /* faster(0) or slower(1) slew rate. */
#define RXACTIVE (0x01 << 5) /* Input enable value for the Pad */
#define PULLTYPESEL (0x01 << 4) /* Pad pullup/pulldown type selection */
#define PULLUDEN (0x01 << 3) /* Pullup/pulldown disabled */
#define PADCONF_OUTPUT (0)
#define PADCONF_OUTPUT_PULLUP (PULLTYPESEL)
#define PADCONF_INPUT (RXACTIVE | PULLUDEN)
#define PADCONF_INPUT_PULLUP (RXACTIVE | PULLTYPESEL)
#define PADCONF_INPUT_PULLDOWN (RXACTIVE)
#define PADCONF_INPUT_PULLUP_SLOW (PADCONF_INPUT_PULLUP | SLEWCTRL)
#endif /* AM335X_SCM_PADCONF_H */

View File

@ -3,6 +3,7 @@
arm/ti/aintc.c standard
arm/ti/am335x/am335x_dmtimer.c standard
arm/ti/am335x/am335x_gpio.c optional gpio
arm/ti/am335x/am335x_lcd.c optional sc
arm/ti/am335x/am335x_lcd_syscons.c optional sc
arm/ti/am335x/am335x_pmic.c optional am335x_pmic

View File

@ -15,12 +15,13 @@ arm/ti/ti_cpuid.c standard
arm/ti/ti_machdep.c standard
arm/ti/ti_prcm.c standard
arm/ti/ti_scm.c standard
dev/mbox/mbox_if.m standard
arm/ti/ti_mbox.c standard
arm/ti/ti_pruss.c standard
dev/mbox/mbox_if.m optional ti_mbox
arm/ti/ti_mbox.c optional ti_mbox
arm/ti/ti_pruss.c optional ti_pruss
arm/ti/ti_wdt.c optional ti_wdt
arm/ti/ti_adc.c optional ti_adc
arm/ti/ti_gpio.c optional gpio
arm/ti/ti_gpio_if.m optional gpio
arm/ti/ti_i2c.c optional ti_i2c
arm/ti/ti_sdhci.c optional sdhci

View File

@ -7,6 +7,7 @@ arm/ti/ti_smc.S standard
arm/ti/usb/omap_ehci.c optional usb ehci
arm/ti/ti_sdma.c optional ti_sdma
arm/ti/omap4/omap4_gpio.c optional gpio
arm/ti/omap4/omap4_l2cache.c optional pl310
arm/ti/omap4/omap4_prcm_clks.c standard
arm/ti/omap4/omap4_scm_padconf.c standard

View File

@ -0,0 +1,143 @@
/*-
* Copyright (c) 2011 Ben Gray <ben.r.gray@gmail.com>.
* Copyright (c) 2014 Andrew Turner <andrew@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY BEN GRAY ``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 BEN GRAY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/gpio.h>
#include <machine/bus.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <arm/ti/ti_cpuid.h>
#include <arm/ti/ti_gpio.h>
#include <arm/ti/ti_scm.h>
#include <arm/ti/omap4/omap4_scm_padconf.h>
#include "ti_gpio_if.h"
static struct ofw_compat_data compat_data[] = {
{"ti,omap4-gpio", 1},
{"ti,gpio", 1},
{NULL, 0},
};
static int
omap4_gpio_probe(device_t dev)
{
if (ti_chip() != CHIP_OMAP_4)
return (ENXIO);
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
return (ENXIO);
device_set_desc(dev, "Ti OMAP4 General Purpose I/O (GPIO)");
return (0);
}
static int
omap4_gpio_set_flags(device_t dev, uint32_t gpio, uint32_t flags)
{
unsigned int state = 0;
/* First the SCM driver needs to be told to put the pad into GPIO mode */
if (flags & GPIO_PIN_OUTPUT)
state = PADCONF_PIN_OUTPUT;
else if (flags & GPIO_PIN_INPUT) {
if (flags & GPIO_PIN_PULLUP)
state = PADCONF_PIN_INPUT_PULLUP;
else if (flags & GPIO_PIN_PULLDOWN)
state = PADCONF_PIN_INPUT_PULLDOWN;
else
state = PADCONF_PIN_INPUT;
}
return ti_scm_padconf_set_gpiomode(gpio, state);
}
static int
omap4_gpio_get_flags(device_t dev, uint32_t gpio, uint32_t *flags)
{
unsigned int state;
/* Get the current pin state */
if (ti_scm_padconf_get_gpiomode(gpio, &state) != 0) {
*flags = 0;
return (EINVAL);
} else {
switch (state) {
case PADCONF_PIN_OUTPUT:
*flags = GPIO_PIN_OUTPUT;
break;
case PADCONF_PIN_INPUT:
*flags = GPIO_PIN_INPUT;
break;
case PADCONF_PIN_INPUT_PULLUP:
*flags = GPIO_PIN_INPUT | GPIO_PIN_PULLUP;
break;
case PADCONF_PIN_INPUT_PULLDOWN:
*flags = GPIO_PIN_INPUT | GPIO_PIN_PULLDOWN;
break;
default:
*flags = 0;
break;
}
}
return (0);
}
static device_method_t omap4_gpio_methods[] = {
/* bus interface */
DEVMETHOD(device_probe, omap4_gpio_probe),
/* ti_gpio interface */
DEVMETHOD(ti_gpio_set_flags, omap4_gpio_set_flags),
DEVMETHOD(ti_gpio_get_flags, omap4_gpio_get_flags),
DEVMETHOD_END
};
extern driver_t ti_gpio_driver;
static devclass_t omap4_gpio_devclass;
DEFINE_CLASS_1(gpio, omap4_gpio_driver, omap4_gpio_methods,
sizeof(struct ti_gpio_softc), ti_gpio_driver);
DRIVER_MODULE(omap4_gpio, simplebus, omap4_gpio_driver, omap4_gpio_devclass,
0, 0);

View File

@ -40,16 +40,9 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/intr.h>
#include <sys/gpio.h>
#include <arm/ti/tivar.h>
#include <arm/ti/ti_scm.h>
#include <arm/ti/omap4/omap4var.h>
#include <arm/ti/omap4/omap4_reg.h>
#include <arm/ti/omap4/omap4_scm_padconf.h>
/*
@ -69,53 +62,6 @@ __FBSDID("$FreeBSD$");
*
*/
#define CONTROL_PADCONF_WAKEUP_EVENT (1UL << 15)
#define CONTROL_PADCONF_WAKEUP_ENABLE (1UL << 14)
#define CONTROL_PADCONF_OFF_PULL_UP (1UL << 13)
#define CONTROL_PADCONF_OFF_PULL_ENABLE (1UL << 12)
#define CONTROL_PADCONF_OFF_OUT_HIGH (1UL << 11)
#define CONTROL_PADCONF_OFF_OUT_ENABLE (1UL << 10)
#define CONTROL_PADCONF_OFF_ENABLE (1UL << 9)
#define CONTROL_PADCONF_INPUT_ENABLE (1UL << 8)
#define CONTROL_PADCONF_PULL_UP (1UL << 4)
#define CONTROL_PADCONF_PULL_ENABLE (1UL << 3)
#define CONTROL_PADCONF_MUXMODE_MASK (0x7)
#define CONTROL_PADCONF_SATE_MASK ( CONTROL_PADCONF_WAKEUP_EVENT \
| CONTROL_PADCONF_WAKEUP_ENABLE \
| CONTROL_PADCONF_OFF_PULL_UP \
| CONTROL_PADCONF_OFF_PULL_ENABLE \
| CONTROL_PADCONF_OFF_OUT_HIGH \
| CONTROL_PADCONF_OFF_OUT_ENABLE \
| CONTROL_PADCONF_OFF_ENABLE \
| CONTROL_PADCONF_INPUT_ENABLE \
| CONTROL_PADCONF_PULL_UP \
| CONTROL_PADCONF_PULL_ENABLE )
/* Active pin states */
#define PADCONF_PIN_OUTPUT 0
#define PADCONF_PIN_INPUT CONTROL_PADCONF_INPUT_ENABLE
#define PADCONF_PIN_INPUT_PULLUP ( CONTROL_PADCONF_INPUT_ENABLE \
| CONTROL_PADCONF_PULL_ENABLE \
| CONTROL_PADCONF_PULL_UP)
#define PADCONF_PIN_INPUT_PULLDOWN ( CONTROL_PADCONF_INPUT_ENABLE \
| CONTROL_PADCONF_PULL_ENABLE )
/* Off mode states */
#define PADCONF_PIN_OFF_NONE 0
#define PADCONF_PIN_OFF_OUTPUT_HIGH ( CONTROL_PADCONF_OFF_ENABLE \
| CONTROL_PADCONF_OFF_OUT_ENABLE \
| CONTROL_PADCONF_OFF_OUT_HIGH)
#define PADCONF_PIN_OFF_OUTPUT_LOW ( CONTROL_PADCONF_OFF_ENABLE \
| CONTROL_PADCONF_OFF_OUT_ENABLE)
#define PADCONF_PIN_OFF_INPUT_PULLUP ( CONTROL_PADCONF_OFF_ENABLE \
| CONTROL_PADCONF_OFF_PULL_ENABLE \
| CONTROL_PADCONF_OFF_PULL_UP)
#define PADCONF_PIN_OFF_INPUT_PULLDOWN ( CONTROL_PADCONF_OFF_ENABLE \
| CONTROL_PADCONF_OFF_PULL_ENABLE)
#define PADCONF_PIN_OFF_WAKEUPENABLE CONTROL_PADCONF_WAKEUP_ENABLE
#define _PINDEF(r, b, gp, gm, m0, m1, m2, m3, m4, m5, m6, m7) \
{ .reg_off = r, \
.gpio_pin = gp, \
@ -355,50 +301,3 @@ const struct ti_scm_device ti_scm_dev = {
.padstate = (struct ti_scm_padstate *) &ti_padstate_devmap,
.padconf = (struct ti_scm_padconf *) &ti_padconf_devmap,
};
int
ti_scm_padconf_set_gpioflags(uint32_t gpio, uint32_t flags)
{
unsigned int state = 0;
/* First the SCM driver needs to be told to put the pad into GPIO mode */
if (flags & GPIO_PIN_OUTPUT)
state = PADCONF_PIN_OUTPUT;
else if (flags & GPIO_PIN_INPUT) {
if (flags & GPIO_PIN_PULLUP)
state = PADCONF_PIN_INPUT_PULLUP;
else if (flags & GPIO_PIN_PULLDOWN)
state = PADCONF_PIN_INPUT_PULLDOWN;
else
state = PADCONF_PIN_INPUT;
}
return ti_scm_padconf_set_gpiomode(gpio, state);
}
void
ti_scm_padconf_get_gpioflags(uint32_t gpio, uint32_t *flags)
{
unsigned int state;
/* Get the current pin state */
if (ti_scm_padconf_get_gpiomode(gpio, &state) != 0)
*flags = 0;
else {
switch (state) {
case PADCONF_PIN_OUTPUT:
*flags = GPIO_PIN_OUTPUT;
break;
case PADCONF_PIN_INPUT:
*flags = GPIO_PIN_INPUT;
break;
case PADCONF_PIN_INPUT_PULLUP:
*flags = GPIO_PIN_INPUT | GPIO_PIN_PULLUP;
break;
case PADCONF_PIN_INPUT_PULLDOWN:
*flags = GPIO_PIN_INPUT | GPIO_PIN_PULLDOWN;
break;
default:
*flags = 0;
break;
}
}
}

View File

@ -0,0 +1,81 @@
/*-
* Copyright (c) 2011
* Ben Gray <ben.r.gray@gmail.com>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY BEN GRAY ``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 BEN GRAY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef OMAP4_SCM_PADCONF_H
#define OMAP4_SCM_PADCONF_H
#define CONTROL_PADCONF_WAKEUP_EVENT (1UL << 15)
#define CONTROL_PADCONF_WAKEUP_ENABLE (1UL << 14)
#define CONTROL_PADCONF_OFF_PULL_UP (1UL << 13)
#define CONTROL_PADCONF_OFF_PULL_ENABLE (1UL << 12)
#define CONTROL_PADCONF_OFF_OUT_HIGH (1UL << 11)
#define CONTROL_PADCONF_OFF_OUT_ENABLE (1UL << 10)
#define CONTROL_PADCONF_OFF_ENABLE (1UL << 9)
#define CONTROL_PADCONF_INPUT_ENABLE (1UL << 8)
#define CONTROL_PADCONF_PULL_UP (1UL << 4)
#define CONTROL_PADCONF_PULL_ENABLE (1UL << 3)
#define CONTROL_PADCONF_MUXMODE_MASK (0x7)
#define CONTROL_PADCONF_SATE_MASK ( CONTROL_PADCONF_WAKEUP_EVENT \
| CONTROL_PADCONF_WAKEUP_ENABLE \
| CONTROL_PADCONF_OFF_PULL_UP \
| CONTROL_PADCONF_OFF_PULL_ENABLE \
| CONTROL_PADCONF_OFF_OUT_HIGH \
| CONTROL_PADCONF_OFF_OUT_ENABLE \
| CONTROL_PADCONF_OFF_ENABLE \
| CONTROL_PADCONF_INPUT_ENABLE \
| CONTROL_PADCONF_PULL_UP \
| CONTROL_PADCONF_PULL_ENABLE )
/* Active pin states */
#define PADCONF_PIN_OUTPUT 0
#define PADCONF_PIN_INPUT CONTROL_PADCONF_INPUT_ENABLE
#define PADCONF_PIN_INPUT_PULLUP ( CONTROL_PADCONF_INPUT_ENABLE \
| CONTROL_PADCONF_PULL_ENABLE \
| CONTROL_PADCONF_PULL_UP)
#define PADCONF_PIN_INPUT_PULLDOWN ( CONTROL_PADCONF_INPUT_ENABLE \
| CONTROL_PADCONF_PULL_ENABLE )
/* Off mode states */
#define PADCONF_PIN_OFF_NONE 0
#define PADCONF_PIN_OFF_OUTPUT_HIGH ( CONTROL_PADCONF_OFF_ENABLE \
| CONTROL_PADCONF_OFF_OUT_ENABLE \
| CONTROL_PADCONF_OFF_OUT_HIGH)
#define PADCONF_PIN_OFF_OUTPUT_LOW ( CONTROL_PADCONF_OFF_ENABLE \
| CONTROL_PADCONF_OFF_OUT_ENABLE)
#define PADCONF_PIN_OFF_INPUT_PULLUP ( CONTROL_PADCONF_OFF_ENABLE \
| CONTROL_PADCONF_OFF_PULL_ENABLE \
| CONTROL_PADCONF_OFF_PULL_UP)
#define PADCONF_PIN_OFF_INPUT_PULLDOWN ( CONTROL_PADCONF_OFF_ENABLE \
| CONTROL_PADCONF_OFF_PULL_ENABLE)
#define PADCONF_PIN_OFF_WAKEUPENABLE CONTROL_PADCONF_WAKEUP_ENABLE
#endif /* OMAP4_SCM_PADCONF_H */

View File

@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
#include <machine/resource.h>
#include <arm/ti/ti_cpuid.h>
#include <arm/ti/ti_gpio.h>
#include <arm/ti/ti_scm.h>
#include <arm/ti/ti_prcm.h>
@ -66,6 +67,7 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/ofw_bus_subr.h>
#include "gpio_if.h"
#include "ti_gpio_if.h"
/* Register definitions */
#define TI_GPIO_REVISION 0x0000
@ -115,9 +117,6 @@ __FBSDID("$FreeBSD$");
#define AM335X_INTR_PER_BANK 2
#define AM335X_GPIO_REV 0x50600801
#define PINS_PER_BANK 32
#define MAX_GPIO_BANKS 6
/* Maximum GPIOS possible, max of *_MAX_GPIO_BANKS * *_INTR_PER_BANK */
#define MAX_GPIO_INTRS 8
static u_int
ti_max_gpio_banks(void)
@ -224,33 +223,6 @@ static struct resource_spec ti_gpio_irq_spec[] = {
{ -1, 0, 0 }
};
/**
* Structure that stores the driver context.
*
* This structure is allocated during driver attach.
*/
struct ti_gpio_softc {
device_t sc_dev;
/*
* The memory resource(s) for the PRCM register set, when the device is
* created the caller can assign up to 6 memory regions depending on
* the SoC type.
*/
struct resource *sc_mem_res[MAX_GPIO_BANKS];
struct resource *sc_irq_res[MAX_GPIO_INTRS];
/* The handle for the register IRQ handlers. */
void *sc_irq_hdl[MAX_GPIO_INTRS];
/*
* The following describes the H/W revision of each of the GPIO banks.
*/
uint32_t sc_revision[MAX_GPIO_BANKS];
struct mtx sc_mtx;
};
/**
* Macros for driver mutex locking
*/
@ -418,7 +390,7 @@ ti_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
}
/* Get the current pin state */
ti_scm_padconf_get_gpioflags(pin, flags);
TI_GPIO_GET_FLAGS(dev, pin, flags);
TI_GPIO_UNLOCK(sc);
@ -509,7 +481,7 @@ ti_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
}
/* Set the GPIO mode and state */
if (ti_scm_padconf_set_gpioflags(pin, flags) != 0) {
if (TI_GPIO_SET_FLAGS(dev, pin, flags) != 0) {
TI_GPIO_UNLOCK(sc);
return (EINVAL);
}
@ -669,33 +641,6 @@ ti_gpio_intr(void *arg)
TI_GPIO_UNLOCK(sc);
}
/**
* ti_gpio_probe - probe function for the driver
* @dev: gpio device handle
*
* Simply sets the name of the driver
*
* LOCKING:
* None
*
* RETURNS:
* Always returns 0
*/
static int
ti_gpio_probe(device_t dev)
{
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (!ofw_bus_is_compatible(dev, "ti,gpio"))
return (ENXIO);
device_set_desc(dev, "TI General Purpose I/O (GPIO)");
return (0);
}
static int
ti_gpio_attach_intr(device_t dev)
{
@ -776,8 +721,7 @@ ti_gpio_bank_init(device_t dev, int bank)
/* Init OE register based on pads configuration. */
reg_oe = 0xffffffff;
for (pin = 0; pin < PINS_PER_BANK; pin++) {
ti_scm_padconf_get_gpioflags(PINS_PER_BANK * bank + pin,
&flags);
TI_GPIO_GET_FLAGS(dev, PINS_PER_BANK * bank + pin, &flags);
if (flags & GPIO_PIN_OUTPUT)
reg_oe &= ~(1UL << pin);
}
@ -910,7 +854,6 @@ ti_gpio_get_node(device_t bus, device_t dev)
}
static device_method_t ti_gpio_methods[] = {
DEVMETHOD(device_probe, ti_gpio_probe),
DEVMETHOD(device_attach, ti_gpio_attach),
DEVMETHOD(device_detach, ti_gpio_detach),
@ -930,11 +873,8 @@ static device_method_t ti_gpio_methods[] = {
{0, 0},
};
static driver_t ti_gpio_driver = {
driver_t ti_gpio_driver = {
"gpio",
ti_gpio_methods,
sizeof(struct ti_gpio_softc),
};
static devclass_t ti_gpio_devclass;
DRIVER_MODULE(ti_gpio, simplebus, ti_gpio_driver, ti_gpio_devclass, 0, 0);

69
sys/arm/ti/ti_gpio.h Normal file
View File

@ -0,0 +1,69 @@
/*-
* Copyright (c) 2011
* Ben Gray <ben.r.gray@gmail.com>.
* 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef TI_GPIO_H
#define TI_GPIO_H
/* The maximum number of banks for any SoC */
#define MAX_GPIO_BANKS 6
/*
* Maximum GPIOS possible, max of *_MAX_GPIO_BANKS * *_INTR_PER_BANK.
* These are defined in ti_gpio.c
*/
#define MAX_GPIO_INTRS 8
/**
* Structure that stores the driver context.
*
* This structure is allocated during driver attach.
*/
struct ti_gpio_softc {
device_t sc_dev;
/*
* The memory resource(s) for the PRCM register set, when the device is
* created the caller can assign up to 6 memory regions depending on
* the SoC type.
*/
struct resource *sc_mem_res[MAX_GPIO_BANKS];
struct resource *sc_irq_res[MAX_GPIO_INTRS];
/* The handle for the register IRQ handlers. */
void *sc_irq_hdl[MAX_GPIO_INTRS];
/*
* The following describes the H/W revision of each of the GPIO banks.
*/
uint32_t sc_revision[MAX_GPIO_BANKS];
struct mtx sc_mtx;
};
#endif /* TI_GPIO_H */

49
sys/arm/ti/ti_gpio_if.m Normal file
View File

@ -0,0 +1,49 @@
#-
# Copyright (c) 2014 Andrew Turner <andrew@FreeBSD.org>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# $FreeBSD$
#
#include <sys/bus.h>
INTERFACE ti_gpio;
/**
* Sets the Ti SoCs gpio flags
*/
METHOD int set_flags {
device_t dev;
uint32_t gpio;
uint32_t flags;
};
/**
* Gets the Ti SoCs gpio flags
*/
METHOD int get_flags {
device_t dev;
uint32_t gpio;
uint32_t *flags;
};

View File

@ -380,7 +380,7 @@ ti_i2c_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
/* If the controller is busy wait until it is available. */
while (sc->sc_bus_inuse == 1)
mtx_sleep(dev, &sc->sc_mtx, 0, "i2cbuswait", 0);
mtx_sleep(sc, &sc->sc_mtx, 0, "i2cbuswait", 0);
/* Now we have control over the I2C controller. */
sc->sc_bus_inuse = 1;

View File

@ -76,8 +76,6 @@ int ti_scm_padconf_get(const char *padname, const char **muxmode,
unsigned int *state);
int ti_scm_padconf_set_gpiomode(uint32_t gpio, unsigned int state);
int ti_scm_padconf_get_gpiomode(uint32_t gpio, unsigned int *state);
int ti_scm_padconf_set_gpioflags(uint32_t gpio, uint32_t flags);
void ti_scm_padconf_get_gpioflags(uint32_t gpio, uint32_t *flags);
int ti_scm_reg_read_4(uint32_t reg, uint32_t *val);
int ti_scm_reg_write_4(uint32_t reg, uint32_t val);

277
sys/arm/ti/ti_wdt.c Normal file
View File

@ -0,0 +1,277 @@
/*-
* Copyright (c) 2014 Rui Paulo <rpaulo@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/malloc.h>
#include <sys/rman.h>
#include <sys/event.h>
#include <sys/selinfo.h>
#include <sys/watchdog.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/frame.h>
#include <machine/intr.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <machine/bus.h>
#include <machine/fdt.h>
#include <arm/ti/ti_prcm.h>
#include <arm/ti/ti_wdt.h>
#ifdef DEBUG
#define DPRINTF(fmt, ...) do { \
printf("%s: ", __func__); \
printf(fmt, __VA_ARGS__); \
} while (0)
#else
#define DPRINTF(fmt, ...)
#endif
static device_probe_t ti_wdt_probe;
static device_attach_t ti_wdt_attach;
static device_detach_t ti_wdt_detach;
static void ti_wdt_intr(void *);
static void ti_wdt_event(void *, unsigned int, int *);
struct ti_wdt_softc {
struct resource *sc_mem_res;
struct resource *sc_irq_res;
void *sc_intr;
bus_space_tag_t sc_bt;
bus_space_handle_t sc_bh;
eventhandler_tag sc_ev_tag;
};
static device_method_t ti_wdt_methods[] = {
DEVMETHOD(device_probe, ti_wdt_probe),
DEVMETHOD(device_attach, ti_wdt_attach),
DEVMETHOD(device_detach, ti_wdt_detach),
DEVMETHOD_END
};
static driver_t ti_wdt_driver = {
"ti_wdt",
ti_wdt_methods,
sizeof(struct ti_wdt_softc)
};
static devclass_t ti_wdt_devclass;
DRIVER_MODULE(ti_wdt, simplebus, ti_wdt_driver, ti_wdt_devclass, 0, 0);
static volatile __inline uint32_t
ti_wdt_reg_read(struct ti_wdt_softc *sc, uint32_t reg)
{
return (bus_space_read_4(sc->sc_bt, sc->sc_bh, reg));
}
static __inline void
ti_wdt_reg_write(struct ti_wdt_softc *sc, uint32_t reg, uint32_t val)
{
bus_space_write_4(sc->sc_bt, sc->sc_bh, reg, val);
}
/*
* Wait for the write to a specific synchronised register to complete.
*/
static __inline void
ti_wdt_reg_wait(struct ti_wdt_softc *sc, uint32_t bit)
{
while (ti_wdt_reg_read(sc, TI_WDT_WWPS) & bit)
DELAY(10);
}
static __inline void
ti_wdt_disable(struct ti_wdt_softc *sc)
{
DPRINTF("disabling watchdog %p\n", sc);
ti_wdt_reg_write(sc, TI_WDT_WSPR, 0xAAAA);
ti_wdt_reg_wait(sc, TI_W_PEND_WSPR);
ti_wdt_reg_write(sc, TI_WDT_WSPR, 0x5555);
ti_wdt_reg_wait(sc, TI_W_PEND_WSPR);
}
static __inline void
ti_wdt_enable(struct ti_wdt_softc *sc)
{
DPRINTF("enabling watchdog %p\n", sc);
ti_wdt_reg_write(sc, TI_WDT_WSPR, 0xBBBB);
ti_wdt_reg_wait(sc, TI_W_PEND_WSPR);
ti_wdt_reg_write(sc, TI_WDT_WSPR, 0x4444);
ti_wdt_reg_wait(sc, TI_W_PEND_WSPR);
}
static int
ti_wdt_probe(device_t dev)
{
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (ofw_bus_is_compatible(dev, "ti,omap3-wdt")) {
device_set_desc(dev, "TI Watchdog Timer");
return (BUS_PROBE_DEFAULT);
}
return (ENXIO);
}
static int
ti_wdt_attach(device_t dev)
{
struct ti_wdt_softc *sc;
int rid;
sc = device_get_softc(dev);
rid = 0;
sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (sc->sc_mem_res == NULL) {
device_printf(dev, "could not allocate memory resource\n");
return (ENXIO);
}
sc->sc_bt = rman_get_bustag(sc->sc_mem_res);
sc->sc_bh = rman_get_bushandle(sc->sc_mem_res);
sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
if (sc->sc_irq_res == NULL) {
device_printf(dev, "could not allocate interrupt resource\n");
ti_wdt_detach(dev);
return (ENXIO);
}
if (bus_setup_intr(dev, sc->sc_irq_res, INTR_MPSAFE | INTR_TYPE_MISC,
NULL, ti_wdt_intr, sc, &sc->sc_intr) != 0) {
device_printf(dev,
"unable to setup the interrupt handler\n");
ti_wdt_detach(dev);
return (ENXIO);
}
/* Reset, enable interrupts and stop the watchdog. */
ti_wdt_reg_write(sc, TI_WDT_WDSC,
ti_wdt_reg_read(sc, TI_WDT_WDSC) | TI_WDSC_SR);
while (ti_wdt_reg_read(sc, TI_WDT_WDSC) & TI_WDSC_SR)
DELAY(10);
ti_wdt_reg_write(sc, TI_WDT_WIRQENSET, TI_IRQ_EN_OVF | TI_IRQ_EN_DLY);
ti_wdt_disable(sc);
if (bootverbose)
device_printf(dev, "revision: 0x%x\n",
ti_wdt_reg_read(sc, TI_WDT_WIDR));
sc->sc_ev_tag = EVENTHANDLER_REGISTER(watchdog_list, ti_wdt_event, sc,
0);
return (0);
}
static int
ti_wdt_detach(device_t dev)
{
struct ti_wdt_softc *sc;
sc = device_get_softc(dev);
if (sc->sc_ev_tag)
EVENTHANDLER_DEREGISTER(watchdog_list, sc->sc_ev_tag);
if (sc->sc_intr)
bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intr);
if (sc->sc_irq_res)
bus_release_resource(dev, SYS_RES_IRQ,
rman_get_rid(sc->sc_irq_res), sc->sc_irq_res);
if (sc->sc_mem_res)
bus_release_resource(dev, SYS_RES_MEMORY,
rman_get_rid(sc->sc_mem_res), sc->sc_mem_res);
return (0);
}
static void
ti_wdt_intr(void *arg)
{
struct ti_wdt_softc *sc;
sc = arg;
DPRINTF("interrupt %p", sc);
ti_wdt_reg_write(sc, TI_WDT_WIRQSTAT, TI_IRQ_EV_OVF | TI_IRQ_EV_DLY);
/* TODO: handle interrupt */
}
static void
ti_wdt_event(void *arg, unsigned int cmd, int *error)
{
struct ti_wdt_softc *sc;
uint8_t s;
uint32_t wldr;
uint32_t ptv;
sc = arg;
ti_wdt_disable(sc);
if (cmd == WD_TO_NEVER) {
*error = 0;
return;
}
DPRINTF("cmd 0x%x\n", cmd);
cmd &= WD_INTERVAL;
if (cmd < WD_TO_1SEC) {
*error = EINVAL;
return;
}
s = 1 << (cmd - WD_TO_1SEC);
DPRINTF("seconds %u\n", s);
/*
* Leave the pre-scaler with its default values:
* PTV = 0 == 2**0 == 1
* PRE = 1 (enabled)
*
* Compute the load register value assuming a 32kHz clock.
* See OVF_Rate in the WDT section of the AM335x TRM.
*/
ptv = 0;
wldr = 0xffffffff - (s * (32768 / (1 << ptv))) + 1;
DPRINTF("wldr 0x%x\n", wldr);
ti_wdt_reg_write(sc, TI_WDT_WLDR, wldr);
/*
* Trigger a timer reload.
*/
ti_wdt_reg_write(sc, TI_WDT_WTGR,
ti_wdt_reg_read(sc, TI_WDT_WTGR) + 1);
ti_wdt_reg_wait(sc, TI_W_PEND_WTGR);
ti_wdt_enable(sc);
*error = 0;
}

74
sys/arm/ti/ti_wdt.h Normal file
View File

@ -0,0 +1,74 @@
/*-
* Copyright (c) 2014 Rui Paulo <rpaulo@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _TI_WDT_H_
#define _TI_WDT_H_
/* TI WDT registers */
#define TI_WDT_WIDR 0x00 /* Watchdog Identification Register */
#define TI_WDT_WDSC 0x10 /* Watchdog System Control Register */
#define TI_WDT_WDST 0x14 /* Watchdog Status Register */
#define TI_WDT_WISR 0x18 /* Watchdog Interrupt Status Register */
#define TI_WDT_WIER 0x1c /* Watchdog Interrupt Enable Register */
#define TI_WDT_WCLR 0x24 /* Watchdog Control Register */
#define TI_WDT_WCRR 0x28 /* Watchdog Counter Register */
#define TI_WDT_WLDR 0x2c /* Watchdog Load Register */
#define TI_WDT_WTGR 0x30 /* Watchdog Trigger Register */
#define TI_WDT_WWPS 0x34 /* Watchdog Write Posting Register */
#define TI_WDT_WDLY 0x44 /* Watchdog Delay Configuration Reg */
#define TI_WDT_WSPR 0x48 /* Watchdog Start/Stop Register */
#define TI_WDT_WIRQSTATRAW 0x54 /* Watchdog Raw Interrupt Status Reg. */
#define TI_WDT_WIRQSTAT 0x58 /* Watchdog Int. Status Register */
#define TI_WDT_WIRQENSET 0x5c /* Watchdog Int. Enable Set Register */
#define TI_WDT_WIRQENCLR 0x60 /* Watchdog Int. Enable Clear Reg. */
/* WDT_WDSC Register */
#define TI_WDSC_SR (1 << 1) /* Soft reset */
/*
* WDT_WWPS Register
*
* Writes to some registers require synchronisation with a different clock
* domain. The WDT_WWPS register is the place where this synchronisation
* happens.
*/
#define TI_W_PEND_WCLR (1 << 0)
#define TI_W_PEND_WCRR (1 << 1)
#define TI_W_PEND_WLDR (1 << 2)
#define TI_W_PEND_WTGR (1 << 3)
#define TI_W_PEND_WSPR (1 << 4)
#define TI_W_PEND_WDLY (1 << 5)
/* WDT_WIRQENSET Register */
#define TI_IRQ_EN_OVF (1 << 0) /* Overflow interrupt */
#define TI_IRQ_EN_DLY (1 << 1) /* Delay interrupt */
/* WDT_WIRQSTAT Register */
#define TI_IRQ_EV_OVF (1 << 0) /* Overflow event */
#define TI_IRQ_EV_DLY (1 << 1) /* Delay event */
#endif /* _TI_WDT_H_ */

View File

@ -240,6 +240,7 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off)
Elf_Ehdr *ehdr;
Elf_Phdr *phdr, *php;
Elf_Shdr *shdr;
char *shstr;
int ret;
vm_offset_t firstaddr;
vm_offset_t lastaddr;
@ -248,6 +249,7 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off)
Elf_Addr ssym, esym;
Elf_Dyn *dp;
Elf_Addr adp;
Elf_Addr ctors;
int ndp;
int symstrindex;
int symtabindex;
@ -383,10 +385,11 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off)
lastaddr = roundup(lastaddr, sizeof(long));
/*
* Now grab the symbol tables. This isn't easy if we're reading a
* .gz file. I think the rule is going to have to be that you must
* strip a file to remove symbols before gzipping it so that we do not
* try to lseek() on it.
* Get the section headers. We need this for finding the .ctors
* section as well as for loading any symbols. Both may be hard
* to do if reading from a .gz file as it involves seeking. I
* think the rule is going to have to be that you must strip a
* file to remove symbols before gzipping it.
*/
chunk = ehdr->e_shnum * ehdr->e_shentsize;
if (chunk == 0 || ehdr->e_shoff == 0)
@ -399,6 +402,33 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off)
}
file_addmetadata(fp, MODINFOMD_SHDR, chunk, shdr);
/*
* Read the section string table and look for the .ctors section.
* We need to tell the kernel where it is so that it can call the
* ctors.
*/
chunk = shdr[ehdr->e_shstrndx].sh_size;
if (chunk) {
shstr = alloc_pread(ef->fd, shdr[ehdr->e_shstrndx].sh_offset, chunk);
if (shstr) {
for (i = 0; i < ehdr->e_shnum; i++) {
if (strcmp(shstr + shdr[i].sh_name, ".ctors") != 0)
continue;
ctors = shdr[i].sh_addr;
file_addmetadata(fp, MODINFOMD_CTORS_ADDR, sizeof(ctors),
&ctors);
size = shdr[i].sh_size;
file_addmetadata(fp, MODINFOMD_CTORS_SIZE, sizeof(size),
&size);
break;
}
free(shstr);
}
}
/*
* Now load any symbols.
*/
symtabindex = -1;
symstrindex = -1;
for (i = 0; i < ehdr->e_shnum; i++) {

View File

@ -81,6 +81,13 @@
interrupts = < 16 >;
interrupt-parent = <&AINTC>;
};
wdt1@44E35000 {
compatible = "ti,omap3-wdt";
reg = <0x44E35000 0x1000>;
interrupts = <91>;
interrupt-parent = <&AINTC>;
};
GPIO: gpio {
#gpio-cells = <3>;

View File

@ -0,0 +1,109 @@
/*-
* Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com>
* All rights reserved.
*
* This software was developed by SRI International and the University of
* Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
* ("CTSRD"), as part of the DARPA CRASH research programme.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
/dts-v1/;
/include/ "socfpga.dtsi"
/ {
model = "Terasic SoCKit";
compatible = "altr,socfpga-cyclone5", "altr,socfpga";
/* Reserve first page for secondary CPU trampoline code */
memreserve = < 0x00000000 0x1000 >;
memory {
device_type = "memory";
reg = < 0x00000000 0x40000000 >; /* 1G RAM */
};
SOC: socfpga {
serial0: serial@ffc02000 {
status = "okay";
};
usb1: usb@ffb40000 {
status = "okay";
};
gmac1: ethernet@ff702000 {
status = "okay";
};
mmc: dwmmc@ff704000 {
status = "okay";
num-slots = <1>;
supports-highspeed;
broken-cd;
bus-frequency = <25000000>;
slot@0 {
reg = <0>;
bus-width = <4>;
};
};
beri_debug: ring@c0000000 {
compatible = "sri-cambridge,beri-ring";
reg = <0xc0000000 0x3000>;
interrupts = < 72 73 >;
interrupt-parent = <&GIC>;
device_name = "beri_debug";
data_size = <0x1000>;
data_read = <0x0>;
data_write = <0x1000>;
control_read = <0x2000>;
control_write = <0x2010>;
status = "okay";
};
beri_console: ring@c0004000 {
compatible = "sri-cambridge,beri-ring";
reg = <0xc0004000 0x3000>;
interrupts = < 74 75 >;
interrupt-parent = <&GIC>;
device_name = "beri_console";
data_size = <0x1000>;
data_read = <0x0>;
data_write = <0x1000>;
control_read = <0x2000>;
control_write = <0x2010>;
status = "okay";
};
};
chosen {
bootargs = "-v";
stdin = "serial0";
stdout = "serial0";
};
};

View File

@ -310,10 +310,13 @@ fdt_setup_fdtp()
/*
* If the U-boot environment contains a variable giving the address of a
* valid blob in memory, use it. Board vendors use both fdtaddr and
* fdt_addr names.
* valid blob in memory, use it. The U-boot README says the right
* variable for fdt data loaded into ram is fdt_addr_r, so try that
* first. Board vendors also use both fdtaddr and fdt_addr names.
*/
s = ub_env_get("fdtaddr");
s = ub_env_get("fdt_addr_r");
if (s == NULL)
s = ub_env_get("fdtaddr");
if (s == NULL)
s = ub_env_get("fdt_addr");
if (s != NULL && *s != '\0') {

View File

@ -457,6 +457,14 @@ static struct ada_quirk_entry ada_quirk_table[] =
{ T_DIRECT, SIP_MEDIA_FIXED, "*", "SAMSUNG MZ7WD*", "*" },
/*quirks*/ADA_Q_4K
},
{
/*
* Samsung 850 SSDs
* 4k optimised
*/
{ T_DIRECT, SIP_MEDIA_FIXED, "*", "Samsung SSD 850*", "*" },
/*quirks*/ADA_Q_4K
},
{
/*
* Samsung PM853T Series SSDs

View File

@ -9705,17 +9705,17 @@ ctl_inquiry_evpd_serial(struct ctl_scsiio *ctsio, int alloc_len)
{
struct scsi_vpd_unit_serial_number *sn_ptr;
struct ctl_lun *lun;
int data_len;
lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
ctsio->kern_data_ptr = malloc(sizeof(*sn_ptr), M_CTL, M_WAITOK | M_ZERO);
data_len = 4 + CTL_SN_LEN;
ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
sn_ptr = (struct scsi_vpd_unit_serial_number *)ctsio->kern_data_ptr;
ctsio->kern_sg_entries = 0;
if (sizeof(*sn_ptr) < alloc_len) {
ctsio->residual = alloc_len - sizeof(*sn_ptr);
ctsio->kern_data_len = sizeof(*sn_ptr);
ctsio->kern_total_len = sizeof(*sn_ptr);
if (data_len < alloc_len) {
ctsio->residual = alloc_len - data_len;
ctsio->kern_data_len = data_len;
ctsio->kern_total_len = data_len;
} else {
ctsio->residual = 0;
ctsio->kern_data_len = alloc_len;
@ -9737,16 +9737,16 @@ ctl_inquiry_evpd_serial(struct ctl_scsiio *ctsio, int alloc_len)
sn_ptr->device = (SID_QUAL_LU_OFFLINE << 5) | T_DIRECT;
sn_ptr->page_code = SVPD_UNIT_SERIAL_NUMBER;
sn_ptr->length = ctl_min(sizeof(*sn_ptr) - 4, CTL_SN_LEN);
sn_ptr->length = CTL_SN_LEN;
/*
* If we don't have a LUN, we just leave the serial number as
* all spaces.
*/
memset(sn_ptr->serial_num, 0x20, sizeof(sn_ptr->serial_num));
if (lun != NULL) {
strncpy((char *)sn_ptr->serial_num,
(char *)lun->be_lun->serial_num, CTL_SN_LEN);
}
} else
memset(sn_ptr->serial_num, 0x20, CTL_SN_LEN);
ctsio->scsi_status = SCSI_STATUS_OK;
ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED;

View File

@ -1132,6 +1132,14 @@ static struct da_quirk_entry da_quirk_table[] =
{ T_DIRECT, SIP_MEDIA_FIXED, "ATA", "SAMSUNG MZ7WD*", "*" },
/*quirks*/DA_Q_4K
},
{
/*
* Samsung 850 SSDs
* 4k optimised & trim only works in 4k requests + 4k aligned
*/
{ T_DIRECT, SIP_MEDIA_FIXED, "ATA", "Samsung SSD 850*", "*" },
/*quirks*/DA_Q_4K
},
{
/*
* Samsung PM853T Series SSDs

View File

@ -37,6 +37,8 @@
#include <sys/refcount.h>
#include <sys/zfeature.h>
SYSCTL_DECL(_vfs_zfs);
/*
* The data for a given space map can be kept on blocks of any size.
* Larger blocks entail fewer i/o operations, but they also cause the
@ -44,6 +46,8 @@
* when only a few blocks have changed since the last transaction group.
*/
int space_map_blksz = (1 << 12);
SYSCTL_INT(_vfs_zfs, OID_AUTO, space_map_blksz, CTLFLAG_RDTUN, &space_map_blksz, 0,
"Maximum block size for space map. Must be power of 2 and greater than 4096.");
/*
* Load the space map disk into the specified range tree. Segments of maptype

View File

@ -332,8 +332,8 @@ struct kinfo_proc32 {
signed char ki_nice;
char ki_lock;
char ki_rqindex;
u_char ki_oncpu;
u_char ki_lastcpu;
u_char ki_oncpu_old;
u_char ki_lastcpu_old;
char ki_tdname[TDNAMLEN+1];
char ki_wmesg[WMESGLEN+1];
char ki_login[LOGNAMELEN+1];
@ -343,6 +343,8 @@ struct kinfo_proc32 {
char ki_loginclass[LOGINCLASSLEN+1];
char ki_sparestrings[50];
int ki_spareints[KI_NSPARE_INT];
int ki_oncpu;
int ki_lastcpu;
int ki_tracer;
int ki_flag2;
int ki_fibnum;

View File

@ -77,6 +77,7 @@ FILES_CPU_FUNC = \
$S/$M/$M/cpufunc_asm_pj4b.S $S/$M/$M/cpufunc_asm_armv6.S \
$S/$M/$M/cpufunc_asm_armv7.S
.if defined(KERNPHYSADDR)
KERNEL_EXTRA=trampoline
KERNEL_EXTRA_INSTALL=kernel.gz.tramp
trampoline: ${KERNEL_KO}.tramp
@ -121,6 +122,7 @@ ${KERNEL_KO}.tramp: ${KERNEL_KO} $S/$M/$M/inckern.S $S/$M/$M/elf_trampoline.c
${KERNEL_KO}.gz.tramp.bin
rm ${KERNEL_KO}.tmp.gz ${KERNEL_KO}.tramp.noheader opt_kernname.h \
inflate-tramp.o tmphack.S
.endif
%BEFORE_DEPEND

View File

@ -795,6 +795,10 @@ device ether
# according to IEEE 802.1Q.
device vlan
# The `vxlan' device implements the VXLAN encapsulation of Ethernet
# frames in UDP packets according to RFC7348.
device vxlan
# The `wlan' device provides generic code to support 802.11
# drivers, including host AP mode; it is MANDATORY for the wi,
# and ath drivers and will eventually be required by all 802.11 drivers.

View File

@ -3246,6 +3246,7 @@ net/if_stf.c optional stf inet inet6
net/if_tun.c optional tun
net/if_tap.c optional tap
net/if_vlan.c optional vlan
net/if_vxlan.c optional vxlan inet | vxlan inet6
net/mppcc.c optional netgraph_mppc_compression
net/mppcd.c optional netgraph_mppc_compression
net/netisr.c standard

View File

@ -18,6 +18,7 @@ arm/arm/devmap.c standard
arm/arm/disassem.c optional ddb
arm/arm/dump_machdep.c standard
arm/arm/elf_machdep.c standard
arm/arm/elf_note.S standard
arm/arm/exception.S standard
arm/arm/fiq.c standard
arm/arm/fiq_subr.S standard

View File

@ -306,6 +306,7 @@ struct ata_pci_controller {
#define ATA_JMB365 0x2365197b
#define ATA_JMB366 0x2366197b
#define ATA_JMB368 0x2368197b
#define ATA_JMB368_2 0x0368197b
#define ATA_MARVELL_ID 0x11ab
#define ATA_M88SX5040 0x504011ab

View File

@ -71,6 +71,7 @@ ata_jmicron_probe(device_t dev)
{ ATA_JMB365, 0, 1, 2, ATA_UDMA6, "JMB365" },
{ ATA_JMB366, 0, 2, 2, ATA_UDMA6, "JMB366" },
{ ATA_JMB368, 0, 0, 1, ATA_UDMA6, "JMB368" },
{ ATA_JMB368_2, 0, 0, 1, ATA_UDMA6, "JMB368" },
{ 0, 0, 0, 0, 0, 0}};
char buffer[64];

529
sys/dev/beri/beri_ring.c Normal file
View File

@ -0,0 +1,529 @@
/*-
* Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com>
* All rights reserved.
*
* This software was developed by SRI International and the University of
* Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
* ("CTSRD"), as part of the DARPA CRASH research programme.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* SRI-Cambridge BERI soft processor <-> ARM core ring buffer.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/malloc.h>
#include <sys/rman.h>
#include <sys/timeet.h>
#include <sys/timetc.h>
#include <sys/conf.h>
#include <sys/uio.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/event.h>
#include <sys/selinfo.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <machine/bus.h>
#include <machine/fdt.h>
#include <machine/cpu.h>
#include <machine/intr.h>
#define READ4(_sc, _reg) \
bus_read_4((_sc)->res[0], _reg)
#define WRITE4(_sc, _reg, _val) \
bus_write_4((_sc)->res[0], _reg, _val)
#define CDES_INT_EN (1 << 15)
#define CDES_CAUSE_MASK 0x3
#define CDES_CAUSE_SHIFT 13
#define DEVNAME_MAXLEN 256
typedef struct
{
uint16_t cdes;
uint16_t interrupt_level;
uint16_t in;
uint16_t out;
} control_reg_t;
struct beri_softc {
struct resource *res[3];
bus_space_tag_t bst;
bus_space_handle_t bsh;
struct cdev *cdev;
device_t dev;
void *read_ih;
void *write_ih;
struct selinfo beri_rsel;
struct mtx beri_mtx;
int opened;
char devname[DEVNAME_MAXLEN];
int control_read;
int control_write;
int data_read;
int data_write;
int data_size;
};
static struct resource_spec beri_spec[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
{ SYS_RES_IRQ, 0, RF_ACTIVE },
{ SYS_RES_IRQ, 1, RF_ACTIVE },
{ -1, 0 }
};
static control_reg_t
get_control_reg(struct beri_softc *sc, int dir)
{
uint32_t offset;
uint16_t dst[4];
control_reg_t c;
uint16_t *cp;
int i;
cp = (uint16_t *)&c;
offset = dir ? sc->control_write : sc->control_read;
((uint32_t *)dst)[0] = READ4(sc, offset);
((uint32_t *)dst)[1] = READ4(sc, offset + 4);
for (i = 0; i < 4; i++)
cp[i] = dst[3 - i];
return (c);
}
static void
set_control_reg(struct beri_softc *sc, int dir, control_reg_t *c)
{
uint32_t offset;
uint16_t src[4];
uint16_t *cp;
int i;
cp = (uint16_t *)c;
for (i = 0; i < 4; i++)
src[3 - i] = cp[i];
offset = dir ? sc->control_write : sc->control_read;
WRITE4(sc, offset + 0, ((uint32_t *)src)[0]);
WRITE4(sc, offset + 4, ((uint32_t *)src)[1]);
}
static int
get_stock(struct beri_softc *sc, int dir, control_reg_t *c)
{
uint32_t fill;
fill = (c->in - c->out + sc->data_size) % sc->data_size;
if (dir)
return (sc->data_size - fill - 1);
else
return (fill);
}
static void
beri_intr_write(void *arg)
{
struct beri_softc *sc;
control_reg_t c;
sc = arg;
c = get_control_reg(sc, 1);
if (c.cdes & CDES_INT_EN) {
c.cdes &= ~(CDES_INT_EN);
set_control_reg(sc, 1, &c);
}
mtx_lock(&sc->beri_mtx);
selwakeuppri(&sc->beri_rsel, PZERO + 1);
KNOTE_LOCKED(&sc->beri_rsel.si_note, 0);
mtx_unlock(&sc->beri_mtx);
}
static void
beri_intr_read(void *arg)
{
struct beri_softc *sc;
control_reg_t c;
sc = arg;
c = get_control_reg(sc, 0);
if (c.cdes & CDES_INT_EN) {
c.cdes &= ~(CDES_INT_EN);
set_control_reg(sc, 0, &c);
}
mtx_lock(&sc->beri_mtx);
selwakeuppri(&sc->beri_rsel, PZERO + 1);
KNOTE_LOCKED(&sc->beri_rsel.si_note, 0);
mtx_unlock(&sc->beri_mtx);
}
static int
beri_open(struct cdev *dev, int flags __unused,
int fmt __unused, struct thread *td __unused)
{
struct beri_softc *sc;
control_reg_t c;
sc = dev->si_drv1;
if (sc->opened)
return (1);
/* Setup interrupt handlers */
if (bus_setup_intr(sc->dev, sc->res[1], INTR_TYPE_BIO | INTR_MPSAFE,
NULL, beri_intr_read, sc, &sc->read_ih)) {
device_printf(sc->dev, "Unable to setup read intr\n");
return (1);
}
if (bus_setup_intr(sc->dev, sc->res[2], INTR_TYPE_BIO | INTR_MPSAFE,
NULL, beri_intr_write, sc, &sc->write_ih)) {
device_printf(sc->dev, "Unable to setup write intr\n");
return (1);
}
sc->opened = 1;
/* Clear write buffer */
c = get_control_reg(sc, 1);
c.in = c.out;
c.cdes = 0;
set_control_reg(sc, 1, &c);
/* Clear read buffer */
c = get_control_reg(sc, 0);
c.out = c.in;
c.cdes = 0;
set_control_reg(sc, 0, &c);
return (0);
}
static int
beri_close(struct cdev *dev, int flags __unused,
int fmt __unused, struct thread *td __unused)
{
struct beri_softc *sc;
sc = dev->si_drv1;
if (sc->opened) {
sc->opened = 0;
/* Unsetup interrupt handlers */
bus_teardown_intr(sc->dev, sc->res[1], sc->read_ih);
bus_teardown_intr(sc->dev, sc->res[2], sc->write_ih);
}
return (0);
}
static int
beri_rdwr(struct cdev *dev, struct uio *uio, int ioflag)
{
struct beri_softc *sc;
uint32_t offset;
control_reg_t c;
uint16_t *ptr;
uint8_t *dst;
int stock;
int dir;
int amount;
int count;
sc = dev->si_drv1;
dir = uio->uio_rw ? 1 : 0;
c = get_control_reg(sc, dir);
stock = get_stock(sc, dir, &c);
if (stock < uio->uio_resid) {
device_printf(sc->dev, "Err: no data/space available\n");
return (1);
}
amount = uio->uio_resid;
ptr = dir ? &c.in : &c.out;
count = (sc->data_size - *ptr);
offset = dir ? sc->data_write : sc->data_read;
dst = (uint8_t *)(sc->bsh + offset);
if (amount <= count) {
uiomove(dst + *ptr, amount, uio);
} else {
uiomove(dst + *ptr, count, uio);
uiomove(dst, (amount - count), uio);
}
*ptr = (*ptr + amount) % sc->data_size;
set_control_reg(sc, dir, &c);
return (0);
}
static int
beri_kqread(struct knote *kn, long hint)
{
struct beri_softc *sc;
control_reg_t c;
int stock;
sc = kn->kn_hook;
c = get_control_reg(sc, 0);
stock = get_stock(sc, 0, &c);
if (stock) {
kn->kn_data = stock;
return (1);
}
kn->kn_data = 0;
/* Wait at least one new byte in buffer */
c.interrupt_level = 1;
/* Enable interrupts */
c.cdes |= (CDES_INT_EN);
set_control_reg(sc, 0, &c);
return (0);
}
static int
beri_kqwrite(struct knote *kn, long hint)
{
struct beri_softc *sc;
control_reg_t c;
int stock;
sc = kn->kn_hook;
c = get_control_reg(sc, 1);
stock = get_stock(sc, 1, &c);
if (stock) {
kn->kn_data = stock;
return (1);
}
kn->kn_data = 0;
/* Wait at least one free position in buffer */
c.interrupt_level = sc->data_size - 2;
/* Enable interrupts */
c.cdes |= (CDES_INT_EN);
set_control_reg(sc, 1, &c);
return (0);
}
static void
beri_kqdetach(struct knote *kn)
{
struct beri_softc *sc;
sc = kn->kn_hook;
knlist_remove(&sc->beri_rsel.si_note, kn, 0);
}
static struct filterops beri_read_filterops = {
.f_isfd = 1,
.f_attach = NULL,
.f_detach = beri_kqdetach,
.f_event = beri_kqread,
};
static struct filterops beri_write_filterops = {
.f_isfd = 1,
.f_attach = NULL,
.f_detach = beri_kqdetach,
.f_event = beri_kqwrite,
};
static int
beri_kqfilter(struct cdev *dev, struct knote *kn)
{
struct beri_softc *sc;
sc = dev->si_drv1;
switch(kn->kn_filter) {
case EVFILT_READ:
kn->kn_fop = &beri_read_filterops;
break;
case EVFILT_WRITE:
kn->kn_fop = &beri_write_filterops;
break;
default:
return(EINVAL);
}
kn->kn_hook = sc;
knlist_add(&sc->beri_rsel.si_note, kn, 0);
return (0);
}
static struct cdevsw beri_cdevsw = {
.d_version = D_VERSION,
.d_open = beri_open,
.d_close = beri_close,
.d_write = beri_rdwr,
.d_read = beri_rdwr,
.d_kqfilter = beri_kqfilter,
.d_name = "beri ring buffer",
};
static int
parse_fdt(struct beri_softc *sc)
{
pcell_t dts_value[0];
phandle_t node;
int len;
if ((node = ofw_bus_get_node(sc->dev)) == -1)
return (ENXIO);
/* get device name */
if (OF_getprop(ofw_bus_get_node(sc->dev), "device_name",
&sc->devname, sizeof(sc->devname)) <= 0) {
device_printf(sc->dev, "Can't get device_name\n");
return (ENXIO);
}
if ((len = OF_getproplen(node, "data_size")) <= 0)
return (ENXIO);
OF_getencprop(node, "data_size", dts_value, len);
sc->data_size = dts_value[0];
if ((len = OF_getproplen(node, "data_read")) <= 0)
return (ENXIO);
OF_getencprop(node, "data_read", dts_value, len);
sc->data_read = dts_value[0];
if ((len = OF_getproplen(node, "data_write")) <= 0)
return (ENXIO);
OF_getencprop(node, "data_write", dts_value, len);
sc->data_write = dts_value[0];
if ((len = OF_getproplen(node, "control_read")) <= 0)
return (ENXIO);
OF_getencprop(node, "control_read", dts_value, len);
sc->control_read = dts_value[0];
if ((len = OF_getproplen(node, "control_write")) <= 0)
return (ENXIO);
OF_getencprop(node, "control_write", dts_value, len);
sc->control_write = dts_value[0];
return (0);
}
static int
beri_probe(device_t dev)
{
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (!ofw_bus_is_compatible(dev, "sri-cambridge,beri-ring"))
return (ENXIO);
device_set_desc(dev, "SRI-Cambridge BERI ring buffer");
return (BUS_PROBE_DEFAULT);
}
static int
beri_attach(device_t dev)
{
struct beri_softc *sc;
sc = device_get_softc(dev);
sc->dev = dev;
if (bus_alloc_resources(dev, beri_spec, sc->res)) {
device_printf(dev, "could not allocate resources\n");
return (ENXIO);
}
/* Memory interface */
sc->bst = rman_get_bustag(sc->res[0]);
sc->bsh = rman_get_bushandle(sc->res[0]);
if (parse_fdt(sc)) {
device_printf(sc->dev, "Can't get FDT values\n");
return (ENXIO);
}
sc->cdev = make_dev(&beri_cdevsw, 0, UID_ROOT, GID_WHEEL,
S_IRWXU, "%s", sc->devname);
if (sc->cdev == NULL) {
device_printf(dev, "Failed to create character device.\n");
return (ENXIO);
}
sc->cdev->si_drv1 = sc;
mtx_init(&sc->beri_mtx, "beri_mtx", NULL, MTX_DEF);
knlist_init_mtx(&sc->beri_rsel.si_note, &sc->beri_mtx);
return (0);
}
static device_method_t beri_methods[] = {
DEVMETHOD(device_probe, beri_probe),
DEVMETHOD(device_attach, beri_attach),
{ 0, 0 }
};
static driver_t beri_driver = {
"beri_ring",
beri_methods,
sizeof(struct beri_softc),
};
static devclass_t beri_devclass;
DRIVER_MODULE(beri_ring, simplebus, beri_driver, beri_devclass, 0, 0);

View File

@ -52,7 +52,7 @@ cfe_env_init(void)
if (cfe_enumenv(idx, name, sizeof(name), val, sizeof(val)) != 0)
break;
if (setenv(name, val) != 0) {
if (kern_setenv(name, val) != 0) {
printf("No space to store CFE env: \"%s=%s\"\n",
name, val);
}

View File

@ -1345,8 +1345,10 @@ static int ael2005_intr_handler(struct cphy *phy)
return ret;
ret |= cause;
if (!ret)
if (!ret) {
(void) ael2005_reset(phy, 0);
ret |= cphy_cause_link_change;
}
return ret;
}

View File

@ -133,7 +133,13 @@ simplebus_probe(device_t dev)
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (!ofw_bus_is_compatible(dev, "simple-bus") &&
/*
* FDT data puts a "simple-bus" compatible string on many things that
* have children but aren't really busses in our world. Without a
* ranges property we will fail to attach, so just fail to probe too.
*/
if (!(ofw_bus_is_compatible(dev, "simple-bus") &&
ofw_bus_has_prop(dev, "ranges")) &&
(ofw_bus_get_type(dev) == NULL || strcmp(ofw_bus_get_type(dev),
"soc") != 0))
return (ENXIO);

View File

@ -192,6 +192,7 @@ static int pmc_detach_process(struct proc *p, struct pmc *pm);
static int pmc_detach_one_process(struct proc *p, struct pmc *pm,
int flags);
static void pmc_destroy_owner_descriptor(struct pmc_owner *po);
static void pmc_destroy_pmc_descriptor(struct pmc *pm);
static struct pmc_owner *pmc_find_owner_descriptor(struct proc *p);
static int pmc_find_pmc(pmc_id_t pmcid, struct pmc **pm);
static struct pmc *pmc_find_pmc_descriptor_in_process(struct pmc_owner *po,
@ -748,6 +749,7 @@ pmc_remove_owner(struct pmc_owner *po)
("[pmc,%d] owner %p != po %p", __LINE__, pm->pm_owner, po));
pmc_release_pmc_descriptor(pm); /* will unlink from the list */
pmc_destroy_pmc_descriptor(pm);
}
KASSERT(po->po_sscount == 0,
@ -2160,9 +2162,7 @@ pmc_allocate_pmc_descriptor(void)
static void
pmc_destroy_pmc_descriptor(struct pmc *pm)
{
(void) pm;
#ifdef DEBUG
KASSERT(pm->pm_state == PMC_STATE_DELETED ||
pm->pm_state == PMC_STATE_FREE,
("[pmc,%d] destroying non-deleted PMC", __LINE__));
@ -2173,7 +2173,8 @@ pmc_destroy_pmc_descriptor(struct pmc *pm)
KASSERT(pm->pm_runcount == 0,
("[pmc,%d] pmc has non-zero run count %d", __LINE__,
pm->pm_runcount));
#endif
free(pm, M_PMC);
}
static void
@ -2206,10 +2207,10 @@ pmc_wait_for_pmc_idle(struct pmc *pm)
* - detaches the PMC from hardware
* - unlinks all target threads that were attached to it
* - removes the PMC from its owner's list
* - destroy's the PMC private mutex
* - destroys the PMC private mutex
*
* Once this function completes, the given pmc pointer can be safely
* FREE'd by the caller.
* Once this function completes, the given pmc pointer can be freed by
* calling pmc_destroy_pmc_descriptor().
*/
static void
@ -2359,8 +2360,6 @@ pmc_release_pmc_descriptor(struct pmc *pm)
LIST_REMOVE(pm, pm_next);
pm->pm_owner = NULL;
}
pmc_destroy_pmc_descriptor(pm);
}
/*
@ -3367,7 +3366,6 @@ pmc_syscall_handler(struct thread *td, void *syscall_args)
if (n == (int) md->pmd_npmc) {
pmc_destroy_pmc_descriptor(pmc);
free(pmc, M_PMC);
pmc = NULL;
error = EINVAL;
break;
@ -3403,7 +3401,6 @@ pmc_syscall_handler(struct thread *td, void *syscall_args)
(error = pcd->pcd_config_pmc(cpu, adjri, pmc)) != 0) {
(void) pcd->pcd_release_pmc(cpu, adjri, pmc);
pmc_destroy_pmc_descriptor(pmc);
free(pmc, M_PMC);
pmc = NULL;
pmc_restore_cpu_binding(&pb);
error = EPERM;
@ -3431,7 +3428,7 @@ pmc_syscall_handler(struct thread *td, void *syscall_args)
if ((error =
pmc_register_owner(curthread->td_proc, pmc)) != 0) {
pmc_release_pmc_descriptor(pmc);
free(pmc, M_PMC);
pmc_destroy_pmc_descriptor(pmc);
pmc = NULL;
break;
}
@ -3674,8 +3671,7 @@ pmc_syscall_handler(struct thread *td, void *syscall_args)
po = pm->pm_owner;
pmc_release_pmc_descriptor(pm);
pmc_maybe_remove_owner(po);
free(pm, M_PMC);
pmc_destroy_pmc_descriptor(pm);
}
break;

View File

@ -263,7 +263,7 @@ nvram2env_attach(device_t dev)
if (bootverbose)
printf("ENV: %s=%s\n", pair, value);
#endif
setenv(pair, value);
kern_setenv(pair, value);
if (strcasecmp(pair, "WAN_MAC_ADDR") == 0) {
/* Alias for MAC address of eth0 */
@ -271,7 +271,7 @@ nvram2env_attach(device_t dev)
printf("ENV: aliasing "
"WAN_MAC_ADDR to ethaddr"
" = %s\n", value);
setenv("ethaddr", value);
kern_setenv("ethaddr", value);
}
else if (strcasecmp(pair, "LAN_MAC_ADDR") == 0){
/* Alias for MAC address of eth1 */
@ -279,7 +279,7 @@ nvram2env_attach(device_t dev)
printf("ENV: aliasing "
"LAN_MAC_ADDR to eth1addr"
" = %s\n", value);
setenv("eth1addr", value);
kern_setenv("eth1addr", value);
}
if (strcmp(pair, "bootverbose") == 0)

View File

@ -317,6 +317,8 @@ static const STRUCT_USB_HOST_ID u3g_devs[] = {
U3G_DEV(HUAWEI, MOBILE, U3GINIT_HUAWEI),
U3G_DEV(HUAWEI, E1752, U3GINIT_HUAWEISCSI),
U3G_DEV(HUAWEI, E1820, U3GINIT_HUAWEISCSI),
U3G_DEV(HUAWEI, K3772, U3GINIT_HUAWEI),
U3G_DEV(HUAWEI, K3772_INIT, U3GINIT_HUAWEISCSI2),
U3G_DEV(HUAWEI, K3765, U3GINIT_HUAWEI),
U3G_DEV(HUAWEI, K3765_INIT, U3GINIT_HUAWEISCSI),
U3G_DEV(HUAWEI, K3770, U3GINIT_HUAWEI),
@ -466,7 +468,8 @@ static const STRUCT_USB_HOST_ID u3g_devs[] = {
U3G_DEV(QUALCOMMINC, SURFSTICK, 0),
U3G_DEV(QUALCOMMINC, E2002, 0),
U3G_DEV(QUALCOMMINC, E2003, 0),
U3G_DEV(QUALCOMMINC, K3772_Z, U3GINIT_SCSIEJECT),
U3G_DEV(QUALCOMMINC, K3772_Z, 0),
U3G_DEV(QUALCOMMINC, K3772_Z_INIT, U3GINIT_SCSIEJECT),
U3G_DEV(QUALCOMMINC, MF626, 0),
U3G_DEV(QUALCOMMINC, MF628, 0),
U3G_DEV(QUALCOMMINC, MF633R, 0),

View File

@ -2347,12 +2347,14 @@ product HUAWEI K4505 0x1464 3G modem
product HUAWEI K3765 0x1465 3G modem
product HUAWEI E1820 0x14ac E1820 HSPA+ USB Slider
product HUAWEI K3770 0x14c9 3G modem
product HUAWEI K3772 0x14cf K3772
product HUAWEI K3770_INIT 0x14d1 K3770 Initial
product HUAWEI E3131_INIT 0x14fe 3G modem initial
product HUAWEI E392 0x1505 LTE modem
product HUAWEI E3131 0x1506 3G modem
product HUAWEI K3765_INIT 0x1520 K3765 Initial
product HUAWEI K4505_INIT 0x1521 K4505 Initial
product HUAWEI K3772_INIT 0x1526 K3772 Initial
product HUAWEI E3272_INIT 0x155b LTE modem initial
product HUAWEI R215_INIT 0x1582 LTE modem initial
product HUAWEI R215 0x1588 LTE modem
@ -3636,7 +3638,8 @@ product QUALCOMMINC E0078 0x0078 3G modem
product QUALCOMMINC E0082 0x0082 3G modem
product QUALCOMMINC E0086 0x0086 3G modem
product QUALCOMMINC SURFSTICK 0x0117 1&1 Surf Stick
product QUALCOMMINC K3772_Z 0x1179 3G modem
product QUALCOMMINC K3772_Z_INIT 0x1179 K3772-Z Initial
product QUALCOMMINC K3772_Z 0x1181 K3772-Z
product QUALCOMMINC ZTE_STOR 0x2000 USB ZTE Storage
product QUALCOMMINC E2002 0x2002 3G modem
product QUALCOMMINC E2003 0x2003 3G modem

View File

@ -2207,6 +2207,9 @@ skip_thunk:
case PIO_VFONT: {
struct vt_font *vf;
if (vd->vd_flags & VDF_TEXTMODE)
return (ENOTSUP);
error = vtfont_load((void *)data, &vf);
if (error != 0)
return (error);
@ -2498,6 +2501,8 @@ vt_upgrade(struct vt_device *vd)
if (!vty_enabled(VTY_VT))
return;
if (main_vd->vd_driver == NULL)
return;
for (i = 0; i < VT_MAXWINDOWS; i++) {
vw = vd->vd_windows[i];

View File

@ -198,6 +198,8 @@ nullfs_mount(struct mount *mp)
MNTK_EXTENDED_SHARED);
}
mp->mnt_kern_flag |= MNTK_LOOKUP_EXCL_DOTDOT;
mp->mnt_kern_flag |= lowerrootvp->v_mount->mnt_kern_flag &
MNTK_SUSPENDABLE;
MNT_IUNLOCK(mp);
mp->mnt_data = xmp;
vfs_getnewfsid(mp);

View File

@ -255,6 +255,7 @@ tmpfs_mount(struct mount *mp)
MNT_ILOCK(mp);
mp->mnt_flag |= MNT_LOCAL;
mp->mnt_kern_flag |= MNTK_SUSPENDABLE;
MNT_IUNLOCK(mp);
mp->mnt_data = tmp;

View File

@ -290,6 +290,7 @@ unionfs_domount(struct mount *mp)
return (error);
}
MNT_ILOCK(mp);
/*
* Check mnt_flag
*/
@ -297,6 +298,14 @@ unionfs_domount(struct mount *mp)
(ump->um_uppervp->v_mount->mnt_flag & MNT_LOCAL))
mp->mnt_flag |= MNT_LOCAL;
/*
* Check mnt_kern_flag
*/
if ((ump->um_lowervp->v_mount->mnt_flag & MNTK_SUSPENDABLE) ||
(ump->um_uppervp->v_mount->mnt_flag & MNTK_SUSPENDABLE))
mp->mnt_kern_flag |= MNTK_SUSPENDABLE;
MNT_IUNLOCK(mp);
/*
* Get new fsid
*/

View File

@ -362,8 +362,7 @@ intr_setaffinity(int irq, void *m)
{
struct intr_event *ie;
cpuset_t *mask;
u_char cpu;
int n;
int cpu, n;
mask = m;
cpu = NOCPU;
@ -377,7 +376,7 @@ intr_setaffinity(int irq, void *m)
continue;
if (cpu != NOCPU)
return (EINVAL);
cpu = (u_char)n;
cpu = n;
}
}
ie = intr_lookup(irq);

View File

@ -573,6 +573,8 @@ linker_make_file(const char *pathname, linker_class_t lc)
lf = (linker_file_t)kobj_create((kobj_class_t)lc, M_LINKER, M_WAITOK);
if (lf == NULL)
return (NULL);
lf->ctors_addr = 0;
lf->ctors_size = 0;
lf->refs = 1;
lf->userrefs = 0;
lf->flags = 0;

View File

@ -984,6 +984,25 @@ fill_kinfo_thread(struct thread *td, struct kinfo_proc *kp, int preferthread)
kp->ki_wchan = td->td_wchan;
kp->ki_pri.pri_level = td->td_priority;
kp->ki_pri.pri_native = td->td_base_pri;
/*
* Note: legacy fields; clamp at the old NOCPU value and/or
* the maximum u_char CPU value.
*/
if (td->td_lastcpu == NOCPU)
kp->ki_lastcpu_old = NOCPU_OLD;
else if (td->td_lastcpu > MAXCPU_OLD)
kp->ki_lastcpu_old = MAXCPU_OLD;
else
kp->ki_lastcpu_old = td->td_lastcpu;
if (td->td_oncpu == NOCPU)
kp->ki_oncpu_old = NOCPU_OLD;
else if (td->td_oncpu > MAXCPU_OLD)
kp->ki_oncpu_old = MAXCPU_OLD;
else
kp->ki_oncpu_old = td->td_oncpu;
kp->ki_lastcpu = td->td_lastcpu;
kp->ki_oncpu = td->td_oncpu;
kp->ki_tdflags = td->td_flags;
@ -1164,6 +1183,11 @@ freebsd32_kinfo_proc_out(const struct kinfo_proc *ki, struct kinfo_proc32 *ki32)
CP(*ki, *ki32, ki_rqindex);
CP(*ki, *ki32, ki_oncpu);
CP(*ki, *ki32, ki_lastcpu);
/* XXX TODO: wrap cpu value as appropriate */
CP(*ki, *ki32, ki_oncpu_old);
CP(*ki, *ki32, ki_lastcpu_old);
bcopy(ki->ki_tdname, ki32->ki_tdname, TDNAMLEN + 1);
bcopy(ki->ki_wmesg, ki32->ki_wmesg, WMESGLEN + 1);
bcopy(ki->ki_login, ki32->ki_login, LOGNAMELEN + 1);

View File

@ -331,6 +331,22 @@ link_elf_error(const char *filename, const char *s)
printf("kldload: %s: %s\n", filename, s);
}
static void
link_elf_invoke_ctors(caddr_t addr, size_t size)
{
void (**ctor)(void);
size_t i, cnt;
if (addr == NULL || size == 0)
return;
cnt = size / sizeof(*ctor);
ctor = (void *)addr;
for (i = 0; i < cnt; i++) {
if (ctor[i] != NULL)
(*ctor[i])();
}
}
/*
* Actions performed after linking/loading both the preloaded kernel and any
* modules; whether preloaded or dynamicly loaded.
@ -360,6 +376,8 @@ link_elf_link_common_finish(linker_file_t lf)
GDB_STATE(RT_CONSISTENT);
#endif
/* Invoke .ctors */
link_elf_invoke_ctors(lf->ctors_addr, lf->ctors_size);
return (0);
}
@ -367,6 +385,8 @@ static void
link_elf_init(void* arg)
{
Elf_Dyn *dp;
Elf_Addr *ctors_addrp;
Elf_Size *ctors_sizep;
caddr_t modptr, baseptr, sizeptr;
elf_file_t ef;
char *modname;
@ -408,6 +428,15 @@ link_elf_init(void* arg)
sizeptr = preload_search_info(modptr, MODINFO_SIZE);
if (sizeptr != NULL)
linker_kernel_file->size = *(size_t *)sizeptr;
ctors_addrp = (Elf_Addr *)preload_search_info(modptr,
MODINFO_METADATA | MODINFOMD_CTORS_ADDR);
ctors_sizep = (Elf_Size *)preload_search_info(modptr,
MODINFO_METADATA | MODINFOMD_CTORS_SIZE);
if (ctors_addrp != NULL && ctors_sizep != NULL) {
linker_kernel_file->ctors_addr = ef->address +
*ctors_addrp;
linker_kernel_file->ctors_size = *ctors_sizep;
}
}
(void)link_elf_preload_parse_symbols(ef);
@ -635,6 +664,8 @@ static int
link_elf_link_preload(linker_class_t cls,
const char* filename, linker_file_t *result)
{
Elf_Addr *ctors_addrp;
Elf_Size *ctors_sizep;
caddr_t modptr, baseptr, sizeptr, dynptr;
char *type;
elf_file_t ef;
@ -675,6 +706,15 @@ link_elf_link_preload(linker_class_t cls,
lf->address = ef->address;
lf->size = *(size_t *)sizeptr;
ctors_addrp = (Elf_Addr *)preload_search_info(modptr,
MODINFO_METADATA | MODINFOMD_CTORS_ADDR);
ctors_sizep = (Elf_Size *)preload_search_info(modptr,
MODINFO_METADATA | MODINFOMD_CTORS_SIZE);
if (ctors_addrp != NULL && ctors_sizep != NULL) {
lf->ctors_addr = ef->address + *ctors_addrp;
lf->ctors_size = *ctors_sizep;
}
error = parse_dynamic(ef);
if (error == 0)
error = parse_dpcpu(ef);
@ -734,11 +774,14 @@ link_elf_load_file(linker_class_t cls, const char* filename,
Elf_Shdr *shdr;
int symtabindex;
int symstrindex;
int shstrindex;
int symcnt;
int strcnt;
char *shstrs;
shdr = NULL;
lf = NULL;
shstrs = NULL;
NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, filename, td);
flags = FREAD;
@ -977,12 +1020,31 @@ link_elf_load_file(linker_class_t cls, const char* filename,
&resid, td);
if (error != 0)
goto out;
/* Read section string table */
shstrindex = hdr->e_shstrndx;
if (shstrindex != 0 && shdr[shstrindex].sh_type == SHT_STRTAB &&
shdr[shstrindex].sh_size != 0) {
nbytes = shdr[shstrindex].sh_size;
shstrs = malloc(nbytes, M_LINKER, M_WAITOK | M_ZERO);
error = vn_rdwr(UIO_READ, nd.ni_vp, (caddr_t)shstrs, nbytes,
shdr[shstrindex].sh_offset, UIO_SYSSPACE, IO_NODELOCKED,
td->td_ucred, NOCRED, &resid, td);
if (error)
goto out;
}
symtabindex = -1;
symstrindex = -1;
for (i = 0; i < hdr->e_shnum; i++) {
if (shdr[i].sh_type == SHT_SYMTAB) {
symtabindex = i;
symstrindex = shdr[i].sh_link;
} else if (shstrs != NULL && shdr[i].sh_name != 0 &&
strcmp(shstrs + shdr[i].sh_name, ".ctors") == 0) {
/* Record relocated address and size of .ctors. */
lf->ctors_addr = mapbase + shdr[i].sh_addr - base_vaddr;
lf->ctors_size = shdr[i].sh_size;
}
}
if (symtabindex < 0 || symstrindex < 0)
@ -1027,6 +1089,8 @@ out:
free(shdr, M_LINKER);
if (firstpage != NULL)
free(firstpage, M_LINKER);
if (shstrs != NULL)
free(shstrs, M_LINKER);
return (error);
}

View File

@ -363,6 +363,10 @@ link_elf_link_preload(linker_class_t cls, const char *filename,
vnet_data_copy(vnet_data, shdr[i].sh_size);
ef->progtab[pb].addr = vnet_data;
#endif
} else if (ef->progtab[pb].name != NULL &&
!strcmp(ef->progtab[pb].name, ".ctors")) {
lf->ctors_addr = ef->progtab[pb].addr;
lf->ctors_size = shdr[i].sh_size;
}
/* Update all symbol values with the offset. */
@ -408,6 +412,22 @@ out:
return (error);
}
static void
link_elf_invoke_ctors(caddr_t addr, size_t size)
{
void (**ctor)(void);
size_t i, cnt;
if (addr == NULL || size == 0)
return;
cnt = size / sizeof(*ctor);
ctor = (void *)addr;
for (i = 0; i < cnt; i++) {
if (ctor[i] != NULL)
(*ctor[i])();
}
}
static int
link_elf_link_preload_finish(linker_file_t lf)
{
@ -424,6 +444,8 @@ link_elf_link_preload_finish(linker_file_t lf)
if (error)
return (error);
/* Invoke .ctors */
link_elf_invoke_ctors(lf->ctors_addr, lf->ctors_size);
return (0);
}
@ -727,10 +749,14 @@ link_elf_load_file(linker_class_t cls, const char *filename,
alignmask = shdr[i].sh_addralign - 1;
mapbase += alignmask;
mapbase &= ~alignmask;
if (ef->shstrtab && shdr[i].sh_name != 0)
if (ef->shstrtab != NULL && shdr[i].sh_name != 0) {
ef->progtab[pb].name =
ef->shstrtab + shdr[i].sh_name;
else if (shdr[i].sh_type == SHT_PROGBITS)
if (!strcmp(ef->progtab[pb].name, ".ctors")) {
lf->ctors_addr = (caddr_t)mapbase;
lf->ctors_size = shdr[i].sh_size;
}
} else if (shdr[i].sh_type == SHT_PROGBITS)
ef->progtab[pb].name = "<<PROGBITS>>";
else
ef->progtab[pb].name = "<<NOBITS>>";
@ -860,6 +886,9 @@ link_elf_load_file(linker_class_t cls, const char *filename,
if (error)
goto out;
/* Invoke .ctors */
link_elf_invoke_ctors(lf->ctors_addr, lf->ctors_size);
*result = lf;
out:

View File

@ -90,7 +90,7 @@ dtrace_vtime_switch_func_t dtrace_vtime_switch_func;
struct td_sched {
struct runq *ts_runq; /* Run-queue we're queued on. */
short ts_flags; /* TSF_* flags. */
u_char ts_cpu; /* CPU that we have affinity for. */
int ts_cpu; /* CPU that we have affinity for. */
int ts_rltick; /* Real last tick, for affinity. */
int ts_slice; /* Ticks of slice remaining. */
u_int ts_slptime; /* Number of ticks we vol. slept */

View File

@ -540,50 +540,3 @@ out:
stopprofclock(p);
PROC_UNLOCK(p);
}
#if (defined(__amd64__) || defined(__i386__)) && \
defined(__GNUCLIKE_CTOR_SECTION_HANDLING)
/*
* Support for "--test-coverage --profile-arcs" in GCC.
*
* We need to call all the functions in the .ctor section, in order
* to get all the counter-arrays strung into a list.
*
* XXX: the .ctors call __bb_init_func which is located in over in
* XXX: i386/i386/support.s for historical reasons. There is probably
* XXX: no reason for that to be assembler anymore, but doing it right
* XXX: in MI C code requires one to reverse-engineer the type-selection
* XXX: inside GCC. Have fun.
*
* XXX: Worrisome perspective: Calling the .ctors may make C++ in the
* XXX: kernel feasible. Don't.
*/
typedef void (*ctor_t)(void);
extern ctor_t _start_ctors, _stop_ctors;
static void
tcov_init(void *foo __unused)
{
ctor_t *p, q;
for (p = &_start_ctors; p < &_stop_ctors; p++) {
q = *p;
q();
}
}
SYSINIT(tcov_init, SI_SUB_KPROF, SI_ORDER_SECOND, tcov_init, NULL);
/*
* GCC contains magic to recognize calls to for instance execve() and
* puts in calls to this function to preserve the profile counters.
* XXX: Put zinging punchline here.
*/
void __bb_fork_func(void);
void
__bb_fork_func(void)
{
}
#endif

View File

@ -1572,6 +1572,25 @@ vn_closefile(fp, td)
return (error);
}
static bool
vn_suspendable_mp(struct mount *mp)
{
return ((mp->mnt_kern_flag & MNTK_SUSPENDABLE) != 0);
}
static bool
vn_suspendable(struct vnode *vp, struct mount **mpp)
{
if (vp != NULL)
*mpp = vp->v_mount;
if (*mpp == NULL)
return (false);
return (vn_suspendable_mp(*mpp));
}
/*
* Preparing to start a filesystem write operation. If the operation is
* permitted, then we bump the count of operations in progress and
@ -1621,6 +1640,9 @@ vn_start_write(vp, mpp, flags)
struct mount *mp;
int error;
if (!vn_suspendable(vp, mpp))
return (0);
error = 0;
/*
* If a vnode is provided, get and return the mount point that
@ -1667,6 +1689,9 @@ vn_start_secondary_write(vp, mpp, flags)
struct mount *mp;
int error;
if (!vn_suspendable(vp, mpp))
return (0);
retry:
if (vp != NULL) {
if ((error = VOP_GETWRITEMOUNT(vp, mpp)) != 0) {
@ -1724,7 +1749,7 @@ void
vn_finished_write(mp)
struct mount *mp;
{
if (mp == NULL)
if (mp == NULL || !vn_suspendable_mp(mp))
return;
MNT_ILOCK(mp);
MNT_REL(mp);
@ -1747,7 +1772,7 @@ void
vn_finished_secondary_write(mp)
struct mount *mp;
{
if (mp == NULL)
if (mp == NULL || !vn_suspendable_mp(mp))
return;
MNT_ILOCK(mp);
MNT_REL(mp);
@ -1770,6 +1795,8 @@ vfs_write_suspend(struct mount *mp, int flags)
{
int error;
MPASS(vn_suspendable_mp(mp));
MNT_ILOCK(mp);
if (mp->mnt_susp_owner == curthread) {
MNT_IUNLOCK(mp);
@ -1811,6 +1838,8 @@ void
vfs_write_resume(struct mount *mp, int flags)
{
MPASS(vn_suspendable_mp(mp));
MNT_ILOCK(mp);
if ((mp->mnt_kern_flag & MNTK_SUSPEND) != 0) {
KASSERT(mp->mnt_susp_owner == curthread, ("mnt_susp_owner"));
@ -1844,6 +1873,7 @@ vfs_write_suspend_umnt(struct mount *mp)
{
int error;
MPASS(vn_suspendable_mp(mp));
KASSERT((curthread->td_pflags & TDP_IGNSUSP) == 0,
("vfs_write_suspend_umnt: recursed"));

View File

@ -22,6 +22,8 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#include <sys/hash.h>
@ -32,27 +34,31 @@
#define rol32(i32, n) ((i32) << (n) | (i32) >> (32 - (n)))
/*
* $FreeBSD$
* Simple implementation of the Murmur3-32 hash function optimized for
* aligned sequences of 32-bit words. If len is not a multiple of 4, it
* will be rounded down, droping trailer bytes.
* Simple implementation of the Murmur3-32 hash function.
*
* This implementation is slow but safe. It can be made significantly
* faster if the caller guarantees that the input is correctly aligned for
* 32-bit reads, and slightly faster yet if the caller guarantees that the
* length of the input is always a multiple of 4 bytes.
*/
uint32_t
murmur3_aligned_32(const void *data, size_t len, uint32_t seed)
murmur3_32_hash(const void *data, size_t len, uint32_t seed)
{
const uint32_t *data32;
const uint8_t *bytes;
uint32_t hash, k;
size_t res;
/* initialize */
len -= len % sizeof(*data32);
/* initialization */
bytes = data;
res = len;
data32 = data;
hash = seed;
/* iterate */
for (res = 0; res < len; res += sizeof(*data32), data32++) {
k = le32toh(*data32);
/* main loop */
while (res >= 4) {
/* replace with le32toh() if input is aligned */
k = le32dec(bytes);
bytes += 4;
res -= 4;
k *= 0xcc9e2d51;
k = rol32(k, 15);
k *= 0x1b873593;
@ -62,6 +68,25 @@ murmur3_aligned_32(const void *data, size_t len, uint32_t seed)
hash += 0xe6546b64;
}
/* remainder */
/* remove if input length is a multiple of 4 */
if (res > 0) {
k = 0;
switch (res) {
case 3:
k |= bytes[2] << 16;
case 2:
k |= bytes[1] << 8;
case 1:
k |= bytes[0];
k *= 0xcc9e2d51;
k = rol32(k, 15);
k *= 0x1b873593;
hash ^= k;
break;
}
}
/* finalize */
hash ^= (uint32_t)len;
hash ^= hash >> 16;
@ -72,3 +97,36 @@ murmur3_aligned_32(const void *data, size_t len, uint32_t seed)
return (hash);
}
/*
* Simplified version of the above optimized for aligned sequences of
* 32-bit words. The count argument is the number of words, not the
* length in bytes.
*/
uint32_t
murmur3_32_hash32(const uint32_t *data, size_t count, uint32_t seed)
{
uint32_t hash, k;
size_t res;
/* iterate */
for (res = count, hash = seed; res > 0; res--, data++) {
k = le32toh(*data);
k *= 0xcc9e2d51;
k = rol32(k, 15);
k *= 0x1b873593;
hash ^= k;
hash = rol32(hash, 13);
hash *= 5;
hash += 0xe6546b64;
}
/* finalize */
hash ^= (uint32_t)count;
hash ^= hash >> 16;
hash *= 0x85ebca6b;
hash ^= hash >> 13;
hash *= 0xc2b2ae35;
hash ^= hash >> 16;
return (hash);
}

View File

@ -164,9 +164,9 @@ _parse_bootargs(char *cmdline)
} else {
n = strsep(&v, "=");
if (v == NULL)
setenv(n, "1");
kern_setenv(n, "1");
else
setenv(n, v);
kern_setenv(n, v);
}
}
}

View File

@ -458,9 +458,9 @@ platform_start(__register_t a0 __unused,
printf("\t%s\n", arg);
n = strsep(&arg, "=");
if (arg == NULL)
setenv(n, "1");
kern_setenv(n, "1");
else
setenv(n, arg);
kern_setenv(n, arg);
}
xlr_set_boot_flags();

Some files were not shown because too many files have changed in this diff Show More