IFC @r273338
This commit is contained in:
commit
b02cd3e378
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
16
bin/sh/tests/parser/line-cont1.0
Normal file
16
bin/sh/tests/parser/line-cont1.0
Normal file
@ -0,0 +1,16 @@
|
||||
# $FreeBSD$
|
||||
|
||||
i\
|
||||
f
|
||||
t\
|
||||
r\
|
||||
u\
|
||||
e
|
||||
t\
|
||||
h\
|
||||
e\
|
||||
n
|
||||
:
|
||||
\
|
||||
f\
|
||||
i
|
18
bin/sh/tests/parser/line-cont10.0
Normal file
18
bin/sh/tests/parser/line-cont10.0
Normal file
@ -0,0 +1,18 @@
|
||||
# $FreeBSD$
|
||||
|
||||
v=XaaaXbbbX
|
||||
[ "${v\
|
||||
#\
|
||||
*\
|
||||
a}.${v\
|
||||
#\
|
||||
#\
|
||||
*\
|
||||
a}.${v\
|
||||
%\
|
||||
b\
|
||||
*}.${v\
|
||||
%\
|
||||
%\
|
||||
b\
|
||||
*}" = aaXbbbX.XbbbX.XaaaXbb.XaaaX ]
|
23
bin/sh/tests/parser/line-cont11.0
Normal file
23
bin/sh/tests/parser/line-cont11.0
Normal 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
|
4
bin/sh/tests/parser/line-cont2.0
Normal file
4
bin/sh/tests/parser/line-cont2.0
Normal file
@ -0,0 +1,4 @@
|
||||
# $FreeBSD$
|
||||
|
||||
[ "a\
|
||||
b" = ab ]
|
7
bin/sh/tests/parser/line-cont3.0
Normal file
7
bin/sh/tests/parser/line-cont3.0
Normal file
@ -0,0 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
v=`printf %s 'a\
|
||||
b'`
|
||||
w="`printf %s 'c\
|
||||
d'`"
|
||||
[ "$v$w" = abcd ]
|
8
bin/sh/tests/parser/line-cont4.0
Normal file
8
bin/sh/tests/parser/line-cont4.0
Normal file
@ -0,0 +1,8 @@
|
||||
# $FreeBSD$
|
||||
|
||||
v=abcd
|
||||
[ "$\
|
||||
v.$\
|
||||
{v}.${\
|
||||
v}.${v\
|
||||
}" = abcd.abcd.abcd.abcd ]
|
14
bin/sh/tests/parser/line-cont5.0
Normal file
14
bin/sh/tests/parser/line-cont5.0
Normal file
@ -0,0 +1,14 @@
|
||||
# $FreeBSD$
|
||||
|
||||
bad=1
|
||||
case x in
|
||||
x\
|
||||
) ;\
|
||||
; *) exit 7
|
||||
esac &\
|
||||
& bad= &\
|
||||
& : >\
|
||||
>/dev/null
|
||||
|
||||
false |\
|
||||
| [ -z "$bad" ]
|
23
bin/sh/tests/parser/line-cont6.0
Normal file
23
bin/sh/tests/parser/line-cont6.0
Normal 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" ]
|
7
bin/sh/tests/parser/line-cont7.0
Normal file
7
bin/sh/tests/parser/line-cont7.0
Normal file
@ -0,0 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
[ "$(\
|
||||
(
|
||||
1\
|
||||
+ 1)\
|
||||
)" = 2 ]
|
6
bin/sh/tests/parser/line-cont8.0
Normal file
6
bin/sh/tests/parser/line-cont8.0
Normal file
@ -0,0 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
set -- a b c d e f g h i j
|
||||
[ "${1\
|
||||
0\
|
||||
}" = j ]
|
6
bin/sh/tests/parser/line-cont9.0
Normal file
6
bin/sh/tests/parser/line-cont9.0
Normal file
@ -0,0 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
[ "${$\
|
||||
:\
|
||||
+\
|
||||
xyz}" = xyz ]
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
;;
|
||||
*)
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
648
sbin/ifconfig/ifvxlan.c
Normal 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) ¶ms;
|
||||
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
|
||||
}
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ PROG= ping
|
||||
MAN= ping.8
|
||||
BINOWN= root
|
||||
BINMODE=4555
|
||||
WARNS?= 2
|
||||
WARNS?= 3
|
||||
DPADD= ${LIBM}
|
||||
LDADD= -lm
|
||||
|
||||
|
@ -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);
|
||||
|
@ -5,7 +5,7 @@ MAN= ping6.8
|
||||
|
||||
CFLAGS+=-DIPSEC -DKAME_SCOPEID -DUSE_RFC2292BIS \
|
||||
-DHAVE_ARC4RANDOM
|
||||
WARNS?= 2
|
||||
WARNS?= 3
|
||||
|
||||
BINOWN= root
|
||||
BINMODE=4555
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
235
share/man/man4/vxlan.4
Normal 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 .
|
@ -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
152
share/man/man8/uefi.8
Normal 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.
|
@ -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 .
|
||||
|
@ -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
|
||||
------------------------
|
||||
|
@ -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
|
||||
|
@ -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
36
sys/arm/arm/elf_note.S
Normal 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);
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
140
sys/arm/conf/SOCKIT-BERI
Normal 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
|
@ -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);
|
||||
|
||||
|
@ -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 */
|
||||
|
156
sys/arm/ti/am335x/am335x_gpio.c
Normal file
156
sys/arm/ti/am335x/am335x_gpio.c
Normal 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);
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
44
sys/arm/ti/am335x/am335x_scm_padconf.h
Normal file
44
sys/arm/ti/am335x/am335x_scm_padconf.h
Normal 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 */
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
143
sys/arm/ti/omap4/omap4_gpio.c
Normal file
143
sys/arm/ti/omap4/omap4_gpio.c
Normal 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);
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
81
sys/arm/ti/omap4/omap4_scm_padconf.h
Normal file
81
sys/arm/ti/omap4/omap4_scm_padconf.h
Normal 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 */
|
@ -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
69
sys/arm/ti/ti_gpio.h
Normal 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
49
sys/arm/ti/ti_gpio_if.m
Normal 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;
|
||||
};
|
@ -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;
|
||||
|
@ -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
277
sys/arm/ti/ti_wdt.c
Normal 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
74
sys/arm/ti/ti_wdt.h
Normal 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_ */
|
@ -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++) {
|
||||
|
@ -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>;
|
||||
|
109
sys/boot/fdt/dts/arm/socfpga-sockit-beri.dts
Normal file
109
sys/boot/fdt/dts/arm/socfpga-sockit-beri.dts
Normal 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";
|
||||
};
|
||||
};
|
@ -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') {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
529
sys/dev/beri/beri_ring.c
Normal 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);
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
|
@ -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];
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
||||
|
@ -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"));
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user