Merge ^/head r294599 through r294776.
This commit is contained in:
commit
14d5c08ba8
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/clang380-import/; revision=294777
@ -26,7 +26,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd September 4, 2015
|
||||
.Dd January 23, 2016
|
||||
.Dt SETFACL 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -62,8 +62,9 @@ starting at position
|
||||
counting from zero.
|
||||
This option is only applicable to NFSv4 ACLs.
|
||||
.It Fl b
|
||||
Remove all ACL entries except for the three required entries
|
||||
(POSIX.1e ACLs) or six "canonical" entries (NFSv4 ACLs).
|
||||
Remove all ACL entries except for the ones synthesized
|
||||
from the file mode - the three mandatory entries in case
|
||||
of POSIX.1e ACL.
|
||||
If the POSIX.1e ACL contains a
|
||||
.Dq Li mask
|
||||
entry, the permissions of the
|
||||
|
48
bin/sh/cd.c
48
bin/sh/cd.c
@ -68,15 +68,13 @@ __FBSDID("$FreeBSD$");
|
||||
static int cdlogical(char *);
|
||||
static int cdphysical(char *);
|
||||
static int docd(char *, int, int);
|
||||
static char *getcomponent(void);
|
||||
static char *getcomponent(char **);
|
||||
static char *findcwd(char *);
|
||||
static void updatepwd(char *);
|
||||
static char *getpwd(void);
|
||||
static char *getpwd2(void);
|
||||
|
||||
static char *curdir = NULL; /* current working directory */
|
||||
static char *prevdir; /* previous working directory */
|
||||
static char *cdcomppath;
|
||||
|
||||
int
|
||||
cdcmd(int argc __unused, char **argv __unused)
|
||||
@ -112,11 +110,10 @@ cdcmd(int argc __unused, char **argv __unused)
|
||||
if (*dest == '\0')
|
||||
dest = ".";
|
||||
if (dest[0] == '-' && dest[1] == '\0') {
|
||||
dest = prevdir ? prevdir : curdir;
|
||||
if (dest)
|
||||
print = 1;
|
||||
else
|
||||
dest = ".";
|
||||
dest = bltinlookup("OLDPWD", 1);
|
||||
if (dest == NULL)
|
||||
error("OLDPWD not set");
|
||||
print = 1;
|
||||
}
|
||||
if (dest[0] == '/' ||
|
||||
(dest[0] == '.' && (dest[1] == '/' || dest[1] == '\0')) ||
|
||||
@ -179,6 +176,7 @@ cdlogical(char *dest)
|
||||
char *p;
|
||||
char *q;
|
||||
char *component;
|
||||
char *path;
|
||||
struct stat statb;
|
||||
int first;
|
||||
int badstat;
|
||||
@ -189,14 +187,14 @@ cdlogical(char *dest)
|
||||
* next time we get the value of the current directory.
|
||||
*/
|
||||
badstat = 0;
|
||||
cdcomppath = stsavestr(dest);
|
||||
path = stsavestr(dest);
|
||||
STARTSTACKSTR(p);
|
||||
if (*dest == '/') {
|
||||
STPUTC('/', p);
|
||||
cdcomppath++;
|
||||
path++;
|
||||
}
|
||||
first = 1;
|
||||
while ((q = getcomponent()) != NULL) {
|
||||
while ((q = getcomponent(&path)) != NULL) {
|
||||
if (q[0] == '\0' || (q[0] == '.' && q[1] == '\0'))
|
||||
continue;
|
||||
if (! first)
|
||||
@ -245,25 +243,25 @@ cdphysical(char *dest)
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the next component of the path name pointed to by cdcomppath.
|
||||
* This routine overwrites the string pointed to by cdcomppath.
|
||||
* Get the next component of the path name pointed to by *path.
|
||||
* This routine overwrites *path and the string pointed to by it.
|
||||
*/
|
||||
static char *
|
||||
getcomponent(void)
|
||||
getcomponent(char **path)
|
||||
{
|
||||
char *p;
|
||||
char *start;
|
||||
|
||||
if ((p = cdcomppath) == NULL)
|
||||
if ((p = *path) == NULL)
|
||||
return NULL;
|
||||
start = cdcomppath;
|
||||
start = *path;
|
||||
while (*p != '/' && *p != '\0')
|
||||
p++;
|
||||
if (*p == '\0') {
|
||||
cdcomppath = NULL;
|
||||
*path = NULL;
|
||||
} else {
|
||||
*p++ = '\0';
|
||||
cdcomppath = p;
|
||||
*path = p;
|
||||
}
|
||||
return start;
|
||||
}
|
||||
@ -274,6 +272,7 @@ findcwd(char *dir)
|
||||
{
|
||||
char *new;
|
||||
char *p;
|
||||
char *path;
|
||||
|
||||
/*
|
||||
* If our argument is NULL, we don't know the current directory
|
||||
@ -282,14 +281,14 @@ findcwd(char *dir)
|
||||
*/
|
||||
if (dir == NULL || curdir == NULL)
|
||||
return getpwd2();
|
||||
cdcomppath = stsavestr(dir);
|
||||
path = stsavestr(dir);
|
||||
STARTSTACKSTR(new);
|
||||
if (*dir != '/') {
|
||||
STPUTS(curdir, new);
|
||||
if (STTOPC(new) == '/')
|
||||
STUNPUTC(new);
|
||||
}
|
||||
while ((p = getcomponent()) != NULL) {
|
||||
while ((p = getcomponent(&path)) != NULL) {
|
||||
if (equal(p, "..")) {
|
||||
while (new > stackblock() && (STUNPUTC(new), *new) != '/');
|
||||
} else if (*p != '\0' && ! equal(p, ".")) {
|
||||
@ -311,14 +310,15 @@ findcwd(char *dir)
|
||||
static void
|
||||
updatepwd(char *dir)
|
||||
{
|
||||
char *prevdir;
|
||||
|
||||
hashcd(); /* update command hash table */
|
||||
|
||||
if (prevdir)
|
||||
ckfree(prevdir);
|
||||
setvar("PWD", dir, VEXPORT);
|
||||
setvar("OLDPWD", curdir, VEXPORT);
|
||||
prevdir = curdir;
|
||||
curdir = dir ? savestr(dir) : NULL;
|
||||
setvar("PWD", curdir, VEXPORT);
|
||||
setvar("OLDPWD", prevdir, VEXPORT);
|
||||
ckfree(prevdir);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -91,13 +91,13 @@ struct worddest {
|
||||
static char *expdest; /* output of current string */
|
||||
static struct nodelist *argbackq; /* list of back quote expressions */
|
||||
|
||||
static char *argstr(char *, int, struct worddest *);
|
||||
static char *exptilde(char *, int);
|
||||
static char *expari(char *, int, struct worddest *);
|
||||
static const char *argstr(const char *, int, struct worddest *);
|
||||
static const char *exptilde(const char *, int);
|
||||
static const char *expari(const char *, int, struct worddest *);
|
||||
static void expbackq(union node *, int, int, struct worddest *);
|
||||
static void subevalvar_trim(char *, int, int, int);
|
||||
static int subevalvar_misc(char *, const char *, int, int, int);
|
||||
static char *evalvar(char *, int, struct worddest *);
|
||||
static void subevalvar_trim(const char *, int, int, int);
|
||||
static int subevalvar_misc(const char *, const char *, int, int, int);
|
||||
static const char *evalvar(const char *, int, struct worddest *);
|
||||
static int varisset(const char *, int);
|
||||
static void strtodest(const char *, int, int, int, struct worddest *);
|
||||
static void reprocess(int, int, int, int, struct worddest *);
|
||||
@ -262,8 +262,8 @@ expandarg(union node *arg, struct arglist *arglist, int flag)
|
||||
*
|
||||
* If EXP_SPLIT is set, dst receives any complete words produced.
|
||||
*/
|
||||
static char *
|
||||
argstr(char *p, int flag, struct worddest *dst)
|
||||
static const char *
|
||||
argstr(const char *p, int flag, struct worddest *dst)
|
||||
{
|
||||
char c;
|
||||
int quotes = flag & (EXP_GLOB | EXP_CASE); /* do CTLESC */
|
||||
@ -352,12 +352,15 @@ argstr(char *p, int flag, struct worddest *dst)
|
||||
* Perform tilde expansion, placing the result in the stack string and
|
||||
* returning the next position in the input string to process.
|
||||
*/
|
||||
static char *
|
||||
exptilde(char *p, int flag)
|
||||
static const char *
|
||||
exptilde(const char *p, int flag)
|
||||
{
|
||||
char c, *startp = p;
|
||||
char c;
|
||||
const char *startp = p;
|
||||
const char *user;
|
||||
struct passwd *pw;
|
||||
char *home;
|
||||
int len;
|
||||
|
||||
for (;;) {
|
||||
c = *p;
|
||||
@ -377,14 +380,17 @@ exptilde(char *p, int flag)
|
||||
case '\0':
|
||||
case '/':
|
||||
case CTLENDVAR:
|
||||
*p = '\0';
|
||||
if (*(startp+1) == '\0') {
|
||||
len = p - startp - 1;
|
||||
STPUTBIN(startp + 1, len, expdest);
|
||||
STACKSTRNUL(expdest);
|
||||
user = expdest - len;
|
||||
if (*user == '\0') {
|
||||
home = lookupvar("HOME");
|
||||
} else {
|
||||
pw = getpwnam(startp+1);
|
||||
pw = getpwnam(user);
|
||||
home = pw != NULL ? pw->pw_dir : NULL;
|
||||
}
|
||||
*p = c;
|
||||
STADJUST(-len, expdest);
|
||||
if (home == NULL || *home == '\0')
|
||||
return (startp);
|
||||
strtodest(home, flag, VSNORMAL, 1, NULL);
|
||||
@ -398,8 +404,8 @@ exptilde(char *p, int flag)
|
||||
/*
|
||||
* Expand arithmetic expression.
|
||||
*/
|
||||
static char *
|
||||
expari(char *p, int flag, struct worddest *dst)
|
||||
static const char *
|
||||
expari(const char *p, int flag, struct worddest *dst)
|
||||
{
|
||||
char *q, *start;
|
||||
arith_t result;
|
||||
@ -532,7 +538,7 @@ recordleft(const char *str, const char *loc, char *startp)
|
||||
}
|
||||
|
||||
static void
|
||||
subevalvar_trim(char *p, int strloc, int subtype, int startloc)
|
||||
subevalvar_trim(const char *p, int strloc, int subtype, int startloc)
|
||||
{
|
||||
char *startp;
|
||||
char *loc = NULL;
|
||||
@ -606,7 +612,7 @@ subevalvar_trim(char *p, int strloc, int subtype, int startloc)
|
||||
|
||||
|
||||
static int
|
||||
subevalvar_misc(char *p, const char *var, int subtype, int startloc,
|
||||
subevalvar_misc(const char *p, const char *var, int subtype, int startloc,
|
||||
int varflags)
|
||||
{
|
||||
char *startp;
|
||||
@ -645,12 +651,12 @@ subevalvar_misc(char *p, const char *var, int subtype, int startloc,
|
||||
* input string.
|
||||
*/
|
||||
|
||||
static char *
|
||||
evalvar(char *p, int flag, struct worddest *dst)
|
||||
static const char *
|
||||
evalvar(const char *p, int flag, struct worddest *dst)
|
||||
{
|
||||
int subtype;
|
||||
int varflags;
|
||||
char *var;
|
||||
const char *var;
|
||||
const char *val;
|
||||
int patloc;
|
||||
int c;
|
||||
|
@ -26,7 +26,7 @@ _libzpool= libzpool
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.if ${MACHINE_CPUARCH} != "sparc64"
|
||||
.if ${MACHINE_CPUARCH} != "sparc64" && ${MACHINE_CPUARCH} != "riscv"
|
||||
_drti= drti
|
||||
_libdtrace= libdtrace
|
||||
.endif
|
||||
|
@ -97,6 +97,12 @@
|
||||
#define LIBELF_BYTEORDER ELFDATA2MSB
|
||||
#define LIBELF_CLASS ELFCLASS32
|
||||
|
||||
#elif defined(__riscv64)
|
||||
|
||||
#define LIBELF_ARCH EM_RISCV
|
||||
#define LIBELF_BYTEORDER ELFDATA2LSB
|
||||
#define LIBELF_CLASS ELFCLASS64
|
||||
|
||||
#elif defined(__sparc__)
|
||||
|
||||
#define LIBELF_ARCH EM_SPARCV9
|
||||
|
6
contrib/gcc/config/riscv64/freebsd.h
Normal file
6
contrib/gcc/config/riscv64/freebsd.h
Normal file
@ -0,0 +1,6 @@
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#undef INIT_SECTION_ASM_OP
|
||||
#undef FINI_SECTION_ASM_OP
|
||||
#define INIT_ARRAY_SECTION_ASM_OP "\t.section\t.init_array,\"aw\",%init_array"
|
||||
#define FINI_ARRAY_SECTION_ASM_OP "\t.section\t.fini_array,\"aw\",%fini_array"
|
1
contrib/gcc/config/riscv64/riscv64.h
Normal file
1
contrib/gcc/config/riscv64/riscv64.h
Normal file
@ -0,0 +1 @@
|
||||
/* $FreeBSD$ */
|
@ -5,7 +5,8 @@
|
||||
PROG= rping
|
||||
MAN=
|
||||
SRCS= rping.c
|
||||
LDADD+= -libverbs -lrdmacm -lpthread
|
||||
LDADD+= -lmlx4
|
||||
LIBADD+= ibverbs rdmacm pthread
|
||||
LIBADD+= mlx4
|
||||
LIBADD+= cxgb4
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -134,6 +134,11 @@ daily_status_mail_rejects_enable="YES" # Check mail rejects
|
||||
daily_status_mail_rejects_logs=3 # How many logs to check
|
||||
daily_status_mail_rejects_shorten="NO" # Shorten output
|
||||
|
||||
# 480.leapfile-ntpd
|
||||
daily_ntpd_leapfile_enable="NO" # Fetch NTP leapfile
|
||||
daily_ntpd_avoid_congestion="YES" # Avoid congesting
|
||||
# leapfile sources
|
||||
|
||||
# 480.status-ntpd
|
||||
daily_status_ntpd_enable="NO" # Check NTP status
|
||||
|
||||
|
@ -362,6 +362,15 @@ ntpd_config="/etc/ntp.conf" # ntpd(8) configuration file
|
||||
ntpd_sync_on_start="NO" # Sync time on ntpd startup, even if offset is high
|
||||
ntpd_flags="-p /var/run/ntpd.pid -f /var/db/ntpd.drift"
|
||||
# Flags to ntpd (if enabled).
|
||||
ntp_src_leapfile="/etc/ntp/leap-seconds"
|
||||
# Initial source for ntpd leapfile
|
||||
ntp_db_leapfile="/var/db/ntpd.leap-seconds.list"
|
||||
# Working copy (updated weekly) leapfile
|
||||
ntp_leapfile_sources="https://www.ietf.org/timezones/data/leap-seconds.list"
|
||||
# Source from which to fetch leapfile
|
||||
ntp_leapfile_expiry_days=30 # Check for new leapfile 30 days prior to
|
||||
# expiry.
|
||||
ntp_leapfile_fetch_verbose="NO" # Be verbose during NTP leapfile fetch
|
||||
|
||||
# Network Information Services (NIS) options: All need rpcbind_enable="YES" ###
|
||||
nis_client_enable="NO" # We're an NIS client (or NO).
|
||||
|
@ -81,4 +81,6 @@ restrict 127.127.1.0
|
||||
# See http://support.ntp.org/bin/view/Support/ConfiguringNTP#Section_6.14.
|
||||
# for documentation regarding leapfile. Updates to the file can be obtained
|
||||
# from ftp://time.nist.gov/pub/ or ftp://tycho.usno.navy.mil/pub/ntp/.
|
||||
leapfile "/etc/ntp/leap-seconds"
|
||||
# Use either leapfile in /etc/ntp or weekly updated leapfile in /var/db.
|
||||
#leapfile "/etc/ntp/leap-seconds"
|
||||
leapfile "/var/db/ntpd.leap-seconds.list"
|
||||
|
28
etc/periodic/daily/480.leapfile-ntpd
Executable file
28
etc/periodic/daily/480.leapfile-ntpd
Executable file
@ -0,0 +1,28 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
# If there is a global system configuration file, suck it in.
|
||||
#
|
||||
if [ -r /etc/defaults/periodic.conf ]
|
||||
then
|
||||
. /etc/defaults/periodic.conf
|
||||
source_periodic_confs
|
||||
fi
|
||||
|
||||
case "$daily_ntpd_leapfile_enable" in
|
||||
[Yy][Ee][Ss])
|
||||
case "$daily_ntpd_avoid_congestion" in
|
||||
[Yy][Ee][Ss])
|
||||
# Avoid dogpiling
|
||||
(sleep $(jot -r 1 0 86400); service ntpd fetch) &
|
||||
;;
|
||||
*)
|
||||
service ntpd fetch
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
exit $rc
|
@ -35,7 +35,8 @@ FILES+= 130.clean-msgs
|
||||
.endif
|
||||
|
||||
.if ${MK_NTP} != "no"
|
||||
FILES+= 480.status-ntpd
|
||||
FILES+= 480.status-ntpd \
|
||||
480.leapfile-ntpd
|
||||
.endif
|
||||
|
||||
.if ${MK_RCMDS} != "no"
|
||||
|
@ -32,7 +32,7 @@ need_dad_wait=
|
||||
# Extract value from ${jail_$jv_$name} or ${jail_$name} and
|
||||
# set it to $param. If not defined, $defval is used.
|
||||
# When $num is [0-9]*, ${jail_$jv_$name$num} are looked up and
|
||||
# $param is set by using +=.
|
||||
# $param is set by using +=. $num=0 is optional (params may start at 1).
|
||||
# When $num is YN or NY, the value is interpret as boolean.
|
||||
extract_var()
|
||||
{
|
||||
@ -72,7 +72,7 @@ extract_var()
|
||||
eval _tmpargs=\"\${$_name1:-\${$_name2:-$_def}}\"
|
||||
if [ -n "$_tmpargs" ]; then
|
||||
echo " $_param += \"$_tmpargs\";"
|
||||
else
|
||||
elif [ $i != 0 ]; then
|
||||
break;
|
||||
fi
|
||||
i=$(($i + 1))
|
||||
@ -202,7 +202,7 @@ parse_options()
|
||||
extract_var $_jv exec_poststop exec.poststop 0 ""
|
||||
|
||||
echo " exec.start += \"$_exec_start\";"
|
||||
extract_var $_jv exec_afterstart exec.start 1 ""
|
||||
extract_var $_jv exec_afterstart exec.start 0 ""
|
||||
echo " exec.stop = \"$_exec_stop\";"
|
||||
|
||||
extract_var $_jv consolelog exec.consolelog - \
|
||||
|
@ -14,6 +14,8 @@ name="ntpd"
|
||||
rcvar="ntpd_enable"
|
||||
command="/usr/sbin/${name}"
|
||||
pidfile="/var/run/${name}.pid"
|
||||
extra_commands="fetch"
|
||||
fetch_cmd="ntpd_fetch_leapfile"
|
||||
start_precmd="ntpd_precmd"
|
||||
|
||||
load_rc_config $name
|
||||
@ -30,6 +32,10 @@ ntpd_precmd()
|
||||
return 0;
|
||||
fi
|
||||
|
||||
if [ ! -f $ntp_db_leapfile ]; then
|
||||
ntpd_fetch_leapfile
|
||||
fi
|
||||
|
||||
# If running in a chroot cage, ensure that the appropriate files
|
||||
# exist inside the cage, as well as helper symlinks into the cage
|
||||
# from outside.
|
||||
@ -44,10 +50,71 @@ ntpd_precmd()
|
||||
( cd /dev ; /bin/pax -rw -pe clockctl "${ntpd_chrootdir}/dev" )
|
||||
fi
|
||||
ln -fs "${ntpd_chrootdir}/var/db/ntp.drift" /var/db/ntp.drift
|
||||
ln -fs "${ntpd_chrootdir}${ntp_tmp_leapfile}" ${ntp_tmp_leapfile}
|
||||
|
||||
# Change run_rc_commands()'s internal copy of $ntpd_flags
|
||||
#
|
||||
rc_flags="-u ntpd:ntpd -i ${ntpd_chrootdir} $rc_flags"
|
||||
}
|
||||
|
||||
current_ntp_ts() {
|
||||
# Seconds between 1900-01-01 and 1970-01-01
|
||||
# echo $(((70*365+17)*86400))
|
||||
ntp_to_unix=2208988800
|
||||
|
||||
echo $(($(date -u +%s)+$ntp_to_unix))
|
||||
}
|
||||
|
||||
get_ntp_leapfile_ver() {
|
||||
expr "$(awk '$1 == "#$" { print $2 }' "$1" 2>/dev/null)" : \
|
||||
'^\([1-9][0-9]*\)$' \| 0
|
||||
}
|
||||
|
||||
get_ntp_leapfile_expiry() {
|
||||
expr "$(awk '$1 == "#@" { print $2 }' "$1" 2>/dev/null)" : \
|
||||
'^\([1-9][0-9]*\)$' \| 0
|
||||
}
|
||||
|
||||
ntpd_fetch_leapfile() {
|
||||
local ntp_tmp_leapfile rc verbose
|
||||
|
||||
if checkyesno ntp_leapfile_fetch_verbose; then
|
||||
verbose=echo
|
||||
else
|
||||
verbose=:
|
||||
fi
|
||||
|
||||
ntp_tmp_leapfile="/var/run/ntpd.leap-seconds.list"
|
||||
|
||||
ntp_ver_no_src=$(get_ntp_leapfile_ver $ntp_src_leapfile)
|
||||
ntp_ver_no_db=$(get_ntp_leapfile_ver $ntp_db_leapfile)
|
||||
$verbose ntp_src_leapfile version is $ntp_ver_no_src
|
||||
$verbose ntp_db_leapfile version is $ntp_ver_no_db
|
||||
|
||||
if [ "$ntp_ver_no_src" -gt "$ntp_ver_no_db" ]; then
|
||||
$verbose replacing $ntp_db_leapfile with $ntp_src_leapfile
|
||||
cp -p $ntp_src_leapfile $ntp_db_leapfile
|
||||
ntp_ver_no_db=$ntp_ver_no_src
|
||||
else
|
||||
$verbose not replacing $ntp_db_leapfile with $ntp_src_leapfile
|
||||
fi
|
||||
ntp_leap_expiry=$(get_ntp_leapfile_expiry $ntp_db_leapfile)
|
||||
ntp_leapfile_expiry_seconds=$((ntp_leapfile_expiry_days*86400))
|
||||
ntp_leap_fetch_date=$((ntp_leap_expiry-ntp_leapfile_expiry_seconds))
|
||||
if [ $(current_ntp_ts) -ge $ntp_leap_fetch_date ]; then
|
||||
$verbose Within ntp leapfile expiry limit, initiating fetch
|
||||
for url in $ntp_leapfile_sources ; do
|
||||
$verbose fetching $url
|
||||
fetch -mqo $ntp_tmp_leapfile $url && break
|
||||
done
|
||||
ntp_ver_no_tmp=$(get_ntp_leapfile_ver $ntp_tmp_leapfile)
|
||||
if [ "$ntp_ver_no_tmp" -gt "$ntp_ver_no_db" ]; then
|
||||
$verbose using $url as $ntp_db_leapfile
|
||||
mv $ntp_tmp_leapfile $ntp_db_leapfile
|
||||
else
|
||||
$verbose using existing $ntp_db_leapfile
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
run_rc_command "$1"
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
LIB= readline
|
||||
INTERNALLIB= yes
|
||||
NO_MAN= yes
|
||||
MAN=
|
||||
|
||||
TILDESRC= tilde.c
|
||||
SRCS= readline.c vi_mode.c funmap.c keymaps.c parens.c search.c \
|
||||
|
@ -264,7 +264,8 @@ _libproc= libproc
|
||||
_librtld_db= librtld_db
|
||||
.endif
|
||||
|
||||
.if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "arm"
|
||||
.if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "arm" || \
|
||||
${MACHINE_CPUARCH} == "riscv"
|
||||
_libproc= libproc
|
||||
_librtld_db= librtld_db
|
||||
.endif
|
||||
|
@ -169,15 +169,15 @@ SUBDIR+= tests
|
||||
.if !defined(_SKIP_BUILD)
|
||||
# We need libutil.h, get it directly to avoid
|
||||
# recording a build dependency
|
||||
CFLAGS+= -I${.CURDIR:H}/libutil
|
||||
CFLAGS+= -I${SRCTOP}/lib/libutil
|
||||
# Same issue with libm
|
||||
MSUN_ARCH_SUBDIR != ${MAKE} -B -C ${.CURDIR:H}/msun -V ARCH_SUBDIR
|
||||
MSUN_ARCH_SUBDIR != ${MAKE} -B -C ${SRCTOP}/lib/msun -V ARCH_SUBDIR
|
||||
# unfortunately msun/src contains both private and public headers
|
||||
CFLAGS+= -I${.CURDIR:H}/msun/${MSUN_ARCH_SUBDIR}
|
||||
CFLAGS+= -I${SRCTOP}/lib/msun/${MSUN_ARCH_SUBDIR}
|
||||
.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
|
||||
CFLAGS+= -I${.CURDIR:H}/msun/x86
|
||||
CFLAGS+= -I${SRCTOP}/lib/msun/x86
|
||||
.endif
|
||||
CFLAGS+= -I${.CURDIR:H}/msun/src
|
||||
CFLAGS+= -I${SRCTOP}/lib/msun/src
|
||||
# and we do not want to record a dependency on msun
|
||||
.if ${.MAKE.LEVEL} > 0
|
||||
GENDIRDEPS_FILTER+= N${RELDIR:H}/msun
|
||||
|
@ -46,7 +46,7 @@ char *
|
||||
readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
|
||||
{
|
||||
ssize_t nr;
|
||||
int input, output, save_errno, i, need_restart;
|
||||
int input, output, save_errno, i, need_restart, input_is_tty;
|
||||
char ch, *p, *end;
|
||||
struct termios term, oterm;
|
||||
struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm;
|
||||
@ -68,12 +68,20 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
|
||||
* Read and write to /dev/tty if available. If not, read from
|
||||
* stdin and write to stderr unless a tty is required.
|
||||
*/
|
||||
if ((flags & RPP_STDIN) ||
|
||||
(input = output = _open(_PATH_TTY, O_RDWR | O_CLOEXEC)) == -1) {
|
||||
if (flags & RPP_REQUIRE_TTY) {
|
||||
errno = ENOTTY;
|
||||
return(NULL);
|
||||
input_is_tty = 0;
|
||||
if (!(flags & RPP_STDIN)) {
|
||||
input = output = _open(_PATH_TTY, O_RDWR | O_CLOEXEC);
|
||||
if (input == -1) {
|
||||
if (flags & RPP_REQUIRE_TTY) {
|
||||
errno = ENOTTY;
|
||||
return(NULL);
|
||||
}
|
||||
input = STDIN_FILENO;
|
||||
output = STDERR_FILENO;
|
||||
} else {
|
||||
input_is_tty = 1;
|
||||
}
|
||||
} else {
|
||||
input = STDIN_FILENO;
|
||||
output = STDERR_FILENO;
|
||||
}
|
||||
@ -83,7 +91,7 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
|
||||
* If we are using a tty but are not the foreground pgrp this will
|
||||
* generate SIGTTOU, so do it *before* installing the signal handlers.
|
||||
*/
|
||||
if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) {
|
||||
if (input_is_tty && tcgetattr(input, &oterm) == 0) {
|
||||
memcpy(&term, &oterm, sizeof(term));
|
||||
if (!(flags & RPP_ECHO_ON))
|
||||
term.c_lflag &= ~(ECHO | ECHONL);
|
||||
@ -152,7 +160,7 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
|
||||
(void)__libc_sigaction(SIGTSTP, &savetstp, NULL);
|
||||
(void)__libc_sigaction(SIGTTIN, &savettin, NULL);
|
||||
(void)__libc_sigaction(SIGTTOU, &savettou, NULL);
|
||||
if (input != STDIN_FILENO)
|
||||
if (input_is_tty)
|
||||
(void)_close(input);
|
||||
|
||||
/*
|
||||
|
@ -700,14 +700,19 @@ sctp_sendx(int sd, const void *msg, size_t msg_len,
|
||||
#ifdef SYS_sctp_generic_sendmsg
|
||||
if (addrcnt == 1) {
|
||||
socklen_t l;
|
||||
ssize_t ret;
|
||||
|
||||
/*
|
||||
* Quick way, we don't need to do a connectx so lets use the
|
||||
* syscall directly.
|
||||
*/
|
||||
l = addrs->sa_len;
|
||||
return (syscall(SYS_sctp_generic_sendmsg, sd,
|
||||
msg, msg_len, addrs, l, sinfo, flags));
|
||||
ret = syscall(SYS_sctp_generic_sendmsg, sd,
|
||||
msg, msg_len, addrs, l, sinfo, flags);
|
||||
if ((ret >= 0) && (sinfo != NULL)) {
|
||||
sinfo->sinfo_assoc_id = sctp_getassocid(sd, addrs);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -984,6 +989,7 @@ sctp_sendv(int sd,
|
||||
struct sockaddr *addr;
|
||||
struct sockaddr_in *addr_in;
|
||||
struct sockaddr_in6 *addr_in6;
|
||||
sctp_assoc_t *assoc_id;
|
||||
|
||||
if ((addrcnt < 0) ||
|
||||
(iovcnt < 0) ||
|
||||
@ -1002,6 +1008,7 @@ sctp_sendv(int sd,
|
||||
errno = ENOMEM;
|
||||
return (-1);
|
||||
}
|
||||
assoc_id = NULL;
|
||||
msg.msg_control = cmsgbuf;
|
||||
msg.msg_controllen = 0;
|
||||
cmsg = (struct cmsghdr *)cmsgbuf;
|
||||
@ -1025,6 +1032,7 @@ sctp_sendv(int sd,
|
||||
memcpy(CMSG_DATA(cmsg), info, sizeof(struct sctp_sndinfo));
|
||||
msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndinfo));
|
||||
cmsg = (struct cmsghdr *)((caddr_t)cmsg + CMSG_SPACE(sizeof(struct sctp_sndinfo)));
|
||||
assoc_id = &(((struct sctp_sndinfo *)info)->snd_assoc_id);
|
||||
break;
|
||||
case SCTP_SENDV_PRINFO:
|
||||
if ((info == NULL) || (infolen < sizeof(struct sctp_prinfo))) {
|
||||
@ -1066,6 +1074,7 @@ sctp_sendv(int sd,
|
||||
memcpy(CMSG_DATA(cmsg), &spa_info->sendv_sndinfo, sizeof(struct sctp_sndinfo));
|
||||
msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndinfo));
|
||||
cmsg = (struct cmsghdr *)((caddr_t)cmsg + CMSG_SPACE(sizeof(struct sctp_sndinfo)));
|
||||
assoc_id = &(spa_info->sendv_sndinfo.snd_assoc_id);
|
||||
}
|
||||
if (spa_info->sendv_flags & SCTP_SEND_PRINFO_VALID) {
|
||||
cmsg->cmsg_level = IPPROTO_SCTP;
|
||||
@ -1164,6 +1173,9 @@ sctp_sendv(int sd,
|
||||
msg.msg_flags = 0;
|
||||
ret = sendmsg(sd, &msg, flags);
|
||||
free(cmsgbuf);
|
||||
if ((ret >= 0) && (addrs != NULL) && (assoc_id != NULL)) {
|
||||
*assoc_id = sctp_getassocid(sd, addrs);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,6 @@ SRCS= elftc_bfdtarget.c \
|
||||
INCS= libelftc.h
|
||||
CFLAGS+=-I${ELFTCDIR}/libelftc -I${ELFTCDIR}/common
|
||||
|
||||
NO_MAN= yes
|
||||
MAN=
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
@ -61,6 +61,9 @@ __FBSDID("$FreeBSD$");
|
||||
#elif defined(__powerpc__)
|
||||
#define BREAKPOINT_INSTR 0x7fe00008 /* trap */
|
||||
#define BREAKPOINT_INSTR_SZ 4
|
||||
#elif defined(__riscv__)
|
||||
#define BREAKPOINT_INSTR 0x00100073 /* sbreak */
|
||||
#define BREAKPOINT_INSTR_SZ 4
|
||||
#else
|
||||
#error "Add support for your architecture"
|
||||
#endif
|
||||
|
@ -66,6 +66,8 @@ proc_regget(struct proc_handle *phdl, proc_reg_t reg, unsigned long *regvalue)
|
||||
*regvalue = regs.r_regs[PC];
|
||||
#elif defined(__powerpc__)
|
||||
*regvalue = regs.pc;
|
||||
#elif defined(__riscv__)
|
||||
*regvalue = regs.sepc;
|
||||
#endif
|
||||
break;
|
||||
case REG_SP:
|
||||
@ -81,6 +83,8 @@ proc_regget(struct proc_handle *phdl, proc_reg_t reg, unsigned long *regvalue)
|
||||
*regvalue = regs.r_regs[SP];
|
||||
#elif defined(__powerpc__)
|
||||
*regvalue = regs.fixreg[1];
|
||||
#elif defined(__riscv__)
|
||||
*regvalue = regs.sp;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
@ -117,6 +121,8 @@ proc_regset(struct proc_handle *phdl, proc_reg_t reg, unsigned long regvalue)
|
||||
regs.r_regs[PC] = regvalue;
|
||||
#elif defined(__powerpc__)
|
||||
regs.pc = regvalue;
|
||||
#elif defined(__riscv__)
|
||||
regs.sepc = regvalue;
|
||||
#endif
|
||||
break;
|
||||
case REG_SP:
|
||||
@ -132,6 +138,8 @@ proc_regset(struct proc_handle *phdl, proc_reg_t reg, unsigned long regvalue)
|
||||
regs.r_regs[PC] = regvalue;
|
||||
#elif defined(__powerpc__)
|
||||
regs.fixreg[1] = regvalue;
|
||||
#elif defined(__riscv__)
|
||||
regs.sp = regvalue;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
|
@ -108,4 +108,6 @@ extern void *__tls_get_addr(tls_index* ti);
|
||||
#define RTLD_DEFAULT_STACK_PF_EXEC PF_X
|
||||
#define RTLD_DEFAULT_STACK_EXEC PROT_EXEC
|
||||
|
||||
#define md_abi_variant_hook(x)
|
||||
|
||||
#endif
|
||||
|
@ -99,6 +99,19 @@ setlaggflowidshift(const char *val, int d, int s, const struct afswtch *afp)
|
||||
err(1, "SIOCSLAGGOPTS");
|
||||
}
|
||||
|
||||
static void
|
||||
setlaggrr_limit(const char *val, int d, int s, const struct afswtch *afp)
|
||||
{
|
||||
struct lagg_reqopts ro;
|
||||
|
||||
bzero(&ro, sizeof(ro));
|
||||
strlcpy(ro.ro_ifname, name, sizeof(ro.ro_ifname));
|
||||
ro.ro_bkt = (int)strtol(val, NULL, 10);
|
||||
|
||||
if (ioctl(s, SIOCSLAGGOPTS, &ro) != 0)
|
||||
err(1, "SIOCSLAGG");
|
||||
}
|
||||
|
||||
static void
|
||||
setlaggsetopt(const char *val, int d, int s, const struct afswtch *afp)
|
||||
{
|
||||
@ -252,6 +265,8 @@ lagg_status(int s)
|
||||
printb("\t\tflags", ro.ro_opts, LAGG_OPT_BITS);
|
||||
putchar('\n');
|
||||
printf("\t\tflowid_shift: %d\n", ro.ro_flowid_shift);
|
||||
if (ra.ra_proto == LAGG_PROTO_ROUNDROBIN)
|
||||
printf("\t\trr_limit: %d\n", ro.ro_bkt);
|
||||
printf("\tlagg statistics:\n");
|
||||
printf("\t\tactive ports: %d\n", ro.ro_active);
|
||||
printf("\t\tflapping: %u\n", ro.ro_flapping);
|
||||
@ -298,6 +313,7 @@ static struct cmd lagg_cmds[] = {
|
||||
DEF_CMD("lacp_fast_timeout", LAGG_OPT_LACP_TIMEOUT, setlaggsetopt),
|
||||
DEF_CMD("-lacp_fast_timeout", -LAGG_OPT_LACP_TIMEOUT, setlaggsetopt),
|
||||
DEF_CMD_ARG("flowid_shift", setlaggflowidshift),
|
||||
DEF_CMD_ARG("rr_limit", setlaggrr_limit),
|
||||
};
|
||||
static struct afswtch af_lagg = {
|
||||
.af_name = "af_lagg",
|
||||
|
@ -29,4 +29,6 @@
|
||||
PROG= kldstat
|
||||
MAN= kldstat.8
|
||||
|
||||
LIBADD= util
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -25,7 +25,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd January 22, 2014
|
||||
.Dd January 19, 2016
|
||||
.Dt KLDSTAT 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -33,6 +33,7 @@
|
||||
.Nd display status of dynamic kernel linker
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl h
|
||||
.Op Fl q
|
||||
.Op Fl v
|
||||
.Op Fl i Ar id
|
||||
@ -48,6 +49,9 @@ kernel.
|
||||
.Pp
|
||||
The following options are available:
|
||||
.Bl -tag -width indentXX
|
||||
.It Fl h
|
||||
Display the size field in a human-readable form, using unit suffixes
|
||||
instead of hex values.
|
||||
.It Fl v
|
||||
Be more verbose.
|
||||
.It Fl i Ar id
|
||||
|
@ -28,6 +28,7 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <err.h>
|
||||
#include <libutil.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
@ -51,18 +52,27 @@ printmod(int modid)
|
||||
}
|
||||
|
||||
static void
|
||||
printfile(int fileid, int verbose)
|
||||
printfile(int fileid, int verbose, int humanized)
|
||||
{
|
||||
struct kld_file_stat stat;
|
||||
int modid;
|
||||
char buf[5];
|
||||
|
||||
stat.version = sizeof(struct kld_file_stat);
|
||||
if (kldstat(fileid, &stat) < 0)
|
||||
if (kldstat(fileid, &stat) < 0) {
|
||||
err(1, "can't stat file id %d", fileid);
|
||||
else
|
||||
printf("%2d %4d %p %-8zx %s",
|
||||
stat.id, stat.refs, stat.address, stat.size,
|
||||
stat.name);
|
||||
} else {
|
||||
if (humanized) {
|
||||
humanize_number(buf, sizeof(buf), stat.size,
|
||||
"", HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE);
|
||||
|
||||
printf("%2d %4d %p %5s %s",
|
||||
stat.id, stat.refs, stat.address, buf, stat.name);
|
||||
} else {
|
||||
printf("%2d %4d %p %-8zx %s",
|
||||
stat.id, stat.refs, stat.address, stat.size, stat.name);
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
printf(" (%s)\n", stat.pathname);
|
||||
@ -78,7 +88,7 @@ printfile(int fileid, int verbose)
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: kldstat [-q] [-v] [-i id] [-n filename]\n");
|
||||
fprintf(stderr, "usage: kldstat [-h] [-q] [-v] [-i id] [-n filename]\n");
|
||||
fprintf(stderr, " kldstat [-q] [-m modname]\n");
|
||||
exit(1);
|
||||
}
|
||||
@ -87,6 +97,7 @@ int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
int c;
|
||||
int humanized = 0;
|
||||
int verbose = 0;
|
||||
int fileid = 0;
|
||||
int quiet = 0;
|
||||
@ -94,8 +105,11 @@ main(int argc, char** argv)
|
||||
char* modname = NULL;
|
||||
char* p;
|
||||
|
||||
while ((c = getopt(argc, argv, "i:m:n:qv")) != -1)
|
||||
while ((c = getopt(argc, argv, "hi:m:n:qv")) != -1)
|
||||
switch (c) {
|
||||
case 'h':
|
||||
humanized = 1;
|
||||
break;
|
||||
case 'i':
|
||||
fileid = (int)strtoul(optarg, &p, 10);
|
||||
if (*p != '\0')
|
||||
@ -155,12 +169,15 @@ main(int argc, char** argv)
|
||||
}
|
||||
}
|
||||
|
||||
printf("Id Refs Address%*c Size Name\n", POINTER_WIDTH - 7, ' ');
|
||||
if (humanized)
|
||||
printf("Id Refs Address%*c Size Name\n", POINTER_WIDTH - 7, ' ');
|
||||
else
|
||||
printf("Id Refs Address%*c Size Name\n", POINTER_WIDTH - 7, ' ');
|
||||
if (fileid != 0)
|
||||
printfile(fileid, verbose);
|
||||
printfile(fileid, verbose, humanized);
|
||||
else
|
||||
for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid))
|
||||
printfile(fileid, verbose);
|
||||
printfile(fileid, verbose, humanized);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/usr/sbin/dtrace -s
|
||||
/* -
|
||||
* Copyright (c) 2014-2015 Devin Teske <dteske@FreeBSD.org>
|
||||
* Copyright (c) 2014-2016 Devin Teske <dteske@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
|
@ -16,7 +16,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd November 6, 2015
|
||||
.Dd January 23, 2016
|
||||
.Dt LAGG 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -110,6 +110,11 @@ available, the VLAN tag, and the IP source and destination address.
|
||||
Distributes outgoing traffic using a round-robin scheduler
|
||||
through all active ports and accepts incoming traffic from
|
||||
any active port.
|
||||
Using
|
||||
.Ic roundrobin
|
||||
mode can cause unordered packet arrival at the client.
|
||||
Throughput might be limited as the client performs CPU-intensive packet
|
||||
reordering.
|
||||
.It Ic broadcast
|
||||
Sends frames to all ports of the LAG and receives frames on
|
||||
any port of the LAG.
|
||||
@ -161,6 +166,19 @@ Gigabit Ethernet interfaces:
|
||||
192.168.1.1 netmask 255.255.255.0
|
||||
.Ed
|
||||
.Pp
|
||||
Create a link aggregation using ROUNDROBIN with two
|
||||
.Xr bge 4
|
||||
Gigabit Ethernet interfaces and set the limit of 500 packets
|
||||
per interface:
|
||||
.Bd -literal -offset indent
|
||||
# ifconfig bge0 up
|
||||
# ifconfig bge1 up
|
||||
# ifconfig lagg0 create
|
||||
# ifconfig lagg0 laggproto roundrobin laggport bge0 laggport bge1 \e
|
||||
192.168.1.1 netmask 255.255.255.0
|
||||
# ifconfig lagg0 rr_limit 500
|
||||
.Ed
|
||||
.Pp
|
||||
The following example uses an active failover interface to set up roaming
|
||||
between wired and wireless networks using two network devices.
|
||||
Whenever the wired master interface is unplugged, the wireless failover
|
||||
|
@ -26,12 +26,12 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd October 1, 2013
|
||||
.Dd January 23, 2016
|
||||
.Dt EXT2FS 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm ext2fs
|
||||
.Nd "Ext2fs file system"
|
||||
.Nd "ext2/ext3/ext4 file system"
|
||||
.Sh SYNOPSIS
|
||||
To link into the kernel:
|
||||
.Bd -ragged -offset indent
|
||||
@ -47,8 +47,14 @@ The
|
||||
driver will permit the
|
||||
.Fx
|
||||
kernel to access
|
||||
.Tn Ext2
|
||||
.Tn ext2 ,
|
||||
.Tn ext3 ,
|
||||
and
|
||||
.Tn ext4
|
||||
file systems.
|
||||
The
|
||||
.Tn ext4
|
||||
support is read-only.
|
||||
.Sh EXAMPLES
|
||||
To mount a
|
||||
.Nm
|
||||
|
@ -25,7 +25,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd October 10, 2004
|
||||
.Dd January 23, 2016
|
||||
.Dt HASHINIT 9
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -102,9 +102,11 @@ Any malloc performed by the
|
||||
.Fn hashinit_flags
|
||||
function will not be allowed to wait, and therefore may fail.
|
||||
.It Dv HASH_WAITOK
|
||||
Any malloc performed by the
|
||||
Any malloc performed by
|
||||
.Fn hashinit_flags
|
||||
function is allowed to wait for memory.
|
||||
This is also the behavior of
|
||||
.Fn hashinit .
|
||||
.El
|
||||
.Sh IMPLEMENTATION NOTES
|
||||
The largest prime hash value chosen by
|
||||
|
@ -1,5 +1,5 @@
|
||||
# $FreeBSD$
|
||||
# $Id: auto.obj.mk,v 1.10 2015/04/16 16:59:00 sjg Exp $
|
||||
# $Id: auto.obj.mk,v 1.12 2015/12/16 01:57:06 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2004, Simon J. Gerraty
|
||||
#
|
||||
@ -41,12 +41,12 @@ MKOBJDIRS= auto
|
||||
.if !defined(NOOBJ) && !defined(NO_OBJ) && ${MKOBJDIRS:Uno} == auto
|
||||
# Use __objdir here so it is easier to tweak without impacting
|
||||
# the logic.
|
||||
.if !empty(MAKEOBJDIRPREFIX) && exists(${MAKEOBJDIRPREFIX})
|
||||
.if !empty(MAKEOBJDIRPREFIX)
|
||||
__objdir?= ${MAKEOBJDIRPREFIX}${.CURDIR}
|
||||
.endif
|
||||
__objdir?= ${MAKEOBJDIR:Uobj}
|
||||
__objdir:= ${__objdir:tA}
|
||||
.if ${.OBJDIR} != ${__objdir}
|
||||
__objdir:= ${__objdir}
|
||||
.if ${.OBJDIR:tA} != ${__objdir:tA}
|
||||
# We need to chdir, make the directory if needed
|
||||
.if !exists(${__objdir}/) && \
|
||||
(${.TARGETS} == "" || ${.TARGETS:Nclean*:N*clean:Ndestroy*} != "")
|
||||
@ -54,11 +54,10 @@ __objdir:= ${__objdir:tA}
|
||||
__objdir_made != echo ${__objdir}/; umask ${OBJDIR_UMASK:U002}; \
|
||||
${ECHO_TRACE} "[Creating objdir ${__objdir}...]" >&2; \
|
||||
${Mkdirs}; Mkdirs ${__objdir}
|
||||
__objdir:= ${__objdir:tA}
|
||||
.endif
|
||||
# This causes make to use the specified directory as .OBJDIR
|
||||
.OBJDIR: ${__objdir}
|
||||
.if ${.OBJDIR} != ${__objdir} && ${__objdir_made:Uno:M${__objdir}/*} != ""
|
||||
.if ${.OBJDIR:tA} != ${__objdir:tA} && ${__objdir_made:Uno:M${__objdir}/*} != ""
|
||||
.error could not use ${__objdir}: .OBJDIR=${.OBJDIR}
|
||||
.endif
|
||||
.endif
|
||||
|
@ -56,6 +56,7 @@ _MKDEPCC+= ${DEPFLAGS}
|
||||
.endif
|
||||
MKDEPCMD?= CC='${_MKDEPCC}' mkdep
|
||||
DEPENDFILE?= .depend
|
||||
.MAKE.DEPENDFILE= ${DEPENDFILE}
|
||||
DEPENDFILES= ${DEPENDFILE}
|
||||
|
||||
# Keep `tags' here, before SRCS are mangled below for `depend'.
|
||||
@ -129,25 +130,26 @@ CFLAGS+= -I${.OBJDIR}
|
||||
.endif
|
||||
.for _DSRC in ${SRCS:M*.d:N*/*}
|
||||
.for _D in ${_DSRC:R}
|
||||
DHDRS+= ${_D}.h
|
||||
SRCS+= ${_D}.h
|
||||
${_D}.h: ${_DSRC}
|
||||
${DTRACE} ${DTRACEFLAGS} -h -s ${.ALLSRC}
|
||||
SRCS:= ${SRCS:S/^${_DSRC}$//}
|
||||
OBJS+= ${_D}.o
|
||||
CLEANFILES+= ${_D}.h ${_D}.o
|
||||
${_D}.o: ${_DSRC} ${OBJS:S/^${_D}.o$//}
|
||||
${DTRACE} ${DTRACEFLAGS} -G -o ${.TARGET} -s ${.ALLSRC}
|
||||
@rm -f ${.TARGET}
|
||||
${DTRACE} ${DTRACEFLAGS} -G -o ${.TARGET} -s ${.ALLSRC:N*.h}
|
||||
.if defined(LIB)
|
||||
CLEANFILES+= ${_D}.So ${_D}.po
|
||||
${_D}.So: ${_DSRC} ${SOBJS:S/^${_D}.So$//}
|
||||
${DTRACE} ${DTRACEFLAGS} -G -o ${.TARGET} -s ${.ALLSRC}
|
||||
@rm -f ${.TARGET}
|
||||
${DTRACE} ${DTRACEFLAGS} -G -o ${.TARGET} -s ${.ALLSRC:N*.h}
|
||||
${_D}.po: ${_DSRC} ${POBJS:S/^${_D}.po$//}
|
||||
${DTRACE} ${DTRACEFLAGS} -G -o ${.TARGET} -s ${.ALLSRC}
|
||||
@rm -f ${.TARGET}
|
||||
${DTRACE} ${DTRACEFLAGS} -G -o ${.TARGET} -s ${.ALLSRC:N*.h}
|
||||
.endif
|
||||
.endfor
|
||||
.endfor
|
||||
beforedepend: ${DHDRS}
|
||||
beforebuild: ${DHDRS}
|
||||
|
||||
|
||||
.if ${MK_FAST_DEPEND} == "yes" && \
|
||||
|
@ -1,5 +1,5 @@
|
||||
# $FreeBSD$
|
||||
# $Id: gendirdeps.mk,v 1.27 2015/06/08 20:55:11 sjg Exp $
|
||||
# $Id: gendirdeps.mk,v 1.29 2015/10/03 05:00:46 sjg Exp $
|
||||
|
||||
# Copyright (c) 2010-2013, Juniper Networks, Inc.
|
||||
# All rights reserved.
|
||||
@ -158,7 +158,7 @@ M2D_OBJROOTS += ${SB_BACKING_SB}/${SB_OBJPREFIX}
|
||||
.endif
|
||||
|
||||
# we are only interested in the dirs
|
||||
# sepecifically those we read something from.
|
||||
# specifically those we read something from.
|
||||
# we canonicalize them to keep things simple
|
||||
# if we are using a split-fs sandbox, it gets a little messier.
|
||||
_objtop := ${_OBJTOP:tA}
|
||||
|
@ -1,6 +1,6 @@
|
||||
# $FreeBSD$
|
||||
# RCSid:
|
||||
# $Id: host-target.mk,v 1.7 2014/05/16 17:54:52 sjg Exp $
|
||||
# $Id: host-target.mk,v 1.11 2015/10/25 00:07:20 sjg Exp $
|
||||
|
||||
# Host platform information; may be overridden
|
||||
.if !defined(_HOST_OSNAME)
|
||||
@ -11,24 +11,33 @@ _HOST_OSNAME != uname -s
|
||||
_HOST_OSREL != uname -r
|
||||
.export _HOST_OSREL
|
||||
.endif
|
||||
.if !defined(_HOST_MACHINE)
|
||||
_HOST_MACHINE != uname -m
|
||||
.export _HOST_MACHINE
|
||||
.endif
|
||||
.if !defined(_HOST_ARCH)
|
||||
_HOST_ARCH != uname -p 2>/dev/null || uname -m
|
||||
# for NetBSD prefer $MACHINE (amd64 rather than x86_64)
|
||||
.if ${_HOST_OSNAME:NNetBSD} == ""
|
||||
_HOST_ARCH := ${_HOST_MACHINE}
|
||||
.else
|
||||
_HOST_ARCH != uname -p 2> /dev/null || uname -m
|
||||
# uname -p may produce garbage on linux
|
||||
.if ${_HOST_ARCH:[\#]} > 1
|
||||
_HOST_ARCH != uname -m
|
||||
.if ${_HOST_ARCH:[\#]} > 1 || ${_HOST_ARCH:Nunknown} == ""
|
||||
_HOST_ARCH := ${_HOST_MACHINE}
|
||||
.endif
|
||||
.endif
|
||||
.export _HOST_ARCH
|
||||
.endif
|
||||
.if !defined(HOST_MACHINE)
|
||||
HOST_MACHINE != uname -m
|
||||
HOST_MACHINE := ${_HOST_MACHINE}
|
||||
.export HOST_MACHINE
|
||||
.endif
|
||||
|
||||
HOST_OSMAJOR := ${_HOST_OSREL:C/[^0-9].*//}
|
||||
HOST_OSTYPE := ${_HOST_OSNAME}-${_HOST_OSREL:C/\([^\)]*\)//}-${_HOST_ARCH}
|
||||
HOST_OSTYPE := ${_HOST_OSNAME:S,/,,g}-${_HOST_OSREL:C/\([^\)]*\)//}-${_HOST_ARCH}
|
||||
HOST_OS := ${_HOST_OSNAME}
|
||||
host_os := ${_HOST_OSNAME:tl}
|
||||
HOST_TARGET := ${host_os}${HOST_OSMAJOR}-${_HOST_ARCH}
|
||||
HOST_TARGET := ${host_os:S,/,,g}${HOST_OSMAJOR}-${_HOST_ARCH}
|
||||
|
||||
# tr is insanely non-portable, accommodate the lowest common denominator
|
||||
TR ?= tr
|
||||
|
@ -1,5 +1,5 @@
|
||||
# $FreeBSD$
|
||||
# $Id: meta.subdir.mk,v 1.10 2012/07/03 05:26:46 sjg Exp $
|
||||
# $Id: meta.subdir.mk,v 1.11 2015/11/24 22:26:51 sjg Exp $
|
||||
|
||||
#
|
||||
# @(#) Copyright (c) 2010, Simon J. Gerraty
|
||||
@ -63,7 +63,7 @@ _subdeps != cd ${.CURDIR} && \
|
||||
DIRDEPS =
|
||||
.else
|
||||
# clean up if needed
|
||||
DIRDEPS := ${DIRDEPS:S,^./,,:S,/./,/,g:${SUBDIREPS_FILTER:Uu}}
|
||||
DIRDEPS := ${DIRDEPS:S,^./,,:S,/./,/,g:${SUBDIRDEPS_FILTER:Uu}}
|
||||
.endif
|
||||
# we just dealt with it, if we leave it defined,
|
||||
# dirdeps.mk will compute some interesting combinations.
|
||||
|
@ -530,8 +530,8 @@ struct l_pollfd {
|
||||
|
||||
#define LINUX_ARCH_SET_GS 0x1001
|
||||
#define LINUX_ARCH_SET_FS 0x1002
|
||||
#define LINUX_ARCH_GET_GS 0x1003
|
||||
#define LINUX_ARCH_GET_FS 0x1004
|
||||
#define LINUX_ARCH_GET_FS 0x1003
|
||||
#define LINUX_ARCH_GET_GS 0x1004
|
||||
|
||||
#define linux_copyout_rusage(r, u) copyout(r, u, sizeof(*r))
|
||||
|
||||
|
@ -383,7 +383,6 @@ linux_sigaltstack(struct thread *td, struct linux_sigaltstack_args *uap)
|
||||
return (error);
|
||||
}
|
||||
|
||||
/* XXX do all */
|
||||
int
|
||||
linux_arch_prctl(struct thread *td, struct linux_arch_prctl_args *args)
|
||||
{
|
||||
|
@ -255,6 +255,57 @@ a10_clk_pll6_get_rate(void)
|
||||
return ((CCM_CLK_REF_FREQ * n * k) / 2);
|
||||
}
|
||||
|
||||
static int
|
||||
a10_clk_pll2_set_rate(unsigned int freq)
|
||||
{
|
||||
struct a10_ccm_softc *sc;
|
||||
uint32_t reg_value;
|
||||
unsigned int prediv, postdiv, n;
|
||||
|
||||
sc = a10_ccm_sc;
|
||||
if (sc == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
reg_value = ccm_read_4(sc, CCM_PLL2_CFG);
|
||||
reg_value &= ~(CCM_PLL2_CFG_PREDIV | CCM_PLL2_CFG_POSTDIV |
|
||||
CCM_PLL_CFG_FACTOR_N);
|
||||
|
||||
/*
|
||||
* Audio Codec needs PLL2 to be either 24576000 Hz or 22579200 Hz
|
||||
*
|
||||
* PLL2 output frequency is 24MHz * n / prediv / postdiv.
|
||||
* To get as close as possible to the desired rate, we use a
|
||||
* pre-divider of 21 and a post-divider of 4. With these values,
|
||||
* a multiplier of 86 or 79 gets us close to the target rates.
|
||||
*/
|
||||
prediv = 21;
|
||||
postdiv = 4;
|
||||
|
||||
switch (freq) {
|
||||
case 24576000:
|
||||
n = 86;
|
||||
reg_value |= CCM_PLL_CFG_ENABLE;
|
||||
break;
|
||||
case 22579200:
|
||||
n = 79;
|
||||
reg_value |= CCM_PLL_CFG_ENABLE;
|
||||
break;
|
||||
case 0:
|
||||
n = 1;
|
||||
reg_value &= ~CCM_PLL_CFG_ENABLE;
|
||||
break;
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
reg_value |= (prediv << CCM_PLL2_CFG_PREDIV_SHIFT);
|
||||
reg_value |= (postdiv << CCM_PLL2_CFG_POSTDIV_SHIFT);
|
||||
reg_value |= (n << CCM_PLL_CFG_FACTOR_N_SHIFT);
|
||||
ccm_write_4(sc, CCM_PLL2_CFG, reg_value);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
a10_clk_ahci_activate(void)
|
||||
{
|
||||
@ -347,3 +398,46 @@ a10_clk_mmc_cfg(int devid, int freq)
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
a10_clk_dmac_activate(void)
|
||||
{
|
||||
struct a10_ccm_softc *sc;
|
||||
uint32_t reg_value;
|
||||
|
||||
sc = a10_ccm_sc;
|
||||
if (sc == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
/* Gating AHB clock for DMA controller */
|
||||
reg_value = ccm_read_4(sc, CCM_AHB_GATING0);
|
||||
reg_value |= CCM_AHB_GATING_DMA;
|
||||
ccm_write_4(sc, CCM_AHB_GATING0, reg_value);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
a10_clk_codec_activate(unsigned int freq)
|
||||
{
|
||||
struct a10_ccm_softc *sc;
|
||||
uint32_t reg_value;
|
||||
|
||||
sc = a10_ccm_sc;
|
||||
if (sc == NULL)
|
||||
return (ENXIO);
|
||||
|
||||
a10_clk_pll2_set_rate(freq);
|
||||
|
||||
/* Gating APB clock for ADDA */
|
||||
reg_value = ccm_read_4(sc, CCM_APB0_GATING);
|
||||
reg_value |= CCM_APB0_GATING_ADDA;
|
||||
ccm_write_4(sc, CCM_APB0_GATING, reg_value);
|
||||
|
||||
/* Enable audio codec clock */
|
||||
reg_value = ccm_read_4(sc, CCM_AUDIO_CODEC_CLK);
|
||||
reg_value |= CCM_AUDIO_CODEC_ENABLE;
|
||||
ccm_write_4(sc, CCM_AUDIO_CODEC_CLK, reg_value);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -106,10 +106,14 @@
|
||||
#define CCM_GMAC_CLK_EXT_RGMII 0x1
|
||||
#define CCM_GMAC_CLK_RGMII 0x2
|
||||
|
||||
/* APB0_GATING */
|
||||
#define CCM_APB0_GATING_ADDA (1 << 0)
|
||||
|
||||
/* AHB_GATING_REG0 */
|
||||
#define CCM_AHB_GATING_USB0 (1 << 0)
|
||||
#define CCM_AHB_GATING_EHCI0 (1 << 1)
|
||||
#define CCM_AHB_GATING_EHCI1 (1 << 3)
|
||||
#define CCM_AHB_GATING_DMA (1 << 6)
|
||||
#define CCM_AHB_GATING_SDMMC0 (1 << 8)
|
||||
#define CCM_AHB_GATING_EMAC (1 << 17)
|
||||
#define CCM_AHB_GATING_SATA (1 << 25)
|
||||
@ -132,6 +136,11 @@
|
||||
#define CCM_PLL_CFG_FACTOR_K_SHIFT 4
|
||||
#define CCM_PLL_CFG_FACTOR_M 0x3
|
||||
|
||||
#define CCM_PLL2_CFG_POSTDIV 0x3c000000
|
||||
#define CCM_PLL2_CFG_POSTDIV_SHIFT 26
|
||||
#define CCM_PLL2_CFG_PREDIV 0x1f
|
||||
#define CCM_PLL2_CFG_PREDIV_SHIFT 0
|
||||
|
||||
#define CCM_PLL6_CFG_SATA_CLKEN (1U << 14)
|
||||
|
||||
#define CCM_SD_CLK_SRC_SEL 0x3000000
|
||||
@ -146,6 +155,8 @@
|
||||
#define CCM_SD_CLK_OPHASE_CTR_SHIFT 8
|
||||
#define CCM_SD_CLK_DIV_RATIO_M 0xf
|
||||
|
||||
#define CCM_AUDIO_CODEC_ENABLE (1U << 31)
|
||||
|
||||
#define CCM_CLK_REF_FREQ 24000000U
|
||||
|
||||
int a10_clk_usb_activate(void);
|
||||
@ -155,5 +166,7 @@ int a10_clk_gmac_activate(phandle_t);
|
||||
int a10_clk_ahci_activate(void);
|
||||
int a10_clk_mmc_activate(int);
|
||||
int a10_clk_mmc_cfg(int, int);
|
||||
int a10_clk_dmac_activate(void);
|
||||
int a10_clk_codec_activate(unsigned int);
|
||||
|
||||
#endif /* _A10_CLK_H_ */
|
||||
|
@ -42,6 +42,8 @@ struct fdt_fixup_entry fdt_fixup_table[] = {
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
#ifndef ARM_INTRNG
|
||||
|
||||
static int
|
||||
fdt_aintc_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
|
||||
int *pol)
|
||||
@ -66,3 +68,5 @@ fdt_pic_decode_t fdt_pic_table[] = {
|
||||
&fdt_aintc_decode_ic,
|
||||
NULL
|
||||
};
|
||||
|
||||
#endif /* ARM_INTRNG */
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2012 Ganbold Tsagaankhuu <ganbold@freebsd.org>
|
||||
* Copyright (c) 2015-2016 Emmanuel Vadot <manu@bidouilliste.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software written for Brini by Mark Brinicombe
|
||||
@ -45,34 +46,43 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/bus.h>
|
||||
#include <machine/devmap.h>
|
||||
#include <machine/machdep.h>
|
||||
#include <machine/platform.h>
|
||||
#include <machine/platformvar.h>
|
||||
|
||||
#include <dev/fdt/fdt_common.h>
|
||||
|
||||
#include <arm/allwinner/a10_wdog.h>
|
||||
#include <arm/allwinner/allwinner_machdep.h>
|
||||
|
||||
vm_offset_t
|
||||
platform_lastaddr(void)
|
||||
#include "platform_if.h"
|
||||
|
||||
static u_int soc_type;
|
||||
static u_int soc_family;
|
||||
|
||||
static int
|
||||
a10_attach(platform_t plat)
|
||||
{
|
||||
soc_type = ALLWINNERSOC_A10;
|
||||
soc_family = ALLWINNERSOC_SUN4I;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
a20_attach(platform_t plat)
|
||||
{
|
||||
soc_type = ALLWINNERSOC_A20;
|
||||
soc_family = ALLWINNERSOC_SUN7I;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
static vm_offset_t
|
||||
allwinner_lastaddr(platform_t plat)
|
||||
{
|
||||
|
||||
return (arm_devmap_lastaddr());
|
||||
}
|
||||
|
||||
void
|
||||
platform_probe_and_attach(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
platform_gpio_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
platform_late_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up static device mappings.
|
||||
*
|
||||
@ -83,8 +93,8 @@ platform_late_init(void)
|
||||
* shouldn't be device-mapped. The original code mapped a 4MB block, but
|
||||
* perhaps a 1MB block would be more appropriate.
|
||||
*/
|
||||
int
|
||||
platform_devmap_init(void)
|
||||
static int
|
||||
allwinner_devmap_init(platform_t plat)
|
||||
{
|
||||
|
||||
arm_devmap_add_entry(0x01C00000, 0x00400000); /* 4MB */
|
||||
@ -111,3 +121,34 @@ cpu_reset()
|
||||
printf("Reset failed!\n");
|
||||
while (1);
|
||||
}
|
||||
|
||||
static platform_method_t a10_methods[] = {
|
||||
PLATFORMMETHOD(platform_attach, a10_attach),
|
||||
PLATFORMMETHOD(platform_lastaddr, allwinner_lastaddr),
|
||||
PLATFORMMETHOD(platform_devmap_init, allwinner_devmap_init),
|
||||
|
||||
PLATFORMMETHOD_END,
|
||||
};
|
||||
|
||||
static platform_method_t a20_methods[] = {
|
||||
PLATFORMMETHOD(platform_attach, a20_attach),
|
||||
PLATFORMMETHOD(platform_lastaddr, allwinner_lastaddr),
|
||||
PLATFORMMETHOD(platform_devmap_init, allwinner_devmap_init),
|
||||
|
||||
PLATFORMMETHOD_END,
|
||||
};
|
||||
|
||||
u_int
|
||||
allwinner_soc_type(void)
|
||||
{
|
||||
return (soc_type);
|
||||
}
|
||||
|
||||
u_int
|
||||
allwinner_soc_family(void)
|
||||
{
|
||||
return (soc_family);
|
||||
}
|
||||
|
||||
FDT_PLATFORM_DEF(a10, "a10", 0, "allwinner,sun4i-a10");
|
||||
FDT_PLATFORM_DEF(a20, "a20", 0, "allwinner,sun7i-a20");
|
47
sys/arm/allwinner/allwinner_machdep.h
Normal file
47
sys/arm/allwinner/allwinner_machdep.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*-
|
||||
* Copyright (c) 2015 Emmanuel Vadot <manu@bidouilliste.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software written for Brini by Mark Brinicombe
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 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 AW_MACHDEP_H
|
||||
#define AW_MACHDEP_H
|
||||
|
||||
#define ALLWINNERSOC_A10 0x10000000
|
||||
#define ALLWINNERSOC_A13 0x13000000
|
||||
#define ALLWINNERSOC_A10S 0x10000001
|
||||
#define ALLWINNERSOC_A20 0x20000000
|
||||
|
||||
#define ALLWINNERSOC_SUN4I 0x40000000
|
||||
#define ALLWINNERSOC_SUN5I 0x50000000
|
||||
#define ALLWINNERSOC_SUN7I 0x70000000
|
||||
|
||||
u_int allwinner_soc_type(void);
|
||||
u_int allwinner_soc_family(void);
|
||||
|
||||
#endif /* AW_MACHDEP_H */
|
@ -6,11 +6,11 @@ arm/allwinner/a10_clk.c standard
|
||||
arm/allwinner/a10_common.c standard
|
||||
arm/allwinner/a10_ehci.c optional ehci
|
||||
arm/allwinner/a10_gpio.c optional gpio
|
||||
arm/allwinner/a10_machdep.c standard
|
||||
arm/allwinner/a10_mmc.c optional mmc
|
||||
arm/allwinner/a10_sramc.c standard
|
||||
arm/allwinner/a10_wdog.c standard
|
||||
arm/allwinner/a20/a20_cpu_cfg.c standard
|
||||
arm/allwinner/allwinner_machdep.c standard
|
||||
arm/allwinner/if_emac.c optional emac
|
||||
arm/allwinner/timer.c standard
|
||||
#arm/allwinner/console.c standard
|
||||
|
@ -28,6 +28,7 @@
|
||||
* any improvements or extensions that they make and grant Carnegie the
|
||||
* rights to redistribute these changes.
|
||||
*/
|
||||
#include "opt_ddb.h"
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
@ -43,6 +44,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/asm.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/db_machdep.h>
|
||||
#include <machine/debug_monitor.h>
|
||||
#include <machine/pcb.h>
|
||||
#include <machine/stack.h>
|
||||
#include <machine/vmparam.h>
|
||||
@ -127,22 +129,25 @@ db_stack_trace_cmd(struct unwind_state *state)
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX stubs */
|
||||
void
|
||||
db_md_list_watchpoints()
|
||||
{
|
||||
|
||||
dbg_show_watchpoint();
|
||||
}
|
||||
|
||||
int
|
||||
db_md_clr_watchpoint(db_expr_t addr, db_expr_t size)
|
||||
{
|
||||
return (0);
|
||||
|
||||
return (dbg_remove_watchpoint(addr, size));
|
||||
}
|
||||
|
||||
int
|
||||
db_md_set_watchpoint(db_expr_t addr, db_expr_t size)
|
||||
{
|
||||
return (0);
|
||||
|
||||
return (dbg_setup_watchpoint(addr, size, HW_WATCHPOINT_RW));
|
||||
}
|
||||
|
||||
int
|
||||
|
943
sys/arm/arm/debug_monitor.c
Normal file
943
sys/arm/arm/debug_monitor.c
Normal file
@ -0,0 +1,943 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Juniper Networks Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Developed by Semihalf.
|
||||
*
|
||||
* 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 "opt_ddb.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/kdb.h>
|
||||
#include <sys/pcpu.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
#include <machine/armreg.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/debug_monitor.h>
|
||||
#include <machine/kdb.h>
|
||||
#include <machine/param.h>
|
||||
#include <machine/pcb.h>
|
||||
|
||||
#include <ddb/ddb.h>
|
||||
#include <ddb/db_access.h>
|
||||
#include <ddb/db_sym.h>
|
||||
|
||||
enum dbg_t {
|
||||
DBG_TYPE_BREAKPOINT = 0,
|
||||
DBG_TYPE_WATCHPOINT = 1,
|
||||
};
|
||||
|
||||
struct dbg_wb_conf {
|
||||
enum dbg_t type;
|
||||
enum dbg_access_t access;
|
||||
db_addr_t address;
|
||||
db_expr_t size;
|
||||
u_int slot;
|
||||
};
|
||||
|
||||
static int dbg_reset_state(void);
|
||||
static int dbg_setup_breakpoint(db_expr_t, db_expr_t, u_int);
|
||||
static int dbg_remove_breakpoint(u_int);
|
||||
static u_int dbg_find_slot(enum dbg_t, db_expr_t);
|
||||
static boolean_t dbg_check_slot_free(enum dbg_t, u_int);
|
||||
|
||||
static int dbg_remove_xpoint(struct dbg_wb_conf *);
|
||||
static int dbg_setup_xpoint(struct dbg_wb_conf *);
|
||||
|
||||
static boolean_t dbg_capable; /* Indicates that machine is capable of using
|
||||
HW watchpoints/breakpoints */
|
||||
static boolean_t dbg_ready[MAXCPU]; /* Debug arch. reset performed on this CPU */
|
||||
|
||||
static uint32_t dbg_model; /* Debug Arch. Model */
|
||||
static boolean_t dbg_ossr; /* OS Save and Restore implemented */
|
||||
|
||||
static uint32_t dbg_watchpoint_num;
|
||||
static uint32_t dbg_breakpoint_num;
|
||||
|
||||
static int dbg_ref_count_mme[MAXCPU]; /* Times monitor mode was enabled */
|
||||
|
||||
/* ID_DFR0 - Debug Feature Register 0 */
|
||||
#define ID_DFR0_CP_DEBUG_M_SHIFT 0
|
||||
#define ID_DFR0_CP_DEBUG_M_MASK (0xF << ID_DFR0_CP_DEBUG_M_SHIFT)
|
||||
#define ID_DFR0_CP_DEBUG_M_NS (0x0) /* Not supported */
|
||||
#define ID_DFR0_CP_DEBUG_M_V6 (0x2) /* v6 Debug arch. CP14 access */
|
||||
#define ID_DFR0_CP_DEBUG_M_V6_1 (0x3) /* v6.1 Debug arch. CP14 access */
|
||||
#define ID_DFR0_CP_DEBUG_M_V7 (0x4) /* v7 Debug arch. CP14 access */
|
||||
#define ID_DFR0_CP_DEBUG_M_V7_1 (0x5) /* v7.1 Debug arch. CP14 access */
|
||||
|
||||
/* DBGDIDR - Debug ID Register */
|
||||
#define DBGDIDR_WRPS_SHIFT 28
|
||||
#define DBGDIDR_WRPS_MASK (0xF << DBGDIDR_WRPS_SHIFT)
|
||||
#define DBGDIDR_WRPS_NUM(reg) \
|
||||
((((reg) & DBGDIDR_WRPS_MASK) >> DBGDIDR_WRPS_SHIFT) + 1)
|
||||
|
||||
#define DBGDIDR_BRPS_SHIFT 24
|
||||
#define DBGDIDR_BRPS_MASK (0xF << DBGDIDR_BRPS_SHIFT)
|
||||
#define DBGDIDR_BRPS_NUM(reg) \
|
||||
((((reg) & DBGDIDR_BRPS_MASK) >> DBGDIDR_BRPS_SHIFT) + 1)
|
||||
|
||||
/* DBGPRSR - Device Powerdown and Reset Status Register */
|
||||
#define DBGPRSR_PU (1 << 0) /* Powerup status */
|
||||
|
||||
/* DBGOSLSR - OS Lock Status Register */
|
||||
#define DBGOSLSR_OSLM0 (1 << 0)
|
||||
|
||||
/* DBGOSDLR - OS Double Lock Register */
|
||||
#define DBGPRSR_DLK (1 << 0) /* OS Double Lock set */
|
||||
|
||||
/* DBGDSCR - Debug Status and Control Register */
|
||||
#define DBGSCR_MDBG_EN (1 << 15) /* Monitor debug-mode enable */
|
||||
|
||||
/* DBGWVR - Watchpoint Value Register */
|
||||
#define DBGWVR_ADDR_MASK (~0x3U)
|
||||
|
||||
/* Watchpoints/breakpoints control register bitfields */
|
||||
#define DBG_WB_CTRL_LEN_1 (0x1 << 5)
|
||||
#define DBG_WB_CTRL_LEN_2 (0x3 << 5)
|
||||
#define DBG_WB_CTRL_LEN_4 (0xf << 5)
|
||||
#define DBG_WB_CTRL_LEN_8 (0xff << 5)
|
||||
#define DBG_WB_CTRL_LEN_MASK(x) ((x) & (0xff << 5))
|
||||
#define DBG_WB_CTRL_EXEC (0x0 << 3)
|
||||
#define DBG_WB_CTRL_LOAD (0x1 << 3)
|
||||
#define DBG_WB_CTRL_STORE (0x2 << 3)
|
||||
#define DBG_WB_CTRL_ACCESS_MASK(x) ((x) & (0x3 << 3))
|
||||
|
||||
/* Common for breakpoint and watchpoint */
|
||||
#define DBG_WB_CTRL_PL1 (0x1 << 1)
|
||||
#define DBG_WB_CTRL_PL0 (0x2 << 1)
|
||||
#define DBG_WB_CTRL_PLX_MASK(x) ((x) & (0x3 << 1))
|
||||
#define DBG_WB_CTRL_E (0x1 << 0)
|
||||
|
||||
/*
|
||||
* Watchpoint/breakpoint helpers
|
||||
*/
|
||||
#define DBG_BKPT_BT_SLOT 0 /* Slot for branch taken */
|
||||
#define DBG_BKPT_BNT_SLOT 1 /* Slot for branch not taken */
|
||||
|
||||
#define OP2_SHIFT 4
|
||||
|
||||
/* Opc2 numbers for coprocessor instructions */
|
||||
#define DBG_WB_BVR 4
|
||||
#define DBG_WB_BCR 5
|
||||
#define DBG_WB_WVR 6
|
||||
#define DBG_WB_WCR 7
|
||||
|
||||
#define DBG_REG_BASE_BVR (DBG_WB_BVR << OP2_SHIFT)
|
||||
#define DBG_REG_BASE_BCR (DBG_WB_BCR << OP2_SHIFT)
|
||||
#define DBG_REG_BASE_WVR (DBG_WB_WVR << OP2_SHIFT)
|
||||
#define DBG_REG_BASE_WCR (DBG_WB_WCR << OP2_SHIFT)
|
||||
|
||||
#define DBG_WB_READ(cn, cm, op2, val) do { \
|
||||
__asm __volatile("mrc p14, 0, %0, " #cn "," #cm "," #op2 : "=r" (val)); \
|
||||
} while (0)
|
||||
|
||||
#define DBG_WB_WRITE(cn, cm, op2, val) do { \
|
||||
__asm __volatile("mcr p14, 0, %0, " #cn "," #cm "," #op2 :: "r" (val)); \
|
||||
} while (0)
|
||||
|
||||
#define READ_WB_REG_CASE(op2, m, val) \
|
||||
case (((op2) << OP2_SHIFT) + m): \
|
||||
DBG_WB_READ(c0, c ## m, op2, val); \
|
||||
break
|
||||
|
||||
#define WRITE_WB_REG_CASE(op2, m, val) \
|
||||
case (((op2) << OP2_SHIFT) + m): \
|
||||
DBG_WB_WRITE(c0, c ## m, op2, val); \
|
||||
break
|
||||
|
||||
#define SWITCH_CASES_READ_WB_REG(op2, val) \
|
||||
READ_WB_REG_CASE(op2, 0, val); \
|
||||
READ_WB_REG_CASE(op2, 1, val); \
|
||||
READ_WB_REG_CASE(op2, 2, val); \
|
||||
READ_WB_REG_CASE(op2, 3, val); \
|
||||
READ_WB_REG_CASE(op2, 4, val); \
|
||||
READ_WB_REG_CASE(op2, 5, val); \
|
||||
READ_WB_REG_CASE(op2, 6, val); \
|
||||
READ_WB_REG_CASE(op2, 7, val); \
|
||||
READ_WB_REG_CASE(op2, 8, val); \
|
||||
READ_WB_REG_CASE(op2, 9, val); \
|
||||
READ_WB_REG_CASE(op2, 10, val); \
|
||||
READ_WB_REG_CASE(op2, 11, val); \
|
||||
READ_WB_REG_CASE(op2, 12, val); \
|
||||
READ_WB_REG_CASE(op2, 13, val); \
|
||||
READ_WB_REG_CASE(op2, 14, val); \
|
||||
READ_WB_REG_CASE(op2, 15, val)
|
||||
|
||||
#define SWITCH_CASES_WRITE_WB_REG(op2, val) \
|
||||
WRITE_WB_REG_CASE(op2, 0, val); \
|
||||
WRITE_WB_REG_CASE(op2, 1, val); \
|
||||
WRITE_WB_REG_CASE(op2, 2, val); \
|
||||
WRITE_WB_REG_CASE(op2, 3, val); \
|
||||
WRITE_WB_REG_CASE(op2, 4, val); \
|
||||
WRITE_WB_REG_CASE(op2, 5, val); \
|
||||
WRITE_WB_REG_CASE(op2, 6, val); \
|
||||
WRITE_WB_REG_CASE(op2, 7, val); \
|
||||
WRITE_WB_REG_CASE(op2, 8, val); \
|
||||
WRITE_WB_REG_CASE(op2, 9, val); \
|
||||
WRITE_WB_REG_CASE(op2, 10, val); \
|
||||
WRITE_WB_REG_CASE(op2, 11, val); \
|
||||
WRITE_WB_REG_CASE(op2, 12, val); \
|
||||
WRITE_WB_REG_CASE(op2, 13, val); \
|
||||
WRITE_WB_REG_CASE(op2, 14, val); \
|
||||
WRITE_WB_REG_CASE(op2, 15, val)
|
||||
|
||||
static uint32_t
|
||||
dbg_wb_read_reg(int reg, int n)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
val = 0;
|
||||
|
||||
switch (reg + n) {
|
||||
SWITCH_CASES_READ_WB_REG(DBG_WB_WVR, val);
|
||||
SWITCH_CASES_READ_WB_REG(DBG_WB_WCR, val);
|
||||
SWITCH_CASES_READ_WB_REG(DBG_WB_BVR, val);
|
||||
SWITCH_CASES_READ_WB_REG(DBG_WB_BCR, val);
|
||||
default:
|
||||
db_printf(
|
||||
"trying to read from CP14 reg. using wrong opc2 %d\n",
|
||||
reg >> OP2_SHIFT);
|
||||
}
|
||||
|
||||
return (val);
|
||||
}
|
||||
|
||||
static void
|
||||
dbg_wb_write_reg(int reg, int n, uint32_t val)
|
||||
{
|
||||
|
||||
switch (reg + n) {
|
||||
SWITCH_CASES_WRITE_WB_REG(DBG_WB_WVR, val);
|
||||
SWITCH_CASES_WRITE_WB_REG(DBG_WB_WCR, val);
|
||||
SWITCH_CASES_WRITE_WB_REG(DBG_WB_BVR, val);
|
||||
SWITCH_CASES_WRITE_WB_REG(DBG_WB_BCR, val);
|
||||
default:
|
||||
db_printf(
|
||||
"trying to write to CP14 reg. using wrong opc2 %d\n",
|
||||
reg >> OP2_SHIFT);
|
||||
}
|
||||
isb();
|
||||
}
|
||||
|
||||
boolean_t
|
||||
kdb_cpu_pc_is_singlestep(db_addr_t pc)
|
||||
{
|
||||
|
||||
if (dbg_find_slot(DBG_TYPE_BREAKPOINT, pc) != ~0U)
|
||||
return (TRUE);
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
kdb_cpu_set_singlestep(void)
|
||||
{
|
||||
db_expr_t inst;
|
||||
db_addr_t pc, brpc;
|
||||
uint32_t wcr;
|
||||
u_int i;
|
||||
|
||||
/*
|
||||
* Disable watchpoints, e.g. stepping over watched instruction will
|
||||
* trigger break exception instead of single-step exception and locks
|
||||
* CPU on that instruction for ever.
|
||||
*/
|
||||
for (i = 0; i < dbg_watchpoint_num; i++) {
|
||||
wcr = dbg_wb_read_reg(DBG_REG_BASE_WCR, i);
|
||||
if ((wcr & DBG_WB_CTRL_E) != 0) {
|
||||
dbg_wb_write_reg(DBG_REG_BASE_WCR, i,
|
||||
(wcr & ~DBG_WB_CTRL_E));
|
||||
}
|
||||
}
|
||||
|
||||
pc = PC_REGS();
|
||||
|
||||
inst = db_get_value(pc, sizeof(pc), FALSE);
|
||||
if (inst_branch(inst) || inst_call(inst) || inst_return(inst)) {
|
||||
brpc = branch_taken(inst, pc);
|
||||
dbg_setup_breakpoint(brpc, INSN_SIZE, DBG_BKPT_BT_SLOT);
|
||||
}
|
||||
pc = next_instr_address(pc, 0);
|
||||
dbg_setup_breakpoint(pc, INSN_SIZE, DBG_BKPT_BNT_SLOT);
|
||||
}
|
||||
|
||||
void
|
||||
kdb_cpu_clear_singlestep(void)
|
||||
{
|
||||
uint32_t wvr, wcr;
|
||||
u_int i;
|
||||
|
||||
dbg_remove_breakpoint(DBG_BKPT_BT_SLOT);
|
||||
dbg_remove_breakpoint(DBG_BKPT_BNT_SLOT);
|
||||
|
||||
/* Restore all watchpoints */
|
||||
for (i = 0; i < dbg_watchpoint_num; i++) {
|
||||
wcr = dbg_wb_read_reg(DBG_REG_BASE_WCR, i);
|
||||
wvr = dbg_wb_read_reg(DBG_REG_BASE_WVR, i);
|
||||
/* Watchpoint considered not empty if address value is not 0 */
|
||||
if ((wvr & DBGWVR_ADDR_MASK) != 0) {
|
||||
dbg_wb_write_reg(DBG_REG_BASE_WCR, i,
|
||||
(wcr | DBG_WB_CTRL_E));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
dbg_setup_watchpoint(db_expr_t addr, db_expr_t size, enum dbg_access_t access)
|
||||
{
|
||||
struct dbg_wb_conf conf;
|
||||
|
||||
if (access == HW_BREAKPOINT_X) {
|
||||
db_printf("Invalid access type for watchpoint: %d\n", access);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
conf.address = addr;
|
||||
conf.size = size;
|
||||
conf.access = access;
|
||||
conf.type = DBG_TYPE_WATCHPOINT;
|
||||
|
||||
return (dbg_setup_xpoint(&conf));
|
||||
}
|
||||
|
||||
int
|
||||
dbg_remove_watchpoint(db_expr_t addr, db_expr_t size __unused)
|
||||
{
|
||||
struct dbg_wb_conf conf;
|
||||
|
||||
conf.address = addr;
|
||||
conf.type = DBG_TYPE_WATCHPOINT;
|
||||
|
||||
return (dbg_remove_xpoint(&conf));
|
||||
}
|
||||
|
||||
static int
|
||||
dbg_setup_breakpoint(db_expr_t addr, db_expr_t size, u_int slot)
|
||||
{
|
||||
struct dbg_wb_conf conf;
|
||||
|
||||
conf.address = addr;
|
||||
conf.size = size;
|
||||
conf.access = HW_BREAKPOINT_X;
|
||||
conf.type = DBG_TYPE_BREAKPOINT;
|
||||
conf.slot = slot;
|
||||
|
||||
return (dbg_setup_xpoint(&conf));
|
||||
}
|
||||
|
||||
static int
|
||||
dbg_remove_breakpoint(u_int slot)
|
||||
{
|
||||
struct dbg_wb_conf conf;
|
||||
|
||||
/* Slot already cleared. Don't recurse */
|
||||
if (dbg_check_slot_free(DBG_TYPE_BREAKPOINT, slot))
|
||||
return (0);
|
||||
|
||||
conf.slot = slot;
|
||||
conf.type = DBG_TYPE_BREAKPOINT;
|
||||
|
||||
return (dbg_remove_xpoint(&conf));
|
||||
}
|
||||
|
||||
static const char *
|
||||
dbg_watchtype_str(uint32_t type)
|
||||
{
|
||||
|
||||
switch (type) {
|
||||
case DBG_WB_CTRL_EXEC:
|
||||
return ("execute");
|
||||
case DBG_WB_CTRL_STORE:
|
||||
return ("write");
|
||||
case DBG_WB_CTRL_LOAD:
|
||||
return ("read");
|
||||
case DBG_WB_CTRL_LOAD | DBG_WB_CTRL_STORE:
|
||||
return ("read/write");
|
||||
default:
|
||||
return ("invalid");
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
dbg_watchtype_len(uint32_t len)
|
||||
{
|
||||
|
||||
switch (len) {
|
||||
case DBG_WB_CTRL_LEN_1:
|
||||
return (1);
|
||||
case DBG_WB_CTRL_LEN_2:
|
||||
return (2);
|
||||
case DBG_WB_CTRL_LEN_4:
|
||||
return (4);
|
||||
case DBG_WB_CTRL_LEN_8:
|
||||
return (8);
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dbg_show_watchpoint(void)
|
||||
{
|
||||
uint32_t wcr, len, type;
|
||||
uint32_t addr;
|
||||
boolean_t is_enabled;
|
||||
int i;
|
||||
|
||||
if (!dbg_capable) {
|
||||
db_printf("Architecture does not support HW "
|
||||
"breakpoints/watchpoints\n");
|
||||
return;
|
||||
}
|
||||
|
||||
db_printf("\nhardware watchpoints:\n");
|
||||
db_printf(" watch status type len address symbol\n");
|
||||
db_printf(" ----- -------- ---------- --- ---------- ------------------\n");
|
||||
for (i = 0; i < dbg_watchpoint_num; i++) {
|
||||
wcr = dbg_wb_read_reg(DBG_REG_BASE_WCR, i);
|
||||
if ((wcr & DBG_WB_CTRL_E) != 0)
|
||||
is_enabled = TRUE;
|
||||
else
|
||||
is_enabled = FALSE;
|
||||
|
||||
type = DBG_WB_CTRL_ACCESS_MASK(wcr);
|
||||
len = DBG_WB_CTRL_LEN_MASK(wcr);
|
||||
addr = dbg_wb_read_reg(DBG_REG_BASE_WVR, i) & DBGWVR_ADDR_MASK;
|
||||
db_printf(" %-5d %-8s %10s %3d 0x%08x ", i,
|
||||
is_enabled ? "enabled" : "disabled",
|
||||
is_enabled ? dbg_watchtype_str(type) : "",
|
||||
is_enabled ? dbg_watchtype_len(len) : 0,
|
||||
addr);
|
||||
db_printsym((db_addr_t)addr, DB_STGY_ANY);
|
||||
db_printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
static boolean_t
|
||||
dbg_check_slot_free(enum dbg_t type, u_int slot)
|
||||
{
|
||||
uint32_t cr, vr;
|
||||
uint32_t max;
|
||||
|
||||
switch(type) {
|
||||
case DBG_TYPE_BREAKPOINT:
|
||||
max = dbg_breakpoint_num;
|
||||
cr = DBG_REG_BASE_BCR;
|
||||
vr = DBG_REG_BASE_BVR;
|
||||
break;
|
||||
case DBG_TYPE_WATCHPOINT:
|
||||
max = dbg_watchpoint_num;
|
||||
cr = DBG_REG_BASE_WCR;
|
||||
vr = DBG_REG_BASE_WVR;
|
||||
break;
|
||||
default:
|
||||
db_printf("%s: Unsupported event type %d\n", __func__, type);
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
if (slot >= max) {
|
||||
db_printf("%s: Invalid slot number %d, max %d\n",
|
||||
__func__, slot, max - 1);
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
if ((dbg_wb_read_reg(cr, slot) & DBG_WB_CTRL_E) == 0 &&
|
||||
(dbg_wb_read_reg(vr, slot) & DBGWVR_ADDR_MASK) == 0)
|
||||
return (TRUE);
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
static u_int
|
||||
dbg_find_free_slot(enum dbg_t type)
|
||||
{
|
||||
u_int max, i;
|
||||
|
||||
switch(type) {
|
||||
case DBG_TYPE_BREAKPOINT:
|
||||
max = dbg_breakpoint_num;
|
||||
break;
|
||||
case DBG_TYPE_WATCHPOINT:
|
||||
max = dbg_watchpoint_num;
|
||||
break;
|
||||
default:
|
||||
db_printf("Unsupported debug type\n");
|
||||
return (~0U);
|
||||
}
|
||||
|
||||
for (i = 0; i < max; i++) {
|
||||
if (dbg_check_slot_free(type, i))
|
||||
return (i);
|
||||
}
|
||||
|
||||
return (~0U);
|
||||
}
|
||||
|
||||
static u_int
|
||||
dbg_find_slot(enum dbg_t type, db_expr_t addr)
|
||||
{
|
||||
uint32_t reg_addr, reg_ctrl;
|
||||
u_int max, i;
|
||||
|
||||
switch(type) {
|
||||
case DBG_TYPE_BREAKPOINT:
|
||||
max = dbg_breakpoint_num;
|
||||
reg_addr = DBG_REG_BASE_BVR;
|
||||
reg_ctrl = DBG_REG_BASE_BCR;
|
||||
break;
|
||||
case DBG_TYPE_WATCHPOINT:
|
||||
max = dbg_watchpoint_num;
|
||||
reg_addr = DBG_REG_BASE_WVR;
|
||||
reg_ctrl = DBG_REG_BASE_WCR;
|
||||
break;
|
||||
default:
|
||||
db_printf("Unsupported debug type\n");
|
||||
return (~0U);
|
||||
}
|
||||
|
||||
for (i = 0; i < max; i++) {
|
||||
if ((dbg_wb_read_reg(reg_addr, i) == addr) &&
|
||||
((dbg_wb_read_reg(reg_ctrl, i) & DBG_WB_CTRL_E) != 0))
|
||||
return (i);
|
||||
}
|
||||
|
||||
return (~0U);
|
||||
}
|
||||
|
||||
static __inline boolean_t
|
||||
dbg_monitor_is_enabled(void)
|
||||
{
|
||||
|
||||
return ((cp14_dbgdscrint_get() & DBGSCR_MDBG_EN) != 0);
|
||||
}
|
||||
|
||||
static int
|
||||
dbg_enable_monitor(void)
|
||||
{
|
||||
uint32_t dbg_dscr;
|
||||
|
||||
/* Already enabled? Just increment reference counter and return */
|
||||
if (dbg_monitor_is_enabled()) {
|
||||
dbg_ref_count_mme[PCPU_GET(cpuid)]++;
|
||||
return (0);
|
||||
}
|
||||
|
||||
dbg_dscr = cp14_dbgdscrint_get();
|
||||
|
||||
switch (dbg_model) {
|
||||
case ID_DFR0_CP_DEBUG_M_V6:
|
||||
case ID_DFR0_CP_DEBUG_M_V6_1: /* fall through */
|
||||
cp14_dbgdscr_v6_set(dbg_dscr | DBGSCR_MDBG_EN);
|
||||
break;
|
||||
case ID_DFR0_CP_DEBUG_M_V7: /* fall through */
|
||||
case ID_DFR0_CP_DEBUG_M_V7_1:
|
||||
cp14_dbgdscr_v7_set(dbg_dscr | DBGSCR_MDBG_EN);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
isb();
|
||||
|
||||
/* Verify that Monitor mode is set */
|
||||
if (dbg_monitor_is_enabled()) {
|
||||
dbg_ref_count_mme[PCPU_GET(cpuid)]++;
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
static int
|
||||
dbg_disable_monitor(void)
|
||||
{
|
||||
uint32_t dbg_dscr;
|
||||
|
||||
if (!dbg_monitor_is_enabled())
|
||||
return (0);
|
||||
|
||||
if (--dbg_ref_count_mme[PCPU_GET(cpuid)] > 0)
|
||||
return (0);
|
||||
|
||||
dbg_dscr = cp14_dbgdscrint_get();
|
||||
switch (dbg_model) {
|
||||
case ID_DFR0_CP_DEBUG_M_V6:
|
||||
case ID_DFR0_CP_DEBUG_M_V6_1: /* fall through */
|
||||
dbg_dscr &= ~DBGSCR_MDBG_EN;
|
||||
cp14_dbgdscr_v6_set(dbg_dscr);
|
||||
break;
|
||||
case ID_DFR0_CP_DEBUG_M_V7: /* fall through */
|
||||
case ID_DFR0_CP_DEBUG_M_V7_1:
|
||||
dbg_dscr &= ~DBGSCR_MDBG_EN;
|
||||
cp14_dbgdscr_v7_set(dbg_dscr);
|
||||
break;
|
||||
default:
|
||||
return (ENXIO);
|
||||
}
|
||||
isb();
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
dbg_setup_xpoint(struct dbg_wb_conf *conf)
|
||||
{
|
||||
const char *typestr;
|
||||
uint32_t cr_size, cr_priv, cr_access;
|
||||
uint32_t reg_ctrl, reg_addr, ctrl, addr;
|
||||
boolean_t is_bkpt;
|
||||
u_int cpuid;
|
||||
u_int i;
|
||||
int err;
|
||||
|
||||
if (!dbg_capable)
|
||||
return (ENXIO);
|
||||
|
||||
is_bkpt = (conf->type == DBG_TYPE_BREAKPOINT);
|
||||
typestr = is_bkpt ? "breakpoint" : "watchpoint";
|
||||
|
||||
cpuid = PCPU_GET(cpuid);
|
||||
if (!dbg_ready[cpuid]) {
|
||||
err = dbg_reset_state();
|
||||
if (err != 0)
|
||||
return (err);
|
||||
dbg_ready[cpuid] = TRUE;
|
||||
}
|
||||
|
||||
if (is_bkpt) {
|
||||
if (dbg_breakpoint_num == 0) {
|
||||
db_printf("Breakpoints not supported on this architecture\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
i = conf->slot;
|
||||
if (!dbg_check_slot_free(DBG_TYPE_BREAKPOINT, i)) {
|
||||
/*
|
||||
* This should never happen. If it does it means that
|
||||
* there is an erroneus scenario somewhere. Still, it can
|
||||
* be done but let's inform the user.
|
||||
*/
|
||||
db_printf("ERROR: Breakpoint already set. Replacing...\n");
|
||||
}
|
||||
} else {
|
||||
i = dbg_find_free_slot(DBG_TYPE_WATCHPOINT);
|
||||
if (i == ~0U) {
|
||||
db_printf("Can not find slot for %s, max %d slots supported\n",
|
||||
typestr, dbg_watchpoint_num);
|
||||
return (ENXIO);
|
||||
}
|
||||
}
|
||||
|
||||
/* Kernel access only */
|
||||
cr_priv = DBG_WB_CTRL_PL1;
|
||||
|
||||
switch(conf->size) {
|
||||
case 1:
|
||||
cr_size = DBG_WB_CTRL_LEN_1;
|
||||
break;
|
||||
case 2:
|
||||
cr_size = DBG_WB_CTRL_LEN_2;
|
||||
break;
|
||||
case 4:
|
||||
cr_size = DBG_WB_CTRL_LEN_4;
|
||||
break;
|
||||
case 8:
|
||||
cr_size = DBG_WB_CTRL_LEN_8;
|
||||
break;
|
||||
default:
|
||||
db_printf("Unsupported address size for %s\n", typestr);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
if (is_bkpt) {
|
||||
cr_access = DBG_WB_CTRL_EXEC;
|
||||
reg_ctrl = DBG_REG_BASE_BCR;
|
||||
reg_addr = DBG_REG_BASE_BVR;
|
||||
/* Always unlinked BKPT */
|
||||
ctrl = (cr_size | cr_access | cr_priv | DBG_WB_CTRL_E);
|
||||
} else {
|
||||
switch(conf->access) {
|
||||
case HW_WATCHPOINT_R:
|
||||
cr_access = DBG_WB_CTRL_LOAD;
|
||||
break;
|
||||
case HW_WATCHPOINT_W:
|
||||
cr_access = DBG_WB_CTRL_STORE;
|
||||
break;
|
||||
case HW_WATCHPOINT_RW:
|
||||
cr_access = DBG_WB_CTRL_LOAD | DBG_WB_CTRL_STORE;
|
||||
break;
|
||||
default:
|
||||
db_printf("Unsupported exception level for %s\n", typestr);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
reg_ctrl = DBG_REG_BASE_WCR;
|
||||
reg_addr = DBG_REG_BASE_WVR;
|
||||
ctrl = (cr_size | cr_access | cr_priv | DBG_WB_CTRL_E);
|
||||
}
|
||||
|
||||
addr = conf->address;
|
||||
|
||||
dbg_wb_write_reg(reg_addr, i, addr);
|
||||
dbg_wb_write_reg(reg_ctrl, i, ctrl);
|
||||
|
||||
return (dbg_enable_monitor());
|
||||
}
|
||||
|
||||
static int
|
||||
dbg_remove_xpoint(struct dbg_wb_conf *conf)
|
||||
{
|
||||
uint32_t reg_ctrl, reg_addr, addr;
|
||||
u_int cpuid;
|
||||
u_int i;
|
||||
int err;
|
||||
|
||||
if (!dbg_capable)
|
||||
return (ENXIO);
|
||||
|
||||
cpuid = PCPU_GET(cpuid);
|
||||
if (!dbg_ready[cpuid]) {
|
||||
err = dbg_reset_state();
|
||||
if (err != 0)
|
||||
return (err);
|
||||
dbg_ready[cpuid] = TRUE;
|
||||
}
|
||||
|
||||
addr = conf->address;
|
||||
|
||||
if (conf->type == DBG_TYPE_BREAKPOINT) {
|
||||
i = conf->slot;
|
||||
reg_ctrl = DBG_REG_BASE_BCR;
|
||||
reg_addr = DBG_REG_BASE_BVR;
|
||||
} else {
|
||||
i = dbg_find_slot(DBG_TYPE_WATCHPOINT, addr);
|
||||
if (i == ~0U) {
|
||||
db_printf("Can not find watchpoint for address 0%x\n", addr);
|
||||
return (EINVAL);
|
||||
}
|
||||
reg_ctrl = DBG_REG_BASE_WCR;
|
||||
reg_addr = DBG_REG_BASE_WVR;
|
||||
}
|
||||
|
||||
dbg_wb_write_reg(reg_ctrl, i, 0);
|
||||
dbg_wb_write_reg(reg_addr, i, 0);
|
||||
|
||||
return (dbg_disable_monitor());
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
dbg_get_debug_model(void)
|
||||
{
|
||||
uint32_t dbg_m;
|
||||
|
||||
dbg_m = ((cpuinfo.id_dfr0 & ID_DFR0_CP_DEBUG_M_MASK) >>
|
||||
ID_DFR0_CP_DEBUG_M_SHIFT);
|
||||
|
||||
return (dbg_m);
|
||||
}
|
||||
|
||||
static __inline boolean_t
|
||||
dbg_get_ossr(void)
|
||||
{
|
||||
|
||||
switch (dbg_model) {
|
||||
case ID_DFR0_CP_DEBUG_M_V6_1:
|
||||
if ((cp14_dbgoslsr_get() & DBGOSLSR_OSLM0) != 0)
|
||||
return (TRUE);
|
||||
|
||||
return (FALSE);
|
||||
case ID_DFR0_CP_DEBUG_M_V7_1:
|
||||
return (TRUE);
|
||||
default:
|
||||
return (FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static __inline boolean_t
|
||||
dbg_arch_supported(void)
|
||||
{
|
||||
|
||||
switch (dbg_model) {
|
||||
case ID_DFR0_CP_DEBUG_M_V6:
|
||||
case ID_DFR0_CP_DEBUG_M_V6_1:
|
||||
case ID_DFR0_CP_DEBUG_M_V7:
|
||||
case ID_DFR0_CP_DEBUG_M_V7_1: /* fall through */
|
||||
return (TRUE);
|
||||
default:
|
||||
/* We only support valid v6.x/v7.x modes through CP14 */
|
||||
return (FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
dbg_get_wrp_num(void)
|
||||
{
|
||||
uint32_t dbg_didr;
|
||||
|
||||
dbg_didr = cp14_dbgdidr_get();
|
||||
|
||||
return (DBGDIDR_WRPS_NUM(dbg_didr));
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
dgb_get_brp_num(void)
|
||||
{
|
||||
uint32_t dbg_didr;
|
||||
|
||||
dbg_didr = cp14_dbgdidr_get();
|
||||
|
||||
return (DBGDIDR_BRPS_NUM(dbg_didr));
|
||||
}
|
||||
|
||||
static int
|
||||
dbg_reset_state(void)
|
||||
{
|
||||
u_int cpuid;
|
||||
size_t i;
|
||||
int err;
|
||||
|
||||
cpuid = PCPU_GET(cpuid);
|
||||
err = 0;
|
||||
|
||||
switch (dbg_model) {
|
||||
case ID_DFR0_CP_DEBUG_M_V6:
|
||||
/* v6 Debug logic reset upon power-up */
|
||||
return (0);
|
||||
case ID_DFR0_CP_DEBUG_M_V6_1:
|
||||
/* Is core power domain powered up? */
|
||||
if ((cp14_dbgprsr_get() & DBGPRSR_PU) == 0)
|
||||
err = ENXIO;
|
||||
|
||||
if (err != 0)
|
||||
break;
|
||||
|
||||
if (dbg_ossr)
|
||||
goto vectr_clr;
|
||||
break;
|
||||
case ID_DFR0_CP_DEBUG_M_V7:
|
||||
break;
|
||||
case ID_DFR0_CP_DEBUG_M_V7_1:
|
||||
/* Is double lock set? */
|
||||
if ((cp14_dbgosdlr_get() & DBGPRSR_DLK) != 0)
|
||||
err = ENXIO;
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (err != 0) {
|
||||
db_printf("Debug facility locked (CPU%d)\n", cpuid);
|
||||
return (err);
|
||||
}
|
||||
|
||||
/*
|
||||
* DBGOSLAR is always implemented for v7.1 Debug Arch. however is
|
||||
* optional for v7 (depends on OS save and restore support).
|
||||
*/
|
||||
if (((dbg_model & ID_DFR0_CP_DEBUG_M_V7_1) != 0) || dbg_ossr) {
|
||||
/*
|
||||
* Clear OS lock.
|
||||
* Writing any other value than 0xC5ACCESS will unlock.
|
||||
*/
|
||||
cp14_dbgoslar_set(0);
|
||||
isb();
|
||||
}
|
||||
|
||||
vectr_clr:
|
||||
/*
|
||||
* After reset we must ensure that DBGVCR has a defined value.
|
||||
* Disable all vector catch events. Safe to use - required in all
|
||||
* implementations.
|
||||
*/
|
||||
cp14_dbgvcr_set(0);
|
||||
isb();
|
||||
|
||||
/*
|
||||
* We have limited number of {watch,break}points, each consists of
|
||||
* two registers:
|
||||
* - wcr/bcr regsiter configurates corresponding {watch,break}point
|
||||
* behaviour
|
||||
* - wvr/bvr register keeps address we are hunting for
|
||||
*
|
||||
* Reset all breakpoints and watchpoints.
|
||||
*/
|
||||
for (i = 0; i < dbg_watchpoint_num; ++i) {
|
||||
dbg_wb_write_reg(DBG_REG_BASE_WCR, i, 0);
|
||||
dbg_wb_write_reg(DBG_REG_BASE_WVR, i, 0);
|
||||
}
|
||||
|
||||
for (i = 0; i < dbg_breakpoint_num; ++i) {
|
||||
dbg_wb_write_reg(DBG_REG_BASE_BCR, i, 0);
|
||||
dbg_wb_write_reg(DBG_REG_BASE_BVR, i, 0);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
dbg_monitor_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Fetch ARM Debug Architecture model */
|
||||
dbg_model = dbg_get_debug_model();
|
||||
|
||||
if (!dbg_arch_supported()) {
|
||||
db_printf("ARM Debug Architecture not supported\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (bootverbose) {
|
||||
db_printf("ARM Debug Architecture %s\n",
|
||||
(dbg_model == ID_DFR0_CP_DEBUG_M_V6) ? "v6" :
|
||||
(dbg_model == ID_DFR0_CP_DEBUG_M_V6_1) ? "v6.1" :
|
||||
(dbg_model == ID_DFR0_CP_DEBUG_M_V7) ? "v7" :
|
||||
(dbg_model == ID_DFR0_CP_DEBUG_M_V7_1) ? "v7.1" : "unknown");
|
||||
}
|
||||
|
||||
/* Do we have OS Save and Restore mechanism? */
|
||||
dbg_ossr = dbg_get_ossr();
|
||||
|
||||
/* Find out many breakpoints and watchpoints we can use */
|
||||
dbg_watchpoint_num = dbg_get_wrp_num();
|
||||
dbg_breakpoint_num = dgb_get_brp_num();
|
||||
|
||||
if (bootverbose) {
|
||||
db_printf("%d watchpoints and %d breakpoints supported\n",
|
||||
dbg_watchpoint_num, dbg_breakpoint_num);
|
||||
}
|
||||
|
||||
err = dbg_reset_state();
|
||||
if (err == 0) {
|
||||
dbg_capable = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
db_printf("HW Breakpoints/Watchpoints not enabled on CPU%d\n",
|
||||
PCPU_GET(cpuid));
|
||||
}
|
@ -256,7 +256,7 @@ elf_reloc_local(linker_file_t lf, Elf_Addr relocbase, const void *data,
|
||||
}
|
||||
|
||||
int
|
||||
elf_cpu_load_file(linker_file_t lf __unused)
|
||||
elf_cpu_load_file(linker_file_t lf)
|
||||
{
|
||||
|
||||
/*
|
||||
@ -265,13 +265,25 @@ elf_cpu_load_file(linker_file_t lf __unused)
|
||||
* that kernel memory allocations always have EXECUTABLE protection even
|
||||
* when the memory isn't going to hold executable code. The only time
|
||||
* kernel memory holding instructions does need a sync is after loading
|
||||
* a kernel module, and that's when this function gets called. Normal
|
||||
* data cache maintenance has already been done by the IO code, and TLB
|
||||
* maintenance has been done by the pmap code, so all we have to do here
|
||||
* is invalidate the instruction cache (which also invalidates the
|
||||
* branch predictor cache on platforms that have one).
|
||||
* a kernel module, and that's when this function gets called.
|
||||
*
|
||||
* This syncs data and instruction caches after loading a module. We
|
||||
* don't worry about the kernel itself (lf->id is 1) as locore.S did
|
||||
* that on entry. Even if data cache maintenance was done by IO code,
|
||||
* the relocation fixup process creates dirty cache entries that we must
|
||||
* write back before doing icache sync. The instruction cache sync also
|
||||
* invalidates the branch predictor cache on platforms that have one.
|
||||
*/
|
||||
if (lf->id == 1)
|
||||
return (0);
|
||||
#if __ARM_ARCH >= 6
|
||||
dcache_wb_pou((vm_offset_t)lf->address, (vm_size_t)lf->size);
|
||||
icache_inv_all();
|
||||
#else
|
||||
cpu_dcache_wb_range((vm_offset_t)lf->address, (vm_size_t)lf->size);
|
||||
cpu_l2cache_wb_range((vm_offset_t)lf->address, (vm_size_t)lf->size);
|
||||
cpu_icache_sync_all();
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -96,6 +96,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/atags.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/cpuinfo.h>
|
||||
#include <machine/debug_monitor.h>
|
||||
#include <machine/db_machdep.h>
|
||||
#include <machine/devmap.h>
|
||||
#include <machine/frame.h>
|
||||
@ -1710,6 +1711,7 @@ initarm(struct arm_boot_params *abp)
|
||||
arm_physmem_init_kernel_globals();
|
||||
|
||||
init_param2(physmem);
|
||||
dbg_monitor_init();
|
||||
kdb_init();
|
||||
|
||||
return ((void *)(kernelstack.pv_va + USPACE_SVC_STACK_TOP -
|
||||
@ -1897,6 +1899,7 @@ initarm(struct arm_boot_params *abp)
|
||||
init_param2(physmem);
|
||||
/* Init message buffer. */
|
||||
msgbufinit(msgbufp, msgbufsize);
|
||||
dbg_monitor_init();
|
||||
kdb_init();
|
||||
return ((void *)STACKALIGN(thread0.td_pcb));
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2006 Peter Wemm
|
||||
* Copyright (c) 2008 Semihalf, Grzegorz Bernacki
|
||||
* All rights reserved.
|
||||
*
|
||||
@ -61,14 +62,12 @@ CTASSERT(sizeof(struct kerneldumpheader) == 512);
|
||||
uint32_t *vm_page_dump;
|
||||
int vm_page_dump_size;
|
||||
|
||||
#ifndef ARM_NEW_PMAP
|
||||
|
||||
static struct kerneldumpheader kdh;
|
||||
|
||||
static off_t dumplo;
|
||||
|
||||
/* Handle chunked writes. */
|
||||
static size_t fragsz, offset;
|
||||
static size_t fragsz;
|
||||
static void *dump_va;
|
||||
static uint64_t counter, progress;
|
||||
|
||||
@ -96,10 +95,9 @@ blk_flush(struct dumperinfo *di)
|
||||
if (fragsz == 0)
|
||||
return (0);
|
||||
|
||||
error = dump_write(di, (char*)dump_va + offset, 0, dumplo, fragsz - offset);
|
||||
dumplo += (fragsz - offset);
|
||||
error = dump_write(di, dump_va, 0, dumplo, fragsz);
|
||||
dumplo += fragsz;
|
||||
fragsz = 0;
|
||||
offset = 0;
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -110,36 +108,36 @@ blk_write(struct dumperinfo *di, char *ptr, vm_paddr_t pa, size_t sz)
|
||||
int error, i, c;
|
||||
u_int maxdumpsz;
|
||||
|
||||
maxdumpsz = di->maxiosize;
|
||||
|
||||
maxdumpsz = min(di->maxiosize, MAXDUMPPGS * PAGE_SIZE);
|
||||
if (maxdumpsz == 0) /* seatbelt */
|
||||
maxdumpsz = PAGE_SIZE;
|
||||
|
||||
error = 0;
|
||||
|
||||
if (ptr != NULL && pa != 0) {
|
||||
printf("cant have both va and pa!\n");
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
if (pa != 0) {
|
||||
if ((sz % PAGE_SIZE) != 0) {
|
||||
printf("size not page aligned\n");
|
||||
return (EINVAL);
|
||||
}
|
||||
if ((pa & PAGE_MASK) != 0) {
|
||||
printf("address not page aligned\n");
|
||||
return (EINVAL);
|
||||
}
|
||||
}
|
||||
if (ptr != NULL) {
|
||||
/* If we're doing a virtual dump, flush any pre-existing pa pages */
|
||||
/* Flush any pre-existing pa pages before a virtual dump. */
|
||||
error = blk_flush(di);
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
|
||||
while (sz) {
|
||||
if (fragsz == 0) {
|
||||
offset = pa & PAGE_MASK;
|
||||
fragsz += offset;
|
||||
}
|
||||
len = maxdumpsz - fragsz;
|
||||
if (len > sz)
|
||||
len = sz;
|
||||
counter += len;
|
||||
progress -= len;
|
||||
|
||||
if (counter >> 22) {
|
||||
printf(" %lld", PG2MB(progress >> PAGE_SHIFT));
|
||||
counter &= (1<<22) - 1;
|
||||
@ -180,24 +178,9 @@ blk_write(struct dumperinfo *di, char *ptr, vm_paddr_t pa, size_t sz)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
blk_write_cont(struct dumperinfo *di, vm_paddr_t pa, size_t sz)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = blk_write(di, 0, pa, sz);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
error = blk_flush(di);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* A fake page table page, to avoid having to handle both 4K and 2M pages */
|
||||
static pt_entry_t fakept[NPTEPG];
|
||||
/* A buffer for general use. Its size must be one page at least. */
|
||||
static char dumpbuf[PAGE_SIZE];
|
||||
CTASSERT(sizeof(dumpbuf) % sizeof(pt2_entry_t) == 0);
|
||||
|
||||
int
|
||||
minidumpsys(struct dumperinfo *di)
|
||||
@ -208,9 +191,7 @@ minidumpsys(struct dumperinfo *di)
|
||||
uint32_t bits;
|
||||
uint32_t pa, prev_pa = 0, count = 0;
|
||||
vm_offset_t va;
|
||||
pd_entry_t *pdp;
|
||||
pt_entry_t *pt, *ptp;
|
||||
int i, k, bit, error;
|
||||
int i, bit, error;
|
||||
char *addr;
|
||||
|
||||
/*
|
||||
@ -228,48 +209,11 @@ minidumpsys(struct dumperinfo *di)
|
||||
counter = 0;
|
||||
/* Walk page table pages, set bits in vm_page_dump */
|
||||
ptesize = 0;
|
||||
for (va = KERNBASE; va < kernel_vm_end; va += NBPDR) {
|
||||
/*
|
||||
* We always write a page, even if it is zero. Each
|
||||
* page written corresponds to 2MB of space
|
||||
*/
|
||||
ptesize += L2_TABLE_SIZE_REAL;
|
||||
pmap_get_pde_pte(pmap_kernel(), va, &pdp, &ptp);
|
||||
if (pmap_pde_v(pdp) && pmap_pde_section(pdp)) {
|
||||
/* This is a section mapping 1M page. */
|
||||
pa = (*pdp & L1_S_ADDR_MASK) | (va & ~L1_S_ADDR_MASK);
|
||||
for (k = 0; k < (L1_S_SIZE / PAGE_SIZE); k++) {
|
||||
if (is_dumpable(pa))
|
||||
dump_add_page(pa);
|
||||
pa += PAGE_SIZE;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (pmap_pde_v(pdp) && pmap_pde_page(pdp)) {
|
||||
/* Set bit for each valid page in this 1MB block */
|
||||
addr = pmap_kenter_temporary(*pdp & L1_C_ADDR_MASK, 0);
|
||||
pt = (pt_entry_t*)(addr +
|
||||
(((uint32_t)*pdp & L1_C_ADDR_MASK) & PAGE_MASK));
|
||||
for (k = 0; k < 256; k++) {
|
||||
if ((pt[k] & L2_TYPE_MASK) == L2_TYPE_L) {
|
||||
pa = (pt[k] & L2_L_FRAME) |
|
||||
(va & L2_L_OFFSET);
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (is_dumpable(pa))
|
||||
dump_add_page(pa);
|
||||
k++;
|
||||
pa += PAGE_SIZE;
|
||||
}
|
||||
} else if ((pt[k] & L2_TYPE_MASK) == L2_TYPE_S) {
|
||||
pa = (pt[k] & L2_S_FRAME) |
|
||||
(va & L2_S_OFFSET);
|
||||
if (is_dumpable(pa))
|
||||
dump_add_page(pa);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Nothing, we're going to dump a null page */
|
||||
}
|
||||
for (va = KERNBASE; va < kernel_vm_end; va += PAGE_SIZE) {
|
||||
pa = pmap_dump_kextract(va, NULL);
|
||||
if (pa != 0 && is_dumpable(pa))
|
||||
dump_add_page(pa);
|
||||
ptesize += sizeof(pt2_entry_t);
|
||||
}
|
||||
|
||||
/* Calculate dump size. */
|
||||
@ -331,14 +275,15 @@ minidumpsys(struct dumperinfo *di)
|
||||
dumplo += sizeof(kdh);
|
||||
|
||||
/* Dump my header */
|
||||
bzero(&fakept, sizeof(fakept));
|
||||
bcopy(&mdhdr, &fakept, sizeof(mdhdr));
|
||||
error = blk_write(di, (char *)&fakept, 0, PAGE_SIZE);
|
||||
bzero(dumpbuf, sizeof(dumpbuf));
|
||||
bcopy(&mdhdr, dumpbuf, sizeof(mdhdr));
|
||||
error = blk_write(di, dumpbuf, 0, PAGE_SIZE);
|
||||
if (error)
|
||||
goto fail;
|
||||
|
||||
/* Dump msgbuf up front */
|
||||
error = blk_write(di, (char *)msgbufp->msg_ptr, 0, round_page(msgbufp->msg_size));
|
||||
error = blk_write(di, (char *)msgbufp->msg_ptr, 0,
|
||||
round_page(msgbufp->msg_size));
|
||||
if (error)
|
||||
goto fail;
|
||||
|
||||
@ -349,81 +294,21 @@ minidumpsys(struct dumperinfo *di)
|
||||
goto fail;
|
||||
|
||||
/* Dump kernel page table pages */
|
||||
for (va = KERNBASE; va < kernel_vm_end; va += NBPDR) {
|
||||
/* We always write a page, even if it is zero */
|
||||
pmap_get_pde_pte(pmap_kernel(), va, &pdp, &ptp);
|
||||
|
||||
if (pmap_pde_v(pdp) && pmap_pde_section(pdp)) {
|
||||
if (count) {
|
||||
error = blk_write_cont(di, prev_pa,
|
||||
count * L2_TABLE_SIZE_REAL);
|
||||
if (error)
|
||||
goto fail;
|
||||
count = 0;
|
||||
prev_pa = 0;
|
||||
}
|
||||
/* This is a single 2M block. Generate a fake PTP */
|
||||
pa = (*pdp & L1_S_ADDR_MASK) | (va & ~L1_S_ADDR_MASK);
|
||||
for (k = 0; k < (L1_S_SIZE / PAGE_SIZE); k++) {
|
||||
fakept[k] = L2_S_PROTO | (pa + (k * PAGE_SIZE)) |
|
||||
L2_S_PROT(PTE_KERNEL,
|
||||
VM_PROT_READ | VM_PROT_WRITE);
|
||||
}
|
||||
error = blk_write(di, (char *)&fakept, 0,
|
||||
L2_TABLE_SIZE_REAL);
|
||||
if (error)
|
||||
goto fail;
|
||||
/* Flush, in case we reuse fakept in the same block */
|
||||
error = blk_flush(di);
|
||||
if (error)
|
||||
goto fail;
|
||||
continue;
|
||||
}
|
||||
if (pmap_pde_v(pdp) && pmap_pde_page(pdp)) {
|
||||
pa = *pdp & L1_C_ADDR_MASK;
|
||||
if (!count) {
|
||||
prev_pa = pa;
|
||||
count++;
|
||||
}
|
||||
else {
|
||||
if (pa == (prev_pa + count * L2_TABLE_SIZE_REAL))
|
||||
count++;
|
||||
else {
|
||||
error = blk_write_cont(di, prev_pa,
|
||||
count * L2_TABLE_SIZE_REAL);
|
||||
if (error)
|
||||
goto fail;
|
||||
count = 1;
|
||||
prev_pa = pa;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (count) {
|
||||
error = blk_write_cont(di, prev_pa,
|
||||
count * L2_TABLE_SIZE_REAL);
|
||||
if (error)
|
||||
goto fail;
|
||||
count = 0;
|
||||
prev_pa = 0;
|
||||
}
|
||||
bzero(fakept, sizeof(fakept));
|
||||
error = blk_write(di, (char *)&fakept, 0,
|
||||
L2_TABLE_SIZE_REAL);
|
||||
if (error)
|
||||
goto fail;
|
||||
/* Flush, in case we reuse fakept in the same block */
|
||||
error = blk_flush(di);
|
||||
if (error)
|
||||
addr = dumpbuf;
|
||||
for (va = KERNBASE; va < kernel_vm_end; va += PAGE_SIZE) {
|
||||
pmap_dump_kextract(va, (pt2_entry_t *)addr);
|
||||
addr += sizeof(pt2_entry_t);
|
||||
if (addr == dumpbuf + sizeof(dumpbuf)) {
|
||||
error = blk_write(di, dumpbuf, 0, sizeof(dumpbuf));
|
||||
if (error != 0)
|
||||
goto fail;
|
||||
addr = dumpbuf;
|
||||
}
|
||||
}
|
||||
|
||||
if (count) {
|
||||
error = blk_write_cont(di, prev_pa, count * L2_TABLE_SIZE_REAL);
|
||||
if (error)
|
||||
if (addr != dumpbuf) {
|
||||
error = blk_write(di, dumpbuf, 0, addr - dumpbuf);
|
||||
if (error != 0)
|
||||
goto fail;
|
||||
count = 0;
|
||||
prev_pa = 0;
|
||||
}
|
||||
|
||||
/* Dump memory chunks */
|
||||
@ -440,7 +325,7 @@ minidumpsys(struct dumperinfo *di)
|
||||
if (pa == (prev_pa + count * PAGE_SIZE))
|
||||
count++;
|
||||
else {
|
||||
error = blk_write_cont(di, prev_pa,
|
||||
error = blk_write(di, NULL, prev_pa,
|
||||
count * PAGE_SIZE);
|
||||
if (error)
|
||||
goto fail;
|
||||
@ -452,13 +337,17 @@ minidumpsys(struct dumperinfo *di)
|
||||
}
|
||||
}
|
||||
if (count) {
|
||||
error = blk_write_cont(di, prev_pa, count * PAGE_SIZE);
|
||||
error = blk_write(di, NULL, prev_pa, count * PAGE_SIZE);
|
||||
if (error)
|
||||
goto fail;
|
||||
count = 0;
|
||||
prev_pa = 0;
|
||||
}
|
||||
|
||||
error = blk_flush(di);
|
||||
if (error)
|
||||
goto fail;
|
||||
|
||||
/* Dump trailer */
|
||||
error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
|
||||
if (error)
|
||||
@ -484,17 +373,6 @@ minidumpsys(struct dumperinfo *di)
|
||||
return (0);
|
||||
}
|
||||
|
||||
#else /* ARM_NEW_PMAP */
|
||||
|
||||
int
|
||||
minidumpsys(struct dumperinfo *di)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
dump_add_page(vm_paddr_t pa)
|
||||
{
|
||||
|
@ -49,6 +49,8 @@ __FBSDID("$FreeBSD$");
|
||||
#define MAX_HWCNT 10
|
||||
#define MAX_EXCNT 10
|
||||
|
||||
#define MAX_PHYS_ADDR 0xFFFFFFFFull
|
||||
|
||||
struct region {
|
||||
vm_paddr_t addr;
|
||||
vm_size_t size;
|
||||
@ -273,14 +275,25 @@ insert_region(struct region *regions, size_t rcnt, vm_paddr_t addr,
|
||||
* Add a hardware memory region.
|
||||
*/
|
||||
void
|
||||
arm_physmem_hardware_region(vm_paddr_t pa, vm_size_t sz)
|
||||
arm_physmem_hardware_region(uint64_t pa, uint64_t sz)
|
||||
{
|
||||
vm_offset_t adj;
|
||||
|
||||
/*
|
||||
* Filter out the page at PA 0x00000000. The VM can't handle it, as
|
||||
* pmap_extract() == 0 means failure.
|
||||
*
|
||||
*/
|
||||
if (pa == 0) {
|
||||
if (sz <= PAGE_SIZE)
|
||||
return;
|
||||
pa = PAGE_SIZE;
|
||||
sz -= PAGE_SIZE;
|
||||
} else if (pa > MAX_PHYS_ADDR) {
|
||||
/* This range is past usable memory, ignore it */
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Also filter out the page at the end of the physical address space --
|
||||
* if addr is non-zero and addr+size is zero we wrapped to the next byte
|
||||
* beyond what vm_paddr_t can express. That leads to a NULL pointer
|
||||
@ -291,12 +304,8 @@ arm_physmem_hardware_region(vm_paddr_t pa, vm_size_t sz)
|
||||
* pointer deref in _vm_map_lock_read(). Better to give up a megabyte
|
||||
* than leave some folks with an unusable system while we investigate.
|
||||
*/
|
||||
if (pa == 0) {
|
||||
if (sz <= PAGE_SIZE)
|
||||
return;
|
||||
pa = PAGE_SIZE;
|
||||
sz -= PAGE_SIZE;
|
||||
} else if (pa + sz == 0) {
|
||||
if ((pa + sz) > (MAX_PHYS_ADDR - 1024 * 1024)) {
|
||||
sz = MAX_PHYS_ADDR - pa + 1;
|
||||
if (sz <= 1024 * 1024)
|
||||
return;
|
||||
sz -= 1024 * 1024;
|
||||
|
@ -1049,6 +1049,36 @@ pmap_kextract(vm_offset_t va)
|
||||
return (pa);
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract from the kernel page table the physical address
|
||||
* that is mapped by the given virtual address "va". Also
|
||||
* return L2 page table entry which maps the address.
|
||||
*
|
||||
* This is only intended to be used for panic dumps.
|
||||
*/
|
||||
vm_paddr_t
|
||||
pmap_dump_kextract(vm_offset_t va, pt2_entry_t *pte2p)
|
||||
{
|
||||
vm_paddr_t pa;
|
||||
pt1_entry_t pte1;
|
||||
pt2_entry_t pte2;
|
||||
|
||||
pte1 = pte1_load(kern_pte1(va));
|
||||
if (pte1_is_section(pte1)) {
|
||||
pa = pte1_pa(pte1) | (va & PTE1_OFFSET);
|
||||
pte2 = pa | ATTR_TO_L2(pte1) | PTE2_V;
|
||||
} else if (pte1_is_link(pte1)) {
|
||||
pte2 = pte2_load(pt2map_entry(va));
|
||||
pa = pte2_pa(pte2);
|
||||
} else {
|
||||
pte2 = 0;
|
||||
pa = 0;
|
||||
}
|
||||
if (pte2p != NULL)
|
||||
*pte2p = pte2;
|
||||
return (pa);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* PMAP second stage initialization and utility functions
|
||||
|
@ -3536,6 +3536,52 @@ pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot)
|
||||
return (m);
|
||||
}
|
||||
|
||||
vm_paddr_t
|
||||
pmap_dump_kextract(vm_offset_t va, pt2_entry_t *pte2p)
|
||||
{
|
||||
struct l2_dtable *l2;
|
||||
pd_entry_t l1pd;
|
||||
pt_entry_t *ptep, pte;
|
||||
vm_paddr_t pa;
|
||||
u_int l1idx;
|
||||
|
||||
l1idx = L1_IDX(va);
|
||||
l1pd = kernel_pmap->pm_l1->l1_kva[l1idx];
|
||||
if (l1pte_section_p(l1pd)) {
|
||||
if (l1pd & L1_S_SUPERSEC)
|
||||
pa = (l1pd & L1_SUP_FRAME) | (va & L1_SUP_OFFSET);
|
||||
else
|
||||
pa = (l1pd & L1_S_FRAME) | (va & L1_S_OFFSET);
|
||||
pte = L2_S_PROTO | pa |
|
||||
L2_S_PROT(PTE_KERNEL, VM_PROT_READ | VM_PROT_WRITE);
|
||||
} else {
|
||||
l2 = kernel_pmap->pm_l2[L2_IDX(l1idx)];
|
||||
if (l2 == NULL ||
|
||||
(ptep = l2->l2_bucket[L2_BUCKET(l1idx)].l2b_kva) == NULL) {
|
||||
pte = 0;
|
||||
pa = 0;
|
||||
goto out;
|
||||
}
|
||||
pte = ptep[l2pte_index(va)];
|
||||
if (pte == 0) {
|
||||
pa = 0;
|
||||
goto out;
|
||||
}
|
||||
switch (pte & L2_TYPE_MASK) {
|
||||
case L2_TYPE_L:
|
||||
pa = (pte & L2_L_FRAME) | (va & L2_L_OFFSET);
|
||||
break;
|
||||
default:
|
||||
pa = (pte & L2_S_FRAME) | (va & L2_S_OFFSET);
|
||||
break;
|
||||
}
|
||||
}
|
||||
out:
|
||||
if (pte2p != NULL)
|
||||
*pte2p = pte;
|
||||
return (pa);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize a preallocated and zeroed pmap structure,
|
||||
* such as one in a vmspace structure.
|
||||
|
@ -3738,6 +3738,52 @@ pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot)
|
||||
return (m);
|
||||
}
|
||||
|
||||
vm_paddr_t
|
||||
pmap_dump_kextract(vm_offset_t va, pt2_entry_t *pte2p)
|
||||
{
|
||||
struct l2_dtable *l2;
|
||||
pd_entry_t l1pd;
|
||||
pt_entry_t *ptep, pte;
|
||||
vm_paddr_t pa;
|
||||
u_int l1idx;
|
||||
|
||||
l1idx = L1_IDX(va);
|
||||
l1pd = kernel_pmap->pm_l1->l1_kva[l1idx];
|
||||
if (l1pte_section_p(l1pd)) {
|
||||
if (l1pd & L1_S_SUPERSEC)
|
||||
pa = (l1pd & L1_SUP_FRAME) | (va & L1_SUP_OFFSET);
|
||||
else
|
||||
pa = (l1pd & L1_S_FRAME) | (va & L1_S_OFFSET);
|
||||
pte = L2_S_PROTO | pa |
|
||||
L2_S_PROT(PTE_KERNEL, VM_PROT_READ | VM_PROT_WRITE);
|
||||
} else {
|
||||
l2 = kernel_pmap->pm_l2[L2_IDX(l1idx)];
|
||||
if (l2 == NULL ||
|
||||
(ptep = l2->l2_bucket[L2_BUCKET(l1idx)].l2b_kva) == NULL) {
|
||||
pte = 0;
|
||||
pa = 0;
|
||||
goto out;
|
||||
}
|
||||
pte = ptep[l2pte_index(va)];
|
||||
if (pte == 0) {
|
||||
pa = 0;
|
||||
goto out;
|
||||
}
|
||||
switch (pte & L2_TYPE_MASK) {
|
||||
case L2_TYPE_L:
|
||||
pa = (pte & L2_L_FRAME) | (va & L2_L_OFFSET);
|
||||
break;
|
||||
default:
|
||||
pa = (pte & L2_S_FRAME) | (va & L2_S_OFFSET);
|
||||
break;
|
||||
}
|
||||
}
|
||||
out:
|
||||
if (pte2p != NULL)
|
||||
*pte2p = pte;
|
||||
return (pa);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize a preallocated and zeroed pmap structure,
|
||||
* such as one in a vmspace structure.
|
||||
|
@ -259,7 +259,7 @@ abort_debug(struct trapframe *tf, u_int fsr, u_int prefetch, bool usermode,
|
||||
userret(td, tf);
|
||||
} else {
|
||||
#ifdef KDB
|
||||
kdb_trap(T_BREAKPOINT, 0, tf);
|
||||
kdb_trap((prefetch) ? T_BREAKPOINT : T_WATCHPOINT, 0, tf);
|
||||
#else
|
||||
printf("No debugger in kernel.\n");
|
||||
#endif
|
||||
|
@ -23,9 +23,12 @@ ident A20
|
||||
include "std.armv6"
|
||||
include "../allwinner/a20/std.a20"
|
||||
|
||||
options ARM_INTRNG
|
||||
|
||||
options HZ=100
|
||||
options SCHED_ULE # ULE scheduler
|
||||
options SMP # Enable multiple cores
|
||||
options PLATFORM
|
||||
|
||||
# Debugging for use in -current
|
||||
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
|
||||
|
@ -26,6 +26,7 @@ include "../allwinner/std.a10"
|
||||
|
||||
options HZ=100
|
||||
options SCHED_4BSD # 4BSD scheduler
|
||||
options PLATFORM
|
||||
|
||||
# Debugging for use in -current
|
||||
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
|
||||
|
@ -138,6 +138,18 @@ _WF1(_CP15_ICIMVAU, CP15_ICIMVAU(%0)) /* Instruction cache invalidate */
|
||||
* Publicly accessible functions
|
||||
*/
|
||||
|
||||
/* CP14 Debug Registers */
|
||||
_RF0(cp14_dbgdidr_get, CP14_DBGDIDR(%0))
|
||||
_RF0(cp14_dbgprsr_get, CP14_DBGPRSR(%0))
|
||||
_RF0(cp14_dbgoslsr_get, CP14_DBGOSLSR(%0))
|
||||
_RF0(cp14_dbgosdlr_get, CP14_DBGOSDLR(%0))
|
||||
_RF0(cp14_dbgdscrint_get, CP14_DBGDSCRint(%0))
|
||||
|
||||
_WF1(cp14_dbgdscr_v6_set, CP14_DBGDSCRext_V6(%0))
|
||||
_WF1(cp14_dbgdscr_v7_set, CP14_DBGDSCRext_V7(%0))
|
||||
_WF1(cp14_dbgvcr_set, CP14_DBGVCR(%0))
|
||||
_WF1(cp14_dbgoslar_set, CP14_DBGOSLAR(%0))
|
||||
|
||||
/* Various control registers */
|
||||
|
||||
_RF0(cp15_cpacr_get, CP15_CPACR(%0))
|
||||
|
@ -33,8 +33,10 @@
|
||||
#include <machine/frame.h>
|
||||
#include <machine/trap.h>
|
||||
#include <machine/armreg.h>
|
||||
#include <machine/acle-compat.h>
|
||||
|
||||
#define T_BREAKPOINT (1)
|
||||
#define T_WATCHPOINT (2)
|
||||
typedef vm_offset_t db_addr_t;
|
||||
typedef int db_expr_t;
|
||||
|
||||
@ -48,11 +50,16 @@ typedef int db_expr_t;
|
||||
kdb_frame->tf_pc += BKPT_SIZE; \
|
||||
} while (0)
|
||||
|
||||
#define SOFTWARE_SSTEP 1
|
||||
#if __ARM_ARCH >= 6
|
||||
#define db_clear_single_step kdb_cpu_clear_singlestep
|
||||
#define db_set_single_step kdb_cpu_set_singlestep
|
||||
#define db_pc_is_singlestep kdb_cpu_pc_is_singlestep
|
||||
#else
|
||||
#define SOFTWARE_SSTEP 1
|
||||
#endif
|
||||
|
||||
#define IS_BREAKPOINT_TRAP(type, code) (type == T_BREAKPOINT)
|
||||
#define IS_WATCHPOINT_TRAP(type, code) (0)
|
||||
|
||||
#define IS_WATCHPOINT_TRAP(type, code) (type == T_WATCHPOINT)
|
||||
|
||||
#define inst_trap_return(ins) (0)
|
||||
/* ldmxx reg, {..., pc}
|
||||
|
80
sys/arm/include/debug_monitor.h
Normal file
80
sys/arm/include/debug_monitor.h
Normal file
@ -0,0 +1,80 @@
|
||||
/*-
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Semihalf under
|
||||
* the sponsorship of the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_DEBUG_MONITOR_H_
|
||||
#define _MACHINE_DEBUG_MONITOR_H_
|
||||
|
||||
#ifdef DDB
|
||||
|
||||
#include <machine/db_machdep.h>
|
||||
|
||||
enum dbg_access_t {
|
||||
HW_BREAKPOINT_X = 0,
|
||||
HW_WATCHPOINT_R = 1,
|
||||
HW_WATCHPOINT_W = 2,
|
||||
HW_WATCHPOINT_RW = HW_WATCHPOINT_R | HW_WATCHPOINT_W,
|
||||
};
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
void dbg_monitor_init(void);
|
||||
void dbg_show_watchpoint(void);
|
||||
int dbg_setup_watchpoint(db_expr_t, db_expr_t, enum dbg_access_t);
|
||||
int dbg_remove_watchpoint(db_expr_t, db_expr_t);
|
||||
#else /* __ARM_ARCH >= 6 */
|
||||
static __inline void
|
||||
dbg_show_watchpoint(void)
|
||||
{
|
||||
}
|
||||
static __inline int
|
||||
dbg_setup_watchpoint(db_expr_t addr __unused, db_expr_t size __unused,
|
||||
enum dbg_access_t access __unused)
|
||||
{
|
||||
return (ENXIO);
|
||||
}
|
||||
static __inline int
|
||||
dbg_remove_watchpoint(db_expr_t addr __unused, db_expr_t size __unused)
|
||||
{
|
||||
return (ENXIO);
|
||||
}
|
||||
static __inline void
|
||||
dbg_monitor_init(void)
|
||||
{
|
||||
}
|
||||
#endif /* __ARM_ARCH < 6 */
|
||||
|
||||
#else /* DDB */
|
||||
static __inline void
|
||||
dbg_monitor_init(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _MACHINE_DEBUG_MONITOR_H_ */
|
@ -32,9 +32,15 @@
|
||||
#include <machine/frame.h>
|
||||
#include <machine/psl.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/db_machdep.h>
|
||||
|
||||
#define KDB_STOPPEDPCB(pc) &stoppcbs[pc->pc_cpuid]
|
||||
|
||||
#if __ARM_ARCH >= 6
|
||||
extern void kdb_cpu_clear_singlestep(void);
|
||||
extern void kdb_cpu_set_singlestep(void);
|
||||
boolean_t kdb_cpu_pc_is_singlestep(db_addr_t);
|
||||
#else
|
||||
static __inline void
|
||||
kdb_cpu_clear_singlestep(void)
|
||||
{
|
||||
@ -44,6 +50,7 @@ static __inline void
|
||||
kdb_cpu_set_singlestep(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static __inline void
|
||||
kdb_cpu_sync_icache(unsigned char *addr, size_t size)
|
||||
|
@ -40,8 +40,8 @@
|
||||
typedef uint32_t cell_t;
|
||||
|
||||
struct mem_region {
|
||||
vm_offset_t mr_start;
|
||||
vm_size_t mr_size;
|
||||
uint64_t mr_start;
|
||||
uint64_t mr_size;
|
||||
};
|
||||
|
||||
#endif /* _MACHINE_OFW_MACHDEP_H_ */
|
||||
|
@ -52,7 +52,7 @@ extern vm_paddr_t arm_physmem_kernaddr;
|
||||
#define EXFLAG_NODUMP 0x01
|
||||
#define EXFLAG_NOALLOC 0x02
|
||||
|
||||
void arm_physmem_hardware_region(vm_paddr_t pa, vm_size_t sz);
|
||||
void arm_physmem_hardware_region(uint64_t pa, uint64_t sz);
|
||||
void arm_physmem_exclude_region(vm_paddr_t pa, vm_size_t sz, uint32_t flags);
|
||||
void arm_physmem_init_kernel_globals(void);
|
||||
void arm_physmem_print_tables(void);
|
||||
|
@ -200,6 +200,8 @@ void pmap_tlb_flush_range(pmap_t , vm_offset_t , vm_size_t );
|
||||
void pmap_dcache_wb_range(vm_paddr_t , vm_size_t , vm_memattr_t );
|
||||
|
||||
vm_paddr_t pmap_kextract(vm_offset_t );
|
||||
vm_paddr_t pmap_dump_kextract(vm_offset_t, pt2_entry_t *);
|
||||
|
||||
int pmap_fault(pmap_t , vm_offset_t , uint32_t , int , bool);
|
||||
#define vtophys(va) pmap_kextract((vm_offset_t)(va))
|
||||
|
||||
|
@ -263,6 +263,7 @@ void pmap_kremove_device(vm_offset_t, vm_size_t);
|
||||
void *pmap_kenter_temporary(vm_paddr_t pa, int i);
|
||||
void pmap_kenter_user(vm_offset_t va, vm_paddr_t pa);
|
||||
vm_paddr_t pmap_kextract(vm_offset_t va);
|
||||
vm_paddr_t pmap_dump_kextract(vm_offset_t, pt2_entry_t *);
|
||||
void pmap_kremove(vm_offset_t);
|
||||
void *pmap_mapdev(vm_offset_t, vm_size_t);
|
||||
void pmap_unmapdev(vm_offset_t, vm_size_t);
|
||||
|
@ -43,6 +43,7 @@
|
||||
#ifndef LOCORE
|
||||
typedef uint32_t pd_entry_t; /* page directory entry */
|
||||
typedef uint32_t pt_entry_t; /* page table entry */
|
||||
typedef pt_entry_t pt2_entry_t; /* compatibility with v6 */
|
||||
#endif
|
||||
|
||||
#define PG_FRAME 0xfffff000
|
||||
|
@ -41,6 +41,24 @@
|
||||
|
||||
#include <machine/acle-compat.h>
|
||||
|
||||
/*
|
||||
* CP14 registers
|
||||
*/
|
||||
#if __ARM_ARCH >= 6
|
||||
|
||||
#define CP14_DBGDIDR(rr) p14, 0, rr, c0, c0, 0 /* Debug ID Register */
|
||||
#define CP14_DBGDSCRext_V6(rr) p14, 0, rr, c0, c1, 0 /* Debug Status and Ctrl Register v6 */
|
||||
#define CP14_DBGDSCRext_V7(rr) p14, 0, rr, c0, c2, 2 /* Debug Status and Ctrl Register v7 */
|
||||
#define CP14_DBGVCR(rr) p14, 0, rr, c0, c7, 0 /* Vector Catch Register */
|
||||
#define CP14_DBGOSLAR(rr) p14, 0, rr, c1, c0, 4 /* OS Lock Access Register */
|
||||
#define CP14_DBGOSLSR(rr) p14, 0, rr, c1, c1, 4 /* OS Lock Status Register */
|
||||
#define CP14_DBGOSDLR(rr) p14, 0, rr, c1, c3, 4 /* OS Double Lock Register */
|
||||
#define CP14_DBGPRSR(rr) p14, 0, rr, c1, c5, 4 /* Device Powerdown and Reset Status */
|
||||
|
||||
#define CP14_DBGDSCRint(rr) CP14_DBGDSCRext_V6(rr) /* Debug Status and Ctrl internal view */
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* CP15 C0 registers
|
||||
*/
|
||||
|
@ -355,22 +355,6 @@ DEFINE_CLASS_0(gic, arm_gic_driver, arm_gic_methods,
|
||||
#define GICv2M_MSI_SETSPI_NS 0x040
|
||||
#define GICV2M_MSI_IIDR 0xFCC
|
||||
|
||||
struct gicv2m_softc {
|
||||
struct resource *sc_mem;
|
||||
struct mtx sc_mutex;
|
||||
u_int sc_spi_start;
|
||||
u_int sc_spi_count;
|
||||
u_int sc_spi_offset;
|
||||
};
|
||||
|
||||
static int
|
||||
gicv2m_probe(device_t dev)
|
||||
{
|
||||
|
||||
device_set_desc(dev, "ARM Generic Interrupt Controller MSI/MSIX");
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
|
||||
static int
|
||||
gicv2m_attach(device_t dev)
|
||||
{
|
||||
@ -478,7 +462,6 @@ gicv2m_map_msi(device_t dev, device_t pci_dev, int irq, uint64_t *addr,
|
||||
|
||||
static device_method_t arm_gicv2m_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, gicv2m_probe),
|
||||
DEVMETHOD(device_attach, gicv2m_attach),
|
||||
|
||||
/* MSI/MSI-X */
|
||||
@ -489,9 +472,5 @@ static device_method_t arm_gicv2m_methods[] = {
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static devclass_t arm_gicv2m_devclass;
|
||||
|
||||
DEFINE_CLASS_0(gicv2m, arm_gicv2m_driver, arm_gicv2m_methods,
|
||||
sizeof(struct gicv2m_softc));
|
||||
EARLY_DRIVER_MODULE(gicv2m, gic, arm_gicv2m_driver, arm_gicv2m_devclass,
|
||||
0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
|
||||
|
@ -51,6 +51,16 @@ struct arm_gic_softc {
|
||||
uint32_t nirqs;
|
||||
};
|
||||
|
||||
DECLARE_CLASS(arm_gicv2m_driver);
|
||||
|
||||
struct gicv2m_softc {
|
||||
struct resource *sc_mem;
|
||||
struct mtx sc_mutex;
|
||||
u_int sc_spi_start;
|
||||
u_int sc_spi_count;
|
||||
u_int sc_spi_offset;
|
||||
};
|
||||
|
||||
int arm_gic_attach(device_t);
|
||||
|
||||
#endif
|
||||
|
@ -290,3 +290,38 @@ EARLY_DRIVER_MODULE(gic, simplebus, arm_gic_fdt_driver,
|
||||
arm_gic_fdt_devclass, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
|
||||
EARLY_DRIVER_MODULE(gic, ofwbus, arm_gic_fdt_driver, arm_gic_fdt_devclass,
|
||||
0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
|
||||
|
||||
static struct ofw_compat_data gicv2m_compat_data[] = {
|
||||
{"arm,gic-v2m-frame", true},
|
||||
{NULL, false}
|
||||
};
|
||||
|
||||
static int
|
||||
arm_gicv2m_fdt_probe(device_t dev)
|
||||
{
|
||||
|
||||
if (!ofw_bus_status_okay(dev))
|
||||
return (ENXIO);
|
||||
|
||||
if (!ofw_bus_search_compatible(dev, gicv2m_compat_data)->ocd_data)
|
||||
return (ENXIO);
|
||||
|
||||
device_set_desc(dev, "ARM Generic Interrupt Controller MSI/MSIX");
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
|
||||
static device_method_t arm_gicv2m_fdt_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, arm_gicv2m_fdt_probe),
|
||||
|
||||
/* End */
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
DEFINE_CLASS_1(gicv2m, arm_gicv2m_fdt_driver, arm_gicv2m_fdt_methods,
|
||||
sizeof(struct gicv2m_softc), arm_gicv2m_driver);
|
||||
|
||||
static devclass_t arm_gicv2m_fdt_devclass;
|
||||
|
||||
EARLY_DRIVER_MODULE(gicv2m, gic, arm_gicv2m_fdt_driver,
|
||||
arm_gicv2m_fdt_devclass, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
|
||||
|
@ -84,7 +84,7 @@ static device_method_t gic_v3_methods[] = {
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
DEFINE_CLASS_0(gic_v3, gic_v3_driver, gic_v3_methods,
|
||||
DEFINE_CLASS_0(gic, gic_v3_driver, gic_v3_methods,
|
||||
sizeof(struct gic_v3_softc));
|
||||
|
||||
/*
|
||||
|
@ -78,7 +78,7 @@ static device_method_t gic_v3_fdt_methods[] = {
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
DEFINE_CLASS_1(gic_v3, gic_v3_fdt_driver, gic_v3_fdt_methods,
|
||||
DEFINE_CLASS_1(gic, gic_v3_fdt_driver, gic_v3_fdt_methods,
|
||||
sizeof(struct gic_v3_softc), gic_v3_driver);
|
||||
|
||||
static devclass_t gic_v3_fdt_devclass;
|
||||
@ -287,12 +287,12 @@ static device_method_t gic_v3_its_fdt_methods[] = {
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
DEFINE_CLASS_1(gic_v3_its, gic_v3_its_fdt_driver, gic_v3_its_fdt_methods,
|
||||
DEFINE_CLASS_1(its, gic_v3_its_fdt_driver, gic_v3_its_fdt_methods,
|
||||
sizeof(struct gic_v3_its_softc), gic_v3_its_driver);
|
||||
|
||||
static devclass_t gic_v3_its_fdt_devclass;
|
||||
|
||||
EARLY_DRIVER_MODULE(gic_v3_its, gic_v3, gic_v3_its_fdt_driver,
|
||||
EARLY_DRIVER_MODULE(its, gic, gic_v3_its_fdt_driver,
|
||||
gic_v3_its_fdt_devclass, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
|
||||
|
||||
static int
|
||||
|
@ -82,7 +82,7 @@ static device_method_t gic_v3_its_methods[] = {
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
DEFINE_CLASS_0(gic_v3_its, gic_v3_its_driver, gic_v3_its_methods,
|
||||
DEFINE_CLASS_0(its, gic_v3_its_driver, gic_v3_its_methods,
|
||||
sizeof(struct gic_v3_its_softc));
|
||||
|
||||
MALLOC_DEFINE(M_GIC_V3_ITS, "GICv3 ITS", GIC_V3_ITS_DEVSTR);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2008 John Hay
|
||||
* Copyright (c) 2006 Warner Losh
|
||||
* Copyright (c) 2006 M Warner Losh <imp@freebsd.org>
|
||||
* Copyright (c) 1998 Robert Nordier
|
||||
* All rights reserved.
|
||||
*
|
||||
@ -30,52 +30,16 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include "lib.h"
|
||||
#include "board.h"
|
||||
#include "paths.h"
|
||||
#include "rbx.h"
|
||||
|
||||
#define RBX_ASKNAME 0x0 /* -a */
|
||||
#define RBX_SINGLE 0x1 /* -s */
|
||||
/* 0x2 is reserved for log2(RB_NOSYNC). */
|
||||
/* 0x3 is reserved for log2(RB_HALT). */
|
||||
/* 0x4 is reserved for log2(RB_INITNAME). */
|
||||
#define RBX_DFLTROOT 0x5 /* -r */
|
||||
/* #define RBX_KDB 0x6 -d */
|
||||
/* 0x7 is reserved for log2(RB_RDONLY). */
|
||||
/* 0x8 is reserved for log2(RB_DUMP). */
|
||||
/* 0x9 is reserved for log2(RB_MINIROOT). */
|
||||
#define RBX_CONFIG 0xa /* -c */
|
||||
#define RBX_VERBOSE 0xb /* -v */
|
||||
/* #define RBX_SERIAL 0xc -h */
|
||||
/* #define RBX_CDROM 0xd -C */
|
||||
/* 0xe is reserved for log2(RB_POWEROFF). */
|
||||
#define RBX_GDB 0xf /* -g */
|
||||
/* #define RBX_MUTE 0x10 -m */
|
||||
/* 0x11 is reserved for log2(RB_SELFTEST). */
|
||||
/* 0x12 is reserved for boot programs. */
|
||||
/* 0x13 is reserved for boot programs. */
|
||||
/* #define RBX_PAUSE 0x14 -p */
|
||||
/* #define RBX_QUIET 0x15 -q */
|
||||
#define RBX_NOINTR 0x1c /* -n */
|
||||
/* 0x1d is reserved for log2(RB_MULTIPLE) and is just misnamed here. */
|
||||
/* #define RBX_DUAL 0x1d -D */
|
||||
/* 0x1f is reserved for log2(RB_BOOTINFO). */
|
||||
|
||||
/* pass: -a, -s, -r, -v, -g */
|
||||
#define RBX_MASK (OPT_SET(RBX_ASKNAME) | OPT_SET(RBX_SINGLE) | \
|
||||
OPT_SET(RBX_DFLTROOT) | \
|
||||
OPT_SET(RBX_VERBOSE) | \
|
||||
OPT_SET(RBX_GDB))
|
||||
|
||||
#define PATH_DOTCONFIG "/boot.config"
|
||||
#define PATH_CONFIG "/boot/config"
|
||||
//#define PATH_KERNEL "/boot/kernel/kernel"
|
||||
#undef PATH_KERNEL
|
||||
#define PATH_KERNEL "/boot/kernel/kernel.gz.tramp"
|
||||
|
||||
extern uint32_t _end;
|
||||
|
||||
#define NOPT 6
|
||||
|
||||
#define OPT_SET(opt) (1 << (opt))
|
||||
#define OPT_CHECK(opt) ((opts) & OPT_SET(opt))
|
||||
|
||||
static const char optstr[NOPT] = "agnrsv";
|
||||
static const unsigned char bootflags[NOPT] = {
|
||||
RBX_ASKNAME,
|
||||
|
@ -28,51 +28,13 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "lib.h"
|
||||
|
||||
#define RBX_ASKNAME 0x0 /* -a */
|
||||
#define RBX_SINGLE 0x1 /* -s */
|
||||
/* 0x2 is reserved for log2(RB_NOSYNC). */
|
||||
/* 0x3 is reserved for log2(RB_HALT). */
|
||||
/* 0x4 is reserved for log2(RB_INITNAME). */
|
||||
#define RBX_DFLTROOT 0x5 /* -r */
|
||||
/* #define RBX_KDB 0x6 -d */
|
||||
/* 0x7 is reserved for log2(RB_RDONLY). */
|
||||
/* 0x8 is reserved for log2(RB_DUMP). */
|
||||
/* 0x9 is reserved for log2(RB_MINIROOT). */
|
||||
#define RBX_CONFIG 0xa /* -c */
|
||||
#define RBX_VERBOSE 0xb /* -v */
|
||||
/* #define RBX_SERIAL 0xc -h */
|
||||
/* #define RBX_CDROM 0xd -C */
|
||||
/* 0xe is reserved for log2(RB_POWEROFF). */
|
||||
#define RBX_GDB 0xf /* -g */
|
||||
/* #define RBX_MUTE 0x10 -m */
|
||||
/* 0x11 is reserved for log2(RB_SELFTEST). */
|
||||
/* 0x12 is reserved for boot programs. */
|
||||
/* 0x13 is reserved for boot programs. */
|
||||
/* #define RBX_PAUSE 0x14 -p */
|
||||
/* #define RBX_QUIET 0x15 -q */
|
||||
#define RBX_NOINTR 0x1c /* -n */
|
||||
/* 0x1d is reserved for log2(RB_MULTIPLE) and is just misnamed here. */
|
||||
/* #define RBX_DUAL 0x1d -D */
|
||||
/* 0x1f is reserved for log2(RB_BOOTINFO). */
|
||||
|
||||
/* pass: -a, -s, -r, -v, -g */
|
||||
#define RBX_MASK (OPT_SET(RBX_ASKNAME) | OPT_SET(RBX_SINGLE) | \
|
||||
OPT_SET(RBX_DFLTROOT) | \
|
||||
OPT_SET(RBX_VERBOSE) | \
|
||||
OPT_SET(RBX_GDB))
|
||||
|
||||
#define PATH_DOTCONFIG "/boot.config"
|
||||
#define PATH_CONFIG "/boot/config"
|
||||
#define PATH_KERNEL "/boot/kernel/kernel"
|
||||
#include "paths.h"
|
||||
#include "rbx.h"
|
||||
|
||||
extern uint32_t _end;
|
||||
|
||||
#define NOPT 6
|
||||
|
||||
#define OPT_SET(opt) (1 << (opt))
|
||||
#define OPT_CHECK(opt) ((opts) & OPT_SET(opt))
|
||||
|
||||
static const char optstr[NOPT] = "agnrsv";
|
||||
static const unsigned char flags[NOPT] = {
|
||||
RBX_ASKNAME,
|
||||
|
39
sys/boot/common/paths.h
Normal file
39
sys/boot/common/paths.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*-
|
||||
* Copyright (c) 2016 M. Warner Losh <imp@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 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$
|
||||
*/
|
||||
|
||||
#ifndef _PATHS_H_
|
||||
#define _PATHS_H_
|
||||
|
||||
#define PATH_DOTCONFIG "/boot.config"
|
||||
#define PATH_CONFIG "/boot/config"
|
||||
#define PATH_BOOT3 "/boot/loader"
|
||||
#define PATH_LOADER "/boot/loader"
|
||||
#define PATH_LOADER_EFI "/boot/loader.efi"
|
||||
#define PATH_KERNEL "/boot/kernel/kernel"
|
||||
|
||||
#endif /* _PATHS_H_ */
|
@ -31,8 +31,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <eficonsctl.h>
|
||||
|
||||
#include "boot_module.h"
|
||||
|
||||
#define _PATH_LOADER "/boot/loader.efi"
|
||||
#include "paths.h"
|
||||
|
||||
static const boot_module_t *boot_modules[] =
|
||||
{
|
||||
@ -92,20 +91,48 @@ Free(void *buf, const char *file __unused, int line __unused)
|
||||
void
|
||||
try_load(const boot_module_t *mod)
|
||||
{
|
||||
size_t bufsize;
|
||||
size_t bufsize, cmdsize;
|
||||
void *buf;
|
||||
char *cmd;
|
||||
dev_info_t *dev;
|
||||
EFI_HANDLE loaderhandle;
|
||||
EFI_LOADED_IMAGE *loaded_image;
|
||||
EFI_STATUS status;
|
||||
|
||||
status = mod->load(_PATH_LOADER, &dev, &buf, &bufsize);
|
||||
/*
|
||||
* Read in and parse the command line from /boot.config or /boot/config,
|
||||
* if present. We'll pass it the next stage via a simple ASCII
|
||||
* string. loader.efi has a hack for ASCII strings, so we'll use that to
|
||||
* keep the size down here. We only try to read the alternate file if
|
||||
* we get EFI_NOT_FOUND because all other errors mean that the boot_module
|
||||
* had troubles with the filesystem. We could return early, but we'll let
|
||||
* loading the actual kernel sort all that out. Since these files are
|
||||
* optional, we don't report errors in trying to read them.
|
||||
*/
|
||||
cmd = NULL;
|
||||
cmdsize = 0;
|
||||
status = mod->load(PATH_DOTCONFIG, &dev, &buf, &bufsize);
|
||||
if (status == EFI_NOT_FOUND)
|
||||
status = mod->load(PATH_CONFIG, &dev, &buf, &bufsize);
|
||||
if (status == EFI_SUCCESS) {
|
||||
cmdsize = bufsize + 1;
|
||||
cmd = malloc(cmdsize);
|
||||
if (cmd == NULL) {
|
||||
free(buf);
|
||||
return;
|
||||
}
|
||||
memcpy(cmd, buf, bufsize);
|
||||
cmd[bufsize] = '\0';
|
||||
free(buf);
|
||||
}
|
||||
|
||||
status = mod->load(PATH_LOADER_EFI, &dev, &buf, &bufsize);
|
||||
if (status == EFI_NOT_FOUND)
|
||||
return;
|
||||
|
||||
if (status != EFI_SUCCESS) {
|
||||
printf("%s failed to load %s (%lu)\n", mod->name, _PATH_LOADER,
|
||||
EFI_ERROR_CODE(status));
|
||||
printf("%s failed to load %s (%lu)\n", mod->name,
|
||||
PATH_LOADER_EFI, EFI_ERROR_CODE(status));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -116,6 +143,9 @@ try_load(const boot_module_t *mod)
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmd != NULL)
|
||||
printf(" command args: %s\n", cmd);
|
||||
|
||||
if ((status = bs->HandleProtocol(loaderhandle, &LoadedImageGUID,
|
||||
(VOID**)&loaded_image)) != EFI_SUCCESS) {
|
||||
printf("Failed to query LoadedImage provided by %s (%lu)\n",
|
||||
@ -124,11 +154,16 @@ try_load(const boot_module_t *mod)
|
||||
}
|
||||
|
||||
loaded_image->DeviceHandle = dev->devhandle;
|
||||
loaded_image->LoadOptionsSize = cmdsize;
|
||||
loaded_image->LoadOptions = cmd;
|
||||
|
||||
if ((status = bs->StartImage(loaderhandle, NULL, NULL)) !=
|
||||
EFI_SUCCESS) {
|
||||
printf("Failed to start image provided by %s (%lu)\n",
|
||||
mod->name, EFI_ERROR_CODE(status));
|
||||
free(cmd);
|
||||
loaded_image->LoadOptionsSize = 0;
|
||||
loaded_image->LoadOptions = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -174,7 +209,7 @@ efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab)
|
||||
conout->ClearScreen(conout);
|
||||
|
||||
printf("\n>> FreeBSD EFI boot block\n");
|
||||
printf(" Loader path: %s\n\n", _PATH_LOADER);
|
||||
printf(" Loader path: %s\n\n", PATH_LOADER_EFI);
|
||||
printf(" Initializing modules:");
|
||||
for (i = 0; i < NUM_BOOT_MODULES; i++) {
|
||||
if (boot_modules[i] == NULL)
|
||||
|
@ -44,7 +44,7 @@ static CHAR16 *
|
||||
arg_skipsep(CHAR16 *argp)
|
||||
{
|
||||
|
||||
while (*argp == ' ' || *argp == '\t')
|
||||
while (*argp == ' ' || *argp == '\t' || *argp == '\n')
|
||||
argp++;
|
||||
return (argp);
|
||||
}
|
||||
@ -53,7 +53,7 @@ static CHAR16 *
|
||||
arg_skipword(CHAR16 *argp)
|
||||
{
|
||||
|
||||
while (*argp && *argp != ' ' && *argp != '\t')
|
||||
while (*argp && *argp != ' ' && *argp != '\t' && *argp != '\n')
|
||||
argp++;
|
||||
return (argp);
|
||||
}
|
||||
|
@ -29,6 +29,8 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/boot.h>
|
||||
#include <stand.h>
|
||||
#include <string.h>
|
||||
#include <setjmp.h>
|
||||
@ -83,13 +85,22 @@ print_str16(const CHAR16 *str)
|
||||
printf("%c", (char)str[i]);
|
||||
}
|
||||
|
||||
static void
|
||||
cp16to8(const CHAR16 *src, char *dst, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < len && src[i]; i++)
|
||||
dst[i] = (char)src[i];
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
main(int argc, CHAR16 *argv[])
|
||||
{
|
||||
char var[128];
|
||||
EFI_LOADED_IMAGE *img;
|
||||
EFI_GUID *guid;
|
||||
int i, j, vargood, unit;
|
||||
int i, j, vargood, unit, howto;
|
||||
struct devsw *dev;
|
||||
uint64_t pool_guid;
|
||||
UINTN k;
|
||||
@ -113,27 +124,97 @@ main(int argc, CHAR16 *argv[])
|
||||
cons_probe();
|
||||
|
||||
/*
|
||||
* Parse the args to set the console settings, etc
|
||||
* boot1.efi passes these in, if it can read /boot.config or /boot/config
|
||||
* or iPXE may be setup to pass these in.
|
||||
*
|
||||
* Loop through the args, and for each one that contains an '=' that is
|
||||
* not the first character, add it to the environment. This allows
|
||||
* loader and kernel env vars to be passed on the command line. Convert
|
||||
* args from UCS-2 to ASCII (16 to 8 bit) as they are copied.
|
||||
*/
|
||||
howto = 0;
|
||||
for (i = 1; i < argc; i++) {
|
||||
vargood = 0;
|
||||
for (j = 0; argv[i][j] != 0; j++) {
|
||||
if (j == sizeof(var)) {
|
||||
vargood = 0;
|
||||
break;
|
||||
if (argv[i][0] == '-') {
|
||||
for (j = 1; argv[i][j] != 0; j++) {
|
||||
int ch;
|
||||
|
||||
ch = argv[i][j];
|
||||
switch (ch) {
|
||||
case 'a':
|
||||
howto |= RB_ASKNAME;
|
||||
break;
|
||||
case 'd':
|
||||
howto |= RB_KDB;
|
||||
break;
|
||||
case 'D':
|
||||
howto |= RB_MULTIPLE;
|
||||
break;
|
||||
case 'm':
|
||||
howto |= RB_MUTE;
|
||||
break;
|
||||
case 'h':
|
||||
howto |= RB_SERIAL;
|
||||
break;
|
||||
case 'p':
|
||||
howto |= RB_PAUSE;
|
||||
break;
|
||||
case 'r':
|
||||
howto |= RB_DFLTROOT;
|
||||
break;
|
||||
case 's':
|
||||
howto |= RB_SINGLE;
|
||||
break;
|
||||
case 'S':
|
||||
if (argv[i][j + 1] == 0) {
|
||||
if (i + 1 == argc) {
|
||||
setenv("comconsole_speed", "115200", 1);
|
||||
} else {
|
||||
cp16to8(&argv[i + 1][0], var,
|
||||
sizeof(var));
|
||||
setenv("comconsole_speedspeed", var, 1);
|
||||
}
|
||||
i++;
|
||||
break;
|
||||
} else {
|
||||
cp16to8(&argv[i][j + 1], var,
|
||||
sizeof(var));
|
||||
setenv("comconsole_speed", var, 1);
|
||||
break;
|
||||
}
|
||||
case 'v':
|
||||
howto |= RB_VERBOSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
vargood = 0;
|
||||
for (j = 0; argv[i][j] != 0; j++) {
|
||||
if (j == sizeof(var)) {
|
||||
vargood = 0;
|
||||
break;
|
||||
}
|
||||
if (j > 0 && argv[i][j] == '=')
|
||||
vargood = 1;
|
||||
var[j] = (char)argv[i][j];
|
||||
}
|
||||
if (vargood) {
|
||||
var[j] = 0;
|
||||
putenv(var);
|
||||
}
|
||||
if (j > 0 && argv[i][j] == '=')
|
||||
vargood = 1;
|
||||
var[j] = (char)argv[i][j];
|
||||
}
|
||||
if (vargood) {
|
||||
var[j] = 0;
|
||||
putenv(var);
|
||||
}
|
||||
}
|
||||
for (i = 0; howto_names[i].ev != NULL; i++)
|
||||
if (howto & howto_names[i].mask)
|
||||
setenv(howto_names[i].ev, "YES", 1);
|
||||
if (howto & RB_MULTIPLE) {
|
||||
if (howto & RB_SERIAL)
|
||||
setenv("console", "comconsole efi" , 1);
|
||||
else
|
||||
setenv("console", "efi comconsole" , 1);
|
||||
} else if (howto & RB_SERIAL) {
|
||||
setenv("console", "comconsole" , 1);
|
||||
}
|
||||
|
||||
if (efi_copy_init()) {
|
||||
printf("failed to allocate staging area\n");
|
||||
|
@ -33,6 +33,8 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include "boot2.h"
|
||||
#include "lib.h"
|
||||
#include "paths.h"
|
||||
#include "rbx.h"
|
||||
|
||||
/* Define to 0 to omit serial support */
|
||||
#ifndef SERIAL
|
||||
@ -52,46 +54,6 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#define SECOND 18 /* Circa that many ticks in a second. */
|
||||
|
||||
#define RBX_ASKNAME 0x0 /* -a */
|
||||
#define RBX_SINGLE 0x1 /* -s */
|
||||
/* 0x2 is reserved for log2(RB_NOSYNC). */
|
||||
/* 0x3 is reserved for log2(RB_HALT). */
|
||||
/* 0x4 is reserved for log2(RB_INITNAME). */
|
||||
#define RBX_DFLTROOT 0x5 /* -r */
|
||||
#define RBX_KDB 0x6 /* -d */
|
||||
/* 0x7 is reserved for log2(RB_RDONLY). */
|
||||
/* 0x8 is reserved for log2(RB_DUMP). */
|
||||
/* 0x9 is reserved for log2(RB_MINIROOT). */
|
||||
#define RBX_CONFIG 0xa /* -c */
|
||||
#define RBX_VERBOSE 0xb /* -v */
|
||||
#define RBX_SERIAL 0xc /* -h */
|
||||
#define RBX_CDROM 0xd /* -C */
|
||||
/* 0xe is reserved for log2(RB_POWEROFF). */
|
||||
#define RBX_GDB 0xf /* -g */
|
||||
#define RBX_MUTE 0x10 /* -m */
|
||||
/* 0x11 is reserved for log2(RB_SELFTEST). */
|
||||
/* 0x12 is reserved for boot programs. */
|
||||
/* 0x13 is reserved for boot programs. */
|
||||
#define RBX_PAUSE 0x14 /* -p */
|
||||
#define RBX_QUIET 0x15 /* -q */
|
||||
#define RBX_NOINTR 0x1c /* -n */
|
||||
/* 0x1d is reserved for log2(RB_MULTIPLE) and is just misnamed here. */
|
||||
#define RBX_DUAL 0x1d /* -D */
|
||||
/* 0x1f is reserved for log2(RB_BOOTINFO). */
|
||||
|
||||
/* pass: -a, -s, -r, -d, -c, -v, -h, -C, -g, -m, -p, -D */
|
||||
#define RBX_MASK (OPT_SET(RBX_ASKNAME) | OPT_SET(RBX_SINGLE) | \
|
||||
OPT_SET(RBX_DFLTROOT) | OPT_SET(RBX_KDB ) | \
|
||||
OPT_SET(RBX_CONFIG) | OPT_SET(RBX_VERBOSE) | \
|
||||
OPT_SET(RBX_SERIAL) | OPT_SET(RBX_CDROM) | \
|
||||
OPT_SET(RBX_GDB ) | OPT_SET(RBX_MUTE) | \
|
||||
OPT_SET(RBX_PAUSE) | OPT_SET(RBX_DUAL))
|
||||
|
||||
#define PATH_DOTCONFIG "/boot.config"
|
||||
#define PATH_CONFIG "/boot/config"
|
||||
#define PATH_BOOT3 "/boot/loader"
|
||||
#define PATH_KERNEL "/boot/kernel/kernel"
|
||||
|
||||
#define ARGS 0x900
|
||||
#define NOPT 14
|
||||
#define NDEV 3
|
||||
@ -106,9 +68,6 @@ __FBSDID("$FreeBSD$");
|
||||
#define TYPE_MAXHARD TYPE_DA
|
||||
#define TYPE_FD 2
|
||||
|
||||
#define OPT_SET(opt) (1 << (opt))
|
||||
#define OPT_CHECK(opt) ((opts) & OPT_SET(opt))
|
||||
|
||||
extern uint32_t _end;
|
||||
|
||||
static const char optstr[NOPT] = "DhaCcdgmnpqrsv"; /* Also 'P', 'S' */
|
||||
@ -143,7 +102,7 @@ static struct dsk {
|
||||
} dsk;
|
||||
static char cmd[512], cmddup[512], knamebuf[1024];
|
||||
static const char *kname;
|
||||
static uint32_t opts;
|
||||
uint32_t opts;
|
||||
static struct bootinfo bootinfo;
|
||||
#if SERIAL
|
||||
static int comspeed = SIOSPD;
|
||||
|
@ -37,11 +37,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include "util.h"
|
||||
#include "cons.h"
|
||||
#include "gpt.h"
|
||||
|
||||
#define PATH_DOTCONFIG "/boot.config"
|
||||
#define PATH_CONFIG "/boot/config"
|
||||
#define PATH_BOOT3 "/boot/loader"
|
||||
#define PATH_KERNEL "/boot/kernel/kernel"
|
||||
#include "paths.h"
|
||||
|
||||
#define ARGS 0x900
|
||||
#define NOPT 14
|
||||
|
@ -42,14 +42,10 @@ __FBSDID("$FreeBSD$");
|
||||
#include "util.h"
|
||||
#include "cons.h"
|
||||
#include "bootargs.h"
|
||||
#include "paths.h"
|
||||
|
||||
#include "libzfs.h"
|
||||
|
||||
#define PATH_DOTCONFIG "/boot.config"
|
||||
#define PATH_CONFIG "/boot/config"
|
||||
#define PATH_BOOT3 "/boot/zfsloader"
|
||||
#define PATH_KERNEL "/boot/kernel/kernel"
|
||||
|
||||
#define ARGS 0x900
|
||||
#define NOPT 14
|
||||
#define NDEV 3
|
||||
|
@ -64,6 +64,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <mips.h>
|
||||
#include <sdcard.h>
|
||||
|
||||
#include "paths.h"
|
||||
#include "rbx.h"
|
||||
|
||||
static int beri_argc;
|
||||
static const char **beri_argv, **beri_envv;
|
||||
static uint64_t beri_memsize;
|
||||
@ -73,46 +76,6 @@ static uint64_t beri_memsize;
|
||||
|
||||
#define SECOND 1 /* Circa that many ticks in a second. */
|
||||
|
||||
#define RBX_ASKNAME 0x0 /* -a */
|
||||
#define RBX_SINGLE 0x1 /* -s */
|
||||
/* 0x2 is reserved for log2(RB_NOSYNC). */
|
||||
/* 0x3 is reserved for log2(RB_HALT). */
|
||||
/* 0x4 is reserved for log2(RB_INITNAME). */
|
||||
#define RBX_DFLTROOT 0x5 /* -r */
|
||||
#define RBX_KDB 0x6 /* -d */
|
||||
/* 0x7 is reserved for log2(RB_RDONLY). */
|
||||
/* 0x8 is reserved for log2(RB_DUMP). */
|
||||
/* 0x9 is reserved for log2(RB_MINIROOT). */
|
||||
#define RBX_CONFIG 0xa /* -c */
|
||||
#define RBX_VERBOSE 0xb /* -v */
|
||||
#define RBX_SERIAL 0xc /* -h */
|
||||
#define RBX_CDROM 0xd /* -C */
|
||||
/* 0xe is reserved for log2(RB_POWEROFF). */
|
||||
#define RBX_GDB 0xf /* -g */
|
||||
#define RBX_MUTE 0x10 /* -m */
|
||||
/* 0x11 is reserved for log2(RB_SELFTEST). */
|
||||
/* 0x12 is reserved for boot programs. */
|
||||
/* 0x13 is reserved for boot programs. */
|
||||
#define RBX_PAUSE 0x14 /* -p */
|
||||
#define RBX_QUIET 0x15 /* -q */
|
||||
#define RBX_NOINTR 0x1c /* -n */
|
||||
/* 0x1d is reserved for log2(RB_MULTIPLE) and is just misnamed here. */
|
||||
#define RBX_DUAL 0x1d /* -D */
|
||||
/* 0x1f is reserved for log2(RB_BOOTINFO). */
|
||||
|
||||
/* pass: -a, -s, -r, -d, -c, -v, -h, -C, -g, -m, -p, -D */
|
||||
#define RBX_MASK (OPT_SET(RBX_ASKNAME) | OPT_SET(RBX_SINGLE) | \
|
||||
OPT_SET(RBX_DFLTROOT) | OPT_SET(RBX_KDB ) | \
|
||||
OPT_SET(RBX_CONFIG) | OPT_SET(RBX_VERBOSE) | \
|
||||
OPT_SET(RBX_SERIAL) | OPT_SET(RBX_CDROM) | \
|
||||
OPT_SET(RBX_GDB ) | OPT_SET(RBX_MUTE) | \
|
||||
OPT_SET(RBX_PAUSE) | OPT_SET(RBX_DUAL))
|
||||
|
||||
#define PATH_DOTCONFIG "/boot.config"
|
||||
#define PATH_CONFIG "/boot/config"
|
||||
#define PATH_BOOT3 "/boot/loader"
|
||||
#define PATH_KERNEL "/boot/kernel/kernel"
|
||||
|
||||
#define ARGS 0x900
|
||||
#define NOPT 14
|
||||
#define MEM_BASE 0x12
|
||||
@ -131,9 +94,6 @@ static uint64_t beri_memsize;
|
||||
/* Hard-coded assumption about location of JTAG-loaded kernel. */
|
||||
#define DRAM_KERNEL_ADDR ((void *)mips_phys_to_cached(0x20000))
|
||||
|
||||
#define OPT_SET(opt) (1 << (opt))
|
||||
#define OPT_CHECK(opt) ((opts) & OPT_SET(opt))
|
||||
|
||||
extern uint32_t _end;
|
||||
|
||||
static const char optstr[NOPT] = "DhaCcdgmnpqrsv"; /* Also 'P', 'S' */
|
||||
|
@ -35,6 +35,8 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include "boot2.h"
|
||||
#include "lib.h"
|
||||
#include "paths.h"
|
||||
#include "rbx.h"
|
||||
|
||||
/* Define to 0 to omit serial support */
|
||||
#ifndef SERIAL
|
||||
@ -54,46 +56,6 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#define SECOND 1 /* Circa that many ticks in a second. */
|
||||
|
||||
#define RBX_ASKNAME 0x0 /* -a */
|
||||
#define RBX_SINGLE 0x1 /* -s */
|
||||
/* 0x2 is reserved for log2(RB_NOSYNC). */
|
||||
/* 0x3 is reserved for log2(RB_HALT). */
|
||||
/* 0x4 is reserved for log2(RB_INITNAME). */
|
||||
#define RBX_DFLTROOT 0x5 /* -r */
|
||||
#define RBX_KDB 0x6 /* -d */
|
||||
/* 0x7 is reserved for log2(RB_RDONLY). */
|
||||
/* 0x8 is reserved for log2(RB_DUMP). */
|
||||
/* 0x9 is reserved for log2(RB_MINIROOT). */
|
||||
#define RBX_CONFIG 0xa /* -c */
|
||||
#define RBX_VERBOSE 0xb /* -v */
|
||||
#define RBX_SERIAL 0xc /* -h */
|
||||
#define RBX_CDROM 0xd /* -C */
|
||||
/* 0xe is reserved for log2(RB_POWEROFF). */
|
||||
#define RBX_GDB 0xf /* -g */
|
||||
#define RBX_MUTE 0x10 /* -m */
|
||||
/* 0x11 is reserved for log2(RB_SELFTEST). */
|
||||
/* 0x12 is reserved for boot programs. */
|
||||
/* 0x13 is reserved for boot programs. */
|
||||
#define RBX_PAUSE 0x14 /* -p */
|
||||
#define RBX_QUIET 0x15 /* -q */
|
||||
#define RBX_NOINTR 0x1c /* -n */
|
||||
/* 0x1d is reserved for log2(RB_MULTIPLE) and is just misnamed here. */
|
||||
#define RBX_DUAL 0x1d /* -D */
|
||||
/* 0x1f is reserved for log2(RB_BOOTINFO). */
|
||||
|
||||
/* pass: -a, -s, -r, -d, -c, -v, -h, -C, -g, -m, -p, -D */
|
||||
#define RBX_MASK (OPT_SET(RBX_ASKNAME) | OPT_SET(RBX_SINGLE) | \
|
||||
OPT_SET(RBX_DFLTROOT) | OPT_SET(RBX_KDB ) | \
|
||||
OPT_SET(RBX_CONFIG) | OPT_SET(RBX_VERBOSE) | \
|
||||
OPT_SET(RBX_SERIAL) | OPT_SET(RBX_CDROM) | \
|
||||
OPT_SET(RBX_GDB ) | OPT_SET(RBX_MUTE) | \
|
||||
OPT_SET(RBX_PAUSE) | OPT_SET(RBX_DUAL))
|
||||
|
||||
#define PATH_DOTCONFIG "/boot.config"
|
||||
#define PATH_CONFIG "/boot/config"
|
||||
#define PATH_BOOT3 "/boot/loader"
|
||||
#define PATH_KERNEL "/boot/kernel/kernel"
|
||||
|
||||
#define ARGS 0x900
|
||||
#define NOPT 14
|
||||
#define NDEV 3
|
||||
@ -105,9 +67,6 @@ __FBSDID("$FreeBSD$");
|
||||
#define TYPE_DA 1
|
||||
#define TYPE_FD 2
|
||||
|
||||
#define OPT_SET(opt) (1 << (opt))
|
||||
#define OPT_CHECK(opt) ((opts) & OPT_SET(opt))
|
||||
|
||||
extern uint32_t _end;
|
||||
|
||||
static const char optstr[NOPT] = "DhaCcdgmnpqrsv"; /* Also 'P', 'S' */
|
||||
|
@ -23,8 +23,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/elf.h>
|
||||
#include <machine/stdarg.h>
|
||||
|
||||
#define _PATH_LOADER "/boot/loader"
|
||||
#define _PATH_KERNEL "/boot/kernel/kernel"
|
||||
#include "paths.h"
|
||||
|
||||
#define BSIZEMAX 16384
|
||||
|
||||
@ -396,7 +395,7 @@ main(int ac, char **av)
|
||||
char bootpath_full[255];
|
||||
int i, len;
|
||||
|
||||
path = _PATH_LOADER;
|
||||
path = PATH_LOADER;
|
||||
for (i = 0; i < ac; i++) {
|
||||
switch (av[i][0]) {
|
||||
case '-':
|
||||
|
@ -24,8 +24,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/elf.h>
|
||||
#include <machine/stdarg.h>
|
||||
|
||||
#define _PATH_LOADER "/boot/loader"
|
||||
#define _PATH_KERNEL "/boot/kernel/kernel"
|
||||
#include "paths.h"
|
||||
|
||||
#define READ_BUF_SIZE 8192
|
||||
|
||||
typedef int putc_func_t(char c, void *arg);
|
||||
@ -324,7 +324,7 @@ main(int ac, char **av)
|
||||
const char *path;
|
||||
int i;
|
||||
|
||||
path = _PATH_LOADER;
|
||||
path = PATH_LOADER;
|
||||
for (i = 0; i < ac; i++) {
|
||||
switch (av[i][0]) {
|
||||
case '-':
|
||||
|
@ -1,7 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= sysinit
|
||||
NO_MAN=
|
||||
MAN=
|
||||
|
||||
CFLAGS+= -I${.CURDIR}/../../kshim
|
||||
|
||||
|
@ -1420,6 +1420,9 @@ dmu_assign_arcbuf(dmu_buf_t *handle, uint64_t offset, arc_buf_t *buf,
|
||||
*/
|
||||
if (offset == db->db.db_offset && blksz == db->db.db_size &&
|
||||
DBUF_GET_BUFC_TYPE(db) == ARC_BUFC_DATA) {
|
||||
#ifdef _KERNEL
|
||||
curthread->td_ru.ru_oublock++;
|
||||
#endif
|
||||
dbuf_assign_arcbuf(db, buf, tx);
|
||||
dbuf_rele(db, FTAG);
|
||||
} else {
|
||||
|
@ -1410,6 +1410,15 @@ dev/ex/if_ex.c optional ex
|
||||
dev/ex/if_ex_isa.c optional ex isa
|
||||
dev/ex/if_ex_pccard.c optional ex pccard
|
||||
dev/exca/exca.c optional cbb
|
||||
dev/extres/clk/clk.c optional ext_resources clk
|
||||
dev/extres/clk/clkdev_if.m optional ext_resources clk
|
||||
dev/extres/clk/clknode_if.m optional ext_resources clk
|
||||
dev/extres/clk/clk_div.c optional ext_resources clk
|
||||
dev/extres/clk/clk_fixed.c optional ext_resources clk
|
||||
dev/extres/clk/clk_gate.c optional ext_resources clk
|
||||
dev/extres/clk/clk_mux.c optional ext_resources clk
|
||||
dev/extres/hwreset/hwreset.c optional ext_resources hwreset
|
||||
dev/extres/hwreset/hwreset_if.m optional ext_resources hwreset
|
||||
dev/fatm/if_fatm.c optional fatm pci
|
||||
dev/fb/fbd.c optional fbd | vt
|
||||
dev/fb/fb_if.m standard
|
||||
@ -1419,7 +1428,7 @@ dev/fdt/fdt_clock_if.m optional fdt fdt_clock
|
||||
dev/fdt/fdt_common.c optional fdt
|
||||
dev/fdt/fdt_pinctrl.c optional fdt fdt_pinctrl
|
||||
dev/fdt/fdt_pinctrl_if.m optional fdt fdt_pinctrl
|
||||
dev/fdt/fdt_slicer.c optional fdt cfi | fdt nand
|
||||
dev/fdt/fdt_slicer.c optional fdt cfi | fdt nand | fdt mx25l
|
||||
dev/fdt/fdt_static_dtb.S optional fdt fdt_dtb_static \
|
||||
dependency "$S/boot/fdt/dts/${MACHINE}/${FDT_DTS_FILE}"
|
||||
dev/fdt/simplebus.c optional fdt
|
||||
@ -3010,7 +3019,7 @@ geom/geom_disk.c standard
|
||||
geom/geom_dump.c standard
|
||||
geom/geom_event.c standard
|
||||
geom/geom_fox.c optional geom_fox
|
||||
geom/geom_flashmap.c optional fdt cfi | fdt nand
|
||||
geom/geom_flashmap.c optional fdt cfi | fdt nand | fdt mx25l
|
||||
geom/geom_io.c standard
|
||||
geom/geom_kern.c standard
|
||||
geom/geom_map.c optional geom_map
|
||||
|
@ -29,6 +29,7 @@ arm/arm/cpu_asm-v6.S optional armv6
|
||||
arm/arm/db_disasm.c optional ddb
|
||||
arm/arm/db_interface.c optional ddb
|
||||
arm/arm/db_trace.c optional ddb
|
||||
arm/arm/debug_monitor.c optional ddb armv6
|
||||
arm/arm/devmap.c standard
|
||||
arm/arm/disassem.c optional ddb
|
||||
arm/arm/dump_machdep.c standard
|
||||
|
@ -90,6 +90,7 @@ COMPAT_LINUXKPI opt_compat.h
|
||||
COMPILING_LINT opt_global.h
|
||||
CY_PCI_FASTINTR
|
||||
DEADLKRES opt_watchdog.h
|
||||
EXT_RESOURCES opt_global.h
|
||||
DIRECTIO
|
||||
FILEMON opt_dontuse.h
|
||||
FFCLOCK
|
||||
|
@ -174,4 +174,5 @@ static inline void remove_handle(struct iwch_dev *rhp, struct idr *idr, u32 id)
|
||||
}
|
||||
|
||||
void iwch_ev_dispatch(struct iwch_dev *, struct mbuf *);
|
||||
void process_newconn(struct iw_cm_id *parent_cm_id, struct socket *child_so);
|
||||
#endif
|
||||
|
@ -260,7 +260,6 @@ alloc_ep(int size, int flags)
|
||||
void __free_ep(struct iwch_ep_common *epc)
|
||||
{
|
||||
CTR3(KTR_IW_CXGB, "%s ep %p state %s", __FUNCTION__, epc, states[state_read(epc)]);
|
||||
KASSERT(!epc->so, ("%s warning ep->so %p \n", __FUNCTION__, epc->so));
|
||||
KASSERT(!epc->entry.tqe_prev, ("%s epc %p still on req list!\n", __FUNCTION__, epc));
|
||||
free(epc, M_DEVBUF);
|
||||
}
|
||||
@ -1361,7 +1360,7 @@ iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
|
||||
}
|
||||
|
||||
int
|
||||
iwch_create_listen(struct iw_cm_id *cm_id, int backlog)
|
||||
iwch_create_listen_ep(struct iw_cm_id *cm_id, int backlog)
|
||||
{
|
||||
int err = 0;
|
||||
struct iwch_listen_ep *ep;
|
||||
@ -1381,35 +1380,22 @@ iwch_create_listen(struct iw_cm_id *cm_id, int backlog)
|
||||
state_set(&ep->com, LISTEN);
|
||||
|
||||
ep->com.so = cm_id->so;
|
||||
err = init_sock(&ep->com);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
err = solisten(ep->com.so, ep->backlog, ep->com.thread);
|
||||
if (!err) {
|
||||
cm_id->provider_data = ep;
|
||||
goto out;
|
||||
}
|
||||
close_socket(&ep->com, 0);
|
||||
fail:
|
||||
cm_id->rem_ref(cm_id);
|
||||
put_ep(&ep->com);
|
||||
cm_id->provider_data = ep;
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
iwch_destroy_listen(struct iw_cm_id *cm_id)
|
||||
void
|
||||
iwch_destroy_listen_ep(struct iw_cm_id *cm_id)
|
||||
{
|
||||
struct iwch_listen_ep *ep = to_listen_ep(cm_id);
|
||||
|
||||
CTR2(KTR_IW_CXGB, "%s ep %p", __FUNCTION__, ep);
|
||||
|
||||
state_set(&ep->com, DEAD);
|
||||
close_socket(&ep->com, 0);
|
||||
cm_id->rem_ref(cm_id);
|
||||
put_ep(&ep->com);
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
@ -1526,54 +1512,32 @@ process_connected(struct iwch_ep *ep)
|
||||
}
|
||||
}
|
||||
|
||||
static struct socket *
|
||||
dequeue_socket(struct socket *head, struct sockaddr_in **remote, struct iwch_ep *child_ep)
|
||||
void
|
||||
process_newconn(struct iw_cm_id *parent_cm_id, struct socket *child_so)
|
||||
{
|
||||
struct socket *so;
|
||||
|
||||
ACCEPT_LOCK();
|
||||
so = TAILQ_FIRST(&head->so_comp);
|
||||
if (!so) {
|
||||
ACCEPT_UNLOCK();
|
||||
return NULL;
|
||||
}
|
||||
TAILQ_REMOVE(&head->so_comp, so, so_list);
|
||||
head->so_qlen--;
|
||||
SOCK_LOCK(so);
|
||||
so->so_qstate &= ~SQ_COMP;
|
||||
so->so_head = NULL;
|
||||
soref(so);
|
||||
soupcall_set(so, SO_RCV, iwch_so_upcall, child_ep);
|
||||
so->so_state |= SS_NBIO;
|
||||
PANIC_IF(!(so->so_state & SS_ISCONNECTED));
|
||||
PANIC_IF(so->so_error);
|
||||
SOCK_UNLOCK(so);
|
||||
ACCEPT_UNLOCK();
|
||||
soaccept(so, (struct sockaddr **)remote);
|
||||
return so;
|
||||
}
|
||||
|
||||
static void
|
||||
process_newconn(struct iwch_ep *parent_ep)
|
||||
{
|
||||
struct socket *child_so;
|
||||
struct iwch_ep *child_ep;
|
||||
struct sockaddr_in *local;
|
||||
struct sockaddr_in *remote;
|
||||
struct iwch_ep *parent_ep = parent_cm_id->provider_data;
|
||||
|
||||
CTR3(KTR_IW_CXGB, "%s parent ep %p so %p", __FUNCTION__, parent_ep, parent_ep->com.so);
|
||||
if (!child_so) {
|
||||
log(LOG_ERR, "%s - invalid child socket!\n", __func__);
|
||||
return;
|
||||
}
|
||||
child_ep = alloc_ep(sizeof(*child_ep), M_NOWAIT);
|
||||
if (!child_ep) {
|
||||
log(LOG_ERR, "%s - failed to allocate ep entry!\n",
|
||||
__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
child_so = dequeue_socket(parent_ep->com.so, &remote, child_ep);
|
||||
if (!child_so) {
|
||||
log(LOG_ERR, "%s - failed to dequeue child socket!\n",
|
||||
__FUNCTION__);
|
||||
__free_ep(&child_ep->com);
|
||||
return;
|
||||
}
|
||||
SOCKBUF_LOCK(&child_so->so_rcv);
|
||||
soupcall_set(child_so, SO_RCV, iwch_so_upcall, child_ep);
|
||||
SOCKBUF_UNLOCK(&child_so->so_rcv);
|
||||
|
||||
in_getsockaddr(child_so, (struct sockaddr **)&local);
|
||||
in_getpeeraddr(child_so, (struct sockaddr **)&remote);
|
||||
|
||||
CTR3(KTR_IW_CXGB, "%s remote addr %s port %d", __FUNCTION__,
|
||||
inet_ntoa(remote->sin_addr), ntohs(remote->sin_port));
|
||||
child_ep->com.tdev = parent_ep->com.tdev;
|
||||
@ -1590,9 +1554,9 @@ process_newconn(struct iwch_ep *parent_ep)
|
||||
child_ep->com.thread = parent_ep->com.thread;
|
||||
child_ep->parent_ep = parent_ep;
|
||||
|
||||
free(local, M_SONAME);
|
||||
free(remote, M_SONAME);
|
||||
get_ep(&parent_ep->com);
|
||||
child_ep->parent_ep = parent_ep;
|
||||
callout_init(&child_ep->timer, 1);
|
||||
state_set(&child_ep->com, MPA_REQ_WAIT);
|
||||
start_ep_timer(child_ep);
|
||||
@ -1630,7 +1594,10 @@ process_socket_event(struct iwch_ep *ep)
|
||||
}
|
||||
|
||||
if (state == LISTEN) {
|
||||
process_newconn(ep);
|
||||
/* socket listening events are handled at IWCM */
|
||||
CTR3(KTR_IW_CXGB, "%s Invalid ep state:%u, ep:%p", __func__,
|
||||
ep->com.state, ep);
|
||||
BUG();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -231,8 +231,8 @@ iwch_wakeup(struct cv *cv, struct mtx *lock, int *rpl_done)
|
||||
/* CM prototypes */
|
||||
|
||||
int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param);
|
||||
int iwch_create_listen(struct iw_cm_id *cm_id, int backlog);
|
||||
int iwch_destroy_listen(struct iw_cm_id *cm_id);
|
||||
int iwch_create_listen_ep(struct iw_cm_id *cm_id, int backlog);
|
||||
void iwch_destroy_listen_ep(struct iw_cm_id *cm_id);
|
||||
int iwch_reject_cr(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len);
|
||||
int iwch_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param);
|
||||
int iwch_ep_disconnect(struct iwch_ep *ep, int abrupt, int flags);
|
||||
|
@ -1140,8 +1140,9 @@ int iwch_register_device(struct iwch_dev *dev)
|
||||
dev->ibdev.iwcm->connect = iwch_connect;
|
||||
dev->ibdev.iwcm->accept = iwch_accept_cr;
|
||||
dev->ibdev.iwcm->reject = iwch_reject_cr;
|
||||
dev->ibdev.iwcm->create_listen = iwch_create_listen;
|
||||
dev->ibdev.iwcm->destroy_listen = iwch_destroy_listen;
|
||||
dev->ibdev.iwcm->create_listen_ep = iwch_create_listen_ep;
|
||||
dev->ibdev.iwcm->destroy_listen_ep = iwch_destroy_listen_ep;
|
||||
dev->ibdev.iwcm->newconn = process_newconn;
|
||||
dev->ibdev.iwcm->add_ref = iwch_qp_add_ref;
|
||||
dev->ibdev.iwcm->rem_ref = iwch_qp_rem_ref;
|
||||
dev->ibdev.iwcm->get_qp = iwch_get_qp;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2013 Chelsio, Inc. All rights reserved.
|
||||
* Copyright (c) 2009-2013, 2016 Chelsio, Inc. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
@ -111,8 +111,6 @@ static void ep_timeout(unsigned long arg);
|
||||
static void init_sock(struct c4iw_ep_common *epc);
|
||||
static void process_data(struct c4iw_ep *ep);
|
||||
static void process_connected(struct c4iw_ep *ep);
|
||||
static struct socket * dequeue_socket(struct socket *head, struct sockaddr_in **remote, struct c4iw_ep *child_ep);
|
||||
static void process_newconn(struct c4iw_ep *parent_ep);
|
||||
static int c4iw_so_upcall(struct socket *so, void *arg, int waitflag);
|
||||
static void process_socket_event(struct c4iw_ep *ep);
|
||||
static void release_ep_resources(struct c4iw_ep *ep);
|
||||
@ -623,40 +621,21 @@ process_connected(struct c4iw_ep *ep)
|
||||
}
|
||||
}
|
||||
|
||||
static struct socket *
|
||||
dequeue_socket(struct socket *head, struct sockaddr_in **remote,
|
||||
struct c4iw_ep *child_ep)
|
||||
void
|
||||
process_newconn(struct iw_cm_id *parent_cm_id, struct socket *child_so)
|
||||
{
|
||||
struct socket *so;
|
||||
|
||||
ACCEPT_LOCK();
|
||||
so = TAILQ_FIRST(&head->so_comp);
|
||||
if (!so) {
|
||||
ACCEPT_UNLOCK();
|
||||
return (NULL);
|
||||
}
|
||||
TAILQ_REMOVE(&head->so_comp, so, so_list);
|
||||
head->so_qlen--;
|
||||
SOCK_LOCK(so);
|
||||
so->so_qstate &= ~SQ_COMP;
|
||||
so->so_head = NULL;
|
||||
soref(so);
|
||||
soupcall_set(so, SO_RCV, c4iw_so_upcall, child_ep);
|
||||
so->so_state |= SS_NBIO;
|
||||
SOCK_UNLOCK(so);
|
||||
ACCEPT_UNLOCK();
|
||||
soaccept(so, (struct sockaddr **)remote);
|
||||
|
||||
return (so);
|
||||
}
|
||||
|
||||
static void
|
||||
process_newconn(struct c4iw_ep *parent_ep)
|
||||
{
|
||||
struct socket *child_so;
|
||||
struct c4iw_ep *child_ep;
|
||||
struct sockaddr_in *local;
|
||||
struct sockaddr_in *remote;
|
||||
struct c4iw_ep *parent_ep = parent_cm_id->provider_data;
|
||||
|
||||
if (!child_so) {
|
||||
CTR4(KTR_IW_CXGBE,
|
||||
"%s: parent so %p, parent ep %p, child so %p, invalid so",
|
||||
__func__, parent_ep->com.so, parent_ep, child_so);
|
||||
log(LOG_ERR, "%s: invalid child socket\n", __func__);
|
||||
return;
|
||||
}
|
||||
child_ep = alloc_ep(sizeof(*child_ep), M_NOWAIT);
|
||||
if (!child_ep) {
|
||||
CTR3(KTR_IW_CXGBE, "%s: parent so %p, parent ep %p, ENOMEM",
|
||||
@ -664,23 +643,18 @@ process_newconn(struct c4iw_ep *parent_ep)
|
||||
log(LOG_ERR, "%s: failed to allocate ep entry\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
child_so = dequeue_socket(parent_ep->com.so, &remote, child_ep);
|
||||
if (!child_so) {
|
||||
CTR4(KTR_IW_CXGBE,
|
||||
"%s: parent so %p, parent ep %p, child ep %p, dequeue err",
|
||||
__func__, parent_ep->com.so, parent_ep, child_ep);
|
||||
log(LOG_ERR, "%s: failed to dequeue child socket\n", __func__);
|
||||
__free_ep(&child_ep->com);
|
||||
return;
|
||||
|
||||
}
|
||||
SOCKBUF_LOCK(&child_so->so_rcv);
|
||||
soupcall_set(child_so, SO_RCV, c4iw_so_upcall, child_ep);
|
||||
SOCKBUF_UNLOCK(&child_so->so_rcv);
|
||||
|
||||
CTR5(KTR_IW_CXGBE,
|
||||
"%s: parent so %p, parent ep %p, child so %p, child ep %p",
|
||||
__func__, parent_ep->com.so, parent_ep, child_so, child_ep);
|
||||
|
||||
child_ep->com.local_addr = parent_ep->com.local_addr;
|
||||
in_getsockaddr(child_so, (struct sockaddr **)&local);
|
||||
in_getpeeraddr(child_so, (struct sockaddr **)&remote);
|
||||
|
||||
child_ep->com.local_addr = *local;
|
||||
child_ep->com.remote_addr = *remote;
|
||||
child_ep->com.dev = parent_ep->com.dev;
|
||||
child_ep->com.so = child_so;
|
||||
@ -688,15 +662,17 @@ process_newconn(struct c4iw_ep *parent_ep)
|
||||
child_ep->com.thread = parent_ep->com.thread;
|
||||
child_ep->parent_ep = parent_ep;
|
||||
|
||||
free(local, M_SONAME);
|
||||
free(remote, M_SONAME);
|
||||
|
||||
c4iw_get_ep(&parent_ep->com);
|
||||
child_ep->parent_ep = parent_ep;
|
||||
init_timer(&child_ep->timer);
|
||||
state_set(&child_ep->com, MPA_REQ_WAIT);
|
||||
START_EP_TIMER(child_ep);
|
||||
|
||||
/* maybe the request has already been queued up on the socket... */
|
||||
process_mpa_request(child_ep);
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -738,7 +714,10 @@ process_socket_event(struct c4iw_ep *ep)
|
||||
}
|
||||
|
||||
if (state == LISTEN) {
|
||||
process_newconn(ep);
|
||||
/* socket listening events are handled at IWCM */
|
||||
CTR3(KTR_IW_CXGBE, "%s Invalid ep state:%u, ep:%p", __func__,
|
||||
ep->com.state, ep);
|
||||
BUG();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -919,7 +898,6 @@ void _c4iw_free_ep(struct kref *kref)
|
||||
|
||||
ep = container_of(kref, struct c4iw_ep, com.kref);
|
||||
epc = &ep->com;
|
||||
KASSERT(!epc->so, ("%s ep->so %p", __func__, epc->so));
|
||||
KASSERT(!epc->entry.tqe_prev, ("%s epc %p still on req list",
|
||||
__func__, epc));
|
||||
kfree(ep);
|
||||
@ -2126,10 +2104,10 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
|
||||
}
|
||||
|
||||
/*
|
||||
* iwcm->create_listen. Returns -errno on failure.
|
||||
* iwcm->create_listen_ep. Returns -errno on failure.
|
||||
*/
|
||||
int
|
||||
c4iw_create_listen(struct iw_cm_id *cm_id, int backlog)
|
||||
c4iw_create_listen_ep(struct iw_cm_id *cm_id, int backlog)
|
||||
{
|
||||
int rc;
|
||||
struct c4iw_dev *dev = to_c4iw_dev(cm_id->device);
|
||||
@ -2154,17 +2132,6 @@ c4iw_create_listen(struct iw_cm_id *cm_id, int backlog)
|
||||
ep->com.thread = curthread;
|
||||
state_set(&ep->com, LISTEN);
|
||||
ep->com.so = so;
|
||||
init_sock(&ep->com);
|
||||
|
||||
rc = solisten(so, ep->backlog, ep->com.thread);
|
||||
if (rc != 0) {
|
||||
log(LOG_ERR, "%s: failed to start listener: %d\n", __func__,
|
||||
rc);
|
||||
close_socket(&ep->com, 0);
|
||||
cm_id->rem_ref(cm_id);
|
||||
c4iw_put_ep(&ep->com);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
cm_id->provider_data = ep;
|
||||
return (0);
|
||||
@ -2174,21 +2141,19 @@ c4iw_create_listen(struct iw_cm_id *cm_id, int backlog)
|
||||
return (-rc);
|
||||
}
|
||||
|
||||
int
|
||||
c4iw_destroy_listen(struct iw_cm_id *cm_id)
|
||||
void
|
||||
c4iw_destroy_listen_ep(struct iw_cm_id *cm_id)
|
||||
{
|
||||
int rc;
|
||||
struct c4iw_listen_ep *ep = to_listen_ep(cm_id);
|
||||
|
||||
CTR4(KTR_IW_CXGBE, "%s: cm_id %p, so %p, inp %p", __func__, cm_id,
|
||||
cm_id->so, cm_id->so->so_pcb);
|
||||
CTR4(KTR_IW_CXGBE, "%s: cm_id %p, so %p, state %s", __func__, cm_id,
|
||||
cm_id->so, states[ep->com.state]);
|
||||
|
||||
state_set(&ep->com, DEAD);
|
||||
rc = close_socket(&ep->com, 0);
|
||||
cm_id->rem_ref(cm_id);
|
||||
c4iw_put_ep(&ep->com);
|
||||
|
||||
return (rc);
|
||||
return;
|
||||
}
|
||||
|
||||
int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2013 Chelsio, Inc. All rights reserved.
|
||||
* Copyright (c) 2009-2013, 2016 Chelsio, Inc. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
@ -850,8 +850,8 @@ int c4iw_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
|
||||
int c4iw_bind_mw(struct ib_qp *qp, struct ib_mw *mw,
|
||||
struct ib_mw_bind *mw_bind);
|
||||
int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param);
|
||||
int c4iw_create_listen(struct iw_cm_id *cm_id, int backlog);
|
||||
int c4iw_destroy_listen(struct iw_cm_id *cm_id);
|
||||
int c4iw_create_listen_ep(struct iw_cm_id *cm_id, int backlog);
|
||||
void c4iw_destroy_listen_ep(struct iw_cm_id *cm_id);
|
||||
int c4iw_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param);
|
||||
int c4iw_reject_cr(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len);
|
||||
void c4iw_qp_add_ref(struct ib_qp *qp);
|
||||
@ -914,6 +914,8 @@ u32 c4iw_get_qpid(struct c4iw_rdev *rdev, struct c4iw_dev_ucontext *uctx);
|
||||
void c4iw_put_qpid(struct c4iw_rdev *rdev, u32 qid,
|
||||
struct c4iw_dev_ucontext *uctx);
|
||||
void c4iw_ev_dispatch(struct c4iw_dev *dev, struct t4_cqe *err_cqe);
|
||||
void process_newconn(struct iw_cm_id *parent_cm_id,
|
||||
struct socket *child_so);
|
||||
|
||||
extern struct cxgb4_client t4c_client;
|
||||
extern c4iw_handler_func c4iw_handlers[NUM_CPL_CMDS];
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2013 Chelsio, Inc. All rights reserved.
|
||||
* Copyright (c) 2009-2013, 2016 Chelsio, Inc. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
@ -474,8 +474,9 @@ c4iw_register_device(struct c4iw_dev *dev)
|
||||
iwcm->connect = c4iw_connect;
|
||||
iwcm->accept = c4iw_accept_cr;
|
||||
iwcm->reject = c4iw_reject_cr;
|
||||
iwcm->create_listen = c4iw_create_listen;
|
||||
iwcm->destroy_listen = c4iw_destroy_listen;
|
||||
iwcm->create_listen_ep = c4iw_create_listen_ep;
|
||||
iwcm->destroy_listen_ep = c4iw_destroy_listen_ep;
|
||||
iwcm->newconn = process_newconn;
|
||||
iwcm->add_ref = c4iw_qp_add_ref;
|
||||
iwcm->rem_ref = c4iw_qp_rem_ref;
|
||||
iwcm->get_qp = c4iw_get_qp;
|
||||
|
1261
sys/dev/extres/clk/clk.c
Normal file
1261
sys/dev/extres/clk/clk.c
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user